@zipbul/gildash 0.6.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.ko.md CHANGED
@@ -49,7 +49,7 @@ gildash는 TypeScript 코드베이스를 로컬 SQLite 데이터베이스에 인
49
49
  bun add @zipbul/gildash
50
50
  ```
51
51
 
52
- > **피어 의존성** — [`@zipbul/result`](https://www.npmjs.com/package/@zipbul/result) 필요합니다. 모든 public 메서드는 `Result<T, GildashError>`를 반환합니다.
52
+ > **선택적 피어 의존성** — `typescript` (>=5.0.0) `semantic: true` 사용 시에만 필요합니다.
53
53
 
54
54
  <br>
55
55
 
@@ -57,7 +57,6 @@ bun add @zipbul/gildash
57
57
 
58
58
  ```ts
59
59
  import { Gildash } from '@zipbul/gildash';
60
- import { isErr } from '@zipbul/result';
61
60
 
62
61
  // 1. 열기 — 최초 실행 시 전체 .ts 파일 인덱싱, 이후 파일 변경 감시
63
62
  const ledger = await Gildash.open({
@@ -65,10 +64,8 @@ const ledger = await Gildash.open({
65
64
  });
66
65
 
67
66
  // 2. 검색 — 이름으로 심볼 찾기
68
- const result = ledger.searchSymbols({ text: 'UserService', kind: 'class' });
69
- if (!isErr(result)) {
70
- result.forEach(s => console.log(`${s.name} → ${s.filePath}`));
71
- }
67
+ const symbols = ledger.searchSymbols({ text: 'UserService', kind: 'class' });
68
+ symbols.forEach(s => console.log(`${s.name} → ${s.filePath}`));
72
69
 
73
70
  // 3. 종료 — 리소스 해제
74
71
  await ledger.close();
@@ -201,16 +198,18 @@ await ledger.close({ cleanup: true }); // DB 파일까지 삭제
201
198
 
202
199
  ## ❌ 에러 처리
203
200
 
204
- 모든 public 메서드는 [`@zipbul/result`](https://www.npmjs.com/package/@zipbul/result)의 `Result<T, GildashError>`를 반환합니다. `isErr()`로 에러를 분기합니다:
201
+ public 메서드는 값을 직접 반환하고, 실패 시 `GildashError`를 throw합니다. `instanceof`로 분기합니다:
205
202
 
206
203
  ```ts
207
- import { isErr } from '@zipbul/result';
208
-
209
- const result = ledger.searchSymbols({ text: 'foo' });
210
- if (isErr(result)) {
211
- console.error(result.data.type, result.data.message);
212
- } else {
213
- console.log(`${result.length}개 심볼 발견`);
204
+ import { Gildash, GildashError } from '@zipbul/gildash';
205
+
206
+ try {
207
+ const symbols = ledger.searchSymbols({ text: 'foo' });
208
+ console.log(`${symbols.length}개 심볼 발견`);
209
+ } catch (e) {
210
+ if (e instanceof GildashError) {
211
+ console.error(`[${e.type}] ${e.message}`);
212
+ }
214
213
  }
215
214
  ```
216
215
 
@@ -230,9 +229,9 @@ if (isErr(result)) {
230
229
  | `watchMode` | `boolean` | `true` | `false`이면 파일 워처 비활성화 (스캔 전용 모드) |
231
230
  | `semantic` | `boolean` | `false` | tsc TypeChecker 기반 시맨틱 분석 활성화 |
232
231
 
233
- **반환**: `Promise<Gildash>` (`Result`로 래핑됨)
232
+ **반환**: `Promise<Gildash>`. 실패 시 `GildashError`를 throw합니다.
234
233
 
235
- > **참고:** `semantic: true`는 프로젝트 루트에 `tsconfig.json`이 필요합니다. 없으면 `Gildash.open()`이 `GildashError`를 반환합니다.
234
+ > **참고:** `semantic: true`는 프로젝트 루트에 `tsconfig.json`이 필요합니다. 없으면 `Gildash.open()`이 `GildashError`를 throw합니다.
236
235
 
237
236
  <br>
238
237
 
@@ -242,34 +241,34 @@ if (isErr(result)) {
242
241
 
243
242
  | 메서드 | 반환 타입 | 설명 |
244
243
  |--------|-----------|------|
245
- | `searchSymbols(query)` | `Result<SymbolSearchResult[]>` | FTS5 전문검색 + exact/regex/decorator 필터 |
246
- | `searchRelations(query)` | `Result<StoredCodeRelation[]>` | 파일, 심볼, 관계 유형 필터 |
247
- | `searchAllSymbols(query)` | `Result<SymbolSearchResult[]>` | 전체 프로젝트 심볼 검색 |
248
- | `searchAllRelations(query)` | `Result<StoredCodeRelation[]>` | 전체 프로젝트 관계 검색 |
249
- | `listIndexedFiles(project?)` | `Result<FileRecord[]>` | 인덱싱된 파일 목록 |
250
- | `getSymbolsByFile(filePath)` | `Result<SymbolSearchResult[]>` | 단일 파일의 모든 심볼 |
244
+ | `searchSymbols(query)` | `SymbolSearchResult[]` | FTS5 전문검색 + exact/regex/decorator 필터 |
245
+ | `searchRelations(query)` | `StoredCodeRelation[]` | 파일, 심볼, 관계 유형 필터 |
246
+ | `searchAllSymbols(query)` | `SymbolSearchResult[]` | 전체 프로젝트 심볼 검색 |
247
+ | `searchAllRelations(query)` | `StoredCodeRelation[]` | 전체 프로젝트 관계 검색 |
248
+ | `listIndexedFiles(project?)` | `FileRecord[]` | 인덱싱된 파일 목록 |
249
+ | `getSymbolsByFile(filePath)` | `SymbolSearchResult[]` | 단일 파일의 모든 심볼 |
251
250
 
252
251
  ### 의존성 그래프
253
252
 
254
253
  | 메서드 | 반환 타입 | 설명 |
255
254
  |--------|-----------|------|
256
- | `getDependencies(filePath)` | `Result<string[]>` | `filePath`가 import하는 파일 목록 |
257
- | `getDependents(filePath)` | `Result<string[]>` | `filePath`를 import하는 파일 목록 |
258
- | `getAffected(changedFiles)` | `Promise<Result<string[]>>` | 전이적 영향 범위 |
259
- | `hasCycle(project?)` | `Promise<Result<boolean>>` | 순환 의존성 감지 |
260
- | `getCyclePaths(project?, opts?)` | `Promise<Result<string[][]>>` | 모든 순환 경로 (Tarjan SCC + Johnson's). `opts.maxCycles`로 개수 제한 가능. |
261
- | `getImportGraph(project?)` | `Promise<Result<Map>>` | 전체 인접 리스트 |
262
- | `getTransitiveDependencies(filePath)` | `Promise<Result<string[]>>` | 전방 전이적 BFS |
255
+ | `getDependencies(filePath)` | `string[]` | `filePath`가 import하는 파일 목록 |
256
+ | `getDependents(filePath)` | `string[]` | `filePath`를 import하는 파일 목록 |
257
+ | `getAffected(changedFiles)` | `Promise<string[]>` | 전이적 영향 범위 |
258
+ | `hasCycle(project?)` | `Promise<boolean>` | 순환 의존성 감지 |
259
+ | `getCyclePaths(project?, opts?)` | `Promise<string[][]>` | 모든 순환 경로 (Tarjan SCC + Johnson's). `opts.maxCycles`로 개수 제한 가능. |
260
+ | `getImportGraph(project?)` | `Promise<Map>` | 전체 인접 리스트 |
261
+ | `getTransitiveDependencies(filePath)` | `Promise<string[]>` | 전방 전이적 BFS |
263
262
 
264
263
  ### 분석
265
264
 
266
265
  | 메서드 | 반환 타입 | 설명 |
267
266
  |--------|-----------|------|
268
- | `getFullSymbol(name, filePath)` | `Result<FullSymbol>` | 멤버, jsDoc, 데코레이터, 타입 정보 |
269
- | `getFileStats(filePath)` | `Result<FileStats>` | 라인 수, 심볼 수, 파일 크기 |
270
- | `getFanMetrics(filePath)` | `Promise<Result<FanMetrics>>` | fan-in/fan-out 결합도 |
271
- | `getModuleInterface(filePath)` | `Result<ModuleInterface>` | 공개 export와 메타데이터 |
272
- | `getInternalRelations(filePath)` | `Result<StoredCodeRelation[]>` | 파일 내부 관계 |
267
+ | `getFullSymbol(name, filePath)` | `FullSymbol \| null` | 멤버, jsDoc, 데코레이터, 타입 정보 |
268
+ | `getFileStats(filePath)` | `FileStats` | 라인 수, 심볼 수, 파일 크기 |
269
+ | `getFanMetrics(filePath)` | `Promise<FanMetrics>` | fan-in/fan-out 결합도 |
270
+ | `getModuleInterface(filePath)` | `ModuleInterface` | 공개 export와 메타데이터 |
271
+ | `getInternalRelations(filePath)` | `StoredCodeRelation[]` | 파일 내부 관계 |
273
272
  | `diffSymbols(before, after)` | `SymbolDiff` | 스냅샷 diff (추가/삭제/수정) |
274
273
 
275
274
  ### 시맨틱 (opt-in)
@@ -278,10 +277,10 @@ if (isErr(result)) {
278
277
 
279
278
  | 메서드 | 반환 타입 | 설명 |
280
279
  |--------|-----------|------|
281
- | `getResolvedType(name, filePath)` | `Result<ResolvedType \| null>` | tsc TypeChecker로 resolved type 조회 |
282
- | `getSemanticReferences(name, filePath)` | `Result<SemanticReference[]>` | 심볼의 모든 참조 위치 |
283
- | `getImplementations(name, filePath)` | `Result<Implementation[]>` | 인터페이스/추상 클래스 구현체 |
284
- | `getSemanticModuleInterface(filePath)` | `Result<SemanticModuleInterface>` | 모듈 export 목록 + resolved type |
280
+ | `getResolvedType(name, filePath)` | `ResolvedType \| null` | tsc TypeChecker로 resolved type 조회 |
281
+ | `getSemanticReferences(name, filePath)` | `SemanticReference[]` | 심볼의 모든 참조 위치 |
282
+ | `getImplementations(name, filePath)` | `Implementation[]` | 인터페이스/추상 클래스 구현체 |
283
+ | `getSemanticModuleInterface(filePath)` | `SemanticModuleInterface` | 모듈 export 목록 + resolved type |
285
284
 
286
285
  `getFullSymbol()`은 semantic 활성 시 자동으로 `resolvedType` 필드를 보강합니다.
287
286
  `searchSymbols({ resolvedType })`로 resolved type 문자열 기반 필터링이 가능합니다.
@@ -290,25 +289,25 @@ if (isErr(result)) {
290
289
 
291
290
  | 메서드 | 반환 타입 | 설명 |
292
291
  |--------|-----------|------|
293
- | `findPattern(pattern, opts?)` | `Promise<Result<PatternMatch[]>>` | AST 구조적 검색 (ast-grep) |
294
- | `resolveSymbol(name, filePath)` | `Result<ResolvedSymbol>` | re-export 체인을 따라 원본 추적 |
295
- | `getHeritageChain(name, filePath)` | `Promise<Result<HeritageNode>>` | extends/implements 트리 |
296
- | `batchParse(filePaths, opts?)` | `Promise<Result<Map>>` | 다중 파일 동시 파싱. `opts`: oxc-parser `ParserOptions`. |
292
+ | `findPattern(pattern, opts?)` | `Promise<PatternMatch[]>` | AST 구조적 검색 (ast-grep) |
293
+ | `resolveSymbol(name, filePath)` | `ResolvedSymbol` | re-export 체인을 따라 원본 추적 |
294
+ | `getHeritageChain(name, filePath)` | `Promise<HeritageNode>` | extends/implements 트리 |
295
+ | `batchParse(filePaths, opts?)` | `Promise<Map>` | 다중 파일 동시 파싱. `opts`: oxc-parser `ParserOptions`. |
297
296
 
298
297
  ### 라이프사이클 & 저수준
299
298
 
300
299
  | 메서드 | 반환 타입 | 설명 |
301
300
  |--------|-----------|------|
302
- | `reindex()` | `Promise<Result<IndexResult>>` | 강제 전체 재인덱싱 (owner만 가능) |
301
+ | `reindex()` | `Promise<IndexResult>` | 강제 전체 재인덱싱 (owner만 가능) |
303
302
  | `onIndexed(callback)` | `() => void` | 인덱싱 완료 이벤트 구독 |
304
- | `parseSource(filePath, src, opts?)` | `Result<ParsedFile>` | 단일 파일 파싱 & 캐시. `opts`: oxc-parser `ParserOptions`. |
305
- | `extractSymbols(parsed)` | `Result<ExtractedSymbol[]>` | 파싱된 AST에서 심볼 추출 |
306
- | `extractRelations(parsed)` | `Result<CodeRelation[]>` | 파싱된 AST에서 관계 추출 |
303
+ | `parseSource(filePath, src, opts?)` | `ParsedFile` | 단일 파일 파싱 & 캐시. `opts`: oxc-parser `ParserOptions`. |
304
+ | `extractSymbols(parsed)` | `ExtractedSymbol[]` | 파싱된 AST에서 심볼 추출 |
305
+ | `extractRelations(parsed)` | `CodeRelation[]` | 파싱된 AST에서 관계 추출 |
307
306
  | `getParsedAst(filePath)` | `ParsedFile \| undefined` | 캐시된 AST 조회 (읽기 전용) |
308
- | `getFileInfo(filePath)` | `Result<FileRecord \| null>` | 파일 메타데이터 (해시, mtime, 크기) |
309
- | `getStats(project?)` | `Result<SymbolStats>` | 심볼/파일 통계 |
307
+ | `getFileInfo(filePath)` | `FileRecord \| null` | 파일 메타데이터 (해시, mtime, 크기) |
308
+ | `getStats(project?)` | `SymbolStats` | 심볼/파일 통계 |
310
309
  | `projects` | `ProjectBoundary[]` | 탐지된 프로젝트 경계 |
311
- | `close(opts?)` | `Promise<Result<void>>` | 종료 (`{ cleanup: true }`로 DB 삭제 가능) |
310
+ | `close(opts?)` | `Promise<void>` | 종료 (`{ cleanup: true }`로 DB 삭제 가능) |
312
311
 
313
312
  <br>
314
313
 
@@ -362,10 +361,10 @@ interface IndexResult {
362
361
  };
363
362
  }
364
363
 
365
- interface GildashError {
366
- type: GildashErrorType;
367
- message: string;
368
- cause?: unknown;
364
+ class GildashError extends Error {
365
+ readonly type: GildashErrorType;
366
+ readonly message: string;
367
+ readonly cause?: unknown; // Error에서 상속
369
368
  }
370
369
  ```
371
370
 
@@ -412,7 +411,26 @@ Gildash (파사드)
412
411
 
413
412
  <br>
414
413
 
415
- ## ⬆️ 0.5.0에서 업그레이드
414
+ ## ⬆️ 업그레이드
415
+
416
+ ### 0.5.x → 0.6.0
417
+
418
+ **Breaking:** `@zipbul/result`가 더 이상 public API의 일부가 아닙니다. 모든 메서드가 값을 직접 반환하고, 실패 시 `GildashError`를 throw합니다.
419
+
420
+ ```diff
421
+ - import { isErr } from '@zipbul/result';
422
+ - const result = ledger.searchSymbols({ text: 'foo' });
423
+ - if (isErr(result)) { console.error(result.data.message); }
424
+ - else { console.log(result); }
425
+ + const symbols = ledger.searchSymbols({ text: 'foo' }); // 실패 시 GildashError throw
426
+ ```
427
+
428
+ - `@zipbul/result`를 의존성에서 제거하세요 (더 이상 피어 의존성이 아닙니다)
429
+ - `isErr()` 체크를 `try/catch` + `instanceof GildashError`로 교체하세요
430
+ - `getFullSymbol()`, `getFileInfo()`, `getResolvedType()`은 찾지 못하면 에러 대신 `null`을 반환합니다
431
+ - `resolveSymbol()`은 순환 re-export 시 throw 대신 `{ circular: true }`를 반환합니다
432
+
433
+ ### 0.4.x → 0.5.0
416
434
 
417
435
  데이터베이스 디렉토리가 `.zipbul/`에서 `.gildash/`로 변경되었습니다. 데이터베이스는 `<projectRoot>/.gildash/gildash.db`에 저장됩니다.
418
436
 
package/README.md CHANGED
@@ -50,7 +50,7 @@ gildash indexes your TypeScript codebase into a local SQLite database, then lets
50
50
  bun add @zipbul/gildash
51
51
  ```
52
52
 
53
- > **Peer dependency** — [`@zipbul/result`](https://www.npmjs.com/package/@zipbul/result) is required. All public methods return `Result<T, GildashError>`.
53
+ > **Optional peer** — `typescript` (>=5.0.0) is needed only when using `semantic: true`.
54
54
 
55
55
  <br>
56
56
 
@@ -58,7 +58,6 @@ bun add @zipbul/gildash
58
58
 
59
59
  ```ts
60
60
  import { Gildash } from '@zipbul/gildash';
61
- import { isErr } from '@zipbul/result';
62
61
 
63
62
  // 1. Open — indexes every .ts file on first run, then watches for changes
64
63
  const ledger = await Gildash.open({
@@ -66,10 +65,8 @@ const ledger = await Gildash.open({
66
65
  });
67
66
 
68
67
  // 2. Search — find symbols by name
69
- const result = ledger.searchSymbols({ text: 'UserService', kind: 'class' });
70
- if (!isErr(result)) {
71
- result.forEach(s => console.log(`${s.name} → ${s.filePath}`));
72
- }
68
+ const symbols = ledger.searchSymbols({ text: 'UserService', kind: 'class' });
69
+ symbols.forEach(s => console.log(`${s.name} → ${s.filePath}`));
73
70
 
74
71
  // 3. Close — release resources
75
72
  await ledger.close();
@@ -202,16 +199,18 @@ await ledger.close({ cleanup: true }); // delete DB files after use
202
199
 
203
200
  ## ❌ Error Handling
204
201
 
205
- Every public method returns `Result<T, GildashError>` from [`@zipbul/result`](https://www.npmjs.com/package/@zipbul/result). Use `isErr()` to branch:
202
+ Public methods return values directly and throw `GildashError` on failure. Use `instanceof` to branch:
206
203
 
207
204
  ```ts
208
- import { isErr } from '@zipbul/result';
209
-
210
- const result = ledger.searchSymbols({ text: 'foo' });
211
- if (isErr(result)) {
212
- console.error(result.data.type, result.data.message);
213
- } else {
214
- console.log(`Found ${result.length} symbols`);
205
+ import { Gildash, GildashError } from '@zipbul/gildash';
206
+
207
+ try {
208
+ const symbols = ledger.searchSymbols({ text: 'foo' });
209
+ console.log(`Found ${symbols.length} symbols`);
210
+ } catch (e) {
211
+ if (e instanceof GildashError) {
212
+ console.error(`[${e.type}] ${e.message}`);
213
+ }
215
214
  }
216
215
  ```
217
216
 
@@ -231,9 +230,9 @@ if (isErr(result)) {
231
230
  | `watchMode` | `boolean` | `true` | `false` disables the file watcher (scan-only mode) |
232
231
  | `semantic` | `boolean` | `false` | Enable tsc TypeChecker-backed semantic analysis |
233
232
 
234
- Returns `Promise<Gildash>` (wrapped in `Result`).
233
+ Returns `Promise<Gildash>`. Throws `GildashError` on failure.
235
234
 
236
- > **Note:** `semantic: true` requires a `tsconfig.json` in the project root. If not found, `Gildash.open()` returns a `GildashError`.
235
+ > **Note:** `semantic: true` requires a `tsconfig.json` in the project root. If not found, `Gildash.open()` throws a `GildashError`.
237
236
 
238
237
  <br>
239
238
 
@@ -243,34 +242,34 @@ Returns `Promise<Gildash>` (wrapped in `Result`).
243
242
 
244
243
  | Method | Returns | Description |
245
244
  |--------|---------|-------------|
246
- | `searchSymbols(query)` | `Result<SymbolSearchResult[]>` | FTS5 full-text + exact / regex / decorator filters |
247
- | `searchRelations(query)` | `Result<StoredCodeRelation[]>` | Filter by file, symbol, or relation type |
248
- | `searchAllSymbols(query)` | `Result<SymbolSearchResult[]>` | Cross-project symbol search |
249
- | `searchAllRelations(query)` | `Result<StoredCodeRelation[]>` | Cross-project relation search |
250
- | `listIndexedFiles(project?)` | `Result<FileRecord[]>` | All indexed files for a project |
251
- | `getSymbolsByFile(filePath)` | `Result<SymbolSearchResult[]>` | All symbols in a single file |
245
+ | `searchSymbols(query)` | `SymbolSearchResult[]` | FTS5 full-text + exact / regex / decorator filters |
246
+ | `searchRelations(query)` | `StoredCodeRelation[]` | Filter by file, symbol, or relation type |
247
+ | `searchAllSymbols(query)` | `SymbolSearchResult[]` | Cross-project symbol search |
248
+ | `searchAllRelations(query)` | `StoredCodeRelation[]` | Cross-project relation search |
249
+ | `listIndexedFiles(project?)` | `FileRecord[]` | All indexed files for a project |
250
+ | `getSymbolsByFile(filePath)` | `SymbolSearchResult[]` | All symbols in a single file |
252
251
 
253
252
  ### Dependency Graph
254
253
 
255
254
  | Method | Returns | Description |
256
255
  |--------|---------|-------------|
257
- | `getDependencies(filePath)` | `Result<string[]>` | Files imported by `filePath` |
258
- | `getDependents(filePath)` | `Result<string[]>` | Files that import `filePath` |
259
- | `getAffected(changedFiles)` | `Promise<Result<string[]>>` | Transitive impact set |
260
- | `hasCycle(project?)` | `Promise<Result<boolean>>` | Circular dependency check |
261
- | `getCyclePaths(project?, opts?)` | `Promise<Result<string[][]>>` | All cycle paths (Tarjan SCC + Johnson's). `opts.maxCycles` limits results. |
262
- | `getImportGraph(project?)` | `Promise<Result<Map>>` | Full adjacency list |
263
- | `getTransitiveDependencies(filePath)` | `Promise<Result<string[]>>` | Forward transitive BFS |
256
+ | `getDependencies(filePath)` | `string[]` | Files imported by `filePath` |
257
+ | `getDependents(filePath)` | `string[]` | Files that import `filePath` |
258
+ | `getAffected(changedFiles)` | `Promise<string[]>` | Transitive impact set |
259
+ | `hasCycle(project?)` | `Promise<boolean>` | Circular dependency check |
260
+ | `getCyclePaths(project?, opts?)` | `Promise<string[][]>` | All cycle paths (Tarjan SCC + Johnson's). `opts.maxCycles` limits results. |
261
+ | `getImportGraph(project?)` | `Promise<Map>` | Full adjacency list |
262
+ | `getTransitiveDependencies(filePath)` | `Promise<string[]>` | Forward transitive BFS |
264
263
 
265
264
  ### Analysis
266
265
 
267
266
  | Method | Returns | Description |
268
267
  |--------|---------|-------------|
269
- | `getFullSymbol(name, filePath)` | `Result<FullSymbol>` | Members, jsDoc, decorators, type info |
270
- | `getFileStats(filePath)` | `Result<FileStats>` | Line count, symbol count, size |
271
- | `getFanMetrics(filePath)` | `Promise<Result<FanMetrics>>` | Fan-in / fan-out coupling |
272
- | `getModuleInterface(filePath)` | `Result<ModuleInterface>` | Public exports with metadata |
273
- | `getInternalRelations(filePath)` | `Result<StoredCodeRelation[]>` | Intra-file relations |
268
+ | `getFullSymbol(name, filePath)` | `FullSymbol \| null` | Members, jsDoc, decorators, type info |
269
+ | `getFileStats(filePath)` | `FileStats` | Line count, symbol count, size |
270
+ | `getFanMetrics(filePath)` | `Promise<FanMetrics>` | Fan-in / fan-out coupling |
271
+ | `getModuleInterface(filePath)` | `ModuleInterface` | Public exports with metadata |
272
+ | `getInternalRelations(filePath)` | `StoredCodeRelation[]` | Intra-file relations |
274
273
  | `diffSymbols(before, after)` | `SymbolDiff` | Snapshot diff (added / removed / modified) |
275
274
 
276
275
  ### Semantic (opt-in)
@@ -279,10 +278,10 @@ Requires `semantic: true` at open time.
279
278
 
280
279
  | Method | Returns | Description |
281
280
  |--------|---------|-------------|
282
- | `getResolvedType(name, filePath)` | `Result<ResolvedType \| null>` | Resolved type via tsc TypeChecker |
283
- | `getSemanticReferences(name, filePath)` | `Result<SemanticReference[]>` | All references to a symbol |
284
- | `getImplementations(name, filePath)` | `Result<Implementation[]>` | Interface / abstract class implementations |
285
- | `getSemanticModuleInterface(filePath)` | `Result<SemanticModuleInterface>` | Module exports with resolved types |
281
+ | `getResolvedType(name, filePath)` | `ResolvedType \| null` | Resolved type via tsc TypeChecker |
282
+ | `getSemanticReferences(name, filePath)` | `SemanticReference[]` | All references to a symbol |
283
+ | `getImplementations(name, filePath)` | `Implementation[]` | Interface / abstract class implementations |
284
+ | `getSemanticModuleInterface(filePath)` | `SemanticModuleInterface` | Module exports with resolved types |
286
285
 
287
286
  `getFullSymbol()` automatically enriches the result with a `resolvedType` field when semantic is enabled.
288
287
  `searchSymbols({ resolvedType })` filters symbols by their resolved type string.
@@ -291,25 +290,25 @@ Requires `semantic: true` at open time.
291
290
 
292
291
  | Method | Returns | Description |
293
292
  |--------|---------|-------------|
294
- | `findPattern(pattern, opts?)` | `Promise<Result<PatternMatch[]>>` | AST structural search (ast-grep) |
295
- | `resolveSymbol(name, filePath)` | `Result<ResolvedSymbol>` | Follow re-export chain to original |
296
- | `getHeritageChain(name, filePath)` | `Promise<Result<HeritageNode>>` | extends / implements tree |
297
- | `batchParse(filePaths, opts?)` | `Promise<Result<Map>>` | Concurrent multi-file parsing. `opts`: oxc-parser `ParserOptions`. |
293
+ | `findPattern(pattern, opts?)` | `Promise<PatternMatch[]>` | AST structural search (ast-grep) |
294
+ | `resolveSymbol(name, filePath)` | `ResolvedSymbol` | Follow re-export chain to original |
295
+ | `getHeritageChain(name, filePath)` | `Promise<HeritageNode>` | extends / implements tree |
296
+ | `batchParse(filePaths, opts?)` | `Promise<Map>` | Concurrent multi-file parsing. `opts`: oxc-parser `ParserOptions`. |
298
297
 
299
298
  ### Lifecycle & Low-level
300
299
 
301
300
  | Method | Returns | Description |
302
301
  |--------|---------|-------------|
303
- | `reindex()` | `Promise<Result<IndexResult>>` | Force full re-index (owner only) |
302
+ | `reindex()` | `Promise<IndexResult>` | Force full re-index (owner only) |
304
303
  | `onIndexed(callback)` | `() => void` | Subscribe to index-complete events |
305
- | `parseSource(filePath, src, opts?)` | `Result<ParsedFile>` | Parse & cache a single file. `opts`: oxc-parser `ParserOptions`. |
306
- | `extractSymbols(parsed)` | `Result<ExtractedSymbol[]>` | Extract symbols from parsed AST |
307
- | `extractRelations(parsed)` | `Result<CodeRelation[]>` | Extract relations from parsed AST |
304
+ | `parseSource(filePath, src, opts?)` | `ParsedFile` | Parse & cache a single file. `opts`: oxc-parser `ParserOptions`. |
305
+ | `extractSymbols(parsed)` | `ExtractedSymbol[]` | Extract symbols from parsed AST |
306
+ | `extractRelations(parsed)` | `CodeRelation[]` | Extract relations from parsed AST |
308
307
  | `getParsedAst(filePath)` | `ParsedFile \| undefined` | Cached AST lookup (read-only) |
309
- | `getFileInfo(filePath)` | `Result<FileRecord \| null>` | File metadata (hash, mtime, size) |
310
- | `getStats(project?)` | `Result<SymbolStats>` | Symbol / file count statistics |
308
+ | `getFileInfo(filePath)` | `FileRecord \| null` | File metadata (hash, mtime, size) |
309
+ | `getStats(project?)` | `SymbolStats` | Symbol / file count statistics |
311
310
  | `projects` | `ProjectBoundary[]` | Discovered project boundaries |
312
- | `close(opts?)` | `Promise<Result<void>>` | Shutdown (pass `{ cleanup: true }` to delete DB) |
311
+ | `close(opts?)` | `Promise<void>` | Shutdown (pass `{ cleanup: true }` to delete DB) |
313
312
 
314
313
  <br>
315
314
 
@@ -433,6 +432,7 @@ interface ResolvedSymbol {
433
432
  originalName: string;
434
433
  originalFilePath: string;
435
434
  reExportChain: Array<{ filePath: string; exportedAs: string }>;
435
+ circular: boolean; // true when re-export chain contains a cycle
436
436
  }
437
437
 
438
438
  interface HeritageNode {
@@ -472,10 +472,10 @@ interface FileRecord {
472
472
 
473
473
  // ── Errors ──────────────────────────────────────────────────────────────
474
474
 
475
- interface GildashError {
476
- type: GildashErrorType; // see Error Types table below
477
- message: string;
478
- cause?: unknown;
475
+ class GildashError extends Error {
476
+ readonly type: GildashErrorType; // see Error Types table below
477
+ readonly message: string;
478
+ readonly cause?: unknown; // inherited from Error
479
479
  }
480
480
  ```
481
481
 
@@ -522,7 +522,26 @@ When multiple processes share the same SQLite database, gildash enforces a singl
522
522
 
523
523
  <br>
524
524
 
525
- ## ⬆️ Upgrading from 0.5.0
525
+ ## ⬆️ Upgrading
526
+
527
+ ### From 0.5.x to 0.6.0
528
+
529
+ **Breaking:** `@zipbul/result` is no longer part of the public API. All methods now return values directly and throw `GildashError` on failure.
530
+
531
+ ```diff
532
+ - import { isErr } from '@zipbul/result';
533
+ - const result = ledger.searchSymbols({ text: 'foo' });
534
+ - if (isErr(result)) { console.error(result.data.message); }
535
+ - else { console.log(result); }
536
+ + const symbols = ledger.searchSymbols({ text: 'foo' }); // throws GildashError
537
+ ```
538
+
539
+ - Remove `@zipbul/result` from your dependencies (no longer a peer dependency)
540
+ - Replace `isErr()` checks with `try/catch` using `instanceof GildashError`
541
+ - `getFullSymbol()`, `getFileInfo()`, `getResolvedType()` return `null` instead of an error when not found
542
+ - `resolveSymbol()` returns `{ circular: true }` for circular re-exports instead of throwing
543
+
544
+ ### From 0.4.x to 0.5.0
526
545
 
527
546
  The database directory was renamed from `.zipbul/` to `.gildash/`. The database is now stored at `<projectRoot>/.gildash/gildash.db`.
528
547