gitnexus 1.6.8-rc.26 → 1.6.8-rc.28
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 +1 -1
- package/dist/cli/ai-context.js +1 -1
- package/dist/cli/skill-gen.js +1 -1
- package/dist/cli/tool.js +4 -2
- package/dist/mcp/local/local-backend.js +48 -6
- package/dist/mcp/resources.js +1 -1
- package/dist/mcp/tools.js +18 -4
- package/package.json +1 -1
- package/skills/gitnexus-debugging.md +4 -4
- package/skills/gitnexus-exploring.md +3 -3
- package/skills/gitnexus-refactoring.md +1 -1
- package/web/assets/{agent-CJmGaI8F.js → agent-C01BpbCi.js} +91 -91
- package/web/assets/{architectureDiagram-UL44E2DR-D7Nzv8Z7.js → architectureDiagram-UL44E2DR-BETib0Ig.js} +1 -1
- package/web/assets/{chunk-LCXTWHL2-x5GBtTcn.js → chunk-LCXTWHL2-ECvRIdTA.js} +1 -1
- package/web/assets/{chunk-RG4AUYOV-5yz_7HGK.js → chunk-RG4AUYOV-htm8QilK.js} +1 -1
- package/web/assets/{classDiagram-KGZ6W3CR-Ce7th0vG.js → classDiagram-KGZ6W3CR-vJcJG7SW.js} +1 -1
- package/web/assets/{classDiagram-v2-72OJOZXJ-Cc0N-4aA.js → classDiagram-v2-72OJOZXJ-BCJH9y5K.js} +1 -1
- package/web/assets/{context-builder-_HS0v2ma.js → context-builder-C6wAZwss.js} +10 -2
- package/web/assets/{diagram-3NCE3AQN-6wUsUD7U.js → diagram-3NCE3AQN-DgbGdjct.js} +1 -1
- package/web/assets/{diagram-GF46GFSD-Disbhf7W.js → diagram-GF46GFSD-DkQKRTzf.js} +1 -1
- package/web/assets/{diagram-QXG6HAR7-BeFCG-ob.js → diagram-QXG6HAR7-fO9iaqTW.js} +1 -1
- package/web/assets/{diagram-WEQXMOUZ-Bd6Dgwiv.js → diagram-WEQXMOUZ-BFGWbiEm.js} +1 -1
- package/web/assets/{erDiagram-L5TCEMPS-sHox0Zi_.js → erDiagram-L5TCEMPS-IErmkD3i.js} +1 -1
- package/web/assets/{flowDiagram-H6V6AXG4-C0y_PyUc.js → flowDiagram-H6V6AXG4-BOtRGXXs.js} +1 -1
- package/web/assets/index-DKmSSk0F.js +626 -0
- package/web/assets/index-DeuHlyzm.css +2 -0
- package/web/assets/{infoDiagram-3YFTVSEB-K8pFihzq.js → infoDiagram-3YFTVSEB-DKRlh1as.js} +1 -1
- package/web/assets/{ishikawaDiagram-BNXS4ZKH-DnMJCWwI.js → ishikawaDiagram-BNXS4ZKH-B07zhx7A.js} +1 -1
- package/web/assets/{kanban-definition-75IXJCU3-D-4EXdJe.js → kanban-definition-75IXJCU3-_saj34_J.js} +1 -1
- package/web/assets/{mindmap-definition-2TDM6QVE-CC0qeqmA.js → mindmap-definition-2TDM6QVE-iyCoM6pR.js} +1 -1
- package/web/assets/{pieDiagram-CU6KROY3-D-53o4Ll.js → pieDiagram-CU6KROY3-DOeaMPvU.js} +1 -1
- package/web/assets/{requirementDiagram-JXO7QTGE-gNmDM8qN.js → requirementDiagram-JXO7QTGE-DMhAsO2o.js} +1 -1
- package/web/assets/{sequenceDiagram-VS2MUI6T-CxcTKXw1.js → sequenceDiagram-VS2MUI6T-CQZ5FzAV.js} +1 -1
- package/web/assets/{stateDiagram-7D4R322I-CjnhCRbL.js → stateDiagram-7D4R322I-kYVKDLkw.js} +1 -1
- package/web/assets/{stateDiagram-v2-36443NZ5-C5HPpkcW.js → stateDiagram-v2-36443NZ5-DvvdUOce.js} +1 -1
- package/web/assets/{timeline-definition-O6YCAMPW-BmDoRniN.js → timeline-definition-O6YCAMPW-CxBfIWWp.js} +1 -1
- package/web/assets/{vennDiagram-MWXL3ELB-S9b_NlgG.js → vennDiagram-MWXL3ELB-D0m2r7IU.js} +1 -1
- package/web/assets/{wardleyDiagram-CUQ6CDDI-Bbs9z_r0.js → wardleyDiagram-CUQ6CDDI-yBZJHfwp.js} +1 -1
- package/web/assets/{xychartDiagram-N2JHSOCM-FyWVcm04.js → xychartDiagram-N2JHSOCM-CQJMSAIO.js} +1 -1
- package/web/index.html +2 -2
- package/web/assets/index-COMMmbxW.css +0 -2
- package/web/assets/index-C_FZ3Bqu.js +0 -626
package/README.md
CHANGED
|
@@ -134,7 +134,7 @@ Your AI agent gets these tools automatically:
|
|
|
134
134
|
| `rename` | Multi-file coordinated rename with graph + text search | Optional |
|
|
135
135
|
| `cypher` | Raw Cypher graph queries | Optional |
|
|
136
136
|
|
|
137
|
-
> With one indexed repo, the `repo` param is optional. With multiple, specify which: `query({
|
|
137
|
+
> With one indexed repo, the `repo` param is optional. With multiple, specify which: `query({search_query: "auth", repo: "my-app"})`.
|
|
138
138
|
|
|
139
139
|
## MCP Resources
|
|
140
140
|
|
package/dist/cli/ai-context.js
CHANGED
|
@@ -134,7 +134,7 @@ This project is indexed by GitNexus as **${projectName}**${noStats ? '' : ` (${s
|
|
|
134
134
|
- **MUST run impact analysis before editing any symbol.** Before modifying a function, class, or method, run \`impact({target: "symbolName", direction: "upstream"})\` and report the blast radius (direct callers, affected processes, risk level) to the user.
|
|
135
135
|
- **MUST run \`detect_changes()\` before committing** to verify your changes only affect expected symbols and execution flows. For regression review, compare against the default branch: \`detect_changes({scope: "compare", base_ref: ${JSON.stringify(markdownSafeBranch(defaultBranch))}})\`.
|
|
136
136
|
- **MUST warn the user** if impact analysis returns HIGH or CRITICAL risk before proceeding with edits.
|
|
137
|
-
- When exploring unfamiliar code, use \`query({
|
|
137
|
+
- When exploring unfamiliar code, use \`query({search_query: "concept"})\` to find execution flows instead of grepping. It returns process-grouped results ranked by relevance.
|
|
138
138
|
- When you need full context on a specific symbol — callers, callees, which execution flows it participates in — use \`context({name: "symbolName"})\`.
|
|
139
139
|
- For security review, \`explain({target: "fileOrSymbol"})\` lists taint findings (source→sink flows; needs \`analyze --pdg\`).
|
|
140
140
|
|
package/dist/cli/skill-gen.js
CHANGED
|
@@ -483,7 +483,7 @@ const renderSkillMarkdown = (community, projectName, members, files, entryPoints
|
|
|
483
483
|
lines.push('## How to Explore');
|
|
484
484
|
lines.push('');
|
|
485
485
|
lines.push(`1. \`context({name: "${firstEntry}"})\` \u2014 see callers and callees`);
|
|
486
|
-
lines.push(`2. \`query({
|
|
486
|
+
lines.push(`2. \`query({search_query: "${community.label.toLowerCase()}"})\` \u2014 find related execution flows`);
|
|
487
487
|
lines.push('3. Read key files listed above for implementation details');
|
|
488
488
|
lines.push('4. `explain({target: "<file or symbol>"})` — persisted taint findings (source→sink data flows), when indexed with `--pdg`');
|
|
489
489
|
lines.push('');
|
package/dist/cli/tool.js
CHANGED
|
@@ -62,7 +62,8 @@ export async function queryCommand(queryText, options) {
|
|
|
62
62
|
}
|
|
63
63
|
const backend = await getBackend();
|
|
64
64
|
const result = await backend.callTool('query', {
|
|
65
|
-
|
|
65
|
+
// #2175: canonical param is search_query; the backend still accepts legacy "query".
|
|
66
|
+
search_query: queryText,
|
|
66
67
|
task_context: options?.context,
|
|
67
68
|
goal: options?.goal,
|
|
68
69
|
limit: options?.limit ? parseInt(options.limit) : undefined,
|
|
@@ -154,7 +155,8 @@ export async function cypherCommand(query, options) {
|
|
|
154
155
|
}
|
|
155
156
|
const backend = await getBackend();
|
|
156
157
|
const result = await backend.callTool('cypher', {
|
|
157
|
-
query
|
|
158
|
+
// #2175: canonical param is statement; the backend still accepts legacy "query".
|
|
159
|
+
statement: query,
|
|
158
160
|
repo: options?.repo,
|
|
159
161
|
branch: options?.branch,
|
|
160
162
|
});
|
|
@@ -43,6 +43,23 @@ function looksLikeFilePath(target) {
|
|
|
43
43
|
const lower = target.toLowerCase();
|
|
44
44
|
return SOURCE_FILE_EXTENSIONS.some((ext) => lower.endsWith(ext));
|
|
45
45
|
}
|
|
46
|
+
/**
|
|
47
|
+
* Resolve a string tool param from its canonical name or legacy alias (#2175).
|
|
48
|
+
* Returns the first NON-BLANK string of [canonical, legacy] — the canonical (new)
|
|
49
|
+
* name is preferred when it carries a real value, otherwise the legacy value is used.
|
|
50
|
+
* A blank/whitespace new value therefore does NOT clobber a valid legacy value (e.g. a
|
|
51
|
+
* gradually-migrating client that always emits the new key, blank when unset). A
|
|
52
|
+
* non-string value (the MCP envelope is not schema-validated, so clients can send any
|
|
53
|
+
* JSON type) and an all-blank input resolve to `undefined`, so the caller returns a
|
|
54
|
+
* friendly required-param error instead of throwing `TypeError` on `.trim()`.
|
|
55
|
+
*/
|
|
56
|
+
function resolveAliasString(canonical, legacy) {
|
|
57
|
+
for (const value of [canonical, legacy]) {
|
|
58
|
+
if (typeof value === 'string' && value.trim())
|
|
59
|
+
return value;
|
|
60
|
+
}
|
|
61
|
+
return undefined;
|
|
62
|
+
}
|
|
46
63
|
// AI context generation is CLI-only (gitnexus analyze)
|
|
47
64
|
// import { generateAIContextFiles } from '../../cli/ai-context.js';
|
|
48
65
|
/**
|
|
@@ -1030,6 +1047,15 @@ export class LocalBackend {
|
|
|
1030
1047
|
return this.handleGroupTool(method, params || {});
|
|
1031
1048
|
}
|
|
1032
1049
|
const p = params && typeof params === 'object' ? params : {};
|
|
1050
|
+
// #2175: Claude Code drops a tool-call argument named exactly "query", so the
|
|
1051
|
+
// query/cypher tools advertise "search_query"/"statement" while still accepting the
|
|
1052
|
+
// legacy "query" key for backward compat. The alias is resolved with `?? ` (new name
|
|
1053
|
+
// wins) at every consumer site rather than by mutating params here, so precedence is
|
|
1054
|
+
// uniform and there is no hidden mutation: query()/cypher() read it directly, the
|
|
1055
|
+
// legacy "search" alias routes through query(), and the cross-repo group-forward
|
|
1056
|
+
// resolves it self-contained in callToolAtGroupRepo. This is permanent compatibility
|
|
1057
|
+
// — third-party MCP clients may legitimately send "query", so the alias is not slated
|
|
1058
|
+
// for removal even if Claude Code's argument handling later changes.
|
|
1033
1059
|
if ((method === 'impact' || method === 'query' || method === 'context') &&
|
|
1034
1060
|
typeof p.repo === 'string' &&
|
|
1035
1061
|
p.repo.startsWith('@')) {
|
|
@@ -1118,14 +1144,18 @@ export class LocalBackend {
|
|
|
1118
1144
|
* 4. Return: { processes, process_symbols, definitions }
|
|
1119
1145
|
*/
|
|
1120
1146
|
async query(repo, params) {
|
|
1121
|
-
|
|
1122
|
-
|
|
1147
|
+
// #2175: each consumer resolves the search_query/query alias itself (there is no
|
|
1148
|
+
// chokepoint mutation in callTool). This also serves the GroupService port, which
|
|
1149
|
+
// reaches query() carrying only the legacy `query` key.
|
|
1150
|
+
const rawQuery = resolveAliasString(params.search_query, params.query);
|
|
1151
|
+
if (!rawQuery?.trim()) {
|
|
1152
|
+
return { error: 'search_query (or legacy query) parameter is required and cannot be empty.' };
|
|
1123
1153
|
}
|
|
1124
1154
|
await this.ensureInitialized(repo);
|
|
1125
1155
|
const processLimit = params.limit || 5;
|
|
1126
1156
|
const maxSymbolsPerProcess = params.max_symbols || 10;
|
|
1127
1157
|
const includeContent = params.include_content ?? false;
|
|
1128
|
-
const searchQuery =
|
|
1158
|
+
const searchQuery = rawQuery.trim();
|
|
1129
1159
|
// Per-phase timing instrumentation (#553). Records wall time for each
|
|
1130
1160
|
// observable sub-step of the search pipeline so production latency can
|
|
1131
1161
|
// be aggregated offline for Pareto analysis and bottleneck detection.
|
|
@@ -1602,7 +1632,10 @@ export class LocalBackend {
|
|
|
1602
1632
|
const repo = await this.resolveRepo(repoName);
|
|
1603
1633
|
return this.cypher(repo, { query, params });
|
|
1604
1634
|
}
|
|
1605
|
-
async cypher(repo,
|
|
1635
|
+
async cypher(repo,
|
|
1636
|
+
// #2175: "statement" is the advertised param; "query" is the legacy alias,
|
|
1637
|
+
// still accepted (and the field the internal executeCypher() passes). New wins.
|
|
1638
|
+
request) {
|
|
1606
1639
|
await this.ensureInitialized(repo);
|
|
1607
1640
|
if (!isLbugReady(repo.lbugPath)) {
|
|
1608
1641
|
return { error: 'LadybugDB not ready. Index may be corrupted.' };
|
|
@@ -1612,8 +1645,14 @@ export class LocalBackend {
|
|
|
1612
1645
|
error: '"params" must be a plain object with scalar values (string/number/boolean/null).',
|
|
1613
1646
|
};
|
|
1614
1647
|
}
|
|
1648
|
+
const cypherText = resolveAliasString(request.statement, request.query) ?? '';
|
|
1649
|
+
if (!cypherText.trim()) {
|
|
1650
|
+
// Mirror query()'s friendly required-param error instead of letting an empty
|
|
1651
|
+
// string fall through to a raw LadybugDB prepare error (#2175 review).
|
|
1652
|
+
return { error: 'statement (or legacy query) parameter is required and cannot be empty.' };
|
|
1653
|
+
}
|
|
1615
1654
|
try {
|
|
1616
|
-
const result = await executeParameterized(repo.lbugPath,
|
|
1655
|
+
const result = await executeParameterized(repo.lbugPath, cypherText, request.params ?? {});
|
|
1617
1656
|
return result;
|
|
1618
1657
|
}
|
|
1619
1658
|
catch (err) {
|
|
@@ -3984,7 +4023,10 @@ export class LocalBackend {
|
|
|
3984
4023
|
if (method === 'query') {
|
|
3985
4024
|
const queryArgs = {
|
|
3986
4025
|
name: groupName,
|
|
3987
|
-
|
|
4026
|
+
// #2175: resolve the search_query alias here (new name wins, same rule as the
|
|
4027
|
+
// local query() handler) so the group path is self-contained and does not depend
|
|
4028
|
+
// on params being normalized upstream. groupQuery() reads `query`.
|
|
4029
|
+
query: resolveAliasString(params.search_query, params.query),
|
|
3988
4030
|
};
|
|
3989
4031
|
if (typeof params.task_context === 'string')
|
|
3990
4032
|
queryArgs.task_context = params.task_context;
|
package/dist/mcp/resources.js
CHANGED
|
@@ -234,7 +234,7 @@ async function getReposResource(backend) {
|
|
|
234
234
|
if (repos.length > 1) {
|
|
235
235
|
lines.push('');
|
|
236
236
|
lines.push('# Multiple repos indexed. Use repo parameter in tool calls:');
|
|
237
|
-
lines.push(`# query({
|
|
237
|
+
lines.push(`# query({search_query: "auth", repo: "${repos[0].name}"})`);
|
|
238
238
|
}
|
|
239
239
|
return lines.join('\n');
|
|
240
240
|
}
|
package/dist/mcp/tools.js
CHANGED
|
@@ -98,7 +98,14 @@ SERVICE: optional monorepo path prefix (POSIX-style, case-sensitive segments). W
|
|
|
98
98
|
inputSchema: {
|
|
99
99
|
type: 'object',
|
|
100
100
|
properties: {
|
|
101
|
-
|
|
101
|
+
// #2175: the legacy `query` key is still accepted by the handler
|
|
102
|
+
// (resolveAliasString in local-backend.ts), but is deliberately NOT named in the
|
|
103
|
+
// advertised property or its description — surfacing "query" in the schema an LLM
|
|
104
|
+
// reads would nudge it to send `query`, the exact argument Claude Code drops.
|
|
105
|
+
search_query: {
|
|
106
|
+
type: 'string',
|
|
107
|
+
description: 'Natural language or keyword search query.',
|
|
108
|
+
},
|
|
102
109
|
task_context: {
|
|
103
110
|
type: 'string',
|
|
104
111
|
description: 'What you are working on (e.g., "adding OAuth support"). Helps ranking.',
|
|
@@ -136,7 +143,7 @@ SERVICE: optional monorepo path prefix (POSIX-style, case-sensitive segments). W
|
|
|
136
143
|
description: 'Optional monorepo service root (relative path, "/" separators). In group mode (@repo), prefix-matches symbol file paths; ignored for a normal repo name. Empty string is rejected server-side.',
|
|
137
144
|
},
|
|
138
145
|
},
|
|
139
|
-
required: ['
|
|
146
|
+
required: ['search_query'],
|
|
140
147
|
},
|
|
141
148
|
},
|
|
142
149
|
{
|
|
@@ -189,7 +196,14 @@ TIPS:
|
|
|
189
196
|
inputSchema: {
|
|
190
197
|
type: 'object',
|
|
191
198
|
properties: {
|
|
192
|
-
|
|
199
|
+
// #2175: the legacy `query` key is still accepted by the handler
|
|
200
|
+
// (resolveAliasString in local-backend.ts), but is deliberately NOT named in the
|
|
201
|
+
// advertised property or its description — surfacing "query" in the schema an LLM
|
|
202
|
+
// reads would nudge it to send `query`, the exact argument Claude Code drops.
|
|
203
|
+
statement: {
|
|
204
|
+
type: 'string',
|
|
205
|
+
description: 'Cypher statement to execute.',
|
|
206
|
+
},
|
|
193
207
|
params: {
|
|
194
208
|
type: 'object',
|
|
195
209
|
description: 'Optional query parameters for placeholders (e.g. $name) to execute via prepared statement binding.',
|
|
@@ -199,7 +213,7 @@ TIPS:
|
|
|
199
213
|
description: 'Repository name or path. Omit if only one repo is indexed.',
|
|
200
214
|
},
|
|
201
215
|
},
|
|
202
|
-
required: ['
|
|
216
|
+
required: ['statement'],
|
|
203
217
|
},
|
|
204
218
|
},
|
|
205
219
|
{
|
package/package.json
CHANGED
|
@@ -16,10 +16,10 @@ description: "Use when the user is debugging a bug, tracing an error, or asking
|
|
|
16
16
|
## Workflow
|
|
17
17
|
|
|
18
18
|
```
|
|
19
|
-
1. query({
|
|
19
|
+
1. query({search_query: "<error or symptom>"}) → Find related execution flows
|
|
20
20
|
2. context({name: "<suspect>"}) → See callers/callees/processes
|
|
21
21
|
3. READ gitnexus://repo/{name}/process/{name} → Trace execution flow
|
|
22
|
-
4. cypher({
|
|
22
|
+
4. cypher({statement: "MATCH path..."}) → Custom traces if needed
|
|
23
23
|
```
|
|
24
24
|
|
|
25
25
|
> If "Index is stale" → run `node .gitnexus/run.cjs analyze` in terminal.
|
|
@@ -51,7 +51,7 @@ description: "Use when the user is debugging a bug, tracing an error, or asking
|
|
|
51
51
|
**query** — find code related to error:
|
|
52
52
|
|
|
53
53
|
```
|
|
54
|
-
query({
|
|
54
|
+
query({search_query: "payment validation error"})
|
|
55
55
|
→ Processes: CheckoutFlow, ErrorHandling
|
|
56
56
|
→ Symbols: validatePayment, handlePaymentError, PaymentException
|
|
57
57
|
```
|
|
@@ -75,7 +75,7 @@ RETURN [n IN nodes(path) | n.name] AS chain
|
|
|
75
75
|
## Example: "Payment endpoint returns 500 intermittently"
|
|
76
76
|
|
|
77
77
|
```
|
|
78
|
-
1. query({
|
|
78
|
+
1. query({search_query: "payment error handling"})
|
|
79
79
|
→ Processes: CheckoutFlow, ErrorHandling
|
|
80
80
|
→ Symbols: validatePayment, handlePaymentError
|
|
81
81
|
|
|
@@ -18,7 +18,7 @@ description: "Use when the user asks how code works, wants to understand archite
|
|
|
18
18
|
```
|
|
19
19
|
1. READ gitnexus://repos → Discover indexed repos
|
|
20
20
|
2. READ gitnexus://repo/{name}/context → Codebase overview, check staleness
|
|
21
|
-
3. query({
|
|
21
|
+
3. query({search_query: "<what you want to understand>"}) → Find related execution flows
|
|
22
22
|
4. context({name: "<symbol>"}) → Deep dive on specific symbol
|
|
23
23
|
5. READ gitnexus://repo/{name}/process/{name} → Trace full execution flow
|
|
24
24
|
```
|
|
@@ -50,7 +50,7 @@ description: "Use when the user asks how code works, wants to understand archite
|
|
|
50
50
|
**query** — find execution flows related to a concept:
|
|
51
51
|
|
|
52
52
|
```
|
|
53
|
-
query({
|
|
53
|
+
query({search_query: "payment processing"})
|
|
54
54
|
→ Processes: CheckoutFlow, RefundFlow, WebhookHandler
|
|
55
55
|
→ Symbols grouped by flow with file locations
|
|
56
56
|
```
|
|
@@ -68,7 +68,7 @@ context({name: "validateUser"})
|
|
|
68
68
|
|
|
69
69
|
```
|
|
70
70
|
1. READ gitnexus://repo/my-app/context → 918 symbols, 45 processes
|
|
71
|
-
2. query({
|
|
71
|
+
2. query({search_query: "payment processing"})
|
|
72
72
|
→ CheckoutFlow: processPayment → validateCard → chargeStripe
|
|
73
73
|
→ RefundFlow: initiateRefund → calculateRefund → processRefund
|
|
74
74
|
3. context({name: "processPayment"})
|
|
@@ -17,7 +17,7 @@ description: "Use when the user wants to rename, extract, split, move, or restru
|
|
|
17
17
|
|
|
18
18
|
```
|
|
19
19
|
1. impact({target: "X", direction: "upstream"}) → Map all dependents
|
|
20
|
-
2. query({
|
|
20
|
+
2. query({search_query: "X"}) → Find execution flows involving X
|
|
21
21
|
3. context({name: "X"}) → See all incoming/outgoing refs
|
|
22
22
|
4. Plan update order: interfaces → implementations → callers → tests
|
|
23
23
|
```
|