homegraph 1.5.8 → 1.5.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/CHANGELOG.md +16 -0
- package/dist/extraction/index.js +17 -12
- package/dist/extraction/languages/arkts.d.ts +40 -7
- package/dist/extraction/languages/arkts.js +290 -84
- package/dist/extraction/tree-sitter.js +12 -3
- package/dist/index.js +23 -12
- package/dist/mcp/index-availability.d.ts +18 -10
- package/dist/mcp/index-availability.js +50 -23
- package/dist/mcp/server-instructions.d.ts +2 -6
- package/dist/mcp/server-instructions.js +9 -2
- package/dist/mcp/tools.d.ts +5 -0
- package/dist/mcp/tools.js +53 -56
- package/dist/project-map/index.js +2 -42
- package/package.json +2 -2
|
@@ -1,44 +1,58 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/**
|
|
3
|
-
* Product-facing index availability for MCP tool results (Spec 0032).
|
|
3
|
+
* Product-facing index availability for MCP tool results (Spec 0032 + 0035).
|
|
4
4
|
*
|
|
5
|
-
* Internal `build_phase` stays as-is; this layer maps it (+ write-lock / busy
|
|
6
|
-
* to the
|
|
5
|
+
* Internal `build_phase` stays as-is; this layer maps it (+ write-lock / busy /
|
|
6
|
+
* pending dirty files) to the five states hosts and agents should see.
|
|
7
7
|
*/
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.PRODUCT_STATUS_GLOSSARY = void 0;
|
|
9
10
|
exports.productIndexGuidance = productIndexGuidance;
|
|
11
|
+
exports.formatProductStatusLine = formatProductStatusLine;
|
|
10
12
|
exports.resolveProductIndexState = resolveProductIndexState;
|
|
11
13
|
exports.isSqliteBusyMessage = isSqliteBusyMessage;
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
'HomeGraph status=fast — module/file map is ready; full symbol index is still building.',
|
|
18
|
-
'Use `homegraph_project` for the module/file map now, then retry this tool once indexing finishes.',
|
|
19
|
-
];
|
|
20
|
-
const SYNCING_LINES = [
|
|
21
|
-
'HomeGraph status=syncing — the index is being written (lock held or local index/sync in progress).',
|
|
22
|
-
'Retry this tool shortly; do not busy-loop.',
|
|
23
|
-
];
|
|
14
|
+
exports.textAlreadyHasProductStatus = textAlreadyHasProductStatus;
|
|
15
|
+
/** One-line glossary for MCP initialize / tool surface (Spec 0035). */
|
|
16
|
+
exports.PRODUCT_STATUS_GLOSSARY = 'status: empty=not ready · fast=map only (homegraph_project) · full=fresh · dirty=usable but listed paths outdated · syncing=write lock, retry';
|
|
17
|
+
const MAX_DIRTY_PATHS = 5;
|
|
18
|
+
/** Whole-response guidance when the tool cannot usefully answer yet. */
|
|
24
19
|
function productIndexGuidance(state) {
|
|
25
20
|
switch (state) {
|
|
26
21
|
case 'empty':
|
|
27
|
-
return
|
|
22
|
+
return 'HomeGraph status=empty — not ready; retry shortly.';
|
|
28
23
|
case 'fast':
|
|
29
|
-
return
|
|
24
|
+
return 'HomeGraph status=fast — map only; use homegraph_project; retry other tools later.';
|
|
30
25
|
case 'syncing':
|
|
31
|
-
return
|
|
26
|
+
return 'HomeGraph status=syncing — locked; retry shortly, do not loop.';
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Single status line for tool footers (and for guidance-only replies).
|
|
31
|
+
* `pendingPaths` only used when `state === 'dirty'`.
|
|
32
|
+
*/
|
|
33
|
+
function formatProductStatusLine(state, opts) {
|
|
34
|
+
switch (state) {
|
|
35
|
+
case 'empty':
|
|
36
|
+
case 'fast':
|
|
37
|
+
case 'syncing':
|
|
38
|
+
return productIndexGuidance(state);
|
|
39
|
+
case 'full':
|
|
40
|
+
return 'HomeGraph status=full — complete and up to date.';
|
|
41
|
+
case 'dirty': {
|
|
42
|
+
const paths = opts?.pendingPaths ?? [];
|
|
43
|
+
if (paths.length === 0) {
|
|
44
|
+
return 'HomeGraph status=dirty — outdated: pending files';
|
|
45
|
+
}
|
|
46
|
+
const shown = paths.slice(0, MAX_DIRTY_PATHS);
|
|
47
|
+
const more = paths.length > MAX_DIRTY_PATHS ? `, …+${paths.length - MAX_DIRTY_PATHS}` : '';
|
|
48
|
+
return `HomeGraph status=dirty — outdated: ${shown.join(', ')}${more}`;
|
|
49
|
+
}
|
|
32
50
|
}
|
|
33
51
|
}
|
|
34
52
|
/**
|
|
35
53
|
* Resolve the product state from a live HomeGraph handle.
|
|
36
54
|
*
|
|
37
|
-
*
|
|
38
|
-
* - fast: map ready, full index not done (`fast` / `indexing`)
|
|
39
|
-
* - full: symbol index ready
|
|
40
|
-
* - syncing: full (or empty-while-contended-init) and a writer holds the lock /
|
|
41
|
-
* this process is indexing — reads may fail or see a moving target
|
|
55
|
+
* Priority: syncing > empty > fast > dirty > full
|
|
42
56
|
*/
|
|
43
57
|
function resolveProductIndexState(cg) {
|
|
44
58
|
let phase;
|
|
@@ -69,10 +83,23 @@ function resolveProductIndexState(cg) {
|
|
|
69
83
|
catch {
|
|
70
84
|
return 'syncing';
|
|
71
85
|
}
|
|
86
|
+
let pendingCount = 0;
|
|
87
|
+
try {
|
|
88
|
+
pendingCount = cg.getPendingFiles?.()?.length ?? 0;
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
pendingCount = 0;
|
|
92
|
+
}
|
|
93
|
+
if (pendingCount > 0)
|
|
94
|
+
return 'dirty';
|
|
72
95
|
return 'full';
|
|
73
96
|
}
|
|
74
97
|
/** True when an error message indicates SQLite writer contention. */
|
|
75
98
|
function isSqliteBusyMessage(message) {
|
|
76
99
|
return /SQLITE_BUSY|database is locked/i.test(message);
|
|
77
100
|
}
|
|
101
|
+
/** True when text is already a pure (or leading) HomeGraph status line. */
|
|
102
|
+
function textAlreadyHasProductStatus(text) {
|
|
103
|
+
return /^\s*HomeGraph status=/m.test(text);
|
|
104
|
+
}
|
|
78
105
|
//# sourceMappingURL=index-availability.js.map
|
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
* 仅调整检索选择,不改变索引、查询语义或编码任务的验收要求。
|
|
4
|
-
*/
|
|
5
|
-
export declare const SERVER_INSTRUCTIONS = "# HomeGraph \u2014 optional structural evidence for this repo\n\n## When to call (path-first, bash-first)\n\nUse ordinary bash/search/read tools first for repository paths, symbols, literal strings and local changes. Skip HomeGraph when those tools provide sufficient evidence, including for difficult implementation tasks. A known path can be read directly; an adequate source result does not need a second graph lookup.\n\nHomeGraph is optional. Use it only for a concrete unresolved relationship that benefits from graph evidence: cross-file state/event propagation, callers/callees, module dependencies or ArkTS-to-native registration. Name the missing relation and use anchors from the current task or source. There is no mandatory number of bash searches before a useful graph query.\n\nChoose the smallest available tool for that gap:\n- Exact usage/reference locations \u2192 `homegraph_usages`; callers/callees \u2192 the corresponding tool.\n- Named module dependencies/cycles \u2192 `homegraph_modules`; native exports/registration \u2192 `homegraph_native`.\n- One missing symbol body \u2192 `homegraph_node`; prefer direct read if its path is already known.\n- An unresolved cross-symbol mechanism \u2192 `homegraph_explore`. Do not use it for routine pre-edit orientation, a literal search, or to re-confirm source already found with bash.\n- ArkUI migration analysis \u2192 `homegraph_arkui_migrate` when that analysis is needed; SDK contracts \u2192 project declarations or SDK documentation.\n\nDo not call explore after a focused tool already answered the relation. Keep working directly once the edit location and affected behavior are sufficiently supported. Task difficulty and file count alone do not require graph use.\n\n## Query and recovery\n\nWrite one focused sentence: requested action + target + known anchors + unresolved relation + preservation constraints. Use the full public task as `taskContext` when needed. Keep UI labels verbatim; use exact symbols from the task or source instead of inventing names or piling up generic keywords. Use returned repository-relative paths without reconstructing an experiment directory; a path refusal requires valid in-repo relocation, not broader permissions.\n\nA project map is navigation, not proof of a located feature. Preserve requested product/module scope and verify each candidate before editing. Start with one focused graph request; recover only a named missing body/relation. Budget: \u22642 `homegraph_explore` attempts per project, \u22641 focused depth recovery; existing runtime budgets may be tighter. These are ceilings, never a required sequence. If evidence is still missing, use targeted bash/search/read and continue implementation. Do not expand into unrelated files merely to exhaust a budget.\n\n\n- ArkTS evidence packs keep complete declarations and the source dependencies of displayed static relations together. Gaps identify omitted, stale or unindexed evidence; inspect only a gap relevant to the task. A static link does not prove runtime ordering or value propagation, and a complete declaration does not prove its enclosing call conditions.\n- ArkTS path evidence follows typed, directed relations between named anchors within a bounded search. A provided path includes intermediate declarations and registration sites. Check its goal and stop reason; no path in scope does not prove no relationship. Qualify ambiguous symbols with their owning type or file.\n- Reuse complete, unchanged, line-numbered source ranges already visible. An outline, path list, truncated body or SDK declaration cannot replace missing implementation evidence. A slice hash identifies that excerpt, not the whole file. Refresh affected ranges after edits.\n- An empty edge set means the relation may be unindexed, not absent. For partial, stale or irrelevant results, inspect the exact missing source with scoped search/read. After a query adds no evidence, change the method or scope rather than paraphrasing the same explore.\n- Retrieval completion is not task completion. Continue the requested edits and validation; check the original task's behavior and preservation constraints. Build success alone does not establish functional correctness.\n\nNo index \u2192 use ordinary tools; indexing is managed by the host. Do not run HomeGraph initialization as part of solving the task.\n";
|
|
6
|
-
export declare const SERVER_INSTRUCTIONS_NO_ROOT_INDEX = "# HomeGraph \u2014 optional per-project evidence\n\nPass `projectPath` to an already indexed folder with `.homegraph/`. No index \u2192 use ordinary tools; indexing is managed by the host.\n\n## When to call (path-first, bash-first)\n\nUse ordinary bash/search/read tools first for repository paths, symbols, literal strings and local changes. Skip HomeGraph when those tools provide sufficient evidence, including for difficult implementation tasks. A known path can be read directly; an adequate source result does not need a second graph lookup.\n\nHomeGraph is optional. Use it only for a concrete unresolved relationship that benefits from graph evidence: cross-file state/event propagation, callers/callees, module dependencies or ArkTS-to-native registration. Name the missing relation and use anchors from the current task or source. There is no mandatory number of bash searches before a useful graph query.\n\nChoose the smallest available tool for that gap:\n- Exact usage/reference locations \u2192 `homegraph_usages`; callers/callees \u2192 the corresponding tool.\n- Named module dependencies/cycles \u2192 `homegraph_modules`; native exports/registration \u2192 `homegraph_native`.\n- One missing symbol body \u2192 `homegraph_node`; prefer direct read if its path is already known.\n- An unresolved cross-symbol mechanism \u2192 `homegraph_explore`. Do not use it for routine pre-edit orientation, a literal search, or to re-confirm source already found with bash.\n- ArkUI migration analysis \u2192 `homegraph_arkui_migrate` when that analysis is needed; SDK contracts \u2192 project declarations or SDK documentation.\n\nDo not call explore after a focused tool already answered the relation. Keep working directly once the edit location and affected behavior are sufficiently supported. Task difficulty and file count alone do not require graph use.\n\n## Query and recovery\n\nWrite one focused sentence: requested action + target + known anchors + unresolved relation + preservation constraints. Use the full public task as `taskContext` when needed. Keep UI labels verbatim; use exact symbols from the task or source instead of inventing names or piling up generic keywords. Use returned repository-relative paths without reconstructing an experiment directory; a path refusal requires valid in-repo relocation, not broader permissions.\n\nA project map is navigation, not proof of a located feature. Preserve requested product/module scope and verify each candidate before editing. Start with one focused graph request; recover only a named missing body/relation. Budget: \u22642 `homegraph_explore` attempts per project, \u22641 focused depth recovery; existing runtime budgets may be tighter. These are ceilings, never a required sequence. If evidence is still missing, use targeted bash/search/read and continue implementation. Do not expand into unrelated files merely to exhaust a budget.\n\n\n- ArkTS evidence packs keep complete declarations and the source dependencies of displayed static relations together. Gaps identify omitted, stale or unindexed evidence; inspect only a gap relevant to the task. A static link does not prove runtime ordering or value propagation, and a complete declaration does not prove its enclosing call conditions.\n- ArkTS path evidence follows typed, directed relations between named anchors within a bounded search. A provided path includes intermediate declarations and registration sites. Check its goal and stop reason; no path in scope does not prove no relationship. Qualify ambiguous symbols with their owning type or file.\n- Reuse complete, unchanged, line-numbered source ranges already visible. An outline, path list, truncated body or SDK declaration cannot replace missing implementation evidence. A slice hash identifies that excerpt, not the whole file. Refresh affected ranges after edits.\n- An empty edge set means the relation may be unindexed, not absent. For partial, stale or irrelevant results, inspect the exact missing source with scoped search/read. After a query adds no evidence, change the method or scope rather than paraphrasing the same explore.\n- Retrieval completion is not task completion. Continue the requested edits and validation; check the original task's behavior and preservation constraints. Build success alone does not establish functional correctness.\n\n";
|
|
1
|
+
export declare const SERVER_INSTRUCTIONS = "# HomeGraph \u2014 optional structural evidence for this repo\n\n## When to call (path-first, bash-first)\n\nUse ordinary bash/search/read tools first for repository paths, symbols, literal strings and local changes. Skip HomeGraph when those tools provide sufficient evidence, including for difficult implementation tasks. A known path can be read directly; an adequate source result does not need a second graph lookup.\n\nHomeGraph is optional. Use it only for a concrete unresolved relationship that benefits from graph evidence: cross-file state/event propagation, callers/callees, module dependencies or ArkTS-to-native registration. Name the missing relation and use anchors from the current task or source. There is no mandatory number of bash searches before a useful graph query.\n\nChoose the smallest available tool for that gap:\n- Exact usage/reference locations \u2192 `homegraph_usages`; callers/callees \u2192 the corresponding tool.\n- Named module dependencies/cycles \u2192 `homegraph_modules`; native exports/registration \u2192 `homegraph_native`.\n- One missing symbol body \u2192 `homegraph_node`; prefer direct read if its path is already known.\n- An unresolved cross-symbol mechanism \u2192 `homegraph_explore`. Do not use it for routine pre-edit orientation, a literal search, or to re-confirm source already found with bash.\n- ArkUI migration analysis \u2192 `homegraph_arkui_migrate` when that analysis is needed; SDK contracts \u2192 project declarations or SDK documentation.\n\nDo not call explore after a focused tool already answered the relation. Keep working directly once the edit location and affected behavior are sufficiently supported. Task difficulty and file count alone do not require graph use.\n\n## Query and recovery\n\nWrite one focused sentence: requested action + target + known anchors + unresolved relation + preservation constraints. Use the full public task as `taskContext` when needed. Keep UI labels verbatim; use exact symbols from the task or source instead of inventing names or piling up generic keywords. Use returned repository-relative paths without reconstructing an experiment directory; a path refusal requires valid in-repo relocation, not broader permissions.\n\nA project map is navigation, not proof of a located feature. Preserve requested product/module scope and verify each candidate before editing. Start with one focused graph request; recover only a named missing body/relation. Budget: \u22642 `homegraph_explore` attempts per project, \u22641 focused depth recovery; existing runtime budgets may be tighter. These are ceilings, never a required sequence. If evidence is still missing, use targeted bash/search/read and continue implementation. Do not expand into unrelated files merely to exhaust a budget.\n\n## Index status\n\nTool replies end with `HomeGraph status=\u2026`. status: empty=not ready \u00B7 fast=map only (homegraph_project) \u00B7 full=fresh \u00B7 dirty=usable but listed paths outdated \u00B7 syncing=write lock, retry.\n\n\n- ArkTS evidence packs keep complete declarations and the source dependencies of displayed static relations together. Gaps identify omitted, stale or unindexed evidence; inspect only a gap relevant to the task. A static link does not prove runtime ordering or value propagation, and a complete declaration does not prove its enclosing call conditions.\n- ArkTS path evidence follows typed, directed relations between named anchors within a bounded search. A provided path includes intermediate declarations and registration sites. Check its goal and stop reason; no path in scope does not prove no relationship. Qualify ambiguous symbols with their owning type or file.\n- Reuse complete, unchanged, line-numbered source ranges already visible. An outline, path list, truncated body or SDK declaration cannot replace missing implementation evidence. A slice hash identifies that excerpt, not the whole file. Refresh affected ranges after edits.\n- An empty edge set means the relation may be unindexed, not absent. For partial, stale or irrelevant results, inspect the exact missing source with scoped search/read. After a query adds no evidence, change the method or scope rather than paraphrasing the same explore.\n- Retrieval completion is not task completion. Continue the requested edits and validation; check the original task's behavior and preservation constraints. Build success alone does not establish functional correctness.\n\nNo index \u2192 use ordinary tools; indexing is managed by the host. Do not run HomeGraph initialization as part of solving the task.\n";
|
|
2
|
+
export declare const SERVER_INSTRUCTIONS_NO_ROOT_INDEX = "# HomeGraph \u2014 optional per-project evidence\n\nPass `projectPath` to an already indexed folder with `.homegraph/`. No index \u2192 use ordinary tools; indexing is managed by the host.\n\n## When to call (path-first, bash-first)\n\nUse ordinary bash/search/read tools first for repository paths, symbols, literal strings and local changes. Skip HomeGraph when those tools provide sufficient evidence, including for difficult implementation tasks. A known path can be read directly; an adequate source result does not need a second graph lookup.\n\nHomeGraph is optional. Use it only for a concrete unresolved relationship that benefits from graph evidence: cross-file state/event propagation, callers/callees, module dependencies or ArkTS-to-native registration. Name the missing relation and use anchors from the current task or source. There is no mandatory number of bash searches before a useful graph query.\n\nChoose the smallest available tool for that gap:\n- Exact usage/reference locations \u2192 `homegraph_usages`; callers/callees \u2192 the corresponding tool.\n- Named module dependencies/cycles \u2192 `homegraph_modules`; native exports/registration \u2192 `homegraph_native`.\n- One missing symbol body \u2192 `homegraph_node`; prefer direct read if its path is already known.\n- An unresolved cross-symbol mechanism \u2192 `homegraph_explore`. Do not use it for routine pre-edit orientation, a literal search, or to re-confirm source already found with bash.\n- ArkUI migration analysis \u2192 `homegraph_arkui_migrate` when that analysis is needed; SDK contracts \u2192 project declarations or SDK documentation.\n\nDo not call explore after a focused tool already answered the relation. Keep working directly once the edit location and affected behavior are sufficiently supported. Task difficulty and file count alone do not require graph use.\n\n## Query and recovery\n\nWrite one focused sentence: requested action + target + known anchors + unresolved relation + preservation constraints. Use the full public task as `taskContext` when needed. Keep UI labels verbatim; use exact symbols from the task or source instead of inventing names or piling up generic keywords. Use returned repository-relative paths without reconstructing an experiment directory; a path refusal requires valid in-repo relocation, not broader permissions.\n\nA project map is navigation, not proof of a located feature. Preserve requested product/module scope and verify each candidate before editing. Start with one focused graph request; recover only a named missing body/relation. Budget: \u22642 `homegraph_explore` attempts per project, \u22641 focused depth recovery; existing runtime budgets may be tighter. These are ceilings, never a required sequence. If evidence is still missing, use targeted bash/search/read and continue implementation. Do not expand into unrelated files merely to exhaust a budget.\n\n## Index status\n\nTool replies end with `HomeGraph status=\u2026`. status: empty=not ready \u00B7 fast=map only (homegraph_project) \u00B7 full=fresh \u00B7 dirty=usable but listed paths outdated \u00B7 syncing=write lock, retry.\n\n\n- ArkTS evidence packs keep complete declarations and the source dependencies of displayed static relations together. Gaps identify omitted, stale or unindexed evidence; inspect only a gap relevant to the task. A static link does not prove runtime ordering or value propagation, and a complete declaration does not prove its enclosing call conditions.\n- ArkTS path evidence follows typed, directed relations between named anchors within a bounded search. A provided path includes intermediate declarations and registration sites. Check its goal and stop reason; no path in scope does not prove no relationship. Qualify ambiguous symbols with their owning type or file.\n- Reuse complete, unchanged, line-numbered source ranges already visible. An outline, path list, truncated body or SDK declaration cannot replace missing implementation evidence. A slice hash identifies that excerpt, not the whole file. Refresh affected ranges after edits.\n- An empty edge set means the relation may be unindexed, not absent. For partial, stale or irrelevant results, inspect the exact missing source with scoped search/read. After a query adds no evidence, change the method or scope rather than paraphrasing the same explore.\n- Retrieval completion is not task completion. Continue the requested edits and validation; check the original task's behavior and preservation constraints. Build success alone does not establish functional correctness.\n\n";
|
|
7
3
|
//# sourceMappingURL=server-instructions.d.ts.map
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SERVER_INSTRUCTIONS_NO_ROOT_INDEX = exports.SERVER_INSTRUCTIONS = void 0;
|
|
4
|
+
const index_availability_1 = require("./index-availability");
|
|
2
5
|
/**
|
|
3
6
|
* MCP initialize 中的统一工具指引;工具描述必须遵守相同的按需策略。
|
|
4
7
|
* 仅调整检索选择,不改变索引、查询语义或编码任务的验收要求。
|
|
5
8
|
*/
|
|
6
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.SERVER_INSTRUCTIONS_NO_ROOT_INDEX = exports.SERVER_INSTRUCTIONS = void 0;
|
|
8
9
|
const SOURCE_AND_VALIDATION = `
|
|
9
10
|
- ArkTS evidence packs keep complete declarations and the source dependencies of displayed static relations together. Gaps identify omitted, stale or unindexed evidence; inspect only a gap relevant to the task. A static link does not prove runtime ordering or value propagation, and a complete declaration does not prove its enclosing call conditions.
|
|
10
11
|
- ArkTS path evidence follows typed, directed relations between named anchors within a bounded search. A provided path includes intermediate declarations and registration sites. Check its goal and stop reason; no path in scope does not prove no relationship. Qualify ambiguous symbols with their owning type or file.
|
|
@@ -33,10 +34,15 @@ Write one focused sentence: requested action + target + known anchors + unresolv
|
|
|
33
34
|
|
|
34
35
|
A project map is navigation, not proof of a located feature. Preserve requested product/module scope and verify each candidate before editing. Start with one focused graph request; recover only a named missing body/relation. Budget: ≤2 \`homegraph_explore\` attempts per project, ≤1 focused depth recovery; existing runtime budgets may be tighter. These are ceilings, never a required sequence. If evidence is still missing, use targeted bash/search/read and continue implementation. Do not expand into unrelated files merely to exhaust a budget.
|
|
35
36
|
`;
|
|
37
|
+
const INDEX_STATUS = `## Index status
|
|
38
|
+
|
|
39
|
+
Tool replies end with \`HomeGraph status=…\`. ${index_availability_1.PRODUCT_STATUS_GLOSSARY}.
|
|
40
|
+
`;
|
|
36
41
|
exports.SERVER_INSTRUCTIONS = `# HomeGraph — optional structural evidence for this repo
|
|
37
42
|
|
|
38
43
|
${ON_DEMAND}
|
|
39
44
|
${QUERY}
|
|
45
|
+
${INDEX_STATUS}
|
|
40
46
|
${SOURCE_AND_VALIDATION}
|
|
41
47
|
No index → use ordinary tools; indexing is managed by the host. Do not run HomeGraph initialization as part of solving the task.
|
|
42
48
|
`;
|
|
@@ -46,6 +52,7 @@ Pass \`projectPath\` to an already indexed folder with \`.homegraph/\`. No index
|
|
|
46
52
|
|
|
47
53
|
${ON_DEMAND}
|
|
48
54
|
${QUERY}
|
|
55
|
+
${INDEX_STATUS}
|
|
49
56
|
${SOURCE_AND_VALIDATION}
|
|
50
57
|
`;
|
|
51
58
|
//# sourceMappingURL=server-instructions.js.map
|
package/dist/mcp/tools.d.ts
CHANGED
|
@@ -418,6 +418,11 @@ export declare class ToolHandler {
|
|
|
418
418
|
*/
|
|
419
419
|
private isFileStaleOnDisk;
|
|
420
420
|
private withStalenessNotice;
|
|
421
|
+
/**
|
|
422
|
+
* Append a one-line product index status footer (Spec 0035).
|
|
423
|
+
* Guidance-only replies that already start with `HomeGraph status=` are left alone.
|
|
424
|
+
*/
|
|
425
|
+
private withProductStatusFooter;
|
|
421
426
|
/**
|
|
422
427
|
* Execute a tool by name.
|
|
423
428
|
*
|
package/dist/mcp/tools.js
CHANGED
|
@@ -26,7 +26,6 @@ const evidence_rendering_1 = require("./evidence-rendering");
|
|
|
26
26
|
const arkts_evidence_packs_1 = require("./arkts-evidence-packs");
|
|
27
27
|
const evidence_paths_1 = require("../graph/evidence-paths");
|
|
28
28
|
const query_plan_1 = require("../search/query-plan");
|
|
29
|
-
const memory_budget_1 = require("./memory-budget");
|
|
30
29
|
const index_availability_1 = require("./index-availability");
|
|
31
30
|
const directory_1 = require("../directory");
|
|
32
31
|
// Lazy-load the heavy HomeGraph chain off the MCP startup path — see the same
|
|
@@ -1560,12 +1559,11 @@ class ToolHandler {
|
|
|
1560
1559
|
if (state === 'empty') {
|
|
1561
1560
|
return (0, index_availability_1.productIndexGuidance)('empty');
|
|
1562
1561
|
}
|
|
1563
|
-
if (state === 'fast'
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
: "HomeGraph is still building this project's index. A call right now returns build-progress guidance; use `homegraph_project` for the module/file map, then retry once indexing finishes.";
|
|
1562
|
+
if (state === 'fast') {
|
|
1563
|
+
return (0, index_availability_1.productIndexGuidance)('fast');
|
|
1564
|
+
}
|
|
1565
|
+
if (state === 'syncing') {
|
|
1566
|
+
return (0, index_availability_1.productIndexGuidance)('syncing');
|
|
1569
1567
|
}
|
|
1570
1568
|
}
|
|
1571
1569
|
catch {
|
|
@@ -1894,55 +1892,61 @@ class ToolHandler {
|
|
|
1894
1892
|
const composed = `${formatDegradedBanner(reason)}\n\n${head.text}`;
|
|
1895
1893
|
return { ...result, content: [{ type: 'text', text: composed }, ...tail] };
|
|
1896
1894
|
}
|
|
1897
|
-
//
|
|
1898
|
-
//
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1895
|
+
// Spec 0035: pending/dirty is a one-line status footer (withProductStatusFooter),
|
|
1896
|
+
// not the long ⚠️ stale banner. Keep formatStaleBanner helpers for tests /
|
|
1897
|
+
// status tool; do not prepend them on every read tool.
|
|
1898
|
+
return result;
|
|
1899
|
+
}
|
|
1900
|
+
/**
|
|
1901
|
+
* Append a one-line product index status footer (Spec 0035).
|
|
1902
|
+
* Guidance-only replies that already start with `HomeGraph status=` are left alone.
|
|
1903
|
+
*/
|
|
1904
|
+
withProductStatusFooter(result, projectPath) {
|
|
1905
|
+
if (result.isError)
|
|
1907
1906
|
return result;
|
|
1908
1907
|
const [first, ...rest] = result.content;
|
|
1909
1908
|
if (!first || first.type !== 'text')
|
|
1910
1909
|
return result;
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
inResponse.push(p);
|
|
1920
|
-
else
|
|
1921
|
-
elsewhere.push(p);
|
|
1910
|
+
if ((0, index_availability_1.textAlreadyHasProductStatus)(first.text))
|
|
1911
|
+
return result;
|
|
1912
|
+
let cg;
|
|
1913
|
+
try {
|
|
1914
|
+
cg = this.getHomeGraph(projectPath);
|
|
1915
|
+
}
|
|
1916
|
+
catch {
|
|
1917
|
+
return result;
|
|
1922
1918
|
}
|
|
1923
|
-
|
|
1924
|
-
if (inResponse.length > 0) {
|
|
1925
|
-
let dbPath = null;
|
|
1919
|
+
if (this.cg && cg !== this.cg) {
|
|
1926
1920
|
try {
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1921
|
+
const sameProject = (0, path_1.resolve)(this.cg.getProjectRoot()) === (0, path_1.resolve)(cg.getProjectRoot());
|
|
1922
|
+
if (sameProject)
|
|
1923
|
+
cg = this.cg;
|
|
1930
1924
|
}
|
|
1931
1925
|
catch {
|
|
1932
|
-
|
|
1926
|
+
/* leave cg */
|
|
1933
1927
|
}
|
|
1934
|
-
banner = formatStaleBanner(inResponse, {
|
|
1935
|
-
catchUpDeferred: (0, memory_budget_1.shouldSkipCatchUpSync)(dbPath),
|
|
1936
|
-
});
|
|
1937
1928
|
}
|
|
1938
|
-
let
|
|
1939
|
-
|
|
1940
|
-
|
|
1929
|
+
let state;
|
|
1930
|
+
try {
|
|
1931
|
+
state = (0, index_availability_1.resolveProductIndexState)(cg);
|
|
1941
1932
|
}
|
|
1942
|
-
|
|
1933
|
+
catch {
|
|
1943
1934
|
return result;
|
|
1944
|
-
|
|
1945
|
-
|
|
1935
|
+
}
|
|
1936
|
+
let pendingPaths;
|
|
1937
|
+
if (state === 'dirty') {
|
|
1938
|
+
try {
|
|
1939
|
+
pendingPaths = (cg.getPendingFiles?.() ?? []).map((p) => p.path);
|
|
1940
|
+
}
|
|
1941
|
+
catch {
|
|
1942
|
+
pendingPaths = [];
|
|
1943
|
+
}
|
|
1944
|
+
}
|
|
1945
|
+
const line = (0, index_availability_1.formatProductStatusLine)(state, { pendingPaths });
|
|
1946
|
+
return {
|
|
1947
|
+
...result,
|
|
1948
|
+
content: [{ type: 'text', text: `${first.text}\n\n${line}` }, ...rest],
|
|
1949
|
+
};
|
|
1946
1950
|
}
|
|
1947
1951
|
/**
|
|
1948
1952
|
* Execute a tool by name.
|
|
@@ -2069,7 +2073,7 @@ class ToolHandler {
|
|
|
2069
2073
|
&& this.areEvidenceFilesCurrent(cachedFiles ?? [], cacheCg.getProjectRoot())))) {
|
|
2070
2074
|
const diagnosed = this.withQueryPlanDiagnostics(cached, args, true);
|
|
2071
2075
|
const withWorktree = this.withWorktreeNotice(diagnosed, projectPath);
|
|
2072
|
-
return this.withStalenessNotice(withWorktree, projectPath);
|
|
2076
|
+
return this.withProductStatusFooter(this.withStalenessNotice(withWorktree, projectPath), projectPath);
|
|
2073
2077
|
}
|
|
2074
2078
|
}
|
|
2075
2079
|
catch {
|
|
@@ -2133,7 +2137,7 @@ class ToolHandler {
|
|
|
2133
2137
|
cacheIndex.setEntry(cacheQueries, cacheKey, toolName, served);
|
|
2134
2138
|
}
|
|
2135
2139
|
const withWorktree = this.withWorktreeNotice(served, projectPath);
|
|
2136
|
-
return this.withStalenessNotice(withWorktree, projectPath);
|
|
2140
|
+
return this.withProductStatusFooter(this.withStalenessNotice(withWorktree, projectPath), projectPath);
|
|
2137
2141
|
}
|
|
2138
2142
|
if (requestPlan)
|
|
2139
2143
|
args[QUERY_FAST_ATTEMPTED_ARG] = true;
|
|
@@ -2164,7 +2168,7 @@ class ToolHandler {
|
|
|
2164
2168
|
cacheIndex.setEntry(cacheQueries, cacheKey, toolName, result);
|
|
2165
2169
|
}
|
|
2166
2170
|
const withWorktree = this.withWorktreeNotice(result, projectPath);
|
|
2167
|
-
return this.withStalenessNotice(withWorktree, projectPath);
|
|
2171
|
+
return this.withProductStatusFooter(this.withStalenessNotice(withWorktree, projectPath), projectPath);
|
|
2168
2172
|
}
|
|
2169
2173
|
catch (err) {
|
|
2170
2174
|
// Expected condition, not a malfunction: answer as a SUCCESS so the
|
|
@@ -2509,7 +2513,7 @@ class ToolHandler {
|
|
|
2509
2513
|
*/
|
|
2510
2514
|
maybeDeepToolPhaseGate(cg, _toolName) {
|
|
2511
2515
|
const state = (0, index_availability_1.resolveProductIndexState)(cg);
|
|
2512
|
-
if (state === 'full')
|
|
2516
|
+
if (state === 'full' || state === 'dirty')
|
|
2513
2517
|
return null;
|
|
2514
2518
|
if (state === 'syncing') {
|
|
2515
2519
|
return this.textResult((0, index_availability_1.productIndexGuidance)('syncing'));
|
|
@@ -12190,18 +12194,11 @@ class ToolHandler {
|
|
|
12190
12194
|
return this.textResult('No modules found in the project map.');
|
|
12191
12195
|
}
|
|
12192
12196
|
const FILE_CAP = 80;
|
|
12193
|
-
const productState = (0, index_availability_1.resolveProductIndexState)(cg);
|
|
12194
12197
|
const lines = [
|
|
12195
|
-
`**Project map** (
|
|
12198
|
+
`**Project map** (phase=${map.phase})`,
|
|
12196
12199
|
`modules: ${map.modules.length} · files: ${map.fileCount}`,
|
|
12197
12200
|
'',
|
|
12198
12201
|
];
|
|
12199
|
-
if (productState === 'fast' || map.phase === 'fast' || map.phase === 'indexing') {
|
|
12200
|
-
lines.push('_Full symbol index still building — this map has modules/files only (no call graph)._', '');
|
|
12201
|
-
}
|
|
12202
|
-
if (productState === 'syncing') {
|
|
12203
|
-
lines.push('_Index write in progress — map may be briefly stale._', '');
|
|
12204
|
-
}
|
|
12205
12202
|
for (const m of map.modules) {
|
|
12206
12203
|
const rootLabel = m.rootPath || '.';
|
|
12207
12204
|
lines.push(`### ${m.name} (\`${rootLabel}\`) · ${m.kind} · ${m.fileCount} files`);
|
|
@@ -103,7 +103,8 @@ function discoverModules(projectRoot) {
|
|
|
103
103
|
rootPath: '',
|
|
104
104
|
kind: 'root',
|
|
105
105
|
});
|
|
106
|
-
|
|
106
|
+
// Same parser as ArkTS dirty-module mapping (Spec 0034): bare keys + single quotes.
|
|
107
|
+
const harmony = (0, arkts_1.listHarmonyProjectModules)(projectRoot);
|
|
107
108
|
if (harmony.length > 0) {
|
|
108
109
|
for (const m of harmony) {
|
|
109
110
|
ensure({
|
|
@@ -132,47 +133,6 @@ function discoverModules(projectRoot) {
|
|
|
132
133
|
}
|
|
133
134
|
return [...byId.values()];
|
|
134
135
|
}
|
|
135
|
-
function listHarmonyProjectModulesLoose(projectRoot) {
|
|
136
|
-
const strict = (0, arkts_1.listHarmonyProjectModules)(projectRoot);
|
|
137
|
-
if (strict.length > 0)
|
|
138
|
-
return strict;
|
|
139
|
-
// Real DevEco `build-profile.json5` often uses unquoted keys; the strict
|
|
140
|
-
// parser only strips comments/trailing commas. Quote bare keys and retry.
|
|
141
|
-
const profilePath = path.join(projectRoot, 'build-profile.json5');
|
|
142
|
-
if (!fs.existsSync(profilePath))
|
|
143
|
-
return [];
|
|
144
|
-
let raw;
|
|
145
|
-
try {
|
|
146
|
-
const text = fs.readFileSync(profilePath, 'utf-8');
|
|
147
|
-
const stripped = text
|
|
148
|
-
.replace(/\/\/.*$/gm, '')
|
|
149
|
-
.replace(/\/\*[\s\S]*?\*\//g, '')
|
|
150
|
-
.replace(/,(\s*[}\]])/g, '$1')
|
|
151
|
-
.replace(/([{,]\s*)([A-Za-z_][\w]*)\s*:/g, '$1"$2":');
|
|
152
|
-
raw = JSON.parse(stripped);
|
|
153
|
-
}
|
|
154
|
-
catch {
|
|
155
|
-
return [];
|
|
156
|
-
}
|
|
157
|
-
if (!raw || typeof raw !== 'object')
|
|
158
|
-
return [];
|
|
159
|
-
const modules = raw.modules;
|
|
160
|
-
if (!Array.isArray(modules))
|
|
161
|
-
return [];
|
|
162
|
-
const out = [];
|
|
163
|
-
for (const entry of modules) {
|
|
164
|
-
if (!entry || typeof entry !== 'object')
|
|
165
|
-
continue;
|
|
166
|
-
const rec = entry;
|
|
167
|
-
if (typeof rec.name !== 'string' || typeof rec.srcPath !== 'string')
|
|
168
|
-
continue;
|
|
169
|
-
const srcPath = (0, arkts_1.normalizeHarmonyModuleSrcPath)(rec.srcPath);
|
|
170
|
-
if (!srcPath)
|
|
171
|
-
continue;
|
|
172
|
-
out.push({ name: rec.name, srcPath });
|
|
173
|
-
}
|
|
174
|
-
return out;
|
|
175
|
-
}
|
|
176
136
|
function discoverOhpmPackages(projectRoot) {
|
|
177
137
|
const out = [];
|
|
178
138
|
const queue = [{ rel: '', depth: 0 }];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "homegraph",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.10",
|
|
4
4
|
"description": "Supercharge AI coding agents with semantic code intelligence — surgical context, fewer tool calls, faster answers. 100% local.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"license": "MIT",
|
|
37
37
|
"dependencies": {
|
|
38
38
|
"@clack/prompts": "^1.7.0",
|
|
39
|
-
"arkanalyzer": "^1.0.
|
|
39
|
+
"arkanalyzer": "^1.0.94",
|
|
40
40
|
"commander": "^14.0.3",
|
|
41
41
|
"fast-string-width": "^3.0.2",
|
|
42
42
|
"fast-wrap-ansi": "^0.2.0",
|