homegraph 1.6.1 → 1.6.2
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/CHANGELOG.md +22 -0
- package/dist/bin/homegraph.js +2 -2
- package/dist/db/index.js +1 -0
- package/dist/db/migrations.d.ts +6 -1
- package/dist/db/migrations.js +26 -1
- package/dist/db/queries.d.ts +5 -0
- package/dist/db/queries.js +17 -7
- package/dist/db/schema.sql +4 -0
- package/dist/extraction/grammars.js +2 -1
- package/dist/extraction/languages/c-cpp.d.ts +8 -0
- package/dist/extraction/languages/c-cpp.js +44 -0
- package/dist/extraction/wasm-runtime-flags.d.ts +4 -0
- package/dist/extraction/wasm-runtime-flags.js +9 -0
- package/dist/index.js +7 -1
- package/dist/installer/targets/icode.d.ts +43 -0
- package/dist/installer/targets/icode.js +631 -0
- package/dist/installer/targets/registry.js +2 -0
- package/dist/installer/targets/types.d.ts +1 -1
- package/dist/mcp/evidence-rendering.js +1 -1
- package/dist/mcp/explore-repeat-guard.d.ts +19 -5
- package/dist/mcp/explore-repeat-guard.js +35 -14
- package/dist/mcp/explore-session-state.d.ts +5 -0
- package/dist/mcp/explore-session-state.js +1 -0
- package/dist/mcp/locate-contract.js +1 -1
- package/dist/mcp/server-instructions.d.ts +2 -2
- package/dist/mcp/server-instructions.js +10 -10
- package/dist/mcp/session.js +3 -2
- package/dist/mcp/tools.d.ts +21 -2
- package/dist/mcp/tools.js +109 -50
- package/dist/resolution/c-feature-variants.d.ts +40 -0
- package/dist/resolution/c-feature-variants.js +272 -0
- package/dist/resolution/cpp-macro-visibility.d.ts +21 -0
- package/dist/resolution/cpp-macro-visibility.js +393 -0
- package/dist/resolution/index.js +11 -0
- package/dist/resolution/name-matcher.js +49 -2
- package/dist/resolution/types.d.ts +8 -0
- package/dist/resolution/types.js +8 -0
- package/dist/sync/watcher.d.ts +30 -0
- package/dist/sync/watcher.js +45 -0
- package/package.json +1 -1
package/dist/mcp/tools.js
CHANGED
|
@@ -4,6 +4,7 @@ exports.ToolHandler = exports.DEFAULT_MCP_TOOL_SHORT_NAMES = exports.tools = exp
|
|
|
4
4
|
exports.__setLoadHomeGraphForTests = __setLoadHomeGraphForTests;
|
|
5
5
|
exports.normalizeQuerySpelling = normalizeQuerySpelling;
|
|
6
6
|
exports.getExploreBudget = getExploreBudget;
|
|
7
|
+
exports.formatExploreCallBudgetNote = formatExploreCallBudgetNote;
|
|
7
8
|
exports.getExploreOutputBudget = getExploreOutputBudget;
|
|
8
9
|
exports.tightenExploreBudgetForQuery = tightenExploreBudgetForQuery;
|
|
9
10
|
exports.exploreLocatorDigestEnabled = exploreLocatorDigestEnabled;
|
|
@@ -16,6 +17,8 @@ exports.formatStaleBanner = formatStaleBanner;
|
|
|
16
17
|
exports.formatStaleFooter = formatStaleFooter;
|
|
17
18
|
exports.formatDegradedBanner = formatDegradedBanner;
|
|
18
19
|
exports.resolveMcpToolAllowlist = resolveMcpToolAllowlist;
|
|
20
|
+
exports.shortMcpToolNamesEnabled = shortMcpToolNamesEnabled;
|
|
21
|
+
exports.canonicalizeMcpToolName = canonicalizeMcpToolName;
|
|
19
22
|
exports.getStaticTools = getStaticTools;
|
|
20
23
|
exports.extractBareUsageSymbols = extractBareUsageSymbols;
|
|
21
24
|
exports.queryAsBareSymbolInventory = queryAsBareSymbolInventory;
|
|
@@ -309,6 +312,14 @@ function getExploreBudget(fileCount) {
|
|
|
309
312
|
return 4;
|
|
310
313
|
return 5;
|
|
311
314
|
}
|
|
315
|
+
/**
|
|
316
|
+
* Cooldown shown on `homegraph_explore` when the project is indexed.
|
|
317
|
+
* Matches {@link exploreCooldownSeconds}. Output tiers stay on {@link getExploreBudget}.
|
|
318
|
+
*/
|
|
319
|
+
function formatExploreCallBudgetNote(fileCount) {
|
|
320
|
+
const files = Math.max(0, fileCount).toLocaleString();
|
|
321
|
+
return `Wait ${(0, explore_repeat_guard_1.exploreCooldownSeconds)()} seconds after homegraph_explore returns before calling it again (${files} files indexed).`;
|
|
322
|
+
}
|
|
312
323
|
function getExploreOutputBudget(fileCount) {
|
|
313
324
|
// Tiered budget, scaled to project size. The budget is a CEILING (relevance
|
|
314
325
|
// still gates WHAT is included), and it MUST stay under the agent's INLINE
|
|
@@ -884,11 +895,17 @@ function formatDegradedBanner(reason) {
|
|
|
884
895
|
(reason ? `\n Reason: ${reason}` : ''));
|
|
885
896
|
}
|
|
886
897
|
/**
|
|
887
|
-
*
|
|
898
|
+
* projectPath property descriptions — kept in sync with whether the field is
|
|
899
|
+
* in `inputSchema.required`. The optional text is the module-level default
|
|
900
|
+
* (session has a bound root). {@link withRequiredProjectPath} swaps in the
|
|
901
|
+
* required text when there is no default project, so schema and prose agree.
|
|
888
902
|
*/
|
|
903
|
+
const PROJECT_PATH_DESC_OPTIONAL = 'Absolute path to the project to query (or any directory inside it) — homegraph uses the nearest .homegraph/ index at or above that path. Omit to use this session\'s default project. Pass it to query a second codebase, or when the server root has no index of its own (e.g. a monorepo where only sub-projects are indexed, so there is no default project).';
|
|
904
|
+
const PROJECT_PATH_DESC_REQUIRED = 'Required. Absolute path to the project to query (or any directory inside it) — homegraph uses the nearest .homegraph/ index at or above that path. This session has no default project, so every call must pass projectPath (e.g. a monorepo sub-project with its own .homegraph/, or any already-indexed folder).';
|
|
905
|
+
/** Common projectPath property for cross-project queries (optional / default-project sessions). */
|
|
889
906
|
const projectPathProperty = {
|
|
890
907
|
type: 'string',
|
|
891
|
-
description:
|
|
908
|
+
description: PROJECT_PATH_DESC_OPTIONAL,
|
|
892
909
|
};
|
|
893
910
|
/**
|
|
894
911
|
* EVERY homegraph tool is query-only: it reads the pre-built index and never
|
|
@@ -1181,15 +1198,15 @@ exports.tools = [
|
|
|
1181
1198
|
},
|
|
1182
1199
|
{
|
|
1183
1200
|
name: 'homegraph_explore',
|
|
1184
|
-
description: '
|
|
1201
|
+
description: 'Default locator when the task touches existing code in THIS repo. Required: `query`. ' +
|
|
1202
|
+
'Open alone (no parallel grep/glob/read in the same step) with feature/component/symbol keywords; `taskContext` = the requirement. ' +
|
|
1185
1203
|
'For module/route-profile **paths** and engineering overview use homegraph_project first (not this tool). ' +
|
|
1186
|
-
'
|
|
1187
|
-
'Do not call for routine pre-edit orientation or merely because implementation is difficult. ' +
|
|
1204
|
+
'Do NOT skip because the index might still be building — call anyway. ' +
|
|
1188
1205
|
'Located ArkTS code may include render scope, imported types, module configuration, indexed SDK signatures and control-state gaps. ' +
|
|
1189
1206
|
'Returns call paths and compact line-numbered source (Harmony route_map queries may lead with Registration sources; form/shortcuts queries may lead with Capability profiles; element/string.json literals may lead with Resource hits + optional bound .ets anchors; Seam notes may flag stubs). ArkTS symbol evidence uses complete declarations and bounded directed paths with intermediate source dependencies; explicit Gaps and stop reasons name omitted or unverified evidence. Qualify ambiguous symbols by owning type or file. State the missing relation with known anchors, requested action, scope and constraints; taskContext can carry the full task. ' +
|
|
1190
1207
|
'Reuse unchanged complete ranges; refresh missing, edited or truncated evidence. ' +
|
|
1191
1208
|
'No new evidence → change to a targeted source inspection, not a paraphrased explore. ' +
|
|
1192
|
-
|
|
1209
|
+
`After this tool returns, wait ${(0, explore_repeat_guard_1.exploreCooldownSeconds)()} seconds before calling it again. ` +
|
|
1193
1210
|
'Retrieval completion is not task completion: continue implementation and required validation.',
|
|
1194
1211
|
inputSchema: {
|
|
1195
1212
|
type: 'object',
|
|
@@ -1390,11 +1407,12 @@ exports.tools = [
|
|
|
1390
1407
|
},
|
|
1391
1408
|
];
|
|
1392
1409
|
/**
|
|
1393
|
-
* Return `defs` with `projectPath` marked `required` in each tool's inputSchema
|
|
1410
|
+
* Return `defs` with `projectPath` marked `required` in each tool's inputSchema
|
|
1411
|
+
* and with a matching property description (no "Omit…" wording).
|
|
1394
1412
|
*
|
|
1395
1413
|
* Used for the NO-DEFAULT-PROJECT tool surface (issue #993): when the MCP server
|
|
1396
1414
|
* has no default project to fall back to — a gateway server started outside any
|
|
1397
|
-
* repo, or a monorepo root whose `.
|
|
1415
|
+
* repo, or a monorepo root whose `.homegraph/` indexes live only in sub-projects
|
|
1398
1416
|
* — every call MUST carry an explicit `projectPath`, so the schema should say so.
|
|
1399
1417
|
* A `required` field is a HIGH-salience channel (MCP clients surface and often
|
|
1400
1418
|
* validate it), unlike the instructions text the reporter found too weak to stop
|
|
@@ -1403,20 +1421,31 @@ exports.tools = [
|
|
|
1403
1421
|
*
|
|
1404
1422
|
* Pure: clones each tool's schema rather than mutating the shared module-level
|
|
1405
1423
|
* `tools` array (reused by every session and the static surface). A tool that
|
|
1406
|
-
* doesn't expose projectPath
|
|
1407
|
-
*
|
|
1408
|
-
*
|
|
1424
|
+
* doesn't expose projectPath is returned untouched; explore's `['query']`
|
|
1425
|
+
* becomes `['query', 'projectPath']`, and a tool with no `required` list
|
|
1426
|
+
* (status/files) gains `['projectPath']`. The property description is always
|
|
1427
|
+
* swapped to {@link PROJECT_PATH_DESC_REQUIRED} so it cannot contradict
|
|
1428
|
+
* `required`.
|
|
1409
1429
|
*/
|
|
1410
1430
|
function withRequiredProjectPath(defs) {
|
|
1411
1431
|
return defs.map((tool) => {
|
|
1412
|
-
|
|
1432
|
+
const prop = tool.inputSchema.properties.projectPath;
|
|
1433
|
+
if (!prop)
|
|
1413
1434
|
return tool;
|
|
1414
1435
|
const required = tool.inputSchema.required ?? [];
|
|
1415
|
-
|
|
1416
|
-
|
|
1436
|
+
const nextRequired = required.includes('projectPath')
|
|
1437
|
+
? required
|
|
1438
|
+
: [...required, 'projectPath'];
|
|
1417
1439
|
return {
|
|
1418
1440
|
...tool,
|
|
1419
|
-
inputSchema: {
|
|
1441
|
+
inputSchema: {
|
|
1442
|
+
...tool.inputSchema,
|
|
1443
|
+
properties: {
|
|
1444
|
+
...tool.inputSchema.properties,
|
|
1445
|
+
projectPath: { ...prop, description: PROJECT_PATH_DESC_REQUIRED },
|
|
1446
|
+
},
|
|
1447
|
+
required: nextRequired,
|
|
1448
|
+
},
|
|
1420
1449
|
};
|
|
1421
1450
|
});
|
|
1422
1451
|
}
|
|
@@ -1442,6 +1471,40 @@ function filterToolsByAllowlist(defs, allow) {
|
|
|
1442
1471
|
return defs;
|
|
1443
1472
|
return defs.filter((t) => allow.has(t.name.replace(/^homegraph_/, '')));
|
|
1444
1473
|
}
|
|
1474
|
+
/**
|
|
1475
|
+
* Product hosts that prefix MCP tools with the server name (e.g. DevEco Code
|
|
1476
|
+
* → `homegraph_` + tool name) set `HOMEGRAPH_MCP_SHORT_TOOL_NAMES=1` so
|
|
1477
|
+
* tools/list exposes `explore` / `project` instead of `homegraph_explore`.
|
|
1478
|
+
* After the host prefix, the model-visible name is still `homegraph_explore`.
|
|
1479
|
+
* Cursor / Claude leave this unset and keep the canonical `homegraph_*` names.
|
|
1480
|
+
*/
|
|
1481
|
+
function shortMcpToolNamesEnabled(raw = process.env.HOMEGRAPH_MCP_SHORT_TOOL_NAMES) {
|
|
1482
|
+
const v = (raw ?? '').trim().toLowerCase();
|
|
1483
|
+
return v === '1' || v === 'true' || v === 'yes';
|
|
1484
|
+
}
|
|
1485
|
+
const CANONICAL_TOOL_NAMES = new Set(exports.tools.map((t) => t.name));
|
|
1486
|
+
/**
|
|
1487
|
+
* Map a tools/call name to the canonical `homegraph_*` form.
|
|
1488
|
+
* Accepts both short (`explore`) and long (`homegraph_explore`) so hosts that
|
|
1489
|
+
* list short names (or still pass the long name) both work.
|
|
1490
|
+
*/
|
|
1491
|
+
function canonicalizeMcpToolName(name) {
|
|
1492
|
+
if (!name)
|
|
1493
|
+
return name;
|
|
1494
|
+
if (name.startsWith('homegraph_'))
|
|
1495
|
+
return name;
|
|
1496
|
+
const canonical = `homegraph_${name}`;
|
|
1497
|
+
return CANONICAL_TOOL_NAMES.has(canonical) ? canonical : name;
|
|
1498
|
+
}
|
|
1499
|
+
/** Clone defs with `homegraph_` stripped from each tool name (list surface only). */
|
|
1500
|
+
function withShortToolNames(defs) {
|
|
1501
|
+
if (!shortMcpToolNamesEnabled())
|
|
1502
|
+
return defs;
|
|
1503
|
+
return defs.map((t) => ({
|
|
1504
|
+
...t,
|
|
1505
|
+
name: t.name.replace(/^homegraph_/, ''),
|
|
1506
|
+
}));
|
|
1507
|
+
}
|
|
1445
1508
|
/**
|
|
1446
1509
|
* Allowlist-filtered tool definitions WITHOUT an engine — the static surface the
|
|
1447
1510
|
* proxy answers `tools/list` with before any project is open. Mirrors
|
|
@@ -1449,7 +1512,7 @@ function filterToolsByAllowlist(defs, allow) {
|
|
|
1449
1512
|
* note in a description only adds once `cg` is loaded; the schemas are static).
|
|
1450
1513
|
*/
|
|
1451
1514
|
function getStaticTools() {
|
|
1452
|
-
return filterToolsByAllowlist(exports.tools, resolveMcpToolAllowlist());
|
|
1515
|
+
return withShortToolNames(filterToolsByAllowlist(exports.tools, resolveMcpToolAllowlist()));
|
|
1453
1516
|
}
|
|
1454
1517
|
/** Prose that reads like an identifier but never names a symbol worth scanning. */
|
|
1455
1518
|
const BARE_USAGE_STOPWORDS = new Set([
|
|
@@ -1748,7 +1811,7 @@ class ToolHandler {
|
|
|
1748
1811
|
// IS open we leave projectPath optional (below): a bare call falls back to
|
|
1749
1812
|
// it, exactly as in the common single-project launch.
|
|
1750
1813
|
if (!this.cg)
|
|
1751
|
-
return withRequiredProjectPath(visible);
|
|
1814
|
+
return withShortToolNames(withRequiredProjectPath(visible));
|
|
1752
1815
|
try {
|
|
1753
1816
|
const stats = this.cg.getStats();
|
|
1754
1817
|
// Tiny-repo tool gating applies only when the host asked for the full
|
|
@@ -1771,7 +1834,7 @@ class ToolHandler {
|
|
|
1771
1834
|
if (askedForFullCatalog && stats.fileCount < TINY_REPO_FILE_THRESHOLD) {
|
|
1772
1835
|
visible = visible.filter(t => TINY_REPO_CORE_TOOLS.has(t.name));
|
|
1773
1836
|
}
|
|
1774
|
-
return visible.map(tool => {
|
|
1837
|
+
return withShortToolNames(visible.map(tool => {
|
|
1775
1838
|
if (tool.name === 'homegraph_explore') {
|
|
1776
1839
|
return {
|
|
1777
1840
|
...tool,
|
|
@@ -1779,10 +1842,10 @@ class ToolHandler {
|
|
|
1779
1842
|
};
|
|
1780
1843
|
}
|
|
1781
1844
|
return tool;
|
|
1782
|
-
});
|
|
1845
|
+
}));
|
|
1783
1846
|
}
|
|
1784
1847
|
catch {
|
|
1785
|
-
return visible;
|
|
1848
|
+
return withShortToolNames(visible);
|
|
1786
1849
|
}
|
|
1787
1850
|
}
|
|
1788
1851
|
/**
|
|
@@ -1798,12 +1861,12 @@ class ToolHandler {
|
|
|
1798
1861
|
* guidance so the frozen description and the live call-time response tell
|
|
1799
1862
|
* the same story: failed build → say so (indexing is the user's call, so
|
|
1800
1863
|
* the agent relays it); still building → point at homegraph_project and
|
|
1801
|
-
* retry; genuinely empty → honest empty note. Only fileCount > 0 carries
|
|
1802
|
-
*
|
|
1864
|
+
* retry; genuinely empty → honest empty note. Only fileCount > 0 carries the
|
|
1865
|
+
* return cooldown — there is nothing to cool down over an unbuilt index.
|
|
1803
1866
|
*/
|
|
1804
1867
|
exploreSuffix(fileCount) {
|
|
1805
1868
|
if (fileCount > 0) {
|
|
1806
|
-
return
|
|
1869
|
+
return formatExploreCallBudgetNote(fileCount);
|
|
1807
1870
|
}
|
|
1808
1871
|
const cg = this.cg;
|
|
1809
1872
|
if (cg) {
|
|
@@ -2262,6 +2325,8 @@ class ToolHandler {
|
|
|
2262
2325
|
* it (the CLI does) and explore behaves exactly as before, untracked.
|
|
2263
2326
|
*/
|
|
2264
2327
|
async execute(toolName, args, sessionState) {
|
|
2328
|
+
// Short list names (`explore`) and canonical (`homegraph_explore`) both work.
|
|
2329
|
+
toolName = canonicalizeMcpToolName(toolName);
|
|
2265
2330
|
const requestStartedAt = Date.now();
|
|
2266
2331
|
const result = await this.executeCore(toolName, args, sessionState, requestStartedAt);
|
|
2267
2332
|
this.traceToolCall(toolName, args, result, requestStartedAt);
|
|
@@ -3911,7 +3976,7 @@ class ToolHandler {
|
|
|
3911
3976
|
'',
|
|
3912
3977
|
...notes,
|
|
3913
3978
|
'',
|
|
3914
|
-
'> These sites choose their call target at runtime (registry / bus / reflection) — the site shown IS where the flow continues. To follow it, run homegraph_explore
|
|
3979
|
+
'> These sites choose their call target at runtime (registry / bus / reflection) — the site shown IS where the flow continues. To follow it, run homegraph_explore on a candidate; source for the sites above is included below.',
|
|
3915
3980
|
'',
|
|
3916
3981
|
].join('\n');
|
|
3917
3982
|
}
|
|
@@ -5152,7 +5217,7 @@ class ToolHandler {
|
|
|
5152
5217
|
else {
|
|
5153
5218
|
lines.push('> **Partial locator** — related writers / sibling Managers above are anchors, not a full answer. ' +
|
|
5154
5219
|
'ONE tighter explore with a named Type, or ONE narrow Grep for `@ohos` if still missing — ' +
|
|
5155
|
-
'do **not** fan out
|
|
5220
|
+
'do **not** fan out callers. Do **not** ANSWER NOW from local cache helpers.');
|
|
5156
5221
|
}
|
|
5157
5222
|
lines.push('');
|
|
5158
5223
|
return { section: lines.join('\n'), edgeCount, sdkImportCount, strongCount };
|
|
@@ -5257,7 +5322,7 @@ class ToolHandler {
|
|
|
5257
5322
|
'**Event types → Manager / handler sites**',
|
|
5258
5323
|
'',
|
|
5259
5324
|
'> **Partial locator** — no event Type/enum exports indexed for the named anchors. '
|
|
5260
|
-
+ '
|
|
5325
|
+
+ 'ONE explore on the Event Type file, or ONE Grep for enum members / '
|
|
5261
5326
|
+ '`case` branches — not a repo-wide storm. Do **not** ANSWER NOW.',
|
|
5262
5327
|
'',
|
|
5263
5328
|
].join('\n'),
|
|
@@ -5498,7 +5563,7 @@ class ToolHandler {
|
|
|
5498
5563
|
lines.push('- No Manager import/use sites indexed for these event types.');
|
|
5499
5564
|
lines.push('');
|
|
5500
5565
|
lines.push('> **Partial locator** — event anchors above only. '
|
|
5501
|
-
+ '
|
|
5566
|
+
+ 'ONE Grep for handler/`case` branches — do **not** ANSWER NOW as a full dispatch map.');
|
|
5502
5567
|
}
|
|
5503
5568
|
else {
|
|
5504
5569
|
for (const h of ranked.slice(0, 24)) {
|
|
@@ -5524,7 +5589,7 @@ class ToolHandler {
|
|
|
5524
5589
|
}
|
|
5525
5590
|
else {
|
|
5526
5591
|
lines.push('> **Partial locator** — handler files are anchors, but enum-member coverage may be incomplete. '
|
|
5527
|
-
+ '
|
|
5592
|
+
+ 'ONE Grep for members or `case` — do **not** repo-storm; do **not** ANSWER NOW as a full map.');
|
|
5528
5593
|
}
|
|
5529
5594
|
}
|
|
5530
5595
|
lines.push('');
|
|
@@ -5678,13 +5743,13 @@ class ToolHandler {
|
|
|
5678
5743
|
const hasExtends = extendsHits.length > 0;
|
|
5679
5744
|
if (!hasGraph && !hasExtends) {
|
|
5680
5745
|
lines.push('> **Partial locator** — Type files above are anchors. '
|
|
5681
|
-
+ '`
|
|
5746
|
+
+ '`homegraph_callees` one Type at a time; do **not** ANSWER NOW as a full graph.');
|
|
5682
5747
|
}
|
|
5683
5748
|
else {
|
|
5684
5749
|
lines.push('> Multi-Type dependency inventory — **ANSWER NOW** from locations'
|
|
5685
5750
|
+ (hasExtends ? ' + `extends` bases' : '')
|
|
5686
5751
|
+ (hasGraph ? ' + import/caller edges' : '')
|
|
5687
|
-
+ ' above;
|
|
5752
|
+
+ ' above; one tighter explore if a body detail is still missing.');
|
|
5688
5753
|
}
|
|
5689
5754
|
lines.push('');
|
|
5690
5755
|
return { section: lines.join('\n'), hitCount: locs.length + edges.length + extendsHits.length };
|
|
@@ -6264,9 +6329,9 @@ class ToolHandler {
|
|
|
6264
6329
|
soft
|
|
6265
6330
|
? `Named-Type dependency inventory — **${multi.hitCount}** locator hit(s). `
|
|
6266
6331
|
+ '**Partial locator** — locations above; ONE tighter explore with a named Type, '
|
|
6267
|
-
+ 'or ONE narrow Grep — do **not** fan out
|
|
6332
|
+
+ 'or ONE narrow Grep — do **not** fan out callees.'
|
|
6268
6333
|
: `Named-Type dependency inventory — **${multi.hitCount}** locator hit(s). `
|
|
6269
|
-
+ '**ANSWER NOW** from locations + cross links; one
|
|
6334
|
+
+ '**ANSWER NOW** from locations + cross links; one tighter explore only if a body detail is still missing.',
|
|
6270
6335
|
'',
|
|
6271
6336
|
multi.section,
|
|
6272
6337
|
].join('\n'));
|
|
@@ -6909,7 +6974,7 @@ class ToolHandler {
|
|
|
6909
6974
|
: '> **Partial locator** — Manager / domain inventory below are anchors, not a full mechanism closure. '
|
|
6910
6975
|
+ 'Pick **ONE** concrete `*Manager` / next-hop name from the list for a tighter explore — '
|
|
6911
6976
|
+ 'do **not** re-explore a paraphrase of the same keyword bag. '
|
|
6912
|
-
+ '
|
|
6977
|
+
+ 'Prefer ONE narrow Grep for unlisted wiring — not a repo storm. '
|
|
6913
6978
|
+ 'Do **not** ANSWER NOW yet.',
|
|
6914
6979
|
'',
|
|
6915
6980
|
`Mechanism anchors: **${seedIds.size}** symbol(s) — lightweight explore (seed + flow spine).`,
|
|
@@ -7132,7 +7197,7 @@ class ToolHandler {
|
|
|
7132
7197
|
lines.push('---');
|
|
7133
7198
|
if (mechanismClosed || (hasFlowPath && topIsStrong)) {
|
|
7134
7199
|
lines.push('> **Mechanism explore complete — ANSWER NOW** from the Manager inventory + spine + digests above. '
|
|
7135
|
-
+ 'Do **not**
|
|
7200
|
+
+ 'Do **not** Read or Grep for symbols/files already shown. '
|
|
7136
7201
|
+ 'Only one tighter `homegraph_explore` if a **named** Type essential to the answer is still missing.');
|
|
7137
7202
|
}
|
|
7138
7203
|
else if (softClose) {
|
|
@@ -8293,7 +8358,7 @@ class ToolHandler {
|
|
|
8293
8358
|
}
|
|
8294
8359
|
lines.push('---');
|
|
8295
8360
|
lines.push('> **Compact local explore complete — ANSWER NOW.** ' +
|
|
8296
|
-
'Do **not** Read/Grep/`homegraph_search`/`homegraph_explore
|
|
8361
|
+
'Do **not** Read/Grep/`homegraph_search`/`homegraph_explore` for the same symbols.');
|
|
8297
8362
|
lines.push('');
|
|
8298
8363
|
return this.textResult(lines.join('\n'));
|
|
8299
8364
|
}
|
|
@@ -10021,14 +10086,9 @@ class ToolHandler {
|
|
|
10021
10086
|
const sessionPrior = (0, explore_session_state_1.viewForProject)((0, explore_session_state_1.readExploreSessionView)(args), projectRoot);
|
|
10022
10087
|
const repeat = (0, explore_repeat_guard_1.decideExploreRepeat)(sessionPrior, query);
|
|
10023
10088
|
if (!plan && this.shouldRefuseRepeatedEvidence(repeat, projectRoot)) {
|
|
10024
|
-
|
|
10025
|
-
|
|
10026
|
-
|
|
10027
|
-
query,
|
|
10028
|
-
files: [],
|
|
10029
|
-
sourceBytes: 0,
|
|
10030
|
-
responseBytes: text.length,
|
|
10031
|
-
});
|
|
10089
|
+
// Do not record this refusal. A recorded return would restart the cooldown
|
|
10090
|
+
// and a client retrying inside the window would never get through.
|
|
10091
|
+
return this.textResult((0, explore_repeat_guard_1.formatExploreRepeatRefuse)(repeat, query));
|
|
10032
10092
|
}
|
|
10033
10093
|
// A planned step already tried fast paths once, before entering full explore.
|
|
10034
10094
|
const compactLocal = plan ? null : this.tryFastInventoryExplore(cg, query, projectRoot)
|
|
@@ -11220,9 +11280,9 @@ class ToolHandler {
|
|
|
11220
11280
|
lines.push(exploreLocatorDigestEnabled()
|
|
11221
11281
|
? '> Spine / top-hit digests — treat as already Read. '
|
|
11222
11282
|
+ 'Answer from Flow + Anchors + digests when you can; ONE narrow Grep for residual unindexed wiring. '
|
|
11223
|
-
+ 'Do not re-dump these files via Read
|
|
11283
|
+
+ 'Do not re-dump these files via Read.'
|
|
11224
11284
|
: '> Line-numbered source — treat as already Read. Answer from Flow + Source below when you can; ' +
|
|
11225
|
-
'do not re-read/grep these files, and do not fan out
|
|
11285
|
+
'do not re-read/grep these files, and do not fan out search for symbols already shown. ' +
|
|
11226
11286
|
'Another `homegraph_explore` with tighter names only if a needed symbol is missing.');
|
|
11227
11287
|
lines.push('');
|
|
11228
11288
|
for (const [filePath, group] of filesToRender) {
|
|
@@ -11941,16 +12001,15 @@ class ToolHandler {
|
|
|
11941
12001
|
}
|
|
11942
12002
|
else if (anyFileTrimmed) {
|
|
11943
12003
|
lines.push('');
|
|
11944
|
-
lines.push(`> Some file sections were trimmed for size. For a specific symbol you still need, run another \`homegraph_explore\`
|
|
12004
|
+
lines.push(`> Some file sections were trimmed for size. For a specific symbol you still need, run another \`homegraph_explore\` with its exact name — line-numbered source, cheaper and more complete than Read.`);
|
|
11945
12005
|
}
|
|
11946
12006
|
// Add explore budget note based on project size
|
|
11947
12007
|
if (budget.includeBudgetNote) {
|
|
11948
12008
|
try {
|
|
11949
12009
|
const stats = cg.getStats();
|
|
11950
|
-
const callBudget = getExploreBudget(stats.fileCount);
|
|
11951
12010
|
lines.push('');
|
|
11952
|
-
lines.push(`> **Usually one explore is enough** (
|
|
11953
|
-
'Answer from Flow + Source above. Extra explore
|
|
12011
|
+
lines.push(`> **Usually one explore is enough** (wait ${(0, explore_repeat_guard_1.exploreCooldownSeconds)()}s after this result before another \`homegraph_explore\`; ${stats.fileCount.toLocaleString()} files). ` +
|
|
12012
|
+
'Answer from Flow + Source above. Extra explore/Read for the **same** symbols multiplies tokens — ' +
|
|
11954
12013
|
'only call again for a missing **named** symbol.');
|
|
11955
12014
|
}
|
|
11956
12015
|
catch {
|
|
@@ -12028,7 +12087,7 @@ class ToolHandler {
|
|
|
12028
12087
|
if (!finalText.includes('**Partial result**') && !finalText.includes('> **Explore complete**')) {
|
|
12029
12088
|
finalText +=
|
|
12030
12089
|
'\n\n> **Explore complete — ANSWER NOW.** Flow + Source above are authoritative for this query. ' +
|
|
12031
|
-
'Do **not** grep/read/`
|
|
12090
|
+
'Do **not** grep/read/`homegraph_search` for the same symbols or files (multiplies tokens). ' +
|
|
12032
12091
|
'Only call one tighter `homegraph_explore` if a named symbol essential to the answer is missing.';
|
|
12033
12092
|
}
|
|
12034
12093
|
// Curated header (#1046): substitute the sentinel with the count of files
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Is a C function defined only for a build that turns on a flag nothing in
|
|
3
|
+
* the project turns on? lua-cjson's fpconv.h defines `static inline void
|
|
4
|
+
* fpconv_init()` under `#ifdef USE_INTERNAL_FPCONV` and otherwise declares it
|
|
5
|
+
* `extern`, for fpconv.c to define. Nothing in redis's tree sets
|
|
6
|
+
* USE_INTERNAL_FPCONV, so its build compiles fpconv.c's.
|
|
7
|
+
*
|
|
8
|
+
* The name matcher asks this only when choosing among definitions of one
|
|
9
|
+
* name, where a call has to reach one of them: of a flag nothing sets, the
|
|
10
|
+
* build to follow is the one that leaves it off. Whether a macro is visible
|
|
11
|
+
* at a call (./cpp-macro-visibility) keeps such a flag unknown instead, since
|
|
12
|
+
* there an unknown flag must not suppress anything.
|
|
13
|
+
*
|
|
14
|
+
* A branch is off only when flags decide its test: `#ifdef X`, `#ifndef X`,
|
|
15
|
+
* `#if defined(X)`, `#if X`, `#if 0`, with `!`, `&&`, `||` and parentheses,
|
|
16
|
+
* and the `#elif` and `#else` after them. A flag is set nowhere when the
|
|
17
|
+
* definition's own file doesn't `#define` it, no build file in the
|
|
18
|
+
* directories from the project root down to the definition or the call names
|
|
19
|
+
* it (a Makefile's `-DX`, CMake's `option(X …)`, configure's `AC_DEFINE(X)`)
|
|
20
|
+
* and no C or C++ file of their components does — a component being the
|
|
21
|
+
* tree under the nearest directory with a build file, redis's `deps/lua/src`
|
|
22
|
+
* for fpconv.h. A macro of the compiler or the platform — a reserved name
|
|
23
|
+
* like `_WIN32` or `__linux__`, or `WIN32`, `linux`, `unix` — is unknown, and
|
|
24
|
+
* so is any other test (`#if LEVEL > 1`).
|
|
25
|
+
*/
|
|
26
|
+
import type { Node } from '../types';
|
|
27
|
+
import type { ResolutionContext } from './types';
|
|
28
|
+
export declare function clearCFeatureVariantMemos(context: ResolutionContext): void;
|
|
29
|
+
/**
|
|
30
|
+
* Is `fn`'s definition compiled only by a build that sets a flag nothing in
|
|
31
|
+
* the project sets, for the call at `ref`? A branch around both the
|
|
32
|
+
* definition and the call, in the call's own file, decides nothing.
|
|
33
|
+
*/
|
|
34
|
+
export declare function isCFeatureVariant(fn: Node, ref: {
|
|
35
|
+
filePath: string;
|
|
36
|
+
line: number;
|
|
37
|
+
}, context: ResolutionContext): boolean;
|
|
38
|
+
/** Is line `line` of `path` compiled only by a build that sets a flag nothing in the project sets? */
|
|
39
|
+
export declare function isOffByDefault(path: string, line: number, context: ResolutionContext): boolean;
|
|
40
|
+
//# sourceMappingURL=c-feature-variants.d.ts.map
|