gitnexus 1.4.8 → 1.4.10
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 +7 -0
- package/dist/cli/index-repo.d.ts +15 -0
- package/dist/cli/index-repo.js +115 -0
- package/dist/cli/index.js +11 -2
- package/dist/cli/setup.js +12 -9
- package/dist/cli/wiki.d.ts +4 -0
- package/dist/cli/wiki.js +174 -53
- package/dist/config/supported-languages.d.ts +7 -5
- package/dist/config/supported-languages.js +6 -4
- package/dist/core/graph/graph.js +9 -1
- package/dist/core/graph/types.d.ts +10 -2
- package/dist/core/ingestion/call-processor.d.ts +18 -1
- package/dist/core/ingestion/call-processor.js +297 -38
- package/dist/core/ingestion/call-routing.d.ts +3 -18
- package/dist/core/ingestion/call-routing.js +0 -19
- package/dist/core/ingestion/cobol/cobol-copy-expander.d.ts +57 -0
- package/dist/core/ingestion/cobol/cobol-copy-expander.js +385 -0
- package/dist/core/ingestion/cobol/cobol-preprocessor.d.ts +210 -0
- package/dist/core/ingestion/cobol/cobol-preprocessor.js +1509 -0
- package/dist/core/ingestion/cobol/jcl-parser.d.ts +68 -0
- package/dist/core/ingestion/cobol/jcl-parser.js +217 -0
- package/dist/core/ingestion/cobol/jcl-processor.d.ts +33 -0
- package/dist/core/ingestion/cobol/jcl-processor.js +229 -0
- package/dist/core/ingestion/cobol-processor.d.ts +54 -0
- package/dist/core/ingestion/cobol-processor.js +1186 -0
- package/dist/core/ingestion/entry-point-scoring.d.ts +17 -0
- package/dist/core/ingestion/entry-point-scoring.js +18 -4
- package/dist/core/ingestion/export-detection.d.ts +47 -8
- package/dist/core/ingestion/export-detection.js +29 -50
- package/dist/core/ingestion/field-extractor.d.ts +29 -0
- package/dist/core/ingestion/field-extractor.js +25 -0
- package/dist/core/ingestion/field-extractors/configs/c-cpp.d.ts +3 -0
- package/dist/core/ingestion/field-extractors/configs/c-cpp.js +108 -0
- package/dist/core/ingestion/field-extractors/configs/csharp.d.ts +8 -0
- package/dist/core/ingestion/field-extractors/configs/csharp.js +73 -0
- package/dist/core/ingestion/field-extractors/configs/dart.d.ts +8 -0
- package/dist/core/ingestion/field-extractors/configs/dart.js +76 -0
- package/dist/core/ingestion/field-extractors/configs/go.d.ts +11 -0
- package/dist/core/ingestion/field-extractors/configs/go.js +64 -0
- package/dist/core/ingestion/field-extractors/configs/helpers.d.ts +44 -0
- package/dist/core/ingestion/field-extractors/configs/helpers.js +134 -0
- package/dist/core/ingestion/field-extractors/configs/jvm.d.ts +3 -0
- package/dist/core/ingestion/field-extractors/configs/jvm.js +118 -0
- package/dist/core/ingestion/field-extractors/configs/php.d.ts +8 -0
- package/dist/core/ingestion/field-extractors/configs/php.js +67 -0
- package/dist/core/ingestion/field-extractors/configs/python.d.ts +12 -0
- package/dist/core/ingestion/field-extractors/configs/python.js +91 -0
- package/dist/core/ingestion/field-extractors/configs/ruby.d.ts +16 -0
- package/dist/core/ingestion/field-extractors/configs/ruby.js +75 -0
- package/dist/core/ingestion/field-extractors/configs/rust.d.ts +9 -0
- package/dist/core/ingestion/field-extractors/configs/rust.js +55 -0
- package/dist/core/ingestion/field-extractors/configs/swift.d.ts +8 -0
- package/dist/core/ingestion/field-extractors/configs/swift.js +63 -0
- package/dist/core/ingestion/field-extractors/configs/typescript-javascript.d.ts +3 -0
- package/dist/core/ingestion/field-extractors/configs/typescript-javascript.js +60 -0
- package/dist/core/ingestion/field-extractors/generic.d.ts +46 -0
- package/dist/core/ingestion/field-extractors/generic.js +111 -0
- package/dist/core/ingestion/field-extractors/typescript.d.ts +77 -0
- package/dist/core/ingestion/field-extractors/typescript.js +291 -0
- package/dist/core/ingestion/field-types.d.ts +59 -0
- package/dist/core/ingestion/field-types.js +2 -0
- package/dist/core/ingestion/framework-detection.d.ts +87 -0
- package/dist/core/ingestion/framework-detection.js +65 -2
- package/dist/core/ingestion/heritage-processor.js +15 -17
- package/dist/core/ingestion/import-processor.d.ts +9 -10
- package/dist/core/ingestion/import-processor.js +59 -14
- package/dist/core/ingestion/{resolvers → import-resolvers}/csharp.d.ts +6 -9
- package/dist/core/ingestion/{resolvers → import-resolvers}/csharp.js +20 -2
- package/dist/core/ingestion/import-resolvers/dart.d.ts +7 -0
- package/dist/core/ingestion/import-resolvers/dart.js +44 -0
- package/dist/core/ingestion/{resolvers → import-resolvers}/go.d.ts +4 -5
- package/dist/core/ingestion/{resolvers → import-resolvers}/go.js +17 -0
- package/dist/core/ingestion/{resolvers → import-resolvers}/jvm.d.ts +9 -1
- package/dist/core/ingestion/{resolvers → import-resolvers}/jvm.js +56 -0
- package/dist/core/ingestion/{resolvers → import-resolvers}/php.d.ts +6 -10
- package/dist/core/ingestion/{resolvers → import-resolvers}/php.js +7 -2
- package/dist/core/ingestion/{resolvers → import-resolvers}/python.d.ts +9 -3
- package/dist/core/ingestion/{resolvers → import-resolvers}/python.js +35 -3
- package/dist/core/ingestion/{resolvers → import-resolvers}/ruby.d.ts +5 -2
- package/dist/core/ingestion/{resolvers → import-resolvers}/ruby.js +7 -2
- package/dist/core/ingestion/{resolvers → import-resolvers}/rust.d.ts +5 -2
- package/dist/core/ingestion/{resolvers → import-resolvers}/rust.js +41 -2
- package/dist/core/ingestion/{resolvers → import-resolvers}/standard.d.ts +15 -7
- package/dist/core/ingestion/{resolvers → import-resolvers}/standard.js +22 -3
- package/dist/core/ingestion/import-resolvers/swift.d.ts +7 -0
- package/dist/core/ingestion/import-resolvers/swift.js +23 -0
- package/dist/core/ingestion/import-resolvers/types.d.ts +44 -0
- package/dist/core/ingestion/import-resolvers/types.js +6 -0
- package/dist/core/ingestion/{resolvers → import-resolvers}/utils.d.ts +0 -3
- package/dist/core/ingestion/{resolvers → import-resolvers}/utils.js +0 -9
- package/dist/core/ingestion/language-config.d.ts +4 -1
- package/dist/core/ingestion/language-provider.d.ts +121 -0
- package/dist/core/ingestion/language-provider.js +24 -0
- package/dist/core/ingestion/languages/c-cpp.d.ts +12 -0
- package/dist/core/ingestion/languages/c-cpp.js +71 -0
- package/dist/core/ingestion/languages/cobol.d.ts +1 -0
- package/dist/core/ingestion/languages/cobol.js +26 -0
- package/dist/core/ingestion/languages/csharp.d.ts +8 -0
- package/dist/core/ingestion/languages/csharp.js +49 -0
- package/dist/core/ingestion/languages/dart.d.ts +12 -0
- package/dist/core/ingestion/languages/dart.js +58 -0
- package/dist/core/ingestion/languages/go.d.ts +11 -0
- package/dist/core/ingestion/languages/go.js +28 -0
- package/dist/core/ingestion/languages/index.d.ts +38 -0
- package/dist/core/ingestion/languages/index.js +63 -0
- package/dist/core/ingestion/languages/java.d.ts +9 -0
- package/dist/core/ingestion/languages/java.js +29 -0
- package/dist/core/ingestion/languages/kotlin.d.ts +9 -0
- package/dist/core/ingestion/languages/kotlin.js +53 -0
- package/dist/core/ingestion/languages/php.d.ts +8 -0
- package/dist/core/ingestion/languages/php.js +145 -0
- package/dist/core/ingestion/languages/python.d.ts +12 -0
- package/dist/core/ingestion/languages/python.js +39 -0
- package/dist/core/ingestion/languages/ruby.d.ts +9 -0
- package/dist/core/ingestion/languages/ruby.js +44 -0
- package/dist/core/ingestion/languages/rust.d.ts +12 -0
- package/dist/core/ingestion/languages/rust.js +44 -0
- package/dist/core/ingestion/languages/swift.d.ts +12 -0
- package/dist/core/ingestion/languages/swift.js +133 -0
- package/dist/core/ingestion/languages/typescript.d.ts +10 -0
- package/dist/core/ingestion/languages/typescript.js +60 -0
- package/dist/core/ingestion/mro-processor.js +14 -15
- package/dist/core/ingestion/{named-binding-extraction.d.ts → named-binding-processor.d.ts} +0 -9
- package/dist/core/ingestion/named-binding-processor.js +42 -0
- package/dist/core/ingestion/named-bindings/csharp.d.ts +3 -0
- package/dist/core/ingestion/named-bindings/csharp.js +37 -0
- package/dist/core/ingestion/named-bindings/java.d.ts +3 -0
- package/dist/core/ingestion/named-bindings/java.js +29 -0
- package/dist/core/ingestion/named-bindings/kotlin.d.ts +3 -0
- package/dist/core/ingestion/named-bindings/kotlin.js +36 -0
- package/dist/core/ingestion/named-bindings/php.d.ts +3 -0
- package/dist/core/ingestion/named-bindings/php.js +61 -0
- package/dist/core/ingestion/named-bindings/python.d.ts +3 -0
- package/dist/core/ingestion/named-bindings/python.js +49 -0
- package/dist/core/ingestion/named-bindings/rust.d.ts +3 -0
- package/dist/core/ingestion/named-bindings/rust.js +64 -0
- package/dist/core/ingestion/named-bindings/types.d.ts +16 -0
- package/dist/core/ingestion/named-bindings/types.js +6 -0
- package/dist/core/ingestion/named-bindings/typescript.d.ts +3 -0
- package/dist/core/ingestion/named-bindings/typescript.js +58 -0
- package/dist/core/ingestion/parsing-processor.d.ts +5 -1
- package/dist/core/ingestion/parsing-processor.js +115 -16
- package/dist/core/ingestion/pipeline.js +925 -424
- package/dist/core/ingestion/resolution-context.js +1 -1
- package/dist/core/ingestion/route-extractors/expo.d.ts +1 -0
- package/dist/core/ingestion/route-extractors/expo.js +36 -0
- package/dist/core/ingestion/route-extractors/middleware.d.ts +47 -0
- package/dist/core/ingestion/route-extractors/middleware.js +143 -0
- package/dist/core/ingestion/route-extractors/nextjs.d.ts +3 -0
- package/dist/core/ingestion/route-extractors/nextjs.js +76 -0
- package/dist/core/ingestion/route-extractors/php.d.ts +7 -0
- package/dist/core/ingestion/route-extractors/php.js +21 -0
- package/dist/core/ingestion/route-extractors/response-shapes.d.ts +20 -0
- package/dist/core/ingestion/route-extractors/response-shapes.js +290 -0
- package/dist/core/ingestion/tree-sitter-queries.d.ts +8 -7
- package/dist/core/ingestion/tree-sitter-queries.js +231 -9
- package/dist/core/ingestion/type-env.d.ts +14 -17
- package/dist/core/ingestion/type-env.js +66 -14
- package/dist/core/ingestion/type-extractors/c-cpp.d.ts +1 -1
- package/dist/core/ingestion/type-extractors/csharp.js +1 -1
- package/dist/core/ingestion/type-extractors/dart.d.ts +15 -0
- package/dist/core/ingestion/type-extractors/dart.js +371 -0
- package/dist/core/ingestion/type-extractors/jvm.js +1 -1
- package/dist/core/ingestion/type-extractors/shared.d.ts +1 -13
- package/dist/core/ingestion/type-extractors/shared.js +9 -102
- package/dist/core/ingestion/type-extractors/swift.js +334 -4
- package/dist/core/ingestion/type-extractors/types.d.ts +3 -1
- package/dist/core/ingestion/{ast-helpers.d.ts → utils/ast-helpers.d.ts} +16 -13
- package/dist/core/ingestion/{ast-helpers.js → utils/ast-helpers.js} +111 -32
- package/dist/core/ingestion/{call-analysis.js → utils/call-analysis.js} +37 -0
- package/dist/core/ingestion/utils/event-loop.d.ts +5 -0
- package/dist/core/ingestion/utils/event-loop.js +5 -0
- package/dist/core/ingestion/utils/language-detection.d.ts +9 -0
- package/dist/core/ingestion/utils/language-detection.js +70 -0
- package/dist/core/ingestion/utils/verbose.d.ts +1 -0
- package/dist/core/ingestion/utils/verbose.js +7 -0
- package/dist/core/ingestion/workers/parse-worker.d.ts +43 -2
- package/dist/core/ingestion/workers/parse-worker.js +361 -150
- package/dist/core/lbug/csv-generator.js +34 -1
- package/dist/core/lbug/lbug-adapter.js +6 -0
- package/dist/core/lbug/schema.d.ts +5 -3
- package/dist/core/lbug/schema.js +39 -2
- package/dist/core/tree-sitter/parser-loader.js +7 -1
- package/dist/core/wiki/cursor-client.d.ts +31 -0
- package/dist/core/wiki/cursor-client.js +127 -0
- package/dist/core/wiki/generator.d.ts +28 -9
- package/dist/core/wiki/generator.js +115 -18
- package/dist/core/wiki/graph-queries.d.ts +4 -0
- package/dist/core/wiki/graph-queries.js +7 -1
- package/dist/core/wiki/llm-client.d.ts +2 -0
- package/dist/core/wiki/llm-client.js +8 -4
- package/dist/core/wiki/prompts.d.ts +3 -3
- package/dist/core/wiki/prompts.js +6 -0
- package/dist/mcp/core/lbug-adapter.d.ts +5 -0
- package/dist/mcp/core/lbug-adapter.js +11 -1
- package/dist/mcp/local/local-backend.d.ts +16 -5
- package/dist/mcp/local/local-backend.js +711 -74
- package/dist/mcp/tools.js +71 -2
- package/dist/storage/repo-manager.d.ts +3 -0
- package/package.json +14 -14
- package/dist/core/ingestion/import-resolution.d.ts +0 -101
- package/dist/core/ingestion/import-resolution.js +0 -251
- package/dist/core/ingestion/named-binding-extraction.js +0 -373
- package/dist/core/ingestion/resolvers/index.d.ts +0 -18
- package/dist/core/ingestion/resolvers/index.js +0 -13
- package/dist/core/ingestion/type-extractors/index.d.ts +0 -22
- package/dist/core/ingestion/type-extractors/index.js +0 -31
- package/dist/core/ingestion/utils.d.ts +0 -20
- package/dist/core/ingestion/utils.js +0 -242
- package/scripts/patch-tree-sitter-swift.cjs +0 -74
- /package/dist/core/ingestion/{call-analysis.d.ts → utils/call-analysis.d.ts} +0 -0
package/README.md
CHANGED
|
@@ -53,7 +53,11 @@ If you prefer to configure manually instead of using `gitnexus setup`:
|
|
|
53
53
|
### Claude Code (full support — MCP + skills + hooks)
|
|
54
54
|
|
|
55
55
|
```bash
|
|
56
|
+
# macOS / Linux
|
|
56
57
|
claude mcp add gitnexus -- npx -y gitnexus@latest mcp
|
|
58
|
+
|
|
59
|
+
# Windows
|
|
60
|
+
claude mcp add gitnexus -- cmd /c npx -y gitnexus@latest mcp
|
|
57
61
|
```
|
|
58
62
|
|
|
59
63
|
### Codex (full support — MCP + skills)
|
|
@@ -99,6 +103,8 @@ GitNexus builds a complete knowledge graph of your codebase through a multi-phas
|
|
|
99
103
|
1. **Structure** — Walks the file tree and maps folder/file relationships
|
|
100
104
|
2. **Parsing** — Extracts functions, classes, methods, and interfaces using Tree-sitter ASTs
|
|
101
105
|
3. **Resolution** — Resolves imports and function calls across files with language-aware logic
|
|
106
|
+
- **Field & Property Type Resolution** — Tracks field types across classes and interfaces for deep chain resolution (e.g., `user.address.city.getName()`)
|
|
107
|
+
- **Return-Type-Aware Variable Binding** — Infers variable types from function return types, enabling accurate call-result binding
|
|
102
108
|
4. **Clustering** — Groups related symbols into functional communities
|
|
103
109
|
5. **Processes** — Traces execution flows from entry points through call chains
|
|
104
110
|
6. **Search** — Builds hybrid search indexes for fast retrieval
|
|
@@ -150,6 +156,7 @@ gitnexus analyze --embeddings # Enable embedding generation (slower, better
|
|
|
150
156
|
gitnexus analyze --verbose # Log skipped files when parsers are unavailable
|
|
151
157
|
gitnexus mcp # Start MCP server (stdio) — serves all indexed repos
|
|
152
158
|
gitnexus serve # Start local HTTP server (multi-repo) for web UI
|
|
159
|
+
gitnexus index # Register an existing .gitnexus/ folder into the global registry
|
|
153
160
|
gitnexus list # List all indexed repositories
|
|
154
161
|
gitnexus status # Show index status for current repo
|
|
155
162
|
gitnexus clean # Delete index for current repo
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Index Command
|
|
3
|
+
*
|
|
4
|
+
* Registers an existing .gitnexus/ folder into the global registry so the
|
|
5
|
+
* MCP server can discover the repo without running a full `gitnexus analyze`.
|
|
6
|
+
*
|
|
7
|
+
* Useful when a pre-built .gitnexus/ directory is already present (e.g. after
|
|
8
|
+
* cloning a repo that ships its index, restoring from backup, or using a
|
|
9
|
+
* shared team index).
|
|
10
|
+
*/
|
|
11
|
+
export interface IndexOptions {
|
|
12
|
+
force?: boolean;
|
|
13
|
+
allowNonGit?: boolean;
|
|
14
|
+
}
|
|
15
|
+
export declare const indexCommand: (inputPathParts?: string[], options?: IndexOptions) => Promise<void>;
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Index Command
|
|
3
|
+
*
|
|
4
|
+
* Registers an existing .gitnexus/ folder into the global registry so the
|
|
5
|
+
* MCP server can discover the repo without running a full `gitnexus analyze`.
|
|
6
|
+
*
|
|
7
|
+
* Useful when a pre-built .gitnexus/ directory is already present (e.g. after
|
|
8
|
+
* cloning a repo that ships its index, restoring from backup, or using a
|
|
9
|
+
* shared team index).
|
|
10
|
+
*/
|
|
11
|
+
import path from "path";
|
|
12
|
+
import fs from "fs/promises";
|
|
13
|
+
import { getStoragePaths, loadMeta, addToGitignore, registerRepo, } from "../storage/repo-manager.js";
|
|
14
|
+
import { getGitRoot, isGitRepo } from "../storage/git.js";
|
|
15
|
+
export const indexCommand = async (inputPathParts, options) => {
|
|
16
|
+
console.log("\n GitNexus Index\n");
|
|
17
|
+
const inputPath = inputPathParts?.length
|
|
18
|
+
? inputPathParts.join(" ")
|
|
19
|
+
: undefined;
|
|
20
|
+
if (inputPathParts && inputPathParts.length > 1) {
|
|
21
|
+
const resolvedCombinedPath = path.resolve(inputPath);
|
|
22
|
+
try {
|
|
23
|
+
await fs.access(resolvedCombinedPath);
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
console.log(" The `index` command accepts a single path only.");
|
|
27
|
+
console.log(" If your path contains spaces, wrap it in quotes.");
|
|
28
|
+
console.log(` Received multiple path parts: ${inputPathParts.join(", ")}`);
|
|
29
|
+
console.log("");
|
|
30
|
+
process.exitCode = 1;
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
let repoPath;
|
|
35
|
+
if (inputPath) {
|
|
36
|
+
repoPath = path.resolve(inputPath);
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
const gitRoot = getGitRoot(process.cwd());
|
|
40
|
+
if (!gitRoot) {
|
|
41
|
+
console.log(" Not inside a git repository, try to run git init\n");
|
|
42
|
+
process.exitCode = 1;
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
repoPath = gitRoot;
|
|
46
|
+
}
|
|
47
|
+
if (!options?.allowNonGit && !isGitRepo(repoPath)) {
|
|
48
|
+
console.log(` Not a git repository: ${repoPath}`);
|
|
49
|
+
console.log(" Initialize one with `git init` or choose a valid repo path.\n");
|
|
50
|
+
console.log(" Or use --allow-non-git to register an existing .gitnexus index anyway.\n");
|
|
51
|
+
process.exitCode = 1;
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
const { storagePath, lbugPath } = getStoragePaths(repoPath);
|
|
55
|
+
// ── Verify .gitnexus/ exists ──────────────────────────────────────
|
|
56
|
+
try {
|
|
57
|
+
await fs.access(storagePath);
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
console.log(` No .gitnexus/ folder found at: ${storagePath}`);
|
|
61
|
+
console.log(" Run `gitnexus analyze` to build the index first.\n");
|
|
62
|
+
process.exitCode = 1;
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
// ── Verify lbug database exists ───────────────────────────────────
|
|
66
|
+
try {
|
|
67
|
+
await fs.access(lbugPath);
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
console.log(` .gitnexus/ folder exists but contains no LadybugDB index.`);
|
|
71
|
+
console.log(" Run `gitnexus analyze` to build the index.\n");
|
|
72
|
+
process.exitCode = 1;
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
// ── Load or reconstruct meta ──────────────────────────────────────
|
|
76
|
+
let meta = await loadMeta(storagePath);
|
|
77
|
+
if (!meta) {
|
|
78
|
+
if (!options?.force) {
|
|
79
|
+
console.log(` .gitnexus/ exists but meta.json is missing.`);
|
|
80
|
+
console.log(" Use --force to register anyway (stats will be empty),");
|
|
81
|
+
console.log(" or run `gitnexus analyze` to rebuild properly.\n");
|
|
82
|
+
process.exitCode = 1;
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
// --force: build a minimal meta so the repo can be registered
|
|
86
|
+
meta = {
|
|
87
|
+
repoPath,
|
|
88
|
+
lastCommit: "",
|
|
89
|
+
indexedAt: new Date().toISOString(),
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
// ── Register in global registry ───────────────────────────────────
|
|
93
|
+
await registerRepo(repoPath, meta);
|
|
94
|
+
await addToGitignore(repoPath);
|
|
95
|
+
const projectName = path.basename(repoPath);
|
|
96
|
+
const { stats } = meta;
|
|
97
|
+
console.log(` Repository registered: ${projectName}`);
|
|
98
|
+
if (stats) {
|
|
99
|
+
const parts = [];
|
|
100
|
+
if (stats.nodes != null) {
|
|
101
|
+
parts.push(`${stats.nodes.toLocaleString()} nodes`);
|
|
102
|
+
}
|
|
103
|
+
if (stats.edges != null) {
|
|
104
|
+
parts.push(`${stats.edges.toLocaleString()} edges`);
|
|
105
|
+
}
|
|
106
|
+
if (stats.communities != null)
|
|
107
|
+
parts.push(`${stats.communities} clusters`);
|
|
108
|
+
if (stats.processes != null)
|
|
109
|
+
parts.push(`${stats.processes} flows`);
|
|
110
|
+
if (parts.length)
|
|
111
|
+
console.log(` ${parts.join(" | ")}`);
|
|
112
|
+
}
|
|
113
|
+
console.log(` ${repoPath}`);
|
|
114
|
+
console.log("");
|
|
115
|
+
};
|
package/dist/cli/index.js
CHANGED
|
@@ -25,6 +25,12 @@ program
|
|
|
25
25
|
.option('-v, --verbose', 'Enable verbose ingestion warnings (default: false)')
|
|
26
26
|
.addHelpText('after', '\nEnvironment variables:\n GITNEXUS_NO_GITIGNORE=1 Skip .gitignore parsing (still reads .gitnexusignore)')
|
|
27
27
|
.action(createLazyAction(() => import('./analyze.js'), 'analyzeCommand'));
|
|
28
|
+
program
|
|
29
|
+
.command('index [path...]')
|
|
30
|
+
.description('Register an existing .gitnexus/ folder into the global registry (no re-analysis needed)')
|
|
31
|
+
.option('-f, --force', 'Register even if meta.json is missing (stats will be empty)')
|
|
32
|
+
.option('--allow-non-git', 'Allow registering folders that are not Git repositories')
|
|
33
|
+
.action(createLazyAction(() => import('./index-repo.js'), 'indexCommand'));
|
|
28
34
|
program
|
|
29
35
|
.command('serve')
|
|
30
36
|
.description('Start local HTTP server for web UI connection')
|
|
@@ -53,11 +59,14 @@ program
|
|
|
53
59
|
.command('wiki [path]')
|
|
54
60
|
.description('Generate repository wiki from knowledge graph')
|
|
55
61
|
.option('-f, --force', 'Force full regeneration even if up to date')
|
|
56
|
-
.option('--
|
|
57
|
-
.option('--
|
|
62
|
+
.option('--provider <provider>', 'LLM provider: openai or cursor (default: openai)')
|
|
63
|
+
.option('--model <model>', 'LLM model name (default depends on provider)')
|
|
64
|
+
.option('--base-url <url>', 'LLM API base URL (for openai provider)')
|
|
58
65
|
.option('--api-key <key>', 'LLM API key (saved to ~/.gitnexus/config.json)')
|
|
59
66
|
.option('--concurrency <n>', 'Parallel LLM calls (default: 3)', '3')
|
|
60
67
|
.option('--gist', 'Publish wiki as a public GitHub Gist after generation')
|
|
68
|
+
.option('-v, --verbose', 'Enable verbose output (show LLM commands and responses)')
|
|
69
|
+
.option('--review', 'Stop after grouping to review module structure before generating pages')
|
|
61
70
|
.action(createLazyAction(() => import('./wiki.js'), 'wikiCommand'));
|
|
62
71
|
program
|
|
63
72
|
.command('augment <pattern>')
|
package/dist/cli/setup.js
CHANGED
|
@@ -97,18 +97,21 @@ async function setupCursor(result) {
|
|
|
97
97
|
}
|
|
98
98
|
async function setupClaudeCode(result) {
|
|
99
99
|
const claudeDir = path.join(os.homedir(), '.claude');
|
|
100
|
-
|
|
101
|
-
if (!hasClaude) {
|
|
100
|
+
if (!(await dirExists(claudeDir))) {
|
|
102
101
|
result.skipped.push('Claude Code (not installed)');
|
|
103
102
|
return;
|
|
104
103
|
}
|
|
105
|
-
// Claude Code
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
104
|
+
// Claude Code stores MCP config in ~/.claude.json
|
|
105
|
+
const mcpPath = path.join(os.homedir(), '.claude.json');
|
|
106
|
+
try {
|
|
107
|
+
const existing = await readJsonFile(mcpPath);
|
|
108
|
+
const updated = mergeMcpConfig(existing);
|
|
109
|
+
await writeJsonFile(mcpPath, updated);
|
|
110
|
+
result.configured.push('Claude Code');
|
|
111
|
+
}
|
|
112
|
+
catch (err) {
|
|
113
|
+
result.errors.push(`Claude Code: ${err.message}`);
|
|
114
|
+
}
|
|
112
115
|
}
|
|
113
116
|
/**
|
|
114
117
|
* Install GitNexus skills to ~/.claude/skills/ for Claude Code.
|
package/dist/cli/wiki.d.ts
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* Generates repository documentation from the knowledge graph.
|
|
5
5
|
* Usage: gitnexus wiki [path] [options]
|
|
6
6
|
*/
|
|
7
|
+
import { type LLMProvider } from '../core/wiki/llm-client.js';
|
|
7
8
|
export interface WikiCommandOptions {
|
|
8
9
|
force?: boolean;
|
|
9
10
|
model?: string;
|
|
@@ -11,5 +12,8 @@ export interface WikiCommandOptions {
|
|
|
11
12
|
apiKey?: string;
|
|
12
13
|
concurrency?: string;
|
|
13
14
|
gist?: boolean;
|
|
15
|
+
provider?: LLMProvider;
|
|
16
|
+
verbose?: boolean;
|
|
17
|
+
review?: boolean;
|
|
14
18
|
}
|
|
15
19
|
export declare const wikiCommand: (inputPath?: string, options?: WikiCommandOptions) => Promise<void>;
|
package/dist/cli/wiki.js
CHANGED
|
@@ -12,6 +12,7 @@ import { getGitRoot, isGitRepo } from '../storage/git.js';
|
|
|
12
12
|
import { getStoragePaths, loadMeta, loadCLIConfig, saveCLIConfig } from '../storage/repo-manager.js';
|
|
13
13
|
import { WikiGenerator } from '../core/wiki/generator.js';
|
|
14
14
|
import { resolveLLMConfig } from '../core/wiki/llm-client.js';
|
|
15
|
+
import { detectCursorCLI } from '../core/wiki/cursor-client.js';
|
|
15
16
|
/**
|
|
16
17
|
* Prompt the user for input via stdin.
|
|
17
18
|
*/
|
|
@@ -65,6 +66,10 @@ function prompt(question, hide = false) {
|
|
|
65
66
|
});
|
|
66
67
|
}
|
|
67
68
|
export const wikiCommand = async (inputPath, options) => {
|
|
69
|
+
// Set verbose mode globally for cursor-client to pick up
|
|
70
|
+
if (options?.verbose) {
|
|
71
|
+
process.env.GITNEXUS_VERBOSE = '1';
|
|
72
|
+
}
|
|
68
73
|
console.log('\n GitNexus Wiki Generator\n');
|
|
69
74
|
// ── Resolve repo path ───────────────────────────────────────────────
|
|
70
75
|
let repoPath;
|
|
@@ -96,94 +101,130 @@ export const wikiCommand = async (inputPath, options) => {
|
|
|
96
101
|
}
|
|
97
102
|
// ── Resolve LLM config (with interactive fallback) ─────────────────
|
|
98
103
|
// Save any CLI overrides immediately
|
|
99
|
-
if (options?.apiKey || options?.model || options?.baseUrl) {
|
|
104
|
+
if (options?.apiKey || options?.model || options?.baseUrl || options?.provider) {
|
|
100
105
|
const existing = await loadCLIConfig();
|
|
101
106
|
const updates = {};
|
|
102
107
|
if (options.apiKey)
|
|
103
108
|
updates.apiKey = options.apiKey;
|
|
104
|
-
if (options.model)
|
|
105
|
-
updates.model = options.model;
|
|
106
109
|
if (options.baseUrl)
|
|
107
110
|
updates.baseUrl = options.baseUrl;
|
|
111
|
+
if (options.provider)
|
|
112
|
+
updates.provider = options.provider;
|
|
113
|
+
// Save model to appropriate field based on provider
|
|
114
|
+
if (options.model) {
|
|
115
|
+
if (options.provider === 'cursor') {
|
|
116
|
+
updates.cursorModel = options.model;
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
updates.model = options.model;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
108
122
|
await saveCLIConfig({ ...existing, ...updates });
|
|
109
123
|
console.log(' Config saved to ~/.gitnexus/config.json\n');
|
|
110
124
|
}
|
|
111
125
|
const savedConfig = await loadCLIConfig();
|
|
112
|
-
const hasSavedConfig = !!(savedConfig.apiKey && savedConfig.baseUrl);
|
|
113
|
-
const hasCLIOverrides = !!(options?.apiKey || options?.model || options?.baseUrl);
|
|
126
|
+
const hasSavedConfig = !!(savedConfig.provider === 'cursor' || (savedConfig.apiKey && savedConfig.baseUrl));
|
|
127
|
+
const hasCLIOverrides = !!(options?.apiKey || options?.model || options?.baseUrl || options?.provider);
|
|
114
128
|
let llmConfig = await resolveLLMConfig({
|
|
115
129
|
model: options?.model,
|
|
116
130
|
baseUrl: options?.baseUrl,
|
|
117
131
|
apiKey: options?.apiKey,
|
|
132
|
+
provider: options?.provider,
|
|
118
133
|
});
|
|
119
134
|
// Run interactive setup if no saved config and no CLI flags provided
|
|
120
135
|
// (even if env vars exist — let user explicitly choose their provider)
|
|
121
136
|
if (!hasSavedConfig && !hasCLIOverrides) {
|
|
122
137
|
if (!process.stdin.isTTY) {
|
|
123
|
-
|
|
138
|
+
// Non-interactive mode — need either API key or Cursor CLI
|
|
139
|
+
if (!llmConfig.apiKey && llmConfig.provider !== 'cursor') {
|
|
124
140
|
console.log(' Error: No LLM API key found.');
|
|
125
141
|
console.log(' Set OPENAI_API_KEY or GITNEXUS_API_KEY environment variable,');
|
|
126
|
-
console.log(' or pass --api-key <key
|
|
142
|
+
console.log(' or pass --api-key <key>, or use --provider cursor.\n');
|
|
127
143
|
process.exitCode = 1;
|
|
128
144
|
return;
|
|
129
145
|
}
|
|
130
|
-
// Non-interactive with env var — just use it
|
|
146
|
+
// Non-interactive with env var or cursor — just use it
|
|
131
147
|
}
|
|
132
148
|
else {
|
|
133
149
|
console.log(' No LLM configured. Let\'s set it up.\n');
|
|
134
|
-
console.log(' Supports OpenAI, OpenRouter,
|
|
150
|
+
console.log(' Supports OpenAI, OpenRouter, any OpenAI-compatible API, or Cursor CLI.\n');
|
|
151
|
+
// Check if Cursor CLI is available
|
|
152
|
+
const hasCursor = detectCursorCLI();
|
|
135
153
|
// Provider selection
|
|
136
154
|
console.log(' [1] OpenAI (api.openai.com)');
|
|
137
155
|
console.log(' [2] OpenRouter (openrouter.ai)');
|
|
138
|
-
console.log(' [3] Custom endpoint
|
|
139
|
-
|
|
156
|
+
console.log(' [3] Custom endpoint');
|
|
157
|
+
if (hasCursor) {
|
|
158
|
+
console.log(' [4] Cursor CLI (local, uses your Cursor subscription)');
|
|
159
|
+
}
|
|
160
|
+
console.log('');
|
|
161
|
+
const maxChoice = hasCursor ? '4' : '3';
|
|
162
|
+
const choice = await prompt(` Select provider (1/${maxChoice}): `);
|
|
140
163
|
let baseUrl;
|
|
141
164
|
let defaultModel;
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
baseUrl =
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
165
|
+
let provider = 'openai';
|
|
166
|
+
let key = '';
|
|
167
|
+
if (choice === '4' && hasCursor) {
|
|
168
|
+
// Cursor CLI selected - model defaults to 'auto' (Cursor's default)
|
|
169
|
+
provider = 'cursor';
|
|
170
|
+
baseUrl = '';
|
|
171
|
+
const modelInput = await prompt(' Model (leave empty for auto): ');
|
|
172
|
+
const model = modelInput || '';
|
|
173
|
+
// Save config for Cursor
|
|
174
|
+
const cursorConfig = { provider: 'cursor' };
|
|
175
|
+
if (model)
|
|
176
|
+
cursorConfig.cursorModel = model;
|
|
177
|
+
await saveCLIConfig(cursorConfig);
|
|
178
|
+
console.log(' Config saved to ~/.gitnexus/config.json\n');
|
|
179
|
+
llmConfig = { ...llmConfig, provider: 'cursor', model, apiKey: '', baseUrl: '' };
|
|
154
180
|
}
|
|
155
181
|
else {
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
182
|
+
// OpenAI-compatible provider
|
|
183
|
+
if (choice === '2') {
|
|
184
|
+
baseUrl = 'https://openrouter.ai/api/v1';
|
|
185
|
+
defaultModel = 'minimax/minimax-m2.5';
|
|
186
|
+
}
|
|
187
|
+
else if (choice === '3') {
|
|
188
|
+
baseUrl = await prompt(' Base URL (e.g. http://localhost:11434/v1): ');
|
|
189
|
+
if (!baseUrl) {
|
|
190
|
+
console.log('\n No URL provided. Aborting.\n');
|
|
191
|
+
process.exitCode = 1;
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
defaultModel = 'gpt-4o-mini';
|
|
195
|
+
}
|
|
196
|
+
else {
|
|
197
|
+
baseUrl = 'https://api.openai.com/v1';
|
|
198
|
+
defaultModel = 'gpt-4o-mini';
|
|
199
|
+
}
|
|
200
|
+
// Model
|
|
201
|
+
const modelInput = await prompt(` Model (default: ${defaultModel}): `);
|
|
202
|
+
const model = modelInput || defaultModel;
|
|
203
|
+
// API key — pre-fill hint if env var exists
|
|
204
|
+
const envKey = process.env.GITNEXUS_API_KEY || process.env.OPENAI_API_KEY || '';
|
|
205
|
+
if (envKey) {
|
|
206
|
+
const masked = envKey.slice(0, 6) + '...' + envKey.slice(-4);
|
|
207
|
+
const useEnv = await prompt(` Use existing env key (${masked})? (Y/n): `);
|
|
208
|
+
if (!useEnv || useEnv.toLowerCase() === 'y' || useEnv.toLowerCase() === 'yes') {
|
|
209
|
+
key = envKey;
|
|
210
|
+
}
|
|
211
|
+
else {
|
|
212
|
+
key = await prompt(' API key: ', true);
|
|
213
|
+
}
|
|
170
214
|
}
|
|
171
215
|
else {
|
|
172
216
|
key = await prompt(' API key: ', true);
|
|
173
217
|
}
|
|
218
|
+
if (!key) {
|
|
219
|
+
console.log('\n No key provided. Aborting.\n');
|
|
220
|
+
process.exitCode = 1;
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
// Save
|
|
224
|
+
await saveCLIConfig({ apiKey: key, baseUrl, model, provider: 'openai' });
|
|
225
|
+
console.log(' Config saved to ~/.gitnexus/config.json\n');
|
|
226
|
+
llmConfig = { ...llmConfig, apiKey: key, baseUrl, model, provider: 'openai' };
|
|
174
227
|
}
|
|
175
|
-
else {
|
|
176
|
-
key = await prompt(' API key: ', true);
|
|
177
|
-
}
|
|
178
|
-
if (!key) {
|
|
179
|
-
console.log('\n No key provided. Aborting.\n');
|
|
180
|
-
process.exitCode = 1;
|
|
181
|
-
return;
|
|
182
|
-
}
|
|
183
|
-
// Save
|
|
184
|
-
await saveCLIConfig({ apiKey: key, baseUrl, model });
|
|
185
|
-
console.log(' Config saved to ~/.gitnexus/config.json\n');
|
|
186
|
-
llmConfig = { ...llmConfig, apiKey: key, baseUrl, model };
|
|
187
228
|
}
|
|
188
229
|
}
|
|
189
230
|
// ── Setup progress bar with elapsed timer ──────────────────────────
|
|
@@ -213,9 +254,8 @@ export const wikiCommand = async (inputPath, options) => {
|
|
|
213
254
|
// ── Run generator ───────────────────────────────────────────────────
|
|
214
255
|
const wikiOptions = {
|
|
215
256
|
force: options?.force,
|
|
216
|
-
model: options?.model,
|
|
217
|
-
baseUrl: options?.baseUrl,
|
|
218
257
|
concurrency: options?.concurrency ? parseInt(options.concurrency, 10) : undefined,
|
|
258
|
+
reviewOnly: options?.review,
|
|
219
259
|
};
|
|
220
260
|
const generator = new WikiGenerator(repoPath, storagePath, lbugPath, llmConfig, wikiOptions, (phase, percent, detail) => {
|
|
221
261
|
const label = detail || phase;
|
|
@@ -228,11 +268,92 @@ export const wikiCommand = async (inputPath, options) => {
|
|
|
228
268
|
try {
|
|
229
269
|
const result = await generator.run();
|
|
230
270
|
clearInterval(elapsedTimer);
|
|
231
|
-
bar.update(100, { phase: 'Done' });
|
|
232
271
|
bar.stop();
|
|
233
272
|
const elapsed = ((Date.now() - t0) / 1000).toFixed(1);
|
|
234
273
|
const wikiDir = path.join(storagePath, 'wiki');
|
|
235
274
|
const viewerPath = path.join(wikiDir, 'index.html');
|
|
275
|
+
const treeFile = path.join(wikiDir, 'module_tree.json');
|
|
276
|
+
// Review mode: show module tree and ask for confirmation
|
|
277
|
+
if (options?.review && result.moduleTree) {
|
|
278
|
+
console.log(`\n Module structure ready for review (${elapsed}s)\n`);
|
|
279
|
+
console.log(' Modules to generate:\n');
|
|
280
|
+
const printTree = (nodes, indent = 0) => {
|
|
281
|
+
for (const node of nodes) {
|
|
282
|
+
const prefix = ' '.repeat(indent + 2);
|
|
283
|
+
const fileCount = node.files?.length || 0;
|
|
284
|
+
const childCount = node.children?.length || 0;
|
|
285
|
+
const suffix = fileCount > 0 ? ` (${fileCount} files)` : childCount > 0 ? ` (${childCount} children)` : '';
|
|
286
|
+
console.log(`${prefix}- ${node.name}${suffix}`);
|
|
287
|
+
if (node.children && node.children.length > 0) {
|
|
288
|
+
printTree(node.children, indent + 1);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
};
|
|
292
|
+
printTree(result.moduleTree);
|
|
293
|
+
console.log(`\n Tree saved to: ${treeFile}`);
|
|
294
|
+
console.log(' You can edit this file to remove/rename modules.\n');
|
|
295
|
+
// Ask for confirmation (auto-continue in non-interactive environments)
|
|
296
|
+
if (!process.stdin.isTTY) {
|
|
297
|
+
console.log(' Non-interactive mode — auto-continuing with generation.\n');
|
|
298
|
+
}
|
|
299
|
+
const answer = process.stdin.isTTY
|
|
300
|
+
? await prompt(' Continue with generation? (Y/n/edit): ')
|
|
301
|
+
: 'y';
|
|
302
|
+
const choice = answer.trim().toLowerCase();
|
|
303
|
+
if (choice === 'n' || choice === 'no') {
|
|
304
|
+
console.log('\n Generation cancelled. Run `gitnexus wiki` later to generate.\n');
|
|
305
|
+
return;
|
|
306
|
+
}
|
|
307
|
+
if (choice === 'edit' || choice === 'e') {
|
|
308
|
+
// Open editor for the user
|
|
309
|
+
const editor = process.env.EDITOR || process.env.VISUAL || 'vi';
|
|
310
|
+
console.log(`\n Opening ${treeFile} in ${editor}...`);
|
|
311
|
+
console.log(' Save and close the editor when done.\n');
|
|
312
|
+
try {
|
|
313
|
+
execSync(`${editor} "${treeFile}"`, { stdio: 'inherit' });
|
|
314
|
+
}
|
|
315
|
+
catch {
|
|
316
|
+
console.log(` Could not open editor. Please edit manually:\n ${treeFile}\n`);
|
|
317
|
+
console.log(' Then run `gitnexus wiki` to continue.\n');
|
|
318
|
+
return;
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
// Continue with generation using the (possibly edited) tree
|
|
322
|
+
console.log('\n Continuing with wiki generation...\n');
|
|
323
|
+
bar.start(100, 30, { phase: 'Generating pages...' });
|
|
324
|
+
// Re-run generator without reviewOnly flag
|
|
325
|
+
const continueOptions = {
|
|
326
|
+
...wikiOptions,
|
|
327
|
+
reviewOnly: false,
|
|
328
|
+
};
|
|
329
|
+
const continueGenerator = new WikiGenerator(repoPath, storagePath, lbugPath, llmConfig, continueOptions, (phase, percent, detail) => {
|
|
330
|
+
const label = detail || phase;
|
|
331
|
+
if (label !== lastPhase) {
|
|
332
|
+
lastPhase = label;
|
|
333
|
+
phaseStart = Date.now();
|
|
334
|
+
}
|
|
335
|
+
bar.update(percent, { phase: label });
|
|
336
|
+
});
|
|
337
|
+
const continueResult = await continueGenerator.run();
|
|
338
|
+
bar.update(100, { phase: 'Done' });
|
|
339
|
+
bar.stop();
|
|
340
|
+
const totalElapsed = ((Date.now() - t0) / 1000).toFixed(1);
|
|
341
|
+
console.log(`\n Wiki generated successfully (${totalElapsed}s)\n`);
|
|
342
|
+
console.log(` Mode: ${continueResult.mode}`);
|
|
343
|
+
console.log(` Pages: ${continueResult.pagesGenerated}`);
|
|
344
|
+
console.log(` Output: ${wikiDir}`);
|
|
345
|
+
console.log(` Viewer: ${viewerPath}`);
|
|
346
|
+
if (continueResult.failedModules && continueResult.failedModules.length > 0) {
|
|
347
|
+
console.log(`\n Failed modules (${continueResult.failedModules.length}):`);
|
|
348
|
+
for (const mod of continueResult.failedModules) {
|
|
349
|
+
console.log(` - ${mod}`);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
console.log('');
|
|
353
|
+
await maybePublishGist(viewerPath, options?.gist);
|
|
354
|
+
return;
|
|
355
|
+
}
|
|
356
|
+
bar.update(100, { phase: 'Done' });
|
|
236
357
|
if (result.mode === 'up-to-date' && !options?.force) {
|
|
237
358
|
console.log('\n Wiki is already up to date.');
|
|
238
359
|
console.log(` Viewer: ${viewerPath}\n`);
|
|
@@ -280,7 +401,7 @@ export const wikiCommand = async (inputPath, options) => {
|
|
|
280
401
|
}
|
|
281
402
|
else {
|
|
282
403
|
console.log(`\n Error: ${err.message}\n`);
|
|
283
|
-
if (process.env.
|
|
404
|
+
if (process.env.GITNEXUS_VERBOSE) {
|
|
284
405
|
console.error(err);
|
|
285
406
|
}
|
|
286
407
|
}
|
|
@@ -9,14 +9,13 @@
|
|
|
9
9
|
* ----------------------------------|------------------------------------------|---------------------------
|
|
10
10
|
* tree-sitter-queries.ts | Query string + LANGUAGE_QUERIES entry | (required)
|
|
11
11
|
* export-detection.ts | ExportChecker function + table entry | (required)
|
|
12
|
-
* import-
|
|
13
|
-
*
|
|
14
|
-
* call-routing.ts | callRouters entry | noRouting
|
|
12
|
+
* import-resolvers/<lang>.ts | Exported resolve<Lang>Import function | resolveStandard(...)
|
|
13
|
+
* call-routing.ts | CallRouter function (or noRouting) | noRouting
|
|
15
14
|
* entry-point-scoring.ts | ENTRY_POINT_PATTERNS entry | []
|
|
16
15
|
* framework-detection.ts | AST_FRAMEWORK_PATTERNS entry | []
|
|
17
16
|
* type-extractors/<lang>.ts | New file + index.ts import | (required)
|
|
18
17
|
* resolvers/<lang>.ts | Resolver file (if non-standard) | (only if resolveStandard insufficient)
|
|
19
|
-
* named-
|
|
18
|
+
* named-bindings/<lang>.ts | Extractor (if named imports) | (only if language has named imports)
|
|
20
19
|
*
|
|
21
20
|
* 4. Also check these files for language-specific if-checks (no compile-time guard):
|
|
22
21
|
* - mro-processor.ts (MRO strategy selection)
|
|
@@ -41,5 +40,8 @@ export declare enum SupportedLanguages {
|
|
|
41
40
|
Rust = "rust",
|
|
42
41
|
PHP = "php",
|
|
43
42
|
Kotlin = "kotlin",
|
|
44
|
-
Swift = "swift"
|
|
43
|
+
Swift = "swift",
|
|
44
|
+
Dart = "dart",
|
|
45
|
+
/** Standalone regex processor — no tree-sitter, no LanguageProvider. */
|
|
46
|
+
Cobol = "cobol"
|
|
45
47
|
}
|
|
@@ -9,14 +9,13 @@
|
|
|
9
9
|
* ----------------------------------|------------------------------------------|---------------------------
|
|
10
10
|
* tree-sitter-queries.ts | Query string + LANGUAGE_QUERIES entry | (required)
|
|
11
11
|
* export-detection.ts | ExportChecker function + table entry | (required)
|
|
12
|
-
* import-
|
|
13
|
-
*
|
|
14
|
-
* call-routing.ts | callRouters entry | noRouting
|
|
12
|
+
* import-resolvers/<lang>.ts | Exported resolve<Lang>Import function | resolveStandard(...)
|
|
13
|
+
* call-routing.ts | CallRouter function (or noRouting) | noRouting
|
|
15
14
|
* entry-point-scoring.ts | ENTRY_POINT_PATTERNS entry | []
|
|
16
15
|
* framework-detection.ts | AST_FRAMEWORK_PATTERNS entry | []
|
|
17
16
|
* type-extractors/<lang>.ts | New file + index.ts import | (required)
|
|
18
17
|
* resolvers/<lang>.ts | Resolver file (if non-standard) | (only if resolveStandard insufficient)
|
|
19
|
-
* named-
|
|
18
|
+
* named-bindings/<lang>.ts | Extractor (if named imports) | (only if language has named imports)
|
|
20
19
|
*
|
|
21
20
|
* 4. Also check these files for language-specific if-checks (no compile-time guard):
|
|
22
21
|
* - mro-processor.ts (MRO strategy selection)
|
|
@@ -43,4 +42,7 @@ export var SupportedLanguages;
|
|
|
43
42
|
SupportedLanguages["PHP"] = "php";
|
|
44
43
|
SupportedLanguages["Kotlin"] = "kotlin";
|
|
45
44
|
SupportedLanguages["Swift"] = "swift";
|
|
45
|
+
SupportedLanguages["Dart"] = "dart";
|
|
46
|
+
/** Standalone regex processor — no tree-sitter, no LanguageProvider. */
|
|
47
|
+
SupportedLanguages["Cobol"] = "cobol";
|
|
46
48
|
})(SupportedLanguages || (SupportedLanguages = {}));
|
package/dist/core/graph/graph.js
CHANGED
|
@@ -27,7 +27,14 @@ export const createKnowledgeGraph = () => {
|
|
|
27
27
|
return true;
|
|
28
28
|
};
|
|
29
29
|
/**
|
|
30
|
-
* Remove
|
|
30
|
+
* Remove a single relationship by id.
|
|
31
|
+
* Returns true if the relationship existed and was removed, false otherwise.
|
|
32
|
+
*/
|
|
33
|
+
const removeRelationship = (relationshipId) => {
|
|
34
|
+
return relationshipMap.delete(relationshipId);
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* Remove all nodes (and their relationships) belonging to a file.
|
|
31
38
|
*/
|
|
32
39
|
const removeNodesByFile = (filePath) => {
|
|
33
40
|
let removed = 0;
|
|
@@ -62,5 +69,6 @@ export const createKnowledgeGraph = () => {
|
|
|
62
69
|
addRelationship,
|
|
63
70
|
removeNode,
|
|
64
71
|
removeNodesByFile,
|
|
72
|
+
removeRelationship,
|
|
65
73
|
};
|
|
66
74
|
};
|