@colbymchenry/codegraph 0.9.7 → 0.9.8
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.md +111 -24
- package/dist/bin/codegraph.d.ts +25 -0
- package/dist/bin/node-version-check.d.ts +37 -0
- package/dist/bin/uninstall.d.ts +14 -0
- package/dist/context/formatter.d.ts +30 -0
- package/dist/context/index.d.ts +110 -0
- package/dist/db/index.d.ts +101 -0
- package/dist/db/migrations.d.ts +44 -0
- package/dist/db/queries.d.ts +344 -0
- package/dist/db/sqlite-adapter.d.ts +46 -0
- package/dist/directory.d.ts +57 -0
- package/dist/errors.d.ts +136 -0
- package/dist/extraction/dfm-extractor.d.ts +31 -0
- package/dist/extraction/generated-detection.d.ts +30 -0
- package/dist/extraction/grammars.d.ts +100 -0
- package/dist/extraction/index.d.ts +138 -0
- package/dist/extraction/languages/c-cpp.d.ts +4 -0
- package/dist/extraction/languages/csharp.d.ts +3 -0
- package/dist/extraction/languages/dart.d.ts +3 -0
- package/dist/extraction/languages/go.d.ts +3 -0
- package/dist/extraction/languages/index.d.ts +10 -0
- package/dist/extraction/languages/java.d.ts +3 -0
- package/dist/extraction/languages/javascript.d.ts +3 -0
- package/dist/extraction/languages/kotlin.d.ts +3 -0
- package/dist/extraction/languages/lua.d.ts +3 -0
- package/dist/extraction/languages/luau.d.ts +3 -0
- package/dist/extraction/languages/objc.d.ts +3 -0
- package/dist/extraction/languages/pascal.d.ts +3 -0
- package/dist/extraction/languages/php.d.ts +3 -0
- package/dist/extraction/languages/python.d.ts +3 -0
- package/dist/extraction/languages/ruby.d.ts +3 -0
- package/dist/extraction/languages/rust.d.ts +3 -0
- package/dist/extraction/languages/scala.d.ts +3 -0
- package/dist/extraction/languages/swift.d.ts +3 -0
- package/dist/extraction/languages/typescript.d.ts +3 -0
- package/dist/extraction/liquid-extractor.d.ts +52 -0
- package/dist/extraction/mybatis-extractor.d.ts +48 -0
- package/dist/extraction/parse-worker.d.ts +8 -0
- package/dist/extraction/svelte-extractor.d.ts +56 -0
- package/dist/extraction/tree-sitter-helpers.d.ts +28 -0
- package/dist/extraction/tree-sitter-types.d.ts +193 -0
- package/dist/extraction/tree-sitter.d.ts +291 -0
- package/dist/extraction/vue-extractor.d.ts +36 -0
- package/dist/extraction/wasm-runtime-flags.d.ts +38 -0
- package/dist/graph/index.d.ts +8 -0
- package/dist/graph/queries.d.ts +106 -0
- package/dist/graph/traversal.d.ts +127 -0
- package/dist/index.d.ts +492 -0
- package/dist/installer/config-writer.d.ts +28 -0
- package/dist/installer/index.d.ts +100 -0
- package/dist/installer/instructions-template.d.ts +18 -0
- package/dist/installer/targets/antigravity.d.ts +57 -0
- package/dist/installer/targets/claude.d.ts +56 -0
- package/dist/installer/targets/codex.d.ts +18 -0
- package/dist/installer/targets/cursor.d.ts +35 -0
- package/dist/installer/targets/gemini.d.ts +26 -0
- package/dist/installer/targets/hermes.d.ts +18 -0
- package/dist/installer/targets/kiro.d.ts +27 -0
- package/dist/installer/targets/opencode.d.ts +30 -0
- package/dist/installer/targets/registry.d.ts +35 -0
- package/dist/installer/targets/shared.d.ts +77 -0
- package/dist/installer/targets/toml.d.ts +52 -0
- package/dist/installer/targets/types.d.ts +101 -0
- package/dist/mcp/daemon-paths.d.ts +46 -0
- package/dist/mcp/daemon.d.ts +161 -0
- package/dist/mcp/engine.d.ts +105 -0
- package/dist/mcp/index.d.ts +112 -0
- package/dist/mcp/proxy.d.ts +81 -0
- package/dist/mcp/server-instructions.d.ts +19 -0
- package/dist/mcp/session.d.ts +77 -0
- package/dist/mcp/tools.d.ts +423 -0
- package/dist/mcp/transport.d.ts +188 -0
- package/dist/mcp/version.d.ts +19 -0
- package/dist/resolution/callback-synthesizer.d.ts +10 -0
- package/dist/resolution/frameworks/cargo-workspace.d.ts +18 -0
- package/dist/resolution/frameworks/csharp.d.ts +8 -0
- package/dist/resolution/frameworks/drupal.d.ts +51 -0
- package/dist/resolution/frameworks/expo-modules.d.ts +3 -0
- package/dist/resolution/frameworks/express.d.ts +8 -0
- package/dist/resolution/frameworks/fabric.d.ts +3 -0
- package/dist/resolution/frameworks/go.d.ts +8 -0
- package/dist/resolution/frameworks/index.d.ts +48 -0
- package/dist/resolution/frameworks/java.d.ts +8 -0
- package/dist/resolution/frameworks/laravel.d.ts +13 -0
- package/dist/resolution/frameworks/nestjs.d.ts +26 -0
- package/dist/resolution/frameworks/play.d.ts +19 -0
- package/dist/resolution/frameworks/python.d.ts +10 -0
- package/dist/resolution/frameworks/react-native.d.ts +3 -0
- package/dist/resolution/frameworks/react.d.ts +8 -0
- package/dist/resolution/frameworks/ruby.d.ts +8 -0
- package/dist/resolution/frameworks/rust.d.ts +8 -0
- package/dist/resolution/frameworks/svelte.d.ts +9 -0
- package/dist/resolution/frameworks/swift-objc.d.ts +37 -0
- package/dist/resolution/frameworks/swift.d.ts +10 -0
- package/dist/resolution/frameworks/vue.d.ts +9 -0
- package/dist/resolution/go-module.d.ts +26 -0
- package/dist/resolution/import-resolver.d.ts +68 -0
- package/dist/resolution/index.d.ts +116 -0
- package/dist/resolution/lru-cache.d.ts +24 -0
- package/dist/resolution/name-matcher.d.ts +32 -0
- package/dist/resolution/path-aliases.d.ts +68 -0
- package/dist/resolution/strip-comments.d.ts +27 -0
- package/dist/resolution/swift-objc-bridge.d.ts +134 -0
- package/dist/resolution/types.d.ts +209 -0
- package/dist/search/query-parser.d.ts +57 -0
- package/dist/search/query-utils.d.ts +53 -0
- package/dist/sync/git-hooks.d.ts +45 -0
- package/dist/sync/index.d.ts +19 -0
- package/dist/sync/watch-policy.d.ts +48 -0
- package/dist/sync/watcher.d.ts +191 -0
- package/dist/sync/worktree.d.ts +54 -0
- package/dist/types.d.ts +369 -0
- package/dist/ui/glyphs.d.ts +42 -0
- package/dist/ui/shimmer-progress.d.ts +11 -0
- package/dist/ui/shimmer-worker.d.ts +2 -0
- package/dist/ui/types.d.ts +17 -0
- package/dist/utils.d.ts +205 -0
- package/npm-sdk.js +75 -0
- package/package.json +18 -7
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-language comment stripper for framework route extractors.
|
|
3
|
+
*
|
|
4
|
+
* Replaces comment characters and string-literal contents that hide
|
|
5
|
+
* routing-shaped text with spaces (NOT removal) so that source offsets
|
|
6
|
+
* are preserved. This means `match.index` from a regex run on the
|
|
7
|
+
* stripped output still maps to the same line in the original source.
|
|
8
|
+
*
|
|
9
|
+
* Example:
|
|
10
|
+
* Input: "x = 1 # path('/fake/', V)\n real = 2"
|
|
11
|
+
* Output: "x = 1 \n real = 2"
|
|
12
|
+
*
|
|
13
|
+
* Why strip strings/docstrings as well as comments? Python module/class
|
|
14
|
+
* docstrings are a common source of false positives — they often contain
|
|
15
|
+
* `path('/example/', View)` examples in usage docs. We treat triple-quoted
|
|
16
|
+
* strings the same as comments. Single-line strings stay intact (a `#`
|
|
17
|
+
* inside a Python string is NOT a comment).
|
|
18
|
+
*
|
|
19
|
+
* Scope: this is a pragmatic, regex-supporting helper, not a full parser.
|
|
20
|
+
* It does NOT try to detect JS regex literals, Python f-string expressions,
|
|
21
|
+
* or shell-style heredocs. Those edge cases are not load-bearing for the
|
|
22
|
+
* `path(...)`, `Route::get(...)`, `app.get(...)` style patterns that
|
|
23
|
+
* framework extractors scan for.
|
|
24
|
+
*/
|
|
25
|
+
export type CommentLang = 'python' | 'javascript' | 'typescript' | 'php' | 'ruby' | 'java' | 'csharp' | 'swift' | 'go' | 'rust';
|
|
26
|
+
export declare function stripCommentsForRegex(content: string, lang: CommentLang): string;
|
|
27
|
+
//# sourceMappingURL=strip-comments.d.ts.map
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Swift ↔ Objective-C bridging rules.
|
|
3
|
+
*
|
|
4
|
+
* Apple's auto-bridging mechanism exposes Swift declarations to the ObjC
|
|
5
|
+
* runtime under a deterministic selector name. The full rule set:
|
|
6
|
+
* https://developer.apple.com/documentation/swift/importing-swift-into-objective-c
|
|
7
|
+
*
|
|
8
|
+
* This module is **pure name math** — given a Swift declaration's base name
|
|
9
|
+
* + parameter external labels (or the raw signature text), produce the
|
|
10
|
+
* bridged ObjC selector(s); given an ObjC selector, produce the
|
|
11
|
+
* candidate Swift base names. No graph/DB access here.
|
|
12
|
+
*
|
|
13
|
+
* Used by `frameworks/swift-objc.ts` (the framework resolver that wires
|
|
14
|
+
* the rules into the resolution pipeline) and by its tests.
|
|
15
|
+
*
|
|
16
|
+
* ─── Bridging cheat sheet ───────────────────────────────────────────────
|
|
17
|
+
*
|
|
18
|
+
* Swift declaration ObjC selector
|
|
19
|
+
* ───────────────────────────────────────── ─────────────────────────
|
|
20
|
+
* func play() play
|
|
21
|
+
* func play(_ song: String) play:
|
|
22
|
+
* func play(song: String) playWithSong:
|
|
23
|
+
* func play(_ song: String, by artist: String) play:by:
|
|
24
|
+
* func play(song: String, by artist: String) playWithSong:by:
|
|
25
|
+
* init(name: String) initWithName:
|
|
26
|
+
* init(name: String, age: Int) initWithName:age:
|
|
27
|
+
* var name: String (getter / setter) name / setName:
|
|
28
|
+
* @objc(custom:) func f(_ x: Int) custom: (literal override)
|
|
29
|
+
*
|
|
30
|
+
* The reverse direction (ObjC → Swift) collapses the bridge: a Swift call
|
|
31
|
+
* site for `play(song:)` reaches us as the bare base name `play` (Swift's
|
|
32
|
+
* tree-sitter call_expression strips parameter labels from the callee
|
|
33
|
+
* name). So `swiftBaseNamesForObjcSelector('playWithSong:')` returns
|
|
34
|
+
* `['play']` — the resolver looks up Swift methods named `play`.
|
|
35
|
+
*/
|
|
36
|
+
/**
|
|
37
|
+
* Compute the auto-bridged ObjC selector for a Swift method declaration.
|
|
38
|
+
*
|
|
39
|
+
* @param baseName The Swift method's base name (e.g. `play`).
|
|
40
|
+
* @param externalLabels Parameter EXTERNAL labels in declaration order;
|
|
41
|
+
* `null` for a `_` (unlabeled) parameter.
|
|
42
|
+
* `[]` for a no-parameter method.
|
|
43
|
+
* @param explicitObjcName If `@objc(customSel:)` was specified, the
|
|
44
|
+
* literal selector — short-circuits the rule
|
|
45
|
+
* and is returned as-is.
|
|
46
|
+
* @returns The ObjC selector (e.g. `playWithSong:by:`), or `null` if it
|
|
47
|
+
* can't be determined.
|
|
48
|
+
*
|
|
49
|
+
* **Method rules:**
|
|
50
|
+
* - No params → base name (no colons)
|
|
51
|
+
* - Single param, `_` label → `baseName:`
|
|
52
|
+
* - Single param, explicit label `L` → `baseNameWithL:`
|
|
53
|
+
* - Multi-param, `_` first label → `baseName:label2:label3:`
|
|
54
|
+
* - Multi-param, explicit first label `L1` → `baseNameWithL1:label2:label3:`
|
|
55
|
+
*
|
|
56
|
+
* Initializer rules are handled by `objcSelectorForSwiftInit`.
|
|
57
|
+
*/
|
|
58
|
+
export declare function objcSelectorForSwiftMethod(baseName: string, externalLabels: (string | null)[], explicitObjcName?: string | null): string | null;
|
|
59
|
+
/**
|
|
60
|
+
* Compute the bridged ObjC selector for a Swift `init(...)` declaration.
|
|
61
|
+
*
|
|
62
|
+
* **Init rules** (different from regular methods — Apple always uses
|
|
63
|
+
* `initWith` regardless of whether the first label is `_`):
|
|
64
|
+
* - `init()` → `init`
|
|
65
|
+
* - `init(_ name: String)` → `initWithName:` (uses the INTERNAL
|
|
66
|
+
* name when external is `_`, per Apple's
|
|
67
|
+
* bridging conventions)
|
|
68
|
+
* - `init(name: String)` → `initWithName:`
|
|
69
|
+
* - `init(name: String, age: Int)` → `initWithName:age:`
|
|
70
|
+
*
|
|
71
|
+
* For the `_` case we need the internal (second identifier) name —
|
|
72
|
+
* passed via `internalNames`.
|
|
73
|
+
*/
|
|
74
|
+
export declare function objcSelectorForSwiftInit(externalLabels: (string | null)[], internalNames: string[], explicitObjcName?: string | null): string | null;
|
|
75
|
+
/**
|
|
76
|
+
* Compute the bridged ObjC getter + setter for a Swift `@objc` property.
|
|
77
|
+
*
|
|
78
|
+
* - `var name: String` → getter `name`, setter `setName:`
|
|
79
|
+
* - `var isReady: Bool` → getter `isReady`, setter `setIsReady:`
|
|
80
|
+
* (no special `is` handling — Swift's `isReady` stays as `isReady` in ObjC;
|
|
81
|
+
* `@objc(name:)` overrides if a Cocoa-style getter `isReady` / setter
|
|
82
|
+
* `setReady:` pairing is needed — that's the responsibility of the
|
|
83
|
+
* declaration's `@objc(customGetter)` annotation, which we surface via
|
|
84
|
+
* `explicitObjcName`.)
|
|
85
|
+
*/
|
|
86
|
+
export declare function objcAccessorsForSwiftProperty(swiftName: string, explicitObjcName?: string | null): {
|
|
87
|
+
getter: string;
|
|
88
|
+
setter: string;
|
|
89
|
+
} | null;
|
|
90
|
+
/**
|
|
91
|
+
* Reverse: from an ObjC selector, return the candidate Swift base names
|
|
92
|
+
* the resolver should try when looking for the bridged Swift declaration.
|
|
93
|
+
*
|
|
94
|
+
* Examples:
|
|
95
|
+
* `play` → ['play']
|
|
96
|
+
* `play:` → ['play']
|
|
97
|
+
* `playWithSong:` → ['play', 'playWithSong']
|
|
98
|
+
* `play:by:` → ['play']
|
|
99
|
+
* `playWithSong:by:` → ['play', 'playWithSong']
|
|
100
|
+
* `initWithName:` → ['init'] (init is its own base name)
|
|
101
|
+
* `initWithName:age:` → ['init']
|
|
102
|
+
* `setName:` → ['name', 'setName'] (could be a setter OR a regular func)
|
|
103
|
+
* `tableView:didSel…:` → ['tableView']
|
|
104
|
+
*
|
|
105
|
+
* Returns multiple candidates because the bare base name is ambiguous —
|
|
106
|
+
* `playWithSong:` could correspond to either `func play(song:)` or
|
|
107
|
+
* `func playWithSong(_ x:)` (a Swift method literally named that with a
|
|
108
|
+
* `_` first label). The resolver tries each.
|
|
109
|
+
*/
|
|
110
|
+
export declare function swiftBaseNamesForObjcSelector(selector: string): string[];
|
|
111
|
+
/**
|
|
112
|
+
* Detect whether a Swift method `@objc` declaration uses the `@objc(custom:)`
|
|
113
|
+
* override form, returning the literal selector when present.
|
|
114
|
+
*
|
|
115
|
+
* Regex-based scan over the small chunk of source preceding the declaration —
|
|
116
|
+
* tree-sitter would be more precise but this is only consulted as a fallback
|
|
117
|
+
* when the structured AST isn't available (e.g. resolver-time lookups
|
|
118
|
+
* via `context.readFile`).
|
|
119
|
+
*
|
|
120
|
+
* Returns `null` when the declaration is plain `@objc` (no override) or has
|
|
121
|
+
* no `@objc` attribute at all.
|
|
122
|
+
*/
|
|
123
|
+
export declare function detectExplicitObjcName(sourceSlice: string): string | null;
|
|
124
|
+
/**
|
|
125
|
+
* Detect whether a Swift declaration is `@objc`-exposed by scanning the
|
|
126
|
+
* source slice that precedes it. Returns true for explicit `@objc`,
|
|
127
|
+
* `@objc(custom:)`, or membership in a `@objcMembers` class (caller's
|
|
128
|
+
* responsibility to pass class-level context if relevant).
|
|
129
|
+
*
|
|
130
|
+
* `@nonobjc` returns false even if `@objc` also appears (per Swift's rule
|
|
131
|
+
* that `@nonobjc` opts out of class-level `@objcMembers`).
|
|
132
|
+
*/
|
|
133
|
+
export declare function isObjcExposed(sourceSlice: string): boolean;
|
|
134
|
+
//# sourceMappingURL=swift-objc-bridge.d.ts.map
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reference Resolution Types
|
|
3
|
+
*
|
|
4
|
+
* Types for the reference resolution system.
|
|
5
|
+
*/
|
|
6
|
+
import { EdgeKind, Language, Node } from '../types';
|
|
7
|
+
/**
|
|
8
|
+
* An unresolved reference from extraction
|
|
9
|
+
*/
|
|
10
|
+
export interface UnresolvedRef {
|
|
11
|
+
/** ID of the source node containing the reference */
|
|
12
|
+
fromNodeId: string;
|
|
13
|
+
/** The name being referenced */
|
|
14
|
+
referenceName: string;
|
|
15
|
+
/** Type of reference */
|
|
16
|
+
referenceKind: EdgeKind;
|
|
17
|
+
/** Line where reference occurs */
|
|
18
|
+
line: number;
|
|
19
|
+
/** Column where reference occurs */
|
|
20
|
+
column: number;
|
|
21
|
+
/** File path where reference occurs */
|
|
22
|
+
filePath: string;
|
|
23
|
+
/** Language of the source file */
|
|
24
|
+
language: Language;
|
|
25
|
+
/** Possible qualified names it might resolve to */
|
|
26
|
+
candidates?: string[];
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* A resolved reference
|
|
30
|
+
*/
|
|
31
|
+
export interface ResolvedRef {
|
|
32
|
+
/** Original unresolved reference */
|
|
33
|
+
original: UnresolvedRef;
|
|
34
|
+
/** ID of the target node */
|
|
35
|
+
targetNodeId: string;
|
|
36
|
+
/** Confidence score (0-1) */
|
|
37
|
+
confidence: number;
|
|
38
|
+
/** How it was resolved */
|
|
39
|
+
resolvedBy: 'exact-match' | 'import' | 'qualified-name' | 'framework' | 'fuzzy' | 'instance-method' | 'file-path';
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Result of resolution attempt
|
|
43
|
+
*/
|
|
44
|
+
export interface ResolutionResult {
|
|
45
|
+
/** Successfully resolved references */
|
|
46
|
+
resolved: ResolvedRef[];
|
|
47
|
+
/** References that couldn't be resolved */
|
|
48
|
+
unresolved: UnresolvedRef[];
|
|
49
|
+
/** Statistics */
|
|
50
|
+
stats: {
|
|
51
|
+
total: number;
|
|
52
|
+
resolved: number;
|
|
53
|
+
unresolved: number;
|
|
54
|
+
byMethod: Record<string, number>;
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Context for resolution - provides access to the graph
|
|
59
|
+
*/
|
|
60
|
+
export interface ResolutionContext {
|
|
61
|
+
/** Get all nodes in a file */
|
|
62
|
+
getNodesInFile(filePath: string): Node[];
|
|
63
|
+
/** Get all nodes by name */
|
|
64
|
+
getNodesByName(name: string): Node[];
|
|
65
|
+
/** Get all nodes by qualified name */
|
|
66
|
+
getNodesByQualifiedName(qualifiedName: string): Node[];
|
|
67
|
+
/** Get all nodes of a kind */
|
|
68
|
+
getNodesByKind(kind: Node['kind']): Node[];
|
|
69
|
+
/** Check if a file exists */
|
|
70
|
+
fileExists(filePath: string): boolean;
|
|
71
|
+
/** Read file content */
|
|
72
|
+
readFile(filePath: string): string | null;
|
|
73
|
+
/** Get project root */
|
|
74
|
+
getProjectRoot(): string;
|
|
75
|
+
/** Get all files */
|
|
76
|
+
getAllFiles(): string[];
|
|
77
|
+
/** Get nodes by lowercase name (O(1) lookup for fuzzy matching) */
|
|
78
|
+
getNodesByLowerName(lowerName: string): Node[];
|
|
79
|
+
/** Get cached import mappings for a file */
|
|
80
|
+
getImportMappings(filePath: string, language: Language): ImportMapping[];
|
|
81
|
+
/**
|
|
82
|
+
* Project import-path aliases (tsconfig/jsconfig `paths`). Returns
|
|
83
|
+
* `null` when the project doesn't define any. Cached per resolver
|
|
84
|
+
* instance — safe to call from any resolver code path. Optional so
|
|
85
|
+
* existing test fixtures and external context implementations
|
|
86
|
+
* compile without modification; production resolver implements it.
|
|
87
|
+
*/
|
|
88
|
+
getProjectAliases?(): import('./path-aliases').AliasMap | null;
|
|
89
|
+
/**
|
|
90
|
+
* Go module info from `go.mod` at the project root. Returns `null`
|
|
91
|
+
* when the project has no `go.mod` (non-Go projects, pre-modules
|
|
92
|
+
* Go code, or projects whose modules live in subdirectories). Used
|
|
93
|
+
* by the Go branch of import resolution to distinguish in-module
|
|
94
|
+
* cross-package imports from third-party packages.
|
|
95
|
+
*/
|
|
96
|
+
getGoModule?(): import('./go-module').GoModule | null;
|
|
97
|
+
/**
|
|
98
|
+
* Re-exports declared by a file (`export { x } from './other'`,
|
|
99
|
+
* `export * from './other'`). Empty array when the file has none.
|
|
100
|
+
* Optional so older callers compile; the import resolver follows
|
|
101
|
+
* re-export chains when this is provided.
|
|
102
|
+
*/
|
|
103
|
+
getReExports?(filePath: string, language: Language): ReExport[];
|
|
104
|
+
/**
|
|
105
|
+
* List immediate subdirectories of `relativePath` (relative to the
|
|
106
|
+
* project root). Returns an empty array when the path doesn't exist
|
|
107
|
+
* or isn't a directory. Used by framework resolvers that need to
|
|
108
|
+
* walk build-system metadata (e.g. Cargo workspace globs). Optional
|
|
109
|
+
* so external context implementations and test fixtures compile
|
|
110
|
+
* without modification.
|
|
111
|
+
*/
|
|
112
|
+
listDirectories?(relativePath: string): string[];
|
|
113
|
+
/**
|
|
114
|
+
* C/C++ include search directories (relative to project root),
|
|
115
|
+
* extracted from compile_commands.json or discovered by heuristic.
|
|
116
|
+
* Used by resolveCppIncludePath to search -I directories when
|
|
117
|
+
* relative resolution fails. Optional so existing callers compile.
|
|
118
|
+
*/
|
|
119
|
+
getCppIncludeDirs?(): string[];
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Result of framework-specific file extraction.
|
|
123
|
+
*/
|
|
124
|
+
export interface FrameworkExtractionResult {
|
|
125
|
+
/** Framework-specific nodes (e.g. routes) */
|
|
126
|
+
nodes: Node[];
|
|
127
|
+
/** Framework-specific unresolved references (e.g. route -> handler) */
|
|
128
|
+
references: UnresolvedRef[];
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Framework-specific resolver
|
|
132
|
+
*/
|
|
133
|
+
export interface FrameworkResolver {
|
|
134
|
+
/** Framework name */
|
|
135
|
+
name: string;
|
|
136
|
+
/** Languages this framework applies to. If omitted, applies to all languages. */
|
|
137
|
+
languages?: Language[];
|
|
138
|
+
/** Detect if project uses this framework (project-level, called once at startup) */
|
|
139
|
+
detect(context: ResolutionContext): boolean;
|
|
140
|
+
/** Resolve a reference using framework-specific patterns */
|
|
141
|
+
resolve(ref: UnresolvedRef, context: ResolutionContext): ResolvedRef | null;
|
|
142
|
+
/**
|
|
143
|
+
* Opt a reference NAME through the resolver's name-exists pre-filter, even when
|
|
144
|
+
* no node is named that. Needed for dynamic dispatch where the call target is
|
|
145
|
+
* an attribute/descriptor, not a declared symbol (e.g. Django's
|
|
146
|
+
* `self._iterable_class(...)`, React effect callbacks). Returning true lets the
|
|
147
|
+
* ref reach `resolve()` instead of being dropped for having no name match.
|
|
148
|
+
*/
|
|
149
|
+
claimsReference?(name: string): boolean;
|
|
150
|
+
/**
|
|
151
|
+
* Extract framework-specific nodes and references from a file.
|
|
152
|
+
*
|
|
153
|
+
* Returns route nodes, middleware nodes, etc., plus unresolved references
|
|
154
|
+
* that link those nodes to handlers (view classes, controller methods,
|
|
155
|
+
* included modules). Unresolved references flow into the normal resolution
|
|
156
|
+
* pipeline; the framework's own `resolve()` is one of the strategies tried.
|
|
157
|
+
*/
|
|
158
|
+
extract?(filePath: string, content: string): FrameworkExtractionResult;
|
|
159
|
+
/**
|
|
160
|
+
* Cross-file finalization pass, called once after all per-file extraction
|
|
161
|
+
* completes (and again on every incremental sync). Used by frameworks where
|
|
162
|
+
* a symbol's final representation depends on a sibling file the per-file
|
|
163
|
+
* `extract()` never saw — e.g. NestJS's `RouterModule.register([...])`
|
|
164
|
+
* sets route prefixes for controllers declared elsewhere.
|
|
165
|
+
*
|
|
166
|
+
* Implementations return route/etc. nodes with mutated fields (typically
|
|
167
|
+
* `name`); the orchestrator persists each via `updateNode`. The node `id`
|
|
168
|
+
* MUST be preserved so existing edges (route → handler, etc.) stay intact;
|
|
169
|
+
* `qualifiedName` SHOULD be preserved so the pass stays idempotent — a
|
|
170
|
+
* second run can recover the original in-file form from `qualifiedName`.
|
|
171
|
+
*/
|
|
172
|
+
postExtract?(context: ResolutionContext): Node[];
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Import mapping from a file
|
|
176
|
+
*/
|
|
177
|
+
export interface ImportMapping {
|
|
178
|
+
/** Local name used in the file */
|
|
179
|
+
localName: string;
|
|
180
|
+
/** Original exported name (may differ due to aliasing) */
|
|
181
|
+
exportedName: string;
|
|
182
|
+
/** Source module/path */
|
|
183
|
+
source: string;
|
|
184
|
+
/** Whether it's a default import */
|
|
185
|
+
isDefault: boolean;
|
|
186
|
+
/** Whether it's a namespace import (import * as X) */
|
|
187
|
+
isNamespace: boolean;
|
|
188
|
+
/** Resolved file path (if local) */
|
|
189
|
+
resolvedPath?: string;
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Re-export from a file: `export { x } from './other'` or
|
|
193
|
+
* `export * from './other'`. Used by the resolver to chase
|
|
194
|
+
* symbols through barrel files.
|
|
195
|
+
*/
|
|
196
|
+
export type ReExport = {
|
|
197
|
+
kind: 'named';
|
|
198
|
+
/** Name as exported by THIS file. */
|
|
199
|
+
exportedName: string;
|
|
200
|
+
/** Name in the upstream module (differs when renamed: `as`). */
|
|
201
|
+
originalName: string;
|
|
202
|
+
/** Module specifier of the upstream module. */
|
|
203
|
+
source: string;
|
|
204
|
+
} | {
|
|
205
|
+
kind: 'wildcard';
|
|
206
|
+
/** Module specifier of the upstream module. */
|
|
207
|
+
source: string;
|
|
208
|
+
};
|
|
209
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Field-qualified search query parser.
|
|
3
|
+
*
|
|
4
|
+
* Splits a raw query like
|
|
5
|
+
*
|
|
6
|
+
* kind:function name:auth path:src/api authenticate
|
|
7
|
+
*
|
|
8
|
+
* into structured filters (kind=function, name="auth", path prefix
|
|
9
|
+
* "src/api") plus the free-text portion ("authenticate") that goes
|
|
10
|
+
* to FTS. Free-text and filters compose: filters narrow the result
|
|
11
|
+
* set, FTS scores within the narrowed set.
|
|
12
|
+
*
|
|
13
|
+
* Recognised fields (case-insensitive, value is the rest until
|
|
14
|
+
* whitespace):
|
|
15
|
+
*
|
|
16
|
+
* kind: one of function|method|class|interface|struct|...
|
|
17
|
+
* lang: one of typescript|python|go|... (alias: language:)
|
|
18
|
+
* path: case-insensitive substring of file_path
|
|
19
|
+
* name: case-insensitive substring of the symbol's name
|
|
20
|
+
*
|
|
21
|
+
* Unknown field prefixes (e.g. `foo:bar`) are passed through to FTS
|
|
22
|
+
* as plain text — that's how someone searching for `TODO:` gets a
|
|
23
|
+
* result instead of a parse error.
|
|
24
|
+
*
|
|
25
|
+
* Quoting:
|
|
26
|
+
* kind:function path:"src/some path/with spaces" → handled by stripping
|
|
27
|
+
* the surrounding double quotes from the value (single token only,
|
|
28
|
+
* no nested escapes).
|
|
29
|
+
*/
|
|
30
|
+
import type { NodeKind, Language } from '../types';
|
|
31
|
+
export interface ParsedQuery {
|
|
32
|
+
/** Free-text portion to feed to FTS / LIKE. May be empty. */
|
|
33
|
+
text: string;
|
|
34
|
+
/** kind: filters (OR'd). Empty when none specified. */
|
|
35
|
+
kinds: NodeKind[];
|
|
36
|
+
/** lang:/language: filters (OR'd). Empty when none specified. */
|
|
37
|
+
languages: Language[];
|
|
38
|
+
/** path: filters (OR'd, case-insensitive substring of file_path). Empty when none. */
|
|
39
|
+
pathFilters: string[];
|
|
40
|
+
/** name: filters (OR'd, case-insensitive substring of node.name). */
|
|
41
|
+
nameFilters: string[];
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Parse a raw query into structured filters + remaining text.
|
|
45
|
+
* Always returns a value; never throws.
|
|
46
|
+
*/
|
|
47
|
+
export declare function parseQuery(raw: string): ParsedQuery;
|
|
48
|
+
/**
|
|
49
|
+
* Damerau-Levenshtein-ish bounded edit distance. Returns `maxDist + 1`
|
|
50
|
+
* as soon as the distance is known to exceed `maxDist`; that early-exit
|
|
51
|
+
* makes the fuzzy fallback cheap even over tens of thousands of names.
|
|
52
|
+
*
|
|
53
|
+
* Pure DP, O(min(len(a), len(b))) memory. Compares case-folded inputs;
|
|
54
|
+
* callers should pass `lowercase(name)` strings.
|
|
55
|
+
*/
|
|
56
|
+
export declare function boundedEditDistance(a: string, b: string, maxDist: number): number;
|
|
57
|
+
//# sourceMappingURL=query-parser.d.ts.map
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Search Query Utilities
|
|
3
|
+
*
|
|
4
|
+
* Shared module for search term extraction and scoring.
|
|
5
|
+
*/
|
|
6
|
+
import { Node } from '../types';
|
|
7
|
+
/**
|
|
8
|
+
* Common stop words to filter from search queries.
|
|
9
|
+
* Includes generic English + code-specific noise words.
|
|
10
|
+
*/
|
|
11
|
+
export declare const STOP_WORDS: Set<string>;
|
|
12
|
+
/**
|
|
13
|
+
* Generate stem variants of a search term by removing common English suffixes.
|
|
14
|
+
* Used for FTS query expansion so "caching" also finds "cache", "eviction" finds "evict", etc.
|
|
15
|
+
* Stems are used as PREFIX matches in FTS, so they don't need to be perfect English words.
|
|
16
|
+
*/
|
|
17
|
+
export declare function getStemVariants(term: string): string[];
|
|
18
|
+
/**
|
|
19
|
+
* Extract meaningful search terms from a natural language query.
|
|
20
|
+
* Splits camelCase, PascalCase, snake_case, SCREAMING_SNAKE, and dot.notation
|
|
21
|
+
* into individual tokens before filtering.
|
|
22
|
+
*
|
|
23
|
+
* Preserves original compound identifiers (e.g., "scrapeLoop") alongside
|
|
24
|
+
* their split parts so that FTS can match both the full symbol name and
|
|
25
|
+
* individual words within it.
|
|
26
|
+
*
|
|
27
|
+
* Also generates stem variants (e.g., "caching"→"cache", "eviction"→"evict")
|
|
28
|
+
* so FTS prefix matching can find related code symbols.
|
|
29
|
+
*/
|
|
30
|
+
export declare function extractSearchTerms(query: string, options?: {
|
|
31
|
+
stems?: boolean;
|
|
32
|
+
}): string[];
|
|
33
|
+
/**
|
|
34
|
+
* Score path relevance to a query
|
|
35
|
+
* Higher score = more relevant path
|
|
36
|
+
*/
|
|
37
|
+
export declare function scorePathRelevance(filePath: string, query: string): number;
|
|
38
|
+
/**
|
|
39
|
+
* Check if a file path looks like a test file
|
|
40
|
+
*/
|
|
41
|
+
export declare function isTestFile(filePath: string): boolean;
|
|
42
|
+
/**
|
|
43
|
+
* Bonus when a node's name matches the search query.
|
|
44
|
+
* Exact matches get the largest boost; prefix matches get smaller boosts.
|
|
45
|
+
* Multi-word queries also check individual term matches against the name.
|
|
46
|
+
*/
|
|
47
|
+
export declare function nameMatchBonus(nodeName: string, query: string): number;
|
|
48
|
+
/**
|
|
49
|
+
* Kind-based bonus for search ranking
|
|
50
|
+
* Functions and classes are typically more relevant than variables/imports
|
|
51
|
+
*/
|
|
52
|
+
export declare function kindBonus(kind: Node['kind']): number;
|
|
53
|
+
//# sourceMappingURL=query-utils.d.ts.map
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Git Sync Hooks
|
|
3
|
+
*
|
|
4
|
+
* When the live file watcher is disabled (e.g. on WSL2 `/mnt/*` drives,
|
|
5
|
+
* see watch-policy.ts), the CodeGraph index would otherwise go stale until
|
|
6
|
+
* the user runs `codegraph sync` by hand. As an opt-in alternative, we can
|
|
7
|
+
* install git hooks that refresh the index after the operations that change
|
|
8
|
+
* files on disk: commit, merge (covers `git pull`), and checkout.
|
|
9
|
+
*
|
|
10
|
+
* The hooks run `codegraph sync` in the background so they never block git,
|
|
11
|
+
* and are guarded by `command -v codegraph` so they no-op cleanly when the
|
|
12
|
+
* CLI isn't on PATH. Our snippet is delimited by marker comments so install
|
|
13
|
+
* is idempotent and removal preserves any user-authored hook content.
|
|
14
|
+
*/
|
|
15
|
+
export type GitHookName = 'post-commit' | 'post-merge' | 'post-checkout';
|
|
16
|
+
/** Hooks installed by default: commit, merge (git pull), and checkout. */
|
|
17
|
+
export declare const DEFAULT_SYNC_HOOKS: GitHookName[];
|
|
18
|
+
export interface GitHookResult {
|
|
19
|
+
/** Hook names that were created or updated. */
|
|
20
|
+
installed: GitHookName[];
|
|
21
|
+
/** Resolved hooks directory, or null when not a git repo. */
|
|
22
|
+
hooksDir: string | null;
|
|
23
|
+
/** Reason nothing happened (e.g. not a git repository). */
|
|
24
|
+
skipped?: string;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Whether `projectRoot` is inside a git working tree. Returns false if git
|
|
28
|
+
* isn't installed or the path isn't a repo.
|
|
29
|
+
*/
|
|
30
|
+
export declare function isGitRepo(projectRoot: string): boolean;
|
|
31
|
+
/**
|
|
32
|
+
* Install (or update) the CodeGraph sync hooks in a git repository.
|
|
33
|
+
* Idempotent: re-running replaces our marker block rather than duplicating
|
|
34
|
+
* it, and any user-authored hook content is preserved.
|
|
35
|
+
*/
|
|
36
|
+
export declare function installGitSyncHook(projectRoot: string, hooks?: GitHookName[]): GitHookResult;
|
|
37
|
+
/**
|
|
38
|
+
* Remove the CodeGraph sync hooks. Strips only our marker block; deletes the
|
|
39
|
+
* hook file entirely when nothing but a shebang remains, otherwise rewrites
|
|
40
|
+
* the user's content untouched.
|
|
41
|
+
*/
|
|
42
|
+
export declare function removeGitSyncHook(projectRoot: string, hooks?: GitHookName[]): GitHookResult;
|
|
43
|
+
/** Whether any CodeGraph sync hook is currently installed. */
|
|
44
|
+
export declare function isSyncHookInstalled(projectRoot: string, hooks?: GitHookName[]): boolean;
|
|
45
|
+
//# sourceMappingURL=git-hooks.d.ts.map
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sync Module
|
|
3
|
+
*
|
|
4
|
+
* Provides synchronization functionality for keeping the code graph
|
|
5
|
+
* up-to-date with file system changes.
|
|
6
|
+
*
|
|
7
|
+
* Components:
|
|
8
|
+
* - FileWatcher: Debounced fs.watch that auto-triggers sync on file changes
|
|
9
|
+
* - Watch policy: decides when the watcher must be disabled (e.g. WSL2 /mnt)
|
|
10
|
+
* - Git sync hooks: opt-in commit/merge/checkout hooks when watching is off
|
|
11
|
+
* - Git worktree awareness: detect when a query borrows another tree's index
|
|
12
|
+
* - Content hashing for change detection (in extraction module)
|
|
13
|
+
* - Incremental reindexing (in extraction module)
|
|
14
|
+
*/
|
|
15
|
+
export { FileWatcher, WatchOptions, PendingFile, LockUnavailableError } from './watcher';
|
|
16
|
+
export { watchDisabledReason, detectWsl } from './watch-policy';
|
|
17
|
+
export { installGitSyncHook, removeGitSyncHook, isSyncHookInstalled, isGitRepo, DEFAULT_SYNC_HOOKS, type GitHookName, type GitHookResult, } from './git-hooks';
|
|
18
|
+
export { gitWorktreeRoot, detectWorktreeIndexMismatch, worktreeMismatchWarning, worktreeMismatchNotice, type WorktreeIndexMismatch, } from './worktree';
|
|
19
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Watch Policy
|
|
3
|
+
*
|
|
4
|
+
* Decides whether the live file watcher should run for a given project.
|
|
5
|
+
*
|
|
6
|
+
* Native recursive `fs.watch` is pathologically slow on WSL2 `/mnt/*`
|
|
7
|
+
* drives (NTFS exposed over the 9p/drvfs bridge): setting up the recursive
|
|
8
|
+
* watch walks the directory tree, and every readdir/stat crosses the
|
|
9
|
+
* Windows boundary. Inside an MCP server this stalls the event loop during
|
|
10
|
+
* startup long enough to blow past host handshake timeouts (opencode's 30s),
|
|
11
|
+
* so the tools never appear. See issue #199.
|
|
12
|
+
*
|
|
13
|
+
* This module centralizes the on/off decision so the watcher, the MCP
|
|
14
|
+
* server (for diagnostics), and the installer all agree.
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* Detect whether the current process is running under WSL (Windows
|
|
18
|
+
* Subsystem for Linux). Result is cached after the first call.
|
|
19
|
+
*
|
|
20
|
+
* Checks the WSL-specific env vars first (no I/O), then falls back to
|
|
21
|
+
* `/proc/version`, which contains "microsoft" on WSL kernels.
|
|
22
|
+
*/
|
|
23
|
+
export declare function detectWsl(): boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Inputs that can be overridden in tests so the decision is deterministic
|
|
26
|
+
* without touching real env vars or `/proc/version`.
|
|
27
|
+
*/
|
|
28
|
+
export interface WatchProbe {
|
|
29
|
+
/** Defaults to `process.env`. */
|
|
30
|
+
env?: NodeJS.ProcessEnv;
|
|
31
|
+
/** Defaults to `detectWsl()`. */
|
|
32
|
+
isWsl?: boolean;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Decide whether the file watcher should be disabled for a project, and why.
|
|
36
|
+
*
|
|
37
|
+
* Returns a short human-readable reason when watching should be skipped, or
|
|
38
|
+
* `null` when it should run normally.
|
|
39
|
+
*
|
|
40
|
+
* Precedence (first match wins):
|
|
41
|
+
* 1. `CODEGRAPH_NO_WATCH=1` → off (explicit opt-out always wins)
|
|
42
|
+
* 2. `CODEGRAPH_FORCE_WATCH=1` → on (overrides auto-detection)
|
|
43
|
+
* 3. WSL2 + `/mnt/*` drive → off (recursive fs.watch is too slow; #199)
|
|
44
|
+
*/
|
|
45
|
+
export declare function watchDisabledReason(projectRoot: string, probe?: WatchProbe): string | null;
|
|
46
|
+
/** Test-only: reset the cached WSL detection. */
|
|
47
|
+
export declare function __resetWslCacheForTests(): void;
|
|
48
|
+
//# sourceMappingURL=watch-policy.d.ts.map
|