homegraph 1.5.1 → 1.5.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/LICENSE +21 -21
- package/README.md +305 -305
- package/dist/bin/homegraph.js +9 -9
- package/dist/db/index.js +36 -36
- package/dist/db/migrations.js +37 -37
- package/dist/db/queries.js +156 -156
- package/dist/db/schema.sql +203 -203
- package/dist/directory.js +5 -5
- package/dist/extraction/index.d.ts +1 -1
- package/dist/extraction/index.d.ts.map +1 -1
- package/dist/extraction/index.js +54 -43
- package/dist/extraction/index.js.map +1 -1
- package/dist/extraction/languages/arkts.d.ts +53 -6
- package/dist/extraction/languages/arkts.d.ts.map +1 -1
- package/dist/extraction/languages/arkts.js +565 -65
- package/dist/extraction/languages/arkts.js.map +1 -1
- package/dist/extraction/wasm/tree-sitter-c_sharp.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-cfml.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-cfquery.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-cfscript.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-cobol.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-erlang.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-nix.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-pascal.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-vbnet.wasm +0 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/installer/instructions-template.js +9 -9
- package/dist/mcp/diff-impact.d.ts +131 -0
- package/dist/mcp/diff-impact.d.ts.map +1 -0
- package/dist/mcp/diff-impact.js +385 -0
- package/dist/mcp/diff-impact.js.map +1 -0
- package/dist/mcp/liveness-watchdog.js +51 -51
- package/dist/mcp/server-instructions.d.ts +1 -1
- package/dist/mcp/server-instructions.d.ts.map +1 -1
- package/dist/mcp/server-instructions.js +49 -47
- package/dist/mcp/server-instructions.js.map +1 -1
- package/dist/mcp/tools.d.ts +21 -5
- package/dist/mcp/tools.d.ts.map +1 -1
- package/dist/mcp/tools.js +305 -55
- package/dist/mcp/tools.js.map +1 -1
- package/dist/resolution/callback-synthesizer.d.ts +2 -1
- package/dist/resolution/callback-synthesizer.d.ts.map +1 -1
- package/dist/resolution/callback-synthesizer.js +153 -53
- package/dist/resolution/callback-synthesizer.js.map +1 -1
- package/dist/resolution/frameworks/arkts-entry.d.ts.map +1 -1
- package/dist/resolution/frameworks/arkts-entry.js +20 -9
- package/dist/resolution/frameworks/arkts-entry.js.map +1 -1
- package/dist/resolution/index.d.ts.map +1 -1
- package/dist/resolution/index.js +1 -1
- package/dist/resolution/index.js.map +1 -1
- package/dist/resolution/memory-budget.d.ts +33 -0
- package/dist/resolution/memory-budget.d.ts.map +1 -1
- package/dist/resolution/memory-budget.js +58 -0
- package/dist/resolution/memory-budget.js.map +1 -1
- package/dist/resolution/resolver-pool.d.ts +2 -0
- package/dist/resolution/resolver-pool.d.ts.map +1 -1
- package/dist/resolution/resolver-pool.js +4 -0
- package/dist/resolution/resolver-pool.js.map +1 -1
- package/dist/spec/db/commit-node.js +4 -4
- package/dist/spec/db/fragment-node.js +10 -10
- package/dist/spec/db/fts.js +8 -8
- package/dist/spec/db/relations.js +88 -88
- package/dist/spec/db/schema.js +6 -6
- package/dist/spec/db/schema.sql +121 -121
- package/dist/spec/db/spec-node.js +4 -4
- package/dist/spec/llm/prompts.js +53 -53
- package/dist/ui/shimmer-progress.d.ts.map +1 -1
- package/dist/ui/shimmer-progress.js +4 -1
- package/dist/ui/shimmer-progress.js.map +1 -1
- package/package.json +61 -62
- package/dist/extraction/languages/arkts-viewtree.d.ts +0 -22
- package/dist/extraction/languages/arkts-viewtree.d.ts.map +0 -1
- package/dist/extraction/languages/arkts-viewtree.js +0 -133
- package/dist/extraction/languages/arkts-viewtree.js.map +0 -1
- package/dist/reasoning/config.d.ts +0 -45
- package/dist/reasoning/config.d.ts.map +0 -1
- package/dist/reasoning/config.js +0 -171
- package/dist/reasoning/config.js.map +0 -1
- package/dist/reasoning/credentials.d.ts +0 -5
- package/dist/reasoning/credentials.d.ts.map +0 -1
- package/dist/reasoning/credentials.js +0 -83
- package/dist/reasoning/credentials.js.map +0 -1
- package/dist/reasoning/login.d.ts +0 -21
- package/dist/reasoning/login.d.ts.map +0 -1
- package/dist/reasoning/login.js +0 -85
- package/dist/reasoning/login.js.map +0 -1
- package/dist/reasoning/reasoner.d.ts +0 -43
- package/dist/reasoning/reasoner.d.ts.map +0 -1
- package/dist/reasoning/reasoner.js +0 -308
- package/dist/reasoning/reasoner.js.map +0 -1
- package/dist/spec/evolve/llm-client.d.ts +0 -50
- package/dist/spec/evolve/llm-client.d.ts.map +0 -1
- package/dist/spec/evolve/llm-client.js +0 -176
- package/dist/spec/evolve/llm-client.js.map +0 -1
- package/dist/spec/evolve/logic-checker.d.ts +0 -12
- package/dist/spec/evolve/logic-checker.d.ts.map +0 -1
- package/dist/spec/evolve/logic-checker.js +0 -24
- package/dist/spec/evolve/logic-checker.js.map +0 -1
- package/dist/spec/llm/index.d.ts +0 -3
- package/dist/spec/llm/index.d.ts.map +0 -1
- package/dist/spec/llm/index.js +0 -11
- package/dist/spec/llm/index.js.map +0 -1
- package/dist/spec/mining/diff-parser.d.ts +0 -33
- package/dist/spec/mining/diff-parser.d.ts.map +0 -1
- package/dist/spec/mining/diff-parser.js +0 -166
- package/dist/spec/mining/diff-parser.js.map +0 -1
- package/dist/spec/mining/git-scanner.d.ts +0 -103
- package/dist/spec/mining/git-scanner.d.ts.map +0 -1
- package/dist/spec/mining/git-scanner.js +0 -307
- package/dist/spec/mining/git-scanner.js.map +0 -1
- package/dist/spec/mining/pipeline.d.ts +0 -53
- package/dist/spec/mining/pipeline.d.ts.map +0 -1
- package/dist/spec/mining/pipeline.js +0 -178
- package/dist/spec/mining/pipeline.js.map +0 -1
- package/dist/spec/mining/scope-resolver.d.ts +0 -45
- package/dist/spec/mining/scope-resolver.d.ts.map +0 -1
- package/dist/spec/mining/scope-resolver.js +0 -103
- package/dist/spec/mining/scope-resolver.js.map +0 -1
- package/dist/spec/mining/spec-extractor.d.ts +0 -69
- package/dist/spec/mining/spec-extractor.d.ts.map +0 -1
- package/dist/spec/mining/spec-extractor.js +0 -369
- package/dist/spec/mining/spec-extractor.js.map +0 -1
- package/dist/spec/utils.d.ts +0 -167
- package/dist/spec/utils.d.ts.map +0 -1
- package/dist/spec/utils.js +0 -463
- package/dist/spec/utils.js.map +0 -1
- package/scripts/_tmp-cfwk-resolve.log +0 -0
- package/scripts/_tmp-cfwk-sig.log +0 -0
- package/scripts/_tmp-cfwk-vt.log +0 -0
- package/scripts/add-lang/bench.sh +0 -60
- package/scripts/add-lang/check-grammar.mjs +0 -75
- package/scripts/add-lang/dump-ast.mjs +0 -103
- package/scripts/add-lang/verify-extraction.mjs +0 -70
- package/scripts/agent-eval/ab-adoption.sh +0 -91
- package/scripts/agent-eval/ab-hook.sh +0 -86
- package/scripts/agent-eval/ab-impl.sh +0 -78
- package/scripts/agent-eval/ab-new-vs-baseline.sh +0 -102
- package/scripts/agent-eval/ab-sufficiency.sh +0 -78
- package/scripts/agent-eval/arms-F.sh +0 -21
- package/scripts/agent-eval/arms-matrix.sh +0 -37
- package/scripts/agent-eval/audit.sh +0 -68
- package/scripts/agent-eval/bench-readme.sh +0 -28
- package/scripts/agent-eval/bench-why-repo.sh +0 -22
- package/scripts/agent-eval/block-read-hook.sh +0 -19
- package/scripts/agent-eval/hook-settings.json +0 -15
- package/scripts/agent-eval/itrun.sh +0 -120
- package/scripts/agent-eval/offload-eval-3arm.sh +0 -72
- package/scripts/agent-eval/offload-eval-cost.mjs +0 -133
- package/scripts/agent-eval/offload-eval-effort.mjs +0 -108
- package/scripts/agent-eval/offload-eval-frontload-matrix.sh +0 -25
- package/scripts/agent-eval/offload-eval-frontload.sh +0 -47
- package/scripts/agent-eval/offload-eval-ground-truth.json +0 -18
- package/scripts/agent-eval/offload-eval-hook.mjs +0 -84
- package/scripts/agent-eval/offload-eval-judge.mjs +0 -103
- package/scripts/agent-eval/offload-eval-matrix.sh +0 -20
- package/scripts/agent-eval/offload-eval-metrics.mjs +0 -94
- package/scripts/agent-eval/offload-eval-refs1.sh +0 -50
- package/scripts/agent-eval/offload-eval-setup.sh +0 -24
- package/scripts/agent-eval/offload-eval-styles.sh +0 -72
- package/scripts/agent-eval/offload-eval-summarize.mjs +0 -68
- package/scripts/agent-eval/offload-eval.md +0 -76
- package/scripts/agent-eval/parse-arms.mjs +0 -116
- package/scripts/agent-eval/parse-bench-readme.mjs +0 -84
- package/scripts/agent-eval/parse-run.mjs +0 -45
- package/scripts/agent-eval/parse-session.mjs +0 -93
- package/scripts/agent-eval/probe-context.mjs +0 -21
- package/scripts/agent-eval/probe-explore.mjs +0 -40
- package/scripts/agent-eval/probe-node.mjs +0 -20
- package/scripts/agent-eval/probe-sweep.mjs +0 -119
- package/scripts/agent-eval/probe-trace.mjs +0 -20
- package/scripts/agent-eval/redirect-read-hook.sh +0 -38
- package/scripts/agent-eval/repro-concurrent-explore.mjs +0 -119
- package/scripts/agent-eval/repro-daemon-clients.mjs +0 -125
- package/scripts/agent-eval/run-agent.sh +0 -34
- package/scripts/agent-eval/run-all.sh +0 -75
- package/scripts/agent-eval/run-arms.sh +0 -56
- package/scripts/agent-eval/seq-matrix.mjs +0 -137
- package/scripts/bench-arkts-init-rss.log +0 -0
- package/scripts/build-bundle.sh +0 -123
- package/scripts/exp_boundary_eval/README.md +0 -247
- package/scripts/exp_boundary_eval/__pycache__/_utils.cpython-310.pyc +0 -0
- package/scripts/exp_boundary_eval/__pycache__/_utils.cpython-38.pyc +0 -0
- package/scripts/exp_boundary_eval/__pycache__/analyze.cpython-310.pyc +0 -0
- package/scripts/exp_boundary_eval/__pycache__/analyze.cpython-38.pyc +0 -0
- package/scripts/exp_boundary_eval/__pycache__/deveco_arm.cpython-38.pyc +0 -0
- package/scripts/exp_boundary_eval/__pycache__/run_all.cpython-310.pyc +0 -0
- package/scripts/exp_boundary_eval/__pycache__/run_all.cpython-38.pyc +0 -0
- package/scripts/exp_boundary_eval/__pycache__/run_one.cpython-310.pyc +0 -0
- package/scripts/exp_boundary_eval/__pycache__/run_one.cpython-38.pyc +0 -0
- package/scripts/exp_boundary_eval/__pycache__/run_session.cpython-310.pyc +0 -0
- package/scripts/exp_boundary_eval/__pycache__/run_session.cpython-38.pyc +0 -0
- package/scripts/exp_boundary_eval/__pycache__/setup.cpython-310.pyc +0 -0
- package/scripts/exp_boundary_eval/__pycache__/setup.cpython-38.pyc +0 -0
- package/scripts/exp_boundary_eval/__pycache__/win_mcp_launcher.cpython-38.pyc +0 -0
- package/scripts/exp_boundary_eval/_test_mcp_chain.py +0 -78
- package/scripts/exp_boundary_eval/_test_stdin.py +0 -8
- package/scripts/exp_boundary_eval/_utils.py +0 -1116
- package/scripts/exp_boundary_eval/analyze.py +0 -1313
- package/scripts/exp_boundary_eval/deveco_arm.py +0 -519
- package/scripts/exp_boundary_eval/run_all.py +0 -378
- package/scripts/exp_boundary_eval/run_one.py +0 -165
- package/scripts/exp_boundary_eval/run_session.py +0 -158
- package/scripts/exp_boundary_eval/setup.py +0 -120
- package/scripts/exp_boundary_eval/win_mcp_launcher.py +0 -73
- package/scripts/exp_boundary_eval/win_mcp_stdio_wrap.js +0 -36
- package/scripts/exp_boundary_eval/win_node_launcher.py +0 -24
- package/scripts/extract-release-notes.mjs +0 -130
- package/scripts/local-install.sh +0 -41
- package/scripts/npm-sdk.js +0 -75
- package/scripts/npm-shim.js +0 -275
- package/scripts/ohos-sdk-publish.mjs +0 -133
- package/scripts/pack-npm.sh +0 -119
- package/scripts/prepare-release.mjs +0 -270
- package/scripts/probe-arkts-mem-why-run.log +0 -0
- package/scripts/probe-banner-livecard-ir.log +0 -0
- package/scripts/probe-cfwk-ast.stderr.log +0 -0
- package/scripts/probe-cfwk-ast.stdout.log +0 -0
- package/scripts/probe-cfwk-attr-shape.log +0 -0
- package/scripts/probe-cfwk-cfgdump.stderr.log +0 -0
- package/scripts/probe-cfwk-cfgdump.stdout.log +0 -0
- package/scripts/probe-cfwk-cvc.stderr.log +0 -0
- package/scripts/probe-cfwk-cvc.stdout.log +0 -0
- package/scripts/probe-cfwk-diag2.log +0 -0
- package/scripts/probe-cfwk-diag3.log +0 -0
- package/scripts/probe-cfwk-fedbg.stderr.log +0 -0
- package/scripts/probe-cfwk-fedbg.stdout.log +0 -0
- package/scripts/probe-cfwk-fileresult.log +0 -0
- package/scripts/probe-cfwk-fix.stderr.log +0 -0
- package/scripts/probe-cfwk-fix.stdout.log +0 -0
- package/scripts/probe-cfwk-fix2.stderr.log +0 -0
- package/scripts/probe-cfwk-fix2.stdout.log +0 -0
- package/scripts/probe-cfwk-fix3.stderr.log +0 -0
- package/scripts/probe-cfwk-fix3.stdout.log +0 -0
- package/scripts/probe-cfwk-foreach.log +0 -0
- package/scripts/probe-cfwk-getmethod-throw.log +0 -0
- package/scripts/probe-cfwk-hg-extract.log +0 -0
- package/scripts/probe-cfwk-pr1003-noprior.stderr.log +0 -0
- package/scripts/probe-cfwk-pr1003-noprior.stdout.log +0 -0
- package/scripts/probe-cfwk-pr1003.stderr.log +0 -0
- package/scripts/probe-cfwk-pr1003.stdout.log +0 -0
- package/scripts/probe-cfwk-preroot-noprior.stderr.log +0 -0
- package/scripts/probe-cfwk-preroot-noprior.stdout.log +0 -0
- package/scripts/probe-cfwk-preroot-prior.stderr.log +0 -0
- package/scripts/probe-cfwk-preroot-prior.stdout.log +0 -0
- package/scripts/probe-cfwk-preroot-skipstate.stderr.log +0 -0
- package/scripts/probe-cfwk-preroot-skipstate.stdout.log +0 -0
- package/scripts/probe-cfwk-resolve-sim.log +0 -0
- package/scripts/probe-cfwk-tree-shape.log +0 -0
- package/scripts/probe-cfwk-walk-abort.log +0 -0
- package/scripts/probe-cfwk.log +0 -0
- package/scripts/probe-force-index.log +0 -0
- package/scripts/probe-no-force-index.log +0 -0
- package/scripts/probe-samefile-ir.stderr.log +0 -0
- package/scripts/probe-samefile-ir.stdout.log +0 -224
- package/scripts/probe-sdk-vs-project.log +0 -0
- package/scripts/probe-viewtree-downgrade.log +0 -0
package/dist/db/queries.js
CHANGED
|
@@ -255,20 +255,20 @@ class QueryBuilder {
|
|
|
255
255
|
*/
|
|
256
256
|
insertNode(node) {
|
|
257
257
|
if (!this.stmts.insertNode) {
|
|
258
|
-
this.stmts.insertNode = this.db.prepare(`
|
|
259
|
-
INSERT OR REPLACE INTO nodes (
|
|
260
|
-
id, kind, name, qualified_name, file_path, language,
|
|
261
|
-
start_line, end_line, start_column, end_column,
|
|
262
|
-
docstring, signature, visibility,
|
|
263
|
-
is_exported, is_async, is_static, is_abstract,
|
|
264
|
-
decorators, type_parameters, return_type, updated_at
|
|
265
|
-
) VALUES (
|
|
266
|
-
@id, @kind, @name, @qualifiedName, @filePath, @language,
|
|
267
|
-
@startLine, @endLine, @startColumn, @endColumn,
|
|
268
|
-
@docstring, @signature, @visibility,
|
|
269
|
-
@isExported, @isAsync, @isStatic, @isAbstract,
|
|
270
|
-
@decorators, @typeParameters, @returnType, @updatedAt
|
|
271
|
-
)
|
|
258
|
+
this.stmts.insertNode = this.db.prepare(`
|
|
259
|
+
INSERT OR REPLACE INTO nodes (
|
|
260
|
+
id, kind, name, qualified_name, file_path, language,
|
|
261
|
+
start_line, end_line, start_column, end_column,
|
|
262
|
+
docstring, signature, visibility,
|
|
263
|
+
is_exported, is_async, is_static, is_abstract,
|
|
264
|
+
decorators, type_parameters, return_type, updated_at
|
|
265
|
+
) VALUES (
|
|
266
|
+
@id, @kind, @name, @qualifiedName, @filePath, @language,
|
|
267
|
+
@startLine, @endLine, @startColumn, @endColumn,
|
|
268
|
+
@docstring, @signature, @visibility,
|
|
269
|
+
@isExported, @isAsync, @isStatic, @isAbstract,
|
|
270
|
+
@decorators, @typeParameters, @returnType, @updatedAt
|
|
271
|
+
)
|
|
272
272
|
`);
|
|
273
273
|
}
|
|
274
274
|
// Validate required fields to prevent SQLite bind errors
|
|
@@ -364,29 +364,29 @@ class QueryBuilder {
|
|
|
364
364
|
*/
|
|
365
365
|
updateNode(node) {
|
|
366
366
|
if (!this.stmts.updateNode) {
|
|
367
|
-
this.stmts.updateNode = this.db.prepare(`
|
|
368
|
-
UPDATE nodes SET
|
|
369
|
-
kind = @kind,
|
|
370
|
-
name = @name,
|
|
371
|
-
qualified_name = @qualifiedName,
|
|
372
|
-
file_path = @filePath,
|
|
373
|
-
language = @language,
|
|
374
|
-
start_line = @startLine,
|
|
375
|
-
end_line = @endLine,
|
|
376
|
-
start_column = @startColumn,
|
|
377
|
-
end_column = @endColumn,
|
|
378
|
-
docstring = @docstring,
|
|
379
|
-
signature = @signature,
|
|
380
|
-
visibility = @visibility,
|
|
381
|
-
is_exported = @isExported,
|
|
382
|
-
is_async = @isAsync,
|
|
383
|
-
is_static = @isStatic,
|
|
384
|
-
is_abstract = @isAbstract,
|
|
385
|
-
decorators = @decorators,
|
|
386
|
-
type_parameters = @typeParameters,
|
|
387
|
-
return_type = @returnType,
|
|
388
|
-
updated_at = @updatedAt
|
|
389
|
-
WHERE id = @id
|
|
367
|
+
this.stmts.updateNode = this.db.prepare(`
|
|
368
|
+
UPDATE nodes SET
|
|
369
|
+
kind = @kind,
|
|
370
|
+
name = @name,
|
|
371
|
+
qualified_name = @qualifiedName,
|
|
372
|
+
file_path = @filePath,
|
|
373
|
+
language = @language,
|
|
374
|
+
start_line = @startLine,
|
|
375
|
+
end_line = @endLine,
|
|
376
|
+
start_column = @startColumn,
|
|
377
|
+
end_column = @endColumn,
|
|
378
|
+
docstring = @docstring,
|
|
379
|
+
signature = @signature,
|
|
380
|
+
visibility = @visibility,
|
|
381
|
+
is_exported = @isExported,
|
|
382
|
+
is_async = @isAsync,
|
|
383
|
+
is_static = @isStatic,
|
|
384
|
+
is_abstract = @isAbstract,
|
|
385
|
+
decorators = @decorators,
|
|
386
|
+
type_parameters = @typeParameters,
|
|
387
|
+
return_type = @returnType,
|
|
388
|
+
updated_at = @updatedAt
|
|
389
|
+
WHERE id = @id
|
|
390
390
|
`);
|
|
391
391
|
}
|
|
392
392
|
// Invalidate cache before update
|
|
@@ -518,12 +518,12 @@ class QueryBuilder {
|
|
|
518
518
|
const placeholders = variants.map(() => '?').join(', ');
|
|
519
519
|
const whens = variants.map(() => 'WHEN ? THEN ?').join(' ');
|
|
520
520
|
const rows = this.db
|
|
521
|
-
.prepare(`SELECT name, COUNT(DISTINCT CASE segment ${whens} END) AS matches
|
|
522
|
-
FROM name_segment_vocab
|
|
523
|
-
WHERE segment IN (${placeholders})
|
|
524
|
-
GROUP BY name
|
|
525
|
-
HAVING matches >= ?
|
|
526
|
-
ORDER BY matches DESC, length(name) ASC
|
|
521
|
+
.prepare(`SELECT name, COUNT(DISTINCT CASE segment ${whens} END) AS matches
|
|
522
|
+
FROM name_segment_vocab
|
|
523
|
+
WHERE segment IN (${placeholders})
|
|
524
|
+
GROUP BY name
|
|
525
|
+
HAVING matches >= ?
|
|
526
|
+
ORDER BY matches DESC, length(name) ASC
|
|
527
527
|
LIMIT ?`)
|
|
528
528
|
.all(...variants.flatMap((v) => [v.segment, v.word]), ...variants.map((v) => v.segment), minWords, limit);
|
|
529
529
|
return rows;
|
|
@@ -535,7 +535,7 @@ class QueryBuilder {
|
|
|
535
535
|
return new Map();
|
|
536
536
|
const placeholders = segments.map(() => '?').join(', ');
|
|
537
537
|
const rows = this.db
|
|
538
|
-
.prepare(`SELECT segment, COUNT(*) AS n FROM name_segment_vocab
|
|
538
|
+
.prepare(`SELECT segment, COUNT(*) AS n FROM name_segment_vocab
|
|
539
539
|
WHERE segment IN (${placeholders}) GROUP BY segment`)
|
|
540
540
|
.all(...segments);
|
|
541
541
|
return new Map(rows.map((r) => [r.segment, r.n]));
|
|
@@ -695,15 +695,15 @@ class QueryBuilder {
|
|
|
695
695
|
// protobuf stub) outranks the real `server/etcdserver/server.go`
|
|
696
696
|
// (470 edges) by 4×, and the boost would push the agent toward
|
|
697
697
|
// generated code.
|
|
698
|
-
this.stmts.getDominantFile = this.db.prepare(`
|
|
699
|
-
SELECT n.file_path AS file_path, COUNT(*) AS edge_count
|
|
700
|
-
FROM edges e
|
|
701
|
-
JOIN nodes n ON e.source = n.id
|
|
702
|
-
JOIN nodes m ON e.target = m.id
|
|
703
|
-
WHERE n.file_path = m.file_path
|
|
704
|
-
GROUP BY n.file_path
|
|
705
|
-
ORDER BY edge_count DESC
|
|
706
|
-
LIMIT 20
|
|
698
|
+
this.stmts.getDominantFile = this.db.prepare(`
|
|
699
|
+
SELECT n.file_path AS file_path, COUNT(*) AS edge_count
|
|
700
|
+
FROM edges e
|
|
701
|
+
JOIN nodes n ON e.source = n.id
|
|
702
|
+
JOIN nodes m ON e.target = m.id
|
|
703
|
+
WHERE n.file_path = m.file_path
|
|
704
|
+
GROUP BY n.file_path
|
|
705
|
+
ORDER BY edge_count DESC
|
|
706
|
+
LIMIT 20
|
|
707
707
|
`);
|
|
708
708
|
}
|
|
709
709
|
const rows = this.stmts.getDominantFile.all();
|
|
@@ -730,13 +730,13 @@ class QueryBuilder {
|
|
|
730
730
|
*/
|
|
731
731
|
getTopRouteFile() {
|
|
732
732
|
if (!this.stmts.getTopRouteFile) {
|
|
733
|
-
this.stmts.getTopRouteFile = this.db.prepare(`
|
|
734
|
-
SELECT file_path, COUNT(*) AS cnt
|
|
735
|
-
FROM nodes
|
|
736
|
-
WHERE kind = 'route'
|
|
737
|
-
GROUP BY file_path
|
|
738
|
-
ORDER BY cnt DESC
|
|
739
|
-
LIMIT 20
|
|
733
|
+
this.stmts.getTopRouteFile = this.db.prepare(`
|
|
734
|
+
SELECT file_path, COUNT(*) AS cnt
|
|
735
|
+
FROM nodes
|
|
736
|
+
WHERE kind = 'route'
|
|
737
|
+
GROUP BY file_path
|
|
738
|
+
ORDER BY cnt DESC
|
|
739
|
+
LIMIT 20
|
|
740
740
|
`);
|
|
741
741
|
}
|
|
742
742
|
const rows = this.stmts.getTopRouteFile.all();
|
|
@@ -767,21 +767,21 @@ class QueryBuilder {
|
|
|
767
767
|
// Edge kind varies across framework resolvers: Spring/Rails/
|
|
768
768
|
// Laravel/Drupal emit `references`, Express emits `calls`. Accept
|
|
769
769
|
// both — the semantic is the same (route → its handler).
|
|
770
|
-
this.stmts.getRoutingManifest = this.db.prepare(`
|
|
771
|
-
SELECT
|
|
772
|
-
r.name AS url,
|
|
773
|
-
h.name AS handler,
|
|
774
|
-
h.file_path AS handler_file,
|
|
775
|
-
h.start_line AS handler_line,
|
|
776
|
-
h.kind AS handler_kind
|
|
777
|
-
FROM nodes r
|
|
778
|
-
JOIN edges e ON e.source = r.id
|
|
779
|
-
JOIN nodes h ON e.target = h.id
|
|
780
|
-
WHERE r.kind = 'route'
|
|
781
|
-
AND e.kind IN ('references', 'calls')
|
|
782
|
-
AND h.kind IN ('function', 'method', 'class')
|
|
783
|
-
ORDER BY r.file_path, r.start_line
|
|
784
|
-
LIMIT ?
|
|
770
|
+
this.stmts.getRoutingManifest = this.db.prepare(`
|
|
771
|
+
SELECT
|
|
772
|
+
r.name AS url,
|
|
773
|
+
h.name AS handler,
|
|
774
|
+
h.file_path AS handler_file,
|
|
775
|
+
h.start_line AS handler_line,
|
|
776
|
+
h.kind AS handler_kind
|
|
777
|
+
FROM nodes r
|
|
778
|
+
JOIN edges e ON e.source = r.id
|
|
779
|
+
JOIN nodes h ON e.target = h.id
|
|
780
|
+
WHERE r.kind = 'route'
|
|
781
|
+
AND e.kind IN ('references', 'calls')
|
|
782
|
+
AND h.kind IN ('function', 'method', 'class')
|
|
783
|
+
ORDER BY r.file_path, r.start_line
|
|
784
|
+
LIMIT ?
|
|
785
785
|
`);
|
|
786
786
|
}
|
|
787
787
|
const rows = this.stmts.getRoutingManifest.all(limit);
|
|
@@ -1036,10 +1036,10 @@ class QueryBuilder {
|
|
|
1036
1036
|
const seen = new Set(existing.map((r) => r.node.id));
|
|
1037
1037
|
const merged = [...existing];
|
|
1038
1038
|
const apiLimit = Math.min(20, Math.max(5, Math.floor(limit / 4)));
|
|
1039
|
-
let sql = `
|
|
1040
|
-
SELECT nodes.*, 0.9 as score
|
|
1041
|
-
FROM ohos_api.nodes
|
|
1042
|
-
WHERE (name LIKE ? OR qualified_name LIKE ?)
|
|
1039
|
+
let sql = `
|
|
1040
|
+
SELECT nodes.*, 0.9 as score
|
|
1041
|
+
FROM ohos_api.nodes
|
|
1042
|
+
WHERE (name LIKE ? OR qualified_name LIKE ?)
|
|
1043
1043
|
`;
|
|
1044
1044
|
const pattern = `%${text}%`;
|
|
1045
1045
|
const params = [pattern, pattern];
|
|
@@ -1178,11 +1178,11 @@ class QueryBuilder {
|
|
|
1178
1178
|
// Fetch 5x requested limit so post-hoc rescoring (kindBonus, pathRelevance,
|
|
1179
1179
|
// nameMatchBonus) can promote results that BM25 alone undervalues.
|
|
1180
1180
|
const ftsLimit = Math.max(limit * 5, 100);
|
|
1181
|
-
let sql = `
|
|
1182
|
-
SELECT nodes.*, bm25(nodes_fts, 0, 20, 5, 1, 2) as score
|
|
1183
|
-
FROM nodes_fts
|
|
1184
|
-
JOIN nodes ON nodes_fts.id = nodes.id
|
|
1185
|
-
WHERE nodes_fts MATCH ?
|
|
1181
|
+
let sql = `
|
|
1182
|
+
SELECT nodes.*, bm25(nodes_fts, 0, 20, 5, 1, 2) as score
|
|
1183
|
+
FROM nodes_fts
|
|
1184
|
+
JOIN nodes ON nodes_fts.id = nodes.id
|
|
1185
|
+
WHERE nodes_fts MATCH ?
|
|
1186
1186
|
`;
|
|
1187
1187
|
const params = [ftsQuery];
|
|
1188
1188
|
if (kinds && kinds.length > 0) {
|
|
@@ -1213,21 +1213,21 @@ class QueryBuilder {
|
|
|
1213
1213
|
*/
|
|
1214
1214
|
searchNodesLike(query, options) {
|
|
1215
1215
|
const { kinds, languages, limit = 100, offset = 0 } = options;
|
|
1216
|
-
let sql = `
|
|
1217
|
-
SELECT nodes.*,
|
|
1218
|
-
CASE
|
|
1219
|
-
WHEN name = ? THEN 1.0
|
|
1220
|
-
WHEN name LIKE ? THEN 0.9
|
|
1221
|
-
WHEN name LIKE ? THEN 0.8
|
|
1222
|
-
WHEN qualified_name LIKE ? THEN 0.7
|
|
1223
|
-
ELSE 0.5
|
|
1224
|
-
END as score
|
|
1225
|
-
FROM nodes
|
|
1226
|
-
WHERE (
|
|
1227
|
-
name LIKE ? OR
|
|
1228
|
-
qualified_name LIKE ? OR
|
|
1229
|
-
name LIKE ?
|
|
1230
|
-
)
|
|
1216
|
+
let sql = `
|
|
1217
|
+
SELECT nodes.*,
|
|
1218
|
+
CASE
|
|
1219
|
+
WHEN name = ? THEN 1.0
|
|
1220
|
+
WHEN name LIKE ? THEN 0.9
|
|
1221
|
+
WHEN name LIKE ? THEN 0.8
|
|
1222
|
+
WHEN qualified_name LIKE ? THEN 0.7
|
|
1223
|
+
ELSE 0.5
|
|
1224
|
+
END as score
|
|
1225
|
+
FROM nodes
|
|
1226
|
+
WHERE (
|
|
1227
|
+
name LIKE ? OR
|
|
1228
|
+
qualified_name LIKE ? OR
|
|
1229
|
+
name LIKE ?
|
|
1230
|
+
)
|
|
1231
1231
|
`;
|
|
1232
1232
|
// Pattern variants for better matching
|
|
1233
1233
|
const exactMatch = query;
|
|
@@ -1301,10 +1301,10 @@ class QueryBuilder {
|
|
|
1301
1301
|
const allResults = [];
|
|
1302
1302
|
const seenIds = new Set();
|
|
1303
1303
|
for (const name of names) {
|
|
1304
|
-
let sql = `
|
|
1305
|
-
SELECT nodes.*, 1.0 as score
|
|
1306
|
-
FROM nodes
|
|
1307
|
-
WHERE name COLLATE NOCASE = ?
|
|
1304
|
+
let sql = `
|
|
1305
|
+
SELECT nodes.*, 1.0 as score
|
|
1306
|
+
FROM nodes
|
|
1307
|
+
WHERE name COLLATE NOCASE = ?
|
|
1308
1308
|
`;
|
|
1309
1309
|
const params = [name];
|
|
1310
1310
|
if (kinds && kinds.length > 0) {
|
|
@@ -1335,10 +1335,10 @@ class QueryBuilder {
|
|
|
1335
1335
|
allResults.push(r);
|
|
1336
1336
|
}
|
|
1337
1337
|
if (this.hasOhosApiAttached()) {
|
|
1338
|
-
let apiSql = `
|
|
1339
|
-
SELECT nodes.*, 0.95 as score
|
|
1340
|
-
FROM ohos_api.nodes
|
|
1341
|
-
WHERE name COLLATE NOCASE = ?
|
|
1338
|
+
let apiSql = `
|
|
1339
|
+
SELECT nodes.*, 0.95 as score
|
|
1340
|
+
FROM ohos_api.nodes
|
|
1341
|
+
WHERE name COLLATE NOCASE = ?
|
|
1342
1342
|
`;
|
|
1343
1343
|
const apiParams = [name];
|
|
1344
1344
|
if (kinds && kinds.length > 0) {
|
|
@@ -1374,10 +1374,10 @@ class QueryBuilder {
|
|
|
1374
1374
|
*/
|
|
1375
1375
|
findNodesByNameSubstring(substring, options = {}) {
|
|
1376
1376
|
const { kinds, languages, limit = 30, excludePrefix } = options;
|
|
1377
|
-
let sql = `
|
|
1378
|
-
SELECT nodes.*, 1.0 as score
|
|
1379
|
-
FROM nodes
|
|
1380
|
-
WHERE name LIKE ?
|
|
1377
|
+
let sql = `
|
|
1378
|
+
SELECT nodes.*, 1.0 as score
|
|
1379
|
+
FROM nodes
|
|
1380
|
+
WHERE name LIKE ?
|
|
1381
1381
|
`;
|
|
1382
1382
|
const params = [`%${substring}%`];
|
|
1383
1383
|
// Exclude prefix matches (handled by FTS-based prefix search in Step 2b)
|
|
@@ -1409,9 +1409,9 @@ class QueryBuilder {
|
|
|
1409
1409
|
*/
|
|
1410
1410
|
insertEdge(edge) {
|
|
1411
1411
|
if (!this.stmts.insertEdge) {
|
|
1412
|
-
this.stmts.insertEdge = this.db.prepare(`
|
|
1413
|
-
INSERT OR IGNORE INTO edges (source, target, kind, metadata, line, col, provenance)
|
|
1414
|
-
VALUES (@source, @target, @kind, @metadata, @line, @col, @provenance)
|
|
1412
|
+
this.stmts.insertEdge = this.db.prepare(`
|
|
1413
|
+
INSERT OR IGNORE INTO edges (source, target, kind, metadata, line, col, provenance)
|
|
1414
|
+
VALUES (@source, @target, @kind, @metadata, @line, @col, @provenance)
|
|
1415
1415
|
`);
|
|
1416
1416
|
}
|
|
1417
1417
|
this.stmts.insertEdge.run({
|
|
@@ -1538,12 +1538,12 @@ class QueryBuilder {
|
|
|
1538
1538
|
* it. One indexed query (idx_nodes_file_path + idx_edges_target_kind).
|
|
1539
1539
|
*/
|
|
1540
1540
|
getDependentFilePaths(filePath) {
|
|
1541
|
-
const sql = `SELECT DISTINCT src.file_path AS fp
|
|
1542
|
-
FROM edges e
|
|
1543
|
-
JOIN nodes tgt ON tgt.id = e.target
|
|
1544
|
-
JOIN nodes src ON src.id = e.source
|
|
1545
|
-
WHERE tgt.file_path = ?
|
|
1546
|
-
AND e.kind != 'contains'
|
|
1541
|
+
const sql = `SELECT DISTINCT src.file_path AS fp
|
|
1542
|
+
FROM edges e
|
|
1543
|
+
JOIN nodes tgt ON tgt.id = e.target
|
|
1544
|
+
JOIN nodes src ON src.id = e.source
|
|
1545
|
+
WHERE tgt.file_path = ?
|
|
1546
|
+
AND e.kind != 'contains'
|
|
1547
1547
|
AND src.file_path != ?`;
|
|
1548
1548
|
const rows = this.db.prepare(sql).all(filePath, filePath);
|
|
1549
1549
|
return rows.map((r) => r.fp);
|
|
@@ -1555,12 +1555,12 @@ class QueryBuilder {
|
|
|
1555
1555
|
* (all kinds except `contains`); same reason imports-only is insufficient.
|
|
1556
1556
|
*/
|
|
1557
1557
|
getDependencyFilePaths(filePath) {
|
|
1558
|
-
const sql = `SELECT DISTINCT tgt.file_path AS fp
|
|
1559
|
-
FROM edges e
|
|
1560
|
-
JOIN nodes src ON src.id = e.source
|
|
1561
|
-
JOIN nodes tgt ON tgt.id = e.target
|
|
1562
|
-
WHERE src.file_path = ?
|
|
1563
|
-
AND e.kind != 'contains'
|
|
1558
|
+
const sql = `SELECT DISTINCT tgt.file_path AS fp
|
|
1559
|
+
FROM edges e
|
|
1560
|
+
JOIN nodes src ON src.id = e.source
|
|
1561
|
+
JOIN nodes tgt ON tgt.id = e.target
|
|
1562
|
+
WHERE src.file_path = ?
|
|
1563
|
+
AND e.kind != 'contains'
|
|
1564
1564
|
AND tgt.file_path != ?`;
|
|
1565
1565
|
const rows = this.db.prepare(sql).all(filePath, filePath);
|
|
1566
1566
|
return rows.map((r) => r.fp);
|
|
@@ -1576,13 +1576,13 @@ class QueryBuilder {
|
|
|
1576
1576
|
* {@link getDependentFilePaths}: all kinds except `contains`.
|
|
1577
1577
|
*/
|
|
1578
1578
|
getCrossFileIncomingEdgesWithTarget(filePath) {
|
|
1579
|
-
const sql = `SELECT e.*, tgt.name AS target_name, tgt.kind AS target_kind,
|
|
1580
|
-
src.file_path AS source_file_path, src.language AS source_language
|
|
1581
|
-
FROM edges e
|
|
1582
|
-
JOIN nodes tgt ON tgt.id = e.target
|
|
1583
|
-
JOIN nodes src ON src.id = e.source
|
|
1584
|
-
WHERE tgt.file_path = ?
|
|
1585
|
-
AND e.kind != 'contains'
|
|
1579
|
+
const sql = `SELECT e.*, tgt.name AS target_name, tgt.kind AS target_kind,
|
|
1580
|
+
src.file_path AS source_file_path, src.language AS source_language
|
|
1581
|
+
FROM edges e
|
|
1582
|
+
JOIN nodes tgt ON tgt.id = e.target
|
|
1583
|
+
JOIN nodes src ON src.id = e.source
|
|
1584
|
+
WHERE tgt.file_path = ?
|
|
1585
|
+
AND e.kind != 'contains'
|
|
1586
1586
|
AND src.file_path != ?`;
|
|
1587
1587
|
const rows = this.db.prepare(sql).all(filePath, filePath);
|
|
1588
1588
|
return rows.map(row => ({
|
|
@@ -1599,10 +1599,10 @@ class QueryBuilder {
|
|
|
1599
1599
|
*/
|
|
1600
1600
|
deleteArkTSCrossFileCallEdges() {
|
|
1601
1601
|
const result = this.db
|
|
1602
|
-
.prepare(`DELETE FROM edges
|
|
1603
|
-
WHERE kind = 'calls'
|
|
1604
|
-
AND provenance = 'heuristic'
|
|
1605
|
-
AND metadata LIKE '%"synthesizedBy":"arkanalyzer"%'
|
|
1602
|
+
.prepare(`DELETE FROM edges
|
|
1603
|
+
WHERE kind = 'calls'
|
|
1604
|
+
AND provenance = 'heuristic'
|
|
1605
|
+
AND metadata LIKE '%"synthesizedBy":"arkanalyzer"%'
|
|
1606
1606
|
AND metadata LIKE '%"sourceFile"%'`)
|
|
1607
1607
|
.run();
|
|
1608
1608
|
return result.changes;
|
|
@@ -1615,17 +1615,17 @@ class QueryBuilder {
|
|
|
1615
1615
|
*/
|
|
1616
1616
|
upsertFile(file) {
|
|
1617
1617
|
if (!this.stmts.upsertFile) {
|
|
1618
|
-
this.stmts.upsertFile = this.db.prepare(`
|
|
1619
|
-
INSERT INTO files (path, content_hash, language, size, modified_at, indexed_at, node_count, errors)
|
|
1620
|
-
VALUES (@path, @contentHash, @language, @size, @modifiedAt, @indexedAt, @nodeCount, @errors)
|
|
1621
|
-
ON CONFLICT(path) DO UPDATE SET
|
|
1622
|
-
content_hash = @contentHash,
|
|
1623
|
-
language = @language,
|
|
1624
|
-
size = @size,
|
|
1625
|
-
modified_at = @modifiedAt,
|
|
1626
|
-
indexed_at = @indexedAt,
|
|
1627
|
-
node_count = @nodeCount,
|
|
1628
|
-
errors = @errors
|
|
1618
|
+
this.stmts.upsertFile = this.db.prepare(`
|
|
1619
|
+
INSERT INTO files (path, content_hash, language, size, modified_at, indexed_at, node_count, errors)
|
|
1620
|
+
VALUES (@path, @contentHash, @language, @size, @modifiedAt, @indexedAt, @nodeCount, @errors)
|
|
1621
|
+
ON CONFLICT(path) DO UPDATE SET
|
|
1622
|
+
content_hash = @contentHash,
|
|
1623
|
+
language = @language,
|
|
1624
|
+
size = @size,
|
|
1625
|
+
modified_at = @modifiedAt,
|
|
1626
|
+
indexed_at = @indexedAt,
|
|
1627
|
+
node_count = @nodeCount,
|
|
1628
|
+
errors = @errors
|
|
1629
1629
|
`);
|
|
1630
1630
|
}
|
|
1631
1631
|
this.stmts.upsertFile.run({
|
|
@@ -1699,9 +1699,9 @@ class QueryBuilder {
|
|
|
1699
1699
|
*/
|
|
1700
1700
|
insertUnresolvedRef(ref) {
|
|
1701
1701
|
if (!this.stmts.insertUnresolved) {
|
|
1702
|
-
this.stmts.insertUnresolved = this.db.prepare(`
|
|
1703
|
-
INSERT INTO unresolved_refs (from_node_id, reference_name, reference_kind, line, col, candidates, file_path, language)
|
|
1704
|
-
VALUES (@fromNodeId, @referenceName, @referenceKind, @line, @col, @candidates, @filePath, @language)
|
|
1702
|
+
this.stmts.insertUnresolved = this.db.prepare(`
|
|
1703
|
+
INSERT INTO unresolved_refs (from_node_id, reference_name, reference_kind, line, col, candidates, file_path, language)
|
|
1704
|
+
VALUES (@fromNodeId, @referenceName, @referenceKind, @line, @col, @candidates, @filePath, @language)
|
|
1705
1705
|
`);
|
|
1706
1706
|
}
|
|
1707
1707
|
this.stmts.insertUnresolved.run({
|
|
@@ -2085,11 +2085,11 @@ class QueryBuilder {
|
|
|
2085
2085
|
*/
|
|
2086
2086
|
getStats() {
|
|
2087
2087
|
// Single query for all three aggregate counts
|
|
2088
|
-
const counts = this.db.prepare(`
|
|
2089
|
-
SELECT
|
|
2090
|
-
(SELECT COUNT(*) FROM nodes) AS node_count,
|
|
2091
|
-
(SELECT COUNT(*) FROM edges) AS edge_count,
|
|
2092
|
-
(SELECT COUNT(*) FROM files) AS file_count
|
|
2088
|
+
const counts = this.db.prepare(`
|
|
2089
|
+
SELECT
|
|
2090
|
+
(SELECT COUNT(*) FROM nodes) AS node_count,
|
|
2091
|
+
(SELECT COUNT(*) FROM edges) AS edge_count,
|
|
2092
|
+
(SELECT COUNT(*) FROM files) AS file_count
|
|
2093
2093
|
`).get();
|
|
2094
2094
|
const nodesByKind = {};
|
|
2095
2095
|
const nodeKindRows = this.db
|