homegraph 1.5.2 → 1.5.3
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 +131 -0
- package/README.md +15 -8
- package/dist/arkui/index.d.ts +4 -0
- package/dist/arkui/index.d.ts.map +1 -0
- package/dist/arkui/index.js +23 -0
- package/dist/arkui/index.js.map +1 -0
- package/dist/arkui/migrate-passage.d.ts +28 -0
- package/dist/arkui/migrate-passage.d.ts.map +1 -0
- package/dist/arkui/migrate-passage.js +310 -0
- package/dist/arkui/migrate-passage.js.map +1 -0
- package/dist/arkui/migrate-semantics.d.ts +47 -0
- package/dist/arkui/migrate-semantics.d.ts.map +1 -0
- package/dist/arkui/migrate-semantics.js +229 -0
- package/dist/arkui/migrate-semantics.js.map +1 -0
- package/dist/arkui/migrate-snapshot.d.ts +79 -0
- package/dist/arkui/migrate-snapshot.d.ts.map +1 -0
- package/dist/arkui/migrate-snapshot.js +340 -0
- package/dist/arkui/migrate-snapshot.js.map +1 -0
- package/dist/bin/fatal-handler.js +2 -2
- package/dist/bin/homegraph.js +105 -156
- package/dist/bin/homegraph.js.map +1 -1
- package/dist/bin/node-version-check.d.ts +6 -15
- package/dist/bin/node-version-check.d.ts.map +1 -1
- package/dist/bin/node-version-check.js +8 -37
- package/dist/bin/node-version-check.js.map +1 -1
- package/dist/db/index.d.ts +36 -1
- package/dist/db/index.d.ts.map +1 -1
- package/dist/db/index.js +92 -6
- package/dist/db/index.js.map +1 -1
- package/dist/db/migrations.d.ts +1 -1
- package/dist/db/migrations.d.ts.map +1 -1
- package/dist/db/migrations.js +15 -1
- package/dist/db/migrations.js.map +1 -1
- package/dist/db/queries.d.ts +42 -0
- package/dist/db/queries.d.ts.map +1 -1
- package/dist/db/queries.js +177 -10
- package/dist/db/queries.js.map +1 -1
- package/dist/db/schema.sql +6 -1
- package/dist/db/sqlite-adapter.d.ts +8 -3
- package/dist/db/sqlite-adapter.d.ts.map +1 -1
- package/dist/db/sqlite-adapter.js +45 -3
- package/dist/db/sqlite-adapter.js.map +1 -1
- package/dist/extraction/extraction-version.d.ts +1 -1
- package/dist/extraction/extraction-version.js +1 -1
- package/dist/extraction/generated-detection.d.ts +42 -11
- package/dist/extraction/generated-detection.d.ts.map +1 -1
- package/dist/extraction/generated-detection.js +141 -20
- package/dist/extraction/generated-detection.js.map +1 -1
- package/dist/extraction/index.d.ts +42 -0
- package/dist/extraction/index.d.ts.map +1 -1
- package/dist/extraction/index.js +96 -0
- package/dist/extraction/index.js.map +1 -1
- package/dist/extraction/languages/arkts.d.ts +19 -2
- package/dist/extraction/languages/arkts.d.ts.map +1 -1
- package/dist/extraction/languages/arkts.js +460 -110
- package/dist/extraction/languages/arkts.js.map +1 -1
- package/dist/extraction/wasm-runtime-flags.d.ts.map +1 -1
- package/dist/extraction/wasm-runtime-flags.js +9 -6
- package/dist/extraction/wasm-runtime-flags.js.map +1 -1
- package/dist/graph-sources.d.ts +41 -0
- package/dist/graph-sources.d.ts.map +1 -0
- package/dist/graph-sources.js +82 -0
- package/dist/graph-sources.js.map +1 -0
- package/dist/index.d.ts +19 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +79 -9
- package/dist/index.js.map +1 -1
- package/dist/installer/index.d.ts.map +1 -1
- package/dist/installer/index.js +0 -48
- package/dist/installer/index.js.map +1 -1
- package/dist/installer/targets/antigravity.js +1 -1
- package/dist/installer/targets/antigravity.js.map +1 -1
- package/dist/installer/targets/deveco.js +1 -1
- package/dist/installer/targets/deveco.js.map +1 -1
- package/dist/installer/targets/hermes.d.ts +1 -1
- package/dist/installer/targets/hermes.js +2 -2
- package/dist/installer/targets/hermes.js.map +1 -1
- package/dist/installer/targets/opencode.js +1 -1
- package/dist/installer/targets/opencode.js.map +1 -1
- package/dist/installer/targets/shared.js +1 -1
- package/dist/installer/targets/shared.js.map +1 -1
- package/dist/mcp/daemon-paths.d.ts +5 -4
- package/dist/mcp/daemon-paths.d.ts.map +1 -1
- package/dist/mcp/daemon-paths.js +28 -13
- package/dist/mcp/daemon-paths.js.map +1 -1
- package/dist/mcp/daemon-registry.d.ts.map +1 -1
- package/dist/mcp/daemon-registry.js +4 -1
- package/dist/mcp/daemon-registry.js.map +1 -1
- package/dist/mcp/daemon.d.ts +1 -1
- package/dist/mcp/daemon.js +1 -1
- package/dist/mcp/engine.d.ts.map +1 -1
- package/dist/mcp/engine.js +12 -3
- package/dist/mcp/engine.js.map +1 -1
- package/dist/mcp/explore-dedup.d.ts +137 -0
- package/dist/mcp/explore-dedup.d.ts.map +1 -0
- package/dist/mcp/explore-dedup.js +236 -0
- package/dist/mcp/explore-dedup.js.map +1 -0
- package/dist/mcp/explore-session-state.d.ts +217 -0
- package/dist/mcp/explore-session-state.d.ts.map +1 -0
- package/dist/mcp/explore-session-state.js +322 -0
- package/dist/mcp/explore-session-state.js.map +1 -0
- package/dist/mcp/index.d.ts.map +1 -1
- package/dist/mcp/index.js +4 -7
- package/dist/mcp/index.js.map +1 -1
- package/dist/mcp/proxy.d.ts.map +1 -1
- package/dist/mcp/proxy.js +5 -14
- package/dist/mcp/proxy.js.map +1 -1
- package/dist/mcp/query-worker.d.ts +1 -1
- package/dist/mcp/query-worker.js +1 -1
- package/dist/mcp/server-instructions.d.ts +7 -2
- package/dist/mcp/server-instructions.d.ts.map +1 -1
- package/dist/mcp/server-instructions.js +104 -28
- package/dist/mcp/server-instructions.js.map +1 -1
- package/dist/mcp/session.d.ts +14 -3
- package/dist/mcp/session.d.ts.map +1 -1
- package/dist/mcp/session.js +17 -14
- package/dist/mcp/session.js.map +1 -1
- package/dist/mcp/startup-handshake.d.ts +1 -1
- package/dist/mcp/startup-handshake.js +1 -1
- package/dist/mcp/tools.d.ts +117 -7
- package/dist/mcp/tools.d.ts.map +1 -1
- package/dist/mcp/tools.js +3056 -503
- package/dist/mcp/tools.js.map +1 -1
- package/dist/resolution/frameworks/arkts-napi.d.ts +14 -0
- package/dist/resolution/frameworks/arkts-napi.d.ts.map +1 -1
- package/dist/resolution/frameworks/arkts-napi.js +169 -49
- package/dist/resolution/frameworks/arkts-napi.js.map +1 -1
- package/dist/search/query-utils.d.ts +116 -4
- package/dist/search/query-utils.d.ts.map +1 -1
- package/dist/search/query-utils.js +869 -60
- package/dist/search/query-utils.js.map +1 -1
- package/dist/types.d.ts +8 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/upgrade/index.d.ts +14 -26
- package/dist/upgrade/index.d.ts.map +1 -1
- package/dist/upgrade/index.js +28 -123
- package/dist/upgrade/index.js.map +1 -1
- package/dist/upgrade/remove-binary.d.ts +19 -19
- package/dist/upgrade/remove-binary.d.ts.map +1 -1
- package/dist/upgrade/remove-binary.js +20 -21
- package/dist/upgrade/remove-binary.js.map +1 -1
- package/dist/upgrade/update-check.d.ts +4 -3
- package/dist/upgrade/update-check.d.ts.map +1 -1
- package/dist/upgrade/update-check.js +4 -3
- package/dist/upgrade/update-check.js.map +1 -1
- package/package.json +12 -8
- package/dist/telemetry/index.d.ts +0 -143
- package/dist/telemetry/index.d.ts.map +0 -1
- package/dist/telemetry/index.js +0 -541
- package/dist/telemetry/index.js.map +0 -1
package/dist/bin/homegraph.js
CHANGED
|
@@ -71,7 +71,6 @@ const fatal_handler_1 = require("./fatal-handler");
|
|
|
71
71
|
const wasm_runtime_flags_1 = require("../extraction/wasm-runtime-flags");
|
|
72
72
|
const command_supervision_1 = require("./command-supervision");
|
|
73
73
|
const extraction_version_1 = require("../extraction/extraction-version");
|
|
74
|
-
const telemetry_1 = require("../telemetry");
|
|
75
74
|
// Lazy-load heavy modules (HomeGraph, runInstaller) to keep CLI startup fast.
|
|
76
75
|
async function loadHomeGraph() {
|
|
77
76
|
try {
|
|
@@ -90,25 +89,13 @@ async function loadHomeGraph() {
|
|
|
90
89
|
// which fails for ESM-only packages. This bypasses the transformation.
|
|
91
90
|
// eslint-disable-next-line @typescript-eslint/no-implied-eval
|
|
92
91
|
const importESM = new Function('specifier', 'return import(specifier)');
|
|
93
|
-
// Block HomeGraph on Node.js 25.x — V8's turboshaft WASM JIT has a Zone
|
|
94
|
-
// allocator bug that reliably crashes when compiling tree-sitter
|
|
95
|
-
// grammars (see #54, #81, #140). The previous behaviour was a soft
|
|
96
|
-
// console.warn that scrolls off-screen before the OOM crash 30 seconds
|
|
97
|
-
// later, leading to a steady stream of "what is this OOM" reports.
|
|
98
|
-
// Hard-exit before any WASM work; allow override via env var for users
|
|
99
|
-
// who patched V8 themselves or want to test a future fix.
|
|
100
|
-
const nodeVersion = process.versions.node;
|
|
101
|
-
const nodeMajor = parseInt(nodeVersion.split('.')[0] ?? '0', 10);
|
|
102
|
-
if (nodeMajor >= 25) {
|
|
103
|
-
process.stderr.write((0, node_version_check_1.buildNode25BlockBanner)(nodeVersion) + '\n');
|
|
104
|
-
if (!process.env.HOMEGRAPH_ALLOW_UNSAFE_NODE) {
|
|
105
|
-
process.exit(1);
|
|
106
|
-
}
|
|
107
|
-
// Override active — banner shown for visibility, continuing.
|
|
108
|
-
}
|
|
109
92
|
// Enforce the supported Node floor. `engines` in package.json only *warns* on
|
|
110
93
|
// install (unless engine-strict), so hard-block here to actually keep users off
|
|
111
|
-
// unsupported versions.
|
|
94
|
+
// unsupported versions. See package.json `engines` and ./node-version-check.
|
|
95
|
+
// Node ≥22 WASM Zone OOM is mitigated by --liftoff-only relaunch below — not by
|
|
96
|
+
// blocking majors (Node 25+ is supported when that flag is applied).
|
|
97
|
+
const nodeVersion = process.versions.node;
|
|
98
|
+
const nodeMajor = parseInt(nodeVersion.split('.')[0] ?? '0', 10);
|
|
112
99
|
if (nodeMajor < node_version_check_1.MIN_NODE_MAJOR) {
|
|
113
100
|
process.stderr.write((0, node_version_check_1.buildNodeTooOldBanner)(nodeVersion) + '\n');
|
|
114
101
|
if (!process.env.HOMEGRAPH_ALLOW_UNSAFE_NODE) {
|
|
@@ -184,30 +171,6 @@ function main() {
|
|
|
184
171
|
.name('homegraph')
|
|
185
172
|
.description('Code intelligence and knowledge graph for any codebase')
|
|
186
173
|
.version(packageJson.version);
|
|
187
|
-
// Anonymous usage telemetry (see TELEMETRY.md): record the invoked subcommand
|
|
188
|
-
// NAME only — never arguments or paths. Counts buffer locally; network sends
|
|
189
|
-
// piggyback on commands that run long anyway (quick commands only append to
|
|
190
|
-
// the local buffer at exit, costing nothing).
|
|
191
|
-
// install/uninstall are absent on purpose: the installer flushes at its own
|
|
192
|
-
// end, AFTER its consent prompt — a flush here would fire the first-run
|
|
193
|
-
// notice before the user ever sees the toggle.
|
|
194
|
-
const TELEMETRY_FLUSH_COMMANDS = new Set(['init', 'uninit', 'index', 'sync', 'upgrade']);
|
|
195
|
-
program.hook('preAction', (_thisCommand, actionCommand) => {
|
|
196
|
-
try {
|
|
197
|
-
// The detached daemon re-invokes `serve --mcp` internally — not a user action.
|
|
198
|
-
if (process.env.HOMEGRAPH_DAEMON_INTERNAL)
|
|
199
|
-
return;
|
|
200
|
-
const name = actionCommand.name();
|
|
201
|
-
if (name === 'telemetry')
|
|
202
|
-
return; // managing telemetry is not usage
|
|
203
|
-
(0, telemetry_1.getTelemetry)().recordUsage('cli_command', name, true);
|
|
204
|
-
if (TELEMETRY_FLUSH_COMMANDS.has(name))
|
|
205
|
-
(0, telemetry_1.getTelemetry)().maybeFlush();
|
|
206
|
-
}
|
|
207
|
-
catch {
|
|
208
|
-
/* telemetry must never break the CLI */
|
|
209
|
-
}
|
|
210
|
-
});
|
|
211
174
|
// =============================================================================
|
|
212
175
|
// Helper Functions
|
|
213
176
|
// =============================================================================
|
|
@@ -473,15 +436,6 @@ function main() {
|
|
|
473
436
|
}
|
|
474
437
|
fs.writeFileSync(logPath, lines.join('\n') + '\n');
|
|
475
438
|
}
|
|
476
|
-
/**
|
|
477
|
-
* Telemetry for a completed full index (see TELEMETRY.md). The bounded flush
|
|
478
|
-
* keeps init/index responsive (these commands just ran for seconds anyway)
|
|
479
|
-
* while delivering the event promptly.
|
|
480
|
-
*/
|
|
481
|
-
async function recordIndexTelemetry(cg, result) {
|
|
482
|
-
(0, telemetry_1.recordIndexEvent)(cg, result);
|
|
483
|
-
await (0, telemetry_1.getTelemetry)().flushNow();
|
|
484
|
-
}
|
|
485
439
|
// =============================================================================
|
|
486
440
|
// Commands
|
|
487
441
|
// =============================================================================
|
|
@@ -550,7 +504,6 @@ function main() {
|
|
|
550
504
|
supervision.stop();
|
|
551
505
|
}
|
|
552
506
|
printIndexResult(clack, result, projectPath);
|
|
553
|
-
await recordIndexTelemetry(cg, result);
|
|
554
507
|
try {
|
|
555
508
|
const { offerWatchFallback } = await Promise.resolve().then(() => __importStar(require('../installer')));
|
|
556
509
|
await offerWatchFallback(clack, projectPath);
|
|
@@ -604,13 +557,6 @@ function main() {
|
|
|
604
557
|
}
|
|
605
558
|
catch { /* non-fatal */ }
|
|
606
559
|
success(`Removed HomeGraph from ${projectPath}`);
|
|
607
|
-
// Churn signal — and flush now, since after an uninit there may be no
|
|
608
|
-
// "next run" to deliver it.
|
|
609
|
-
try {
|
|
610
|
-
(0, telemetry_1.getTelemetry)().recordLifecycle('uninstall', {});
|
|
611
|
-
await (0, telemetry_1.getTelemetry)().flushNow();
|
|
612
|
-
}
|
|
613
|
-
catch { /* non-fatal */ }
|
|
614
560
|
}
|
|
615
561
|
catch (err) {
|
|
616
562
|
error(`Failed to uninitialize: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -682,7 +628,6 @@ function main() {
|
|
|
682
628
|
await progress.stop();
|
|
683
629
|
}
|
|
684
630
|
printIndexResult(clack, result, projectPath);
|
|
685
|
-
await recordIndexTelemetry(cg, result);
|
|
686
631
|
if (!result.success) {
|
|
687
632
|
process.exit(1);
|
|
688
633
|
}
|
|
@@ -715,7 +660,7 @@ function main() {
|
|
|
715
660
|
process.exit(1);
|
|
716
661
|
}
|
|
717
662
|
const { default: HomeGraph } = await loadHomeGraph();
|
|
718
|
-
const cg = await HomeGraph.open(projectPath);
|
|
663
|
+
const cg = await HomeGraph.open(projectPath, { sources: 'both' });
|
|
719
664
|
if (options.quiet) {
|
|
720
665
|
await cg.sync();
|
|
721
666
|
cg.destroy();
|
|
@@ -809,6 +754,7 @@ function main() {
|
|
|
809
754
|
nodeCount: stats.nodeCount,
|
|
810
755
|
edgeCount: stats.edgeCount,
|
|
811
756
|
dbSizeBytes: stats.dbSizeBytes,
|
|
757
|
+
walSizeBytes: stats.walSizeBytes,
|
|
812
758
|
backend,
|
|
813
759
|
journalMode,
|
|
814
760
|
nodesByKind: stats.nodesByKind,
|
|
@@ -824,6 +770,7 @@ function main() {
|
|
|
824
770
|
ohosApi: ohosApi
|
|
825
771
|
? { version: ohosApi.version, packageName: ohosApi.packageName, dbPath: ohosApi.dbPath }
|
|
826
772
|
: null,
|
|
773
|
+
graphSources: cg.getGraphSources(),
|
|
827
774
|
index: {
|
|
828
775
|
state: indexState,
|
|
829
776
|
builtWithVersion: buildInfo.version,
|
|
@@ -848,6 +795,19 @@ function main() {
|
|
|
848
795
|
console.log(` Nodes: ${formatNumber(stats.nodeCount)}`);
|
|
849
796
|
console.log(` Edges: ${formatNumber(stats.edgeCount)}`);
|
|
850
797
|
console.log(` DB Size: ${(stats.dbSizeBytes / 1024 / 1024).toFixed(2)} MB`);
|
|
798
|
+
// Surface the WAL sidecar (#1431): a WAL that dwarfs the DB at rest is
|
|
799
|
+
// the killed-session leak — invisible before this line, it only showed
|
|
800
|
+
// up as a mysteriously full disk. open() above already kicked off the
|
|
801
|
+
// automatic heal for the oversized case.
|
|
802
|
+
if (stats.walSizeBytes > 0) {
|
|
803
|
+
const { WAL_HEAL_THRESHOLD_BYTES } = await Promise.resolve().then(() => __importStar(require('../db/index')));
|
|
804
|
+
const oversized = stats.walSizeBytes > Math.max(WAL_HEAL_THRESHOLD_BYTES, stats.dbSizeBytes);
|
|
805
|
+
const walLabel = `${(stats.walSizeBytes / 1024 / 1024).toFixed(2)} MB`;
|
|
806
|
+
console.log(` WAL Size: ${oversized ? chalk.yellow(walLabel) : walLabel}`);
|
|
807
|
+
if (oversized) {
|
|
808
|
+
warn('The write-ahead log is larger than the database — killed sessions left it behind. It is reclaimed automatically on open; if it persists across runs, another live HomeGraph process is holding it.');
|
|
809
|
+
}
|
|
810
|
+
}
|
|
851
811
|
// Prefer node:sqlite → better-sqlite3; wasm is last-resort (no WAL).
|
|
852
812
|
const backendLabel = backend === 'node-sqlite' ? chalk.green('node-sqlite')
|
|
853
813
|
: backend === 'native' ? chalk.green('native (better-sqlite3)')
|
|
@@ -857,6 +817,7 @@ function main() {
|
|
|
857
817
|
? chalk.green('wal')
|
|
858
818
|
: chalk.yellow(`${journalMode || 'unknown'} ${(0, glyphs_1.getGlyphs)().dash} WAL inactive; reads can block on writes`);
|
|
859
819
|
console.log(` Journal: ${journalLabel}`);
|
|
820
|
+
console.log(` Sources: ${cg.getGraphSources()} (project index / OHOS SDK API)`);
|
|
860
821
|
console.log();
|
|
861
822
|
// Node breakdown
|
|
862
823
|
console.log(chalk.bold('Nodes by Kind:'));
|
|
@@ -1441,75 +1402,102 @@ function main() {
|
|
|
1441
1402
|
});
|
|
1442
1403
|
});
|
|
1443
1404
|
/**
|
|
1444
|
-
* homegraph serve
|
|
1405
|
+
* homegraph serve / homegraph serve mcp
|
|
1406
|
+
*
|
|
1407
|
+
* Preferred: `homegraph serve mcp`
|
|
1408
|
+
* Legacy (still supported): `homegraph serve --mcp`
|
|
1409
|
+
*
|
|
1410
|
+
* Hidden from `--help`: this is the stdio entry point an AI agent launches
|
|
1411
|
+
* for itself (the installer wires it into every agent's MCP config), not a
|
|
1412
|
+
* command a human runs. It still works when invoked — hiding only removes it
|
|
1413
|
+
* from the listing. See the interactive-TTY guard in `runServeMcp`, which
|
|
1414
|
+
* explains this to anyone who runs it by hand.
|
|
1445
1415
|
*/
|
|
1446
|
-
|
|
1447
|
-
// Hidden from `--help`: this is the stdio entry point an AI agent launches
|
|
1448
|
-
// for itself (the installer wires `args: ['serve','--mcp']` into every
|
|
1449
|
-
// agent's MCP config), not a command a human runs. It still works when
|
|
1450
|
-
// invoked — hiding only removes it from the listing. See the interactive-TTY
|
|
1451
|
-
// guard below, which explains this to anyone who runs it by hand.
|
|
1452
|
-
.command('serve', { hidden: true })
|
|
1453
|
-
.description('Start HomeGraph as an MCP server for AI assistants')
|
|
1454
|
-
.option('-p, --path <path>', 'Project path (optional for MCP mode, uses rootUri from client)')
|
|
1455
|
-
.option('--mcp', 'Run as MCP server (stdio transport)')
|
|
1456
|
-
.option('--no-watch', 'Disable the file watcher (no auto-sync; useful on slow filesystems like WSL2 /mnt drives)')
|
|
1457
|
-
.action(async (options) => {
|
|
1416
|
+
async function runServeMcp(options) {
|
|
1458
1417
|
const projectPath = options.path ? resolveProjectPath(options.path) : undefined;
|
|
1459
1418
|
// Commander sets watch=false when --no-watch is passed. Route it through
|
|
1460
1419
|
// the same env-var chokepoint the watcher and MCP server already honor.
|
|
1461
1420
|
if (options.watch === false) {
|
|
1462
1421
|
process.env.HOMEGRAPH_NO_WATCH = '1';
|
|
1463
1422
|
}
|
|
1423
|
+
// Spec 0005: resolve --sources over HOMEGRAPH_SOURCES, then stamp env so
|
|
1424
|
+
// detached daemons and in-process opens share the same mode.
|
|
1425
|
+
const { resolveGraphSources, applyGraphSourcesToEnv, GRAPH_SOURCES_MODES } = await Promise.resolve().then(() => __importStar(require('../graph-sources')));
|
|
1464
1426
|
try {
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1427
|
+
const mode = resolveGraphSources(options.sources);
|
|
1428
|
+
applyGraphSourcesToEnv(mode);
|
|
1429
|
+
}
|
|
1430
|
+
catch (err) {
|
|
1431
|
+
error(err instanceof Error ? err.message : String(err));
|
|
1432
|
+
error(`Valid values: ${GRAPH_SOURCES_MODES.join(', ')}`);
|
|
1433
|
+
process.exit(1);
|
|
1434
|
+
}
|
|
1435
|
+
// The stdio MCP server an AI agent launches for itself — not a command to
|
|
1436
|
+
// run by hand. A human in a terminal would otherwise see it hang waiting
|
|
1437
|
+
// for JSON-RPC on stdin. The agent's pipe and the detached daemon both
|
|
1438
|
+
// have a non-TTY stdin, so this only ever fires for a person who typed it.
|
|
1439
|
+
if (process.stdin.isTTY && !process.env.HOMEGRAPH_DAEMON_INTERNAL) {
|
|
1440
|
+
console.error(chalk.bold('\nHomeGraph MCP server\n'));
|
|
1441
|
+
console.error("This is the MCP server your AI agent (Claude Code, Cursor, Codex, opencode, …)");
|
|
1442
|
+
console.error("starts automatically — you don't run it yourself.");
|
|
1443
|
+
console.error(`\nIt's already wired up by ${chalk.cyan('homegraph install')}. To check on things:`);
|
|
1444
|
+
console.error(` ${chalk.cyan('homegraph status')} ${chalk.dim('— is this project indexed and healthy?')}`);
|
|
1445
|
+
console.error(` ${chalk.cyan('homegraph daemon')} ${chalk.dim('— list or stop background MCP servers')}`);
|
|
1446
|
+
console.error(chalk.dim('\n(Running it directly only does something when an MCP client drives it over stdin.)'));
|
|
1447
|
+
return;
|
|
1448
|
+
}
|
|
1449
|
+
const { MCPServer } = await Promise.resolve().then(() => __importStar(require('../mcp/index')));
|
|
1450
|
+
const server = new MCPServer(projectPath);
|
|
1451
|
+
await server.start();
|
|
1452
|
+
}
|
|
1453
|
+
function printServeUsage() {
|
|
1454
|
+
// Use stderr so stdout stays clean for any piped/stdio usage.
|
|
1455
|
+
console.error(chalk.bold('\nHomeGraph MCP Server\n'));
|
|
1456
|
+
console.error(chalk.blue((0, glyphs_1.getGlyphs)().info) + ' Start with: ' + chalk.cyan('homegraph serve mcp'));
|
|
1457
|
+
console.error(chalk.dim(' (legacy alias also works: homegraph serve --mcp)'));
|
|
1458
|
+
console.error('\nTo use with Claude Code, add to your MCP configuration:');
|
|
1459
|
+
console.error(chalk.dim(`
|
|
1495
1460
|
{
|
|
1496
1461
|
"mcpServers": {
|
|
1497
1462
|
"homegraph": {
|
|
1498
1463
|
"command": "homegraph",
|
|
1499
|
-
"args": ["serve", "
|
|
1464
|
+
"args": ["serve", "mcp"]
|
|
1500
1465
|
}
|
|
1501
1466
|
}
|
|
1502
1467
|
}
|
|
1503
1468
|
`));
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1469
|
+
console.error('Optional: --sources both|project|sdk|none (or HOMEGRAPH_SOURCES) to limit project vs OHOS SDK graphs.');
|
|
1470
|
+
console.error('Available tools:');
|
|
1471
|
+
console.error(chalk.cyan(' homegraph_explore') + ' - Primary: source of the relevant symbols for any question');
|
|
1472
|
+
console.error(chalk.cyan(' homegraph_search') + ' - Search for code symbols');
|
|
1473
|
+
console.error(chalk.cyan(' homegraph_callers') + ' - Find callers of a symbol');
|
|
1474
|
+
console.error(chalk.cyan(' homegraph_callees') + ' - Find what a symbol calls');
|
|
1475
|
+
console.error(chalk.cyan(' homegraph_impact') + ' - Analyze impact of changes');
|
|
1476
|
+
console.error(chalk.cyan(' homegraph_node') + ' - Get symbol details');
|
|
1477
|
+
console.error(chalk.cyan(' homegraph_files') + ' - Get project file structure');
|
|
1478
|
+
console.error(chalk.cyan(' homegraph_status') + ' - Get index status');
|
|
1479
|
+
}
|
|
1480
|
+
// IMPORTANT: keep `mcp` as an argument (not a nested Commander subcommand).
|
|
1481
|
+
// Nested `serve.command('mcp')` + a parent `-p/--path` made Commander 14 drop
|
|
1482
|
+
// `--path` on `serve mcp --path <repo>` — the daemon then keyed off cwd, so
|
|
1483
|
+
// prewarm/eval looked "timed out" while a useless daemon bound the wrong root.
|
|
1484
|
+
// `spawnDetachedDaemon` also invokes `serve mcp --path <root>`; that path must
|
|
1485
|
+
// stick. Legacy `serve --mcp` stays supported.
|
|
1486
|
+
program
|
|
1487
|
+
.command('serve', { hidden: true })
|
|
1488
|
+
.description('Start HomeGraph protocol servers for AI assistants')
|
|
1489
|
+
.argument('[mode]', 'Run as MCP server (stdio transport)', undefined)
|
|
1490
|
+
.option('-p, --path <path>', 'Project path (optional for MCP mode, uses rootUri from client)')
|
|
1491
|
+
.option('--mcp', 'Legacy alias for `serve mcp` (stdio MCP server)')
|
|
1492
|
+
.option('--no-watch', 'Disable the file watcher (no auto-sync; useful on slow filesystems like WSL2 /mnt drives)')
|
|
1493
|
+
.option('--sources <mode>', 'Graph sources for MCP queries: both|project|sdk|none (default both; env HOMEGRAPH_SOURCES)')
|
|
1494
|
+
.action(async (mode, options) => {
|
|
1495
|
+
try {
|
|
1496
|
+
if (mode === 'mcp' || options.mcp) {
|
|
1497
|
+
await runServeMcp(options);
|
|
1498
|
+
}
|
|
1499
|
+
else {
|
|
1500
|
+
printServeUsage();
|
|
1513
1501
|
}
|
|
1514
1502
|
}
|
|
1515
1503
|
catch (err) {
|
|
@@ -2971,45 +2959,6 @@ function main() {
|
|
|
2971
2959
|
catch { /* best effort */ }
|
|
2972
2960
|
}
|
|
2973
2961
|
});
|
|
2974
|
-
/**
|
|
2975
|
-
* homegraph telemetry [on|off|status]
|
|
2976
|
-
*/
|
|
2977
|
-
program
|
|
2978
|
-
.command('telemetry [action]')
|
|
2979
|
-
.description('Show or change anonymous usage telemetry (status, on, off)')
|
|
2980
|
-
.action((action) => {
|
|
2981
|
-
const t = (0, telemetry_1.getTelemetry)();
|
|
2982
|
-
if (action === 'on' || action === 'off') {
|
|
2983
|
-
t.setEnabled(action === 'on', 'cli');
|
|
2984
|
-
if (action === 'on') {
|
|
2985
|
-
success('Telemetry enabled — anonymous usage stats only (no code, paths, or names).');
|
|
2986
|
-
}
|
|
2987
|
-
else {
|
|
2988
|
-
success('Telemetry disabled. Buffered, unsent data was deleted.');
|
|
2989
|
-
}
|
|
2990
|
-
const effective = t.getStatus();
|
|
2991
|
-
if (effective.decidedBy === 'DO_NOT_TRACK' || effective.decidedBy === 'HOMEGRAPH_TELEMETRY') {
|
|
2992
|
-
warn(`The ${effective.decidedBy} environment variable overrides this choice — ` +
|
|
2993
|
-
`effective state right now: ${effective.enabled ? 'enabled' : 'disabled'}.`);
|
|
2994
|
-
}
|
|
2995
|
-
return;
|
|
2996
|
-
}
|
|
2997
|
-
if (action !== undefined && action !== 'status') {
|
|
2998
|
-
error(`Unknown action: ${action} (expected status, on, or off)`);
|
|
2999
|
-
process.exit(1);
|
|
3000
|
-
}
|
|
3001
|
-
const s = t.getStatus();
|
|
3002
|
-
const decidedBy = {
|
|
3003
|
-
DO_NOT_TRACK: 'DO_NOT_TRACK environment variable',
|
|
3004
|
-
HOMEGRAPH_TELEMETRY: 'HOMEGRAPH_TELEMETRY environment variable',
|
|
3005
|
-
config: 'your saved choice',
|
|
3006
|
-
default: 'default',
|
|
3007
|
-
};
|
|
3008
|
-
console.log(`\nTelemetry: ${s.enabled ? chalk.green('enabled') : chalk.yellow('disabled')} ${chalk.dim(`(${decidedBy[s.decidedBy]})`)}`);
|
|
3009
|
-
console.log(`Machine ID: ${s.machineId ?? chalk.dim('(random UUID, created on first use)')}`);
|
|
3010
|
-
console.log(`Config: ${s.configPath}`);
|
|
3011
|
-
console.log(chalk.dim(`\nExactly what is collected (and never collected): ${telemetry_1.TELEMETRY_DOCS}\n`));
|
|
3012
|
-
});
|
|
3013
2962
|
/**
|
|
3014
2963
|
* homegraph index-api <input> [version]
|
|
3015
2964
|
* Build a standalone OHOS API database from command-line-tools SDK.
|
|
@@ -3070,9 +3019,9 @@ function main() {
|
|
|
3070
3019
|
/**
|
|
3071
3020
|
* homegraph upgrade [version]
|
|
3072
3021
|
*
|
|
3073
|
-
* Self-update
|
|
3074
|
-
*
|
|
3075
|
-
* per-method upgrade logic.
|
|
3022
|
+
* Self-update for npm-global / npx / source installs. A leftover standalone
|
|
3023
|
+
* bundle install is detected and refused (guide the user to `npm i -g`).
|
|
3024
|
+
* See ../upgrade for detection and per-method upgrade logic.
|
|
3076
3025
|
*/
|
|
3077
3026
|
program
|
|
3078
3027
|
.command('upgrade [version]')
|