gitnexus 1.4.0 → 1.4.1

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.
Files changed (131) hide show
  1. package/README.md +194 -214
  2. package/dist/cli/ai-context.d.ts +1 -2
  3. package/dist/cli/ai-context.js +90 -117
  4. package/dist/cli/analyze.d.ts +0 -2
  5. package/dist/cli/analyze.js +2 -20
  6. package/dist/cli/index.js +25 -17
  7. package/dist/cli/setup.js +19 -17
  8. package/dist/core/augmentation/engine.js +20 -20
  9. package/dist/core/embeddings/embedding-pipeline.js +26 -26
  10. package/dist/core/graph/types.d.ts +2 -5
  11. package/dist/core/ingestion/ast-cache.js +2 -3
  12. package/dist/core/ingestion/call-processor.d.ts +5 -5
  13. package/dist/core/ingestion/call-processor.js +258 -173
  14. package/dist/core/ingestion/cluster-enricher.js +16 -16
  15. package/dist/core/ingestion/entry-point-scoring.d.ts +1 -2
  16. package/dist/core/ingestion/entry-point-scoring.js +22 -81
  17. package/dist/core/ingestion/framework-detection.d.ts +1 -5
  18. package/dist/core/ingestion/framework-detection.js +8 -39
  19. package/dist/core/ingestion/heritage-processor.d.ts +4 -13
  20. package/dist/core/ingestion/heritage-processor.js +28 -92
  21. package/dist/core/ingestion/import-processor.d.ts +19 -17
  22. package/dist/core/ingestion/import-processor.js +695 -170
  23. package/dist/core/ingestion/parsing-processor.d.ts +10 -1
  24. package/dist/core/ingestion/parsing-processor.js +177 -41
  25. package/dist/core/ingestion/pipeline.js +26 -49
  26. package/dist/core/ingestion/process-processor.js +1 -2
  27. package/dist/core/ingestion/symbol-table.d.ts +1 -12
  28. package/dist/core/ingestion/symbol-table.js +12 -19
  29. package/dist/core/ingestion/tree-sitter-queries.d.ts +11 -11
  30. package/dist/core/ingestion/tree-sitter-queries.js +485 -590
  31. package/dist/core/ingestion/utils.d.ts +0 -67
  32. package/dist/core/ingestion/utils.js +9 -692
  33. package/dist/core/ingestion/workers/parse-worker.d.ts +3 -20
  34. package/dist/core/ingestion/workers/parse-worker.js +345 -84
  35. package/dist/core/ingestion/workers/worker-pool.js +0 -8
  36. package/dist/core/kuzu/csv-generator.js +3 -19
  37. package/dist/core/kuzu/kuzu-adapter.js +19 -14
  38. package/dist/core/kuzu/schema.d.ts +3 -3
  39. package/dist/core/kuzu/schema.js +288 -303
  40. package/dist/core/search/bm25-index.js +6 -7
  41. package/dist/core/search/hybrid-search.js +3 -3
  42. package/dist/core/wiki/diagrams.d.ts +27 -0
  43. package/dist/core/wiki/diagrams.js +163 -0
  44. package/dist/core/wiki/generator.d.ts +50 -2
  45. package/dist/core/wiki/generator.js +548 -49
  46. package/dist/core/wiki/graph-queries.d.ts +42 -0
  47. package/dist/core/wiki/graph-queries.js +276 -97
  48. package/dist/core/wiki/html-viewer.js +192 -192
  49. package/dist/core/wiki/llm-client.js +73 -11
  50. package/dist/core/wiki/prompts.d.ts +52 -8
  51. package/dist/core/wiki/prompts.js +200 -86
  52. package/dist/mcp/core/kuzu-adapter.d.ts +3 -1
  53. package/dist/mcp/core/kuzu-adapter.js +44 -13
  54. package/dist/mcp/local/local-backend.js +128 -128
  55. package/dist/mcp/resources.js +42 -42
  56. package/dist/mcp/server.js +19 -18
  57. package/dist/mcp/tools.js +104 -103
  58. package/hooks/claude/gitnexus-hook.cjs +155 -238
  59. package/hooks/claude/pre-tool-use.sh +79 -79
  60. package/hooks/claude/session-start.sh +42 -42
  61. package/package.json +96 -96
  62. package/scripts/patch-tree-sitter-swift.cjs +74 -74
  63. package/skills/gitnexus-cli.md +82 -82
  64. package/skills/gitnexus-debugging.md +89 -89
  65. package/skills/gitnexus-exploring.md +78 -78
  66. package/skills/gitnexus-guide.md +64 -64
  67. package/skills/gitnexus-impact-analysis.md +97 -97
  68. package/skills/gitnexus-pr-review.md +163 -163
  69. package/skills/gitnexus-refactoring.md +121 -121
  70. package/vendor/leiden/index.cjs +355 -355
  71. package/vendor/leiden/utils.cjs +392 -392
  72. package/dist/cli/lazy-action.d.ts +0 -6
  73. package/dist/cli/lazy-action.js +0 -18
  74. package/dist/cli/skill-gen.d.ts +0 -26
  75. package/dist/cli/skill-gen.js +0 -549
  76. package/dist/core/ingestion/constants.d.ts +0 -16
  77. package/dist/core/ingestion/constants.js +0 -16
  78. package/dist/core/ingestion/export-detection.d.ts +0 -18
  79. package/dist/core/ingestion/export-detection.js +0 -230
  80. package/dist/core/ingestion/language-config.d.ts +0 -46
  81. package/dist/core/ingestion/language-config.js +0 -167
  82. package/dist/core/ingestion/mro-processor.d.ts +0 -45
  83. package/dist/core/ingestion/mro-processor.js +0 -369
  84. package/dist/core/ingestion/named-binding-extraction.d.ts +0 -61
  85. package/dist/core/ingestion/named-binding-extraction.js +0 -363
  86. package/dist/core/ingestion/resolvers/csharp.d.ts +0 -22
  87. package/dist/core/ingestion/resolvers/csharp.js +0 -109
  88. package/dist/core/ingestion/resolvers/go.d.ts +0 -19
  89. package/dist/core/ingestion/resolvers/go.js +0 -42
  90. package/dist/core/ingestion/resolvers/index.d.ts +0 -16
  91. package/dist/core/ingestion/resolvers/index.js +0 -11
  92. package/dist/core/ingestion/resolvers/jvm.d.ts +0 -23
  93. package/dist/core/ingestion/resolvers/jvm.js +0 -87
  94. package/dist/core/ingestion/resolvers/php.d.ts +0 -15
  95. package/dist/core/ingestion/resolvers/php.js +0 -35
  96. package/dist/core/ingestion/resolvers/rust.d.ts +0 -15
  97. package/dist/core/ingestion/resolvers/rust.js +0 -73
  98. package/dist/core/ingestion/resolvers/standard.d.ts +0 -28
  99. package/dist/core/ingestion/resolvers/standard.js +0 -145
  100. package/dist/core/ingestion/resolvers/utils.d.ts +0 -33
  101. package/dist/core/ingestion/resolvers/utils.js +0 -120
  102. package/dist/core/ingestion/symbol-resolver.d.ts +0 -32
  103. package/dist/core/ingestion/symbol-resolver.js +0 -83
  104. package/dist/core/ingestion/type-env.d.ts +0 -27
  105. package/dist/core/ingestion/type-env.js +0 -86
  106. package/dist/core/ingestion/type-extractors/c-cpp.d.ts +0 -2
  107. package/dist/core/ingestion/type-extractors/c-cpp.js +0 -60
  108. package/dist/core/ingestion/type-extractors/csharp.d.ts +0 -2
  109. package/dist/core/ingestion/type-extractors/csharp.js +0 -89
  110. package/dist/core/ingestion/type-extractors/go.d.ts +0 -2
  111. package/dist/core/ingestion/type-extractors/go.js +0 -105
  112. package/dist/core/ingestion/type-extractors/index.d.ts +0 -21
  113. package/dist/core/ingestion/type-extractors/index.js +0 -29
  114. package/dist/core/ingestion/type-extractors/jvm.d.ts +0 -3
  115. package/dist/core/ingestion/type-extractors/jvm.js +0 -121
  116. package/dist/core/ingestion/type-extractors/php.d.ts +0 -2
  117. package/dist/core/ingestion/type-extractors/php.js +0 -31
  118. package/dist/core/ingestion/type-extractors/python.d.ts +0 -2
  119. package/dist/core/ingestion/type-extractors/python.js +0 -41
  120. package/dist/core/ingestion/type-extractors/rust.d.ts +0 -2
  121. package/dist/core/ingestion/type-extractors/rust.js +0 -39
  122. package/dist/core/ingestion/type-extractors/shared.d.ts +0 -17
  123. package/dist/core/ingestion/type-extractors/shared.js +0 -97
  124. package/dist/core/ingestion/type-extractors/swift.d.ts +0 -2
  125. package/dist/core/ingestion/type-extractors/swift.js +0 -43
  126. package/dist/core/ingestion/type-extractors/types.d.ts +0 -14
  127. package/dist/core/ingestion/type-extractors/types.js +0 -1
  128. package/dist/core/ingestion/type-extractors/typescript.d.ts +0 -2
  129. package/dist/core/ingestion/type-extractors/typescript.js +0 -46
  130. package/dist/mcp/compatible-stdio-transport.d.ts +0 -25
  131. package/dist/mcp/compatible-stdio-transport.js +0 -200
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Deterministic Visual Artifacts for Wiki Generation
3
+ *
4
+ * Pure functions converting graph data to Mermaid diagrams.
5
+ * All node IDs use `n_` prefix to avoid reserved keyword collisions (per commit dfd3d17).
6
+ */
7
+ import type { CallEdge, ProcessInfo } from './graph-queries.js';
8
+ /**
9
+ * Build a Mermaid flowchart of internal call edges within a module.
10
+ * Groups nodes into subgraphs by file. Returns null if no edges.
11
+ */
12
+ export declare function buildCallGraphMermaid(moduleName: string, edges: CallEdge[], maxNodes?: number): string | null;
13
+ /**
14
+ * Build a Mermaid sequence diagram from an execution flow.
15
+ * Participants are unique files; messages are function calls between steps.
16
+ * Returns null if fewer than 2 steps.
17
+ */
18
+ export declare function buildSequenceDiagram(process: ProcessInfo, maxSteps?: number): string | null;
19
+ /**
20
+ * Build a Mermaid graph showing relationships between documentation modules.
21
+ * Prunes to top N modules by total edge weight. Returns null if no edges.
22
+ */
23
+ export declare function buildInterModuleDiagram(edges: Array<{
24
+ from: string;
25
+ to: string;
26
+ count: number;
27
+ }>, maxNodes?: number): string | null;
@@ -0,0 +1,163 @@
1
+ /**
2
+ * Deterministic Visual Artifacts for Wiki Generation
3
+ *
4
+ * Pure functions converting graph data to Mermaid diagrams.
5
+ * All node IDs use `n_` prefix to avoid reserved keyword collisions (per commit dfd3d17).
6
+ */
7
+ import { shortPath } from './prompts.js';
8
+ // ─── Helpers ──────────────────────────────────────────────────────────
9
+ /**
10
+ * Sanitize a string for use as a Mermaid node ID.
11
+ * Prefixes with `n_` and strips non-alphanumeric characters.
12
+ */
13
+ function sanitizeMermaidId(name) {
14
+ return 'n_' + name.replace(/[^a-zA-Z0-9_]/g, '_');
15
+ }
16
+ /**
17
+ * Sanitize a string for use as a Mermaid label (inside quotes).
18
+ * Escapes quotes and strips control characters.
19
+ */
20
+ function sanitizeMermaidLabel(label) {
21
+ return label.replace(/"/g, "'").replace(/[\r\n]/g, ' ');
22
+ }
23
+ // ─── Internal Call Graph (Leaf Pages) ─────────────────────────────────
24
+ /**
25
+ * Build a Mermaid flowchart of internal call edges within a module.
26
+ * Groups nodes into subgraphs by file. Returns null if no edges.
27
+ */
28
+ export function buildCallGraphMermaid(moduleName, edges, maxNodes = 12) {
29
+ if (edges.length === 0)
30
+ return null;
31
+ // Collect unique nodes and group by file
32
+ const nodeSet = new Map();
33
+ for (const e of edges) {
34
+ const fromKey = `${e.fromFile}::${e.fromName}`;
35
+ const toKey = `${e.toFile}::${e.toName}`;
36
+ if (!nodeSet.has(fromKey))
37
+ nodeSet.set(fromKey, { name: e.fromName, file: e.fromFile });
38
+ if (!nodeSet.has(toKey))
39
+ nodeSet.set(toKey, { name: e.toName, file: e.toFile });
40
+ }
41
+ // Prune if too many nodes — keep nodes with most edges
42
+ if (nodeSet.size > maxNodes) {
43
+ const edgeCounts = new Map();
44
+ for (const e of edges) {
45
+ const fromKey = `${e.fromFile}::${e.fromName}`;
46
+ const toKey = `${e.toFile}::${e.toName}`;
47
+ edgeCounts.set(fromKey, (edgeCounts.get(fromKey) || 0) + 1);
48
+ edgeCounts.set(toKey, (edgeCounts.get(toKey) || 0) + 1);
49
+ }
50
+ const sorted = Array.from(edgeCounts.entries()).sort((a, b) => b[1] - a[1]);
51
+ const topKeys = new Set(sorted.slice(0, maxNodes).map(([k]) => k));
52
+ for (const key of nodeSet.keys()) {
53
+ if (!topKeys.has(key))
54
+ nodeSet.delete(key);
55
+ }
56
+ }
57
+ // Group nodes by file
58
+ const fileGroups = new Map();
59
+ for (const [key, node] of nodeSet) {
60
+ let group = fileGroups.get(node.file);
61
+ if (!group) {
62
+ group = [];
63
+ fileGroups.set(node.file, group);
64
+ }
65
+ group.push({ key, name: node.name });
66
+ }
67
+ // Build Mermaid output
68
+ const lines = ['graph TD'];
69
+ const validNodeKeys = new Set(nodeSet.keys());
70
+ for (const [file, nodes] of fileGroups) {
71
+ const subId = sanitizeMermaidId(file);
72
+ lines.push(` subgraph ${subId}["${sanitizeMermaidLabel(shortPath(file))}"]`);
73
+ for (const n of nodes) {
74
+ const nodeId = sanitizeMermaidId(n.key);
75
+ lines.push(` ${nodeId}["${sanitizeMermaidLabel(n.name)}"]`);
76
+ }
77
+ lines.push(' end');
78
+ }
79
+ // Add edges (only between valid nodes)
80
+ for (const e of edges) {
81
+ const fromKey = `${e.fromFile}::${e.fromName}`;
82
+ const toKey = `${e.toFile}::${e.toName}`;
83
+ if (validNodeKeys.has(fromKey) && validNodeKeys.has(toKey)) {
84
+ lines.push(` ${sanitizeMermaidId(fromKey)} --> ${sanitizeMermaidId(toKey)}`);
85
+ }
86
+ }
87
+ return lines.join('\n');
88
+ }
89
+ // ─── Sequence Diagram (Execution Flows) ───────────────────────────────
90
+ /**
91
+ * Build a Mermaid sequence diagram from an execution flow.
92
+ * Participants are unique files; messages are function calls between steps.
93
+ * Returns null if fewer than 2 steps.
94
+ */
95
+ export function buildSequenceDiagram(process, maxSteps = 10) {
96
+ if (process.steps.length < 2)
97
+ return null;
98
+ const steps = process.steps.slice(0, maxSteps);
99
+ // Collect unique participants (files)
100
+ const participantOrder = [];
101
+ const participantSet = new Set();
102
+ for (const s of steps) {
103
+ if (!participantSet.has(s.filePath)) {
104
+ participantSet.add(s.filePath);
105
+ participantOrder.push(s.filePath);
106
+ }
107
+ }
108
+ const lines = ['sequenceDiagram'];
109
+ for (const fp of participantOrder) {
110
+ const alias = sanitizeMermaidId(fp);
111
+ lines.push(` participant ${alias} as ${sanitizeMermaidLabel(shortPath(fp))}`);
112
+ }
113
+ // Generate messages between consecutive steps
114
+ for (let i = 0; i < steps.length - 1; i++) {
115
+ const from = sanitizeMermaidId(steps[i].filePath);
116
+ const to = sanitizeMermaidId(steps[i + 1].filePath);
117
+ const label = sanitizeMermaidLabel(steps[i + 1].name);
118
+ if (from === to) {
119
+ lines.push(` ${from} ->> ${from}: ${label}`);
120
+ }
121
+ else {
122
+ lines.push(` ${from} ->> ${to}: ${label}`);
123
+ }
124
+ }
125
+ return lines.join('\n');
126
+ }
127
+ // ─── Inter-Module Architecture Diagram (Overview Page) ────────────────
128
+ /**
129
+ * Build a Mermaid graph showing relationships between documentation modules.
130
+ * Prunes to top N modules by total edge weight. Returns null if no edges.
131
+ */
132
+ export function buildInterModuleDiagram(edges, maxNodes = 10) {
133
+ if (edges.length === 0)
134
+ return null;
135
+ // Compute total weight per module
136
+ const moduleWeight = new Map();
137
+ for (const e of edges) {
138
+ moduleWeight.set(e.from, (moduleWeight.get(e.from) || 0) + e.count);
139
+ moduleWeight.set(e.to, (moduleWeight.get(e.to) || 0) + e.count);
140
+ }
141
+ // Keep top N modules
142
+ const topModules = new Set(Array.from(moduleWeight.entries())
143
+ .sort((a, b) => b[1] - a[1])
144
+ .slice(0, maxNodes)
145
+ .map(([mod]) => mod));
146
+ // Filter edges to only include top modules
147
+ const filteredEdges = edges.filter(e => topModules.has(e.from) && topModules.has(e.to));
148
+ if (filteredEdges.length === 0)
149
+ return null;
150
+ const lines = ['graph LR'];
151
+ // Declare nodes
152
+ for (const mod of topModules) {
153
+ const nodeId = sanitizeMermaidId(mod);
154
+ lines.push(` ${nodeId}["${sanitizeMermaidLabel(mod)}"]`);
155
+ }
156
+ // Add edges with labels
157
+ for (const e of filteredEdges) {
158
+ const fromId = sanitizeMermaidId(e.from);
159
+ const toId = sanitizeMermaidId(e.to);
160
+ lines.push(` ${fromId} -->|${e.count} calls| ${toId}`);
161
+ }
162
+ return lines.join('\n');
163
+ }
@@ -17,6 +17,8 @@ export interface WikiOptions {
17
17
  apiKey?: string;
18
18
  maxTokensPerModule?: number;
19
19
  concurrency?: number;
20
+ /** Human-readable repo name (e.g. "owner/repo") for the overview title. Falls back to directory basename. */
21
+ repoName?: string;
20
22
  }
21
23
  export interface WikiMeta {
22
24
  fromCommit: string;
@@ -43,6 +45,7 @@ export declare class WikiGenerator {
43
45
  private options;
44
46
  private onProgress;
45
47
  private failedModules;
48
+ private moduleRegistry;
46
49
  constructor(repoPath: string, storagePath: string, kuzuPath: string, llmConfig: LLMConfig, options?: WikiOptions, onProgress?: ProgressCallback);
47
50
  private lastPercent;
48
51
  /**
@@ -66,13 +69,33 @@ export declare class WikiGenerator {
66
69
  */
67
70
  private parseGroupingResponse;
68
71
  /**
69
- * Fallback grouping by top-level directory when LLM parsing fails.
72
+ * Fallback grouping. Uses community file mapping when available,
73
+ * otherwise groups by top-level directory.
70
74
  */
71
75
  private fallbackGrouping;
72
76
  /**
73
77
  * Split a large module into sub-modules by subdirectory.
74
78
  */
75
79
  private splitBySubdirectory;
80
+ /**
81
+ * Split a large module into sub-modules using community data.
82
+ * Falls back to subdirectory splitting if community data doesn't help.
83
+ */
84
+ private splitByCommunity;
85
+ /**
86
+ * Build a registry mapping module slugs to their names and exported symbols.
87
+ */
88
+ private buildModuleRegistry;
89
+ /**
90
+ * Validate and fix cross-reference links in generated markdown.
91
+ * Rewrites invalid slug references using fuzzy matching.
92
+ */
93
+ private validateAndFixCrossReferences;
94
+ /**
95
+ * Extract the overview summary from a generated page.
96
+ * Uses structured markers when available, falls back to heuristics.
97
+ */
98
+ private extractSummary;
76
99
  /**
77
100
  * Generate a leaf module page from source code + graph data.
78
101
  */
@@ -83,8 +106,31 @@ export declare class WikiGenerator {
83
106
  private generateParentPage;
84
107
  private generateOverview;
85
108
  private incrementalUpdate;
109
+ /**
110
+ * Purge deleted files from module metadata and tree.
111
+ * Removes orphaned modules that lost all files.
112
+ */
113
+ private purgeDeletedFiles;
114
+ /**
115
+ * Assign new files to existing modules using call-graph neighbor analysis.
116
+ * Falls back to "Other" if no neighbors found.
117
+ */
118
+ private assignNewFilesToModules;
119
+ /**
120
+ * Sync new file assignments into both moduleFiles and moduleTree.
121
+ */
122
+ private syncNewFilesToTree;
86
123
  private getCurrentCommit;
87
- private getChangedFiles;
124
+ /**
125
+ * Parse git diff --name-status output into structured entries.
126
+ */
127
+ private parseNameStatusOutput;
128
+ /**
129
+ * Get changed files with their status (Added, Modified, Deleted).
130
+ * Handles renames as Delete + Add.
131
+ * Detects shallow clones and attempts to unshallow if needed.
132
+ */
133
+ private getChangedFilesWithStatus;
88
134
  private readSourceFiles;
89
135
  private truncateSource;
90
136
  private estimateModuleTokens;
@@ -102,6 +148,8 @@ export declare class WikiGenerator {
102
148
  */
103
149
  private runParallel;
104
150
  private findNodeBySlug;
151
+ /** Set of all slugs assigned so far — used to prevent collisions. */
152
+ private assignedSlugs;
105
153
  private slugify;
106
154
  private fileExists;
107
155
  private loadWikiMeta;