akm-cli 0.9.16 → 0.9.17-alpha.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 +2101 -0
- package/STABILITY.md +11 -10
- package/dist/akm +124 -193
- package/dist/akm-migrate +38 -19
- package/dist/assets/hints/cli-hints-full.md +6 -7
- package/dist/assets/improve-strategies/catchup.json +0 -3
- package/dist/assets/improve-strategies/consolidate.json +0 -1
- package/dist/assets/improve-strategies/default.json +1 -2
- package/dist/assets/improve-strategies/proactive-maintenance.json +1 -2
- package/dist/assets/improve-strategies/quick.json +1 -2
- package/dist/assets/improve-strategies/reflect-distill.json +1 -2
- package/dist/assets/improve-strategies/thorough.json +0 -3
- package/dist/assets/prompts/consolidate-pair.md +20 -0
- package/dist/assets/prompts/consolidate-system.md +4 -11
- package/dist/assets/prompts/retrieval-relevance-judge.md +6 -0
- package/dist/assets/stash-skeleton/facts/conventions/backlinks.md +20 -20
- package/dist/assets/stash-skeleton/facts/conventions/domains.md +2 -2
- package/dist/assets/templates/html/health.html +3 -5
- package/dist/cli/retired-commands.js +1 -1
- package/dist/cli/shared.js +6 -2
- package/dist/cli/unknown-flags.js +24 -1
- package/dist/cli.js +68 -10
- package/dist/commands/agent/agent-dispatch.js +1 -1
- package/dist/commands/command/command-execution.js +24 -62
- package/dist/commands/feedback-cli.js +0 -1
- package/dist/commands/health/accept-rate.js +6 -0
- package/dist/commands/health/archive-usage.js +92 -0
- package/dist/commands/health/checks.js +83 -74
- package/dist/commands/health/config-skew.js +38 -0
- package/dist/commands/health/data-dir-usage.js +25 -13
- package/dist/commands/health/egress.js +54 -0
- package/dist/commands/health/html-report.js +1 -42
- package/dist/commands/health/improve-metrics.js +136 -591
- package/dist/commands/health/md-report.js +1 -6
- package/dist/commands/health/plugin-staleness.js +53 -3
- package/dist/commands/health/renderers.js +12 -4
- package/dist/commands/health/report-view-model.js +14 -120
- package/dist/commands/health/types-improve.js +4 -19
- package/dist/commands/health/windows.js +64 -74
- package/dist/commands/health.js +145 -143
- package/dist/commands/improve/consolidate/chunking.js +26 -117
- package/dist/commands/improve/consolidate/continuity-check.js +137 -0
- package/dist/commands/improve/consolidate/pair-pass.js +791 -0
- package/dist/commands/improve/consolidate/sanitize.js +54 -149
- package/dist/commands/improve/consolidate.js +589 -1127
- package/dist/commands/improve/content-hash.js +16 -24
- package/dist/commands/improve/distill/content-repair.js +18 -100
- package/dist/commands/improve/distill-guards.js +20 -81
- package/dist/commands/improve/distill-promotion-policy.js +23 -243
- package/dist/commands/improve/distill.js +608 -1041
- package/dist/commands/improve/eligibility.js +126 -390
- package/dist/commands/improve/execution.js +8 -10
- package/dist/commands/improve/extract-prompt.js +1 -2
- package/dist/commands/improve/extract.js +487 -1046
- package/dist/commands/improve/feedback-valence.js +0 -25
- package/dist/commands/improve/improve-cli.js +75 -169
- package/dist/commands/improve/improve-result-file.js +10 -66
- package/dist/commands/improve/improve-strategies.js +52 -4
- package/dist/commands/improve/improve-usage-report.js +18 -64
- package/dist/commands/improve/improve.js +480 -1074
- package/dist/commands/improve/ledger.js +119 -0
- package/dist/commands/improve/locks.js +2 -8
- package/dist/commands/improve/loop-stages.js +415 -1073
- package/dist/commands/improve/memory/derived-ref.js +12 -77
- package/dist/commands/improve/memory/memory-belief.js +16 -118
- package/dist/commands/improve/memory/memory-improve.js +266 -14
- package/dist/commands/improve/outcome-loop.js +28 -156
- package/dist/commands/improve/planner.js +5 -15
- package/dist/commands/improve/preparation.js +779 -2319
- package/dist/commands/improve/proactive-maintenance.js +34 -101
- package/dist/commands/improve/reflect-noise.js +104 -280
- package/dist/commands/improve/reflect.js +642 -1353
- package/dist/commands/improve/retrieval-gate.js +127 -0
- package/dist/commands/improve/retrieval-scope.js +92 -0
- package/dist/commands/improve/salience.js +41 -240
- package/dist/commands/improve/session-asset.js +19 -100
- package/dist/commands/improve/stage.js +322 -0
- package/dist/commands/lint/base-linter.js +37 -15
- package/dist/commands/proposal/drain.js +261 -578
- package/dist/commands/proposal/proposal-cli.js +19 -20
- package/dist/commands/proposal/proposal-types.js +31 -24
- package/dist/commands/proposal/proposal.js +38 -8
- package/dist/commands/proposal/propose.js +134 -160
- package/dist/commands/proposal/repository.js +1097 -1394
- package/dist/commands/proposal/validators/proposal-quality-validators.js +71 -174
- package/dist/commands/proposal/validators/proposal-validators.js +1 -1
- package/dist/commands/proposal/validators/proposals.js +22 -89
- package/dist/commands/read/curate.js +105 -462
- package/dist/commands/read/knowledge.js +3 -2
- package/dist/commands/read/search-cli.js +16 -33
- package/dist/commands/read/search.js +17 -23
- package/dist/commands/read/show.js +57 -108
- package/dist/commands/sources/bundle-cli.js +25 -2
- package/dist/commands/sources/bundle-config-ops.js +4 -0
- package/dist/commands/sources/dangerous-env-audit.js +1 -2
- package/dist/commands/sources/info.js +127 -29
- package/dist/commands/sources/installed-stashes.js +197 -746
- package/dist/commands/sources/schema-repair.js +98 -129
- package/dist/commands/sources/source-add.js +62 -12
- package/dist/commands/sources/source-manage.js +9 -2
- package/dist/commands/sources/stash-cli.js +24 -4
- package/dist/commands/tasks/explain.js +10 -13
- package/dist/commands/tasks/tasks-cli.js +12 -13
- package/dist/commands/tasks/tasks.js +350 -936
- package/dist/commands/tasks/validate.js +26 -24
- package/dist/commands/workflow/plan.js +22 -29
- package/dist/commands/workflow-cli.js +4 -4
- package/dist/core/adapter/adapters/akm-adapter.js +2 -1
- package/dist/core/adapter/adapters/akm-lint.js +2 -3
- package/dist/core/adapter/adapters/akm-metadata.js +42 -12
- package/dist/core/adapter/adapters/akm-task-adapter.js +29 -8
- package/dist/core/adapter/adapters/akm-workflow-adapter.js +1 -1
- package/dist/core/adapter/execution-source.js +17 -29
- package/dist/core/asset/asset-placement.js +4 -13
- package/dist/core/asset/frontmatter.js +106 -1
- package/dist/core/asset/resolve-ref.js +1 -1
- package/dist/core/bundle-id.js +42 -5
- package/dist/core/bundle-rename.js +285 -0
- package/dist/core/config/config-io.js +1 -2
- package/dist/core/config/config-schema.js +9 -34
- package/dist/core/config/config-walker.js +1 -1
- package/dist/core/config/config.js +184 -111
- package/dist/core/config/engine-semantics.js +0 -2
- package/dist/core/config/legacy-source-shape-shim.js +38 -9
- package/dist/core/config/schema/embedding.js +20 -5
- package/dist/core/config/schema/engines.js +5 -0
- package/dist/core/config/schema/execution.js +1 -1
- package/dist/core/config/schema/experimental.js +1 -1
- package/dist/core/config/schema/improve-processes.js +54 -125
- package/dist/core/config/schema/improve.js +4 -42
- package/dist/core/config/schema/index-config.js +9 -48
- package/dist/core/config/schema/scheduler.js +12 -12
- package/dist/core/config/schema/search.js +6 -22
- package/dist/core/env-secret-ref.js +0 -1
- package/dist/core/errors.js +8 -9
- package/dist/core/file-change.js +13 -5
- package/dist/core/file-lock.js +76 -173
- package/dist/core/improve-result.js +35 -7
- package/dist/core/improve-types.js +0 -1
- package/dist/core/logs-db.js +2 -2
- package/dist/core/loopback.js +7 -12
- package/dist/core/non-task-input.js +20 -0
- package/dist/core/parse.js +13 -16
- package/dist/core/paths.js +0 -24
- package/dist/core/redaction.js +109 -2
- package/dist/core/run-lock.js +2 -5
- package/dist/core/spawn-env.js +1 -1
- package/dist/core/state/migrations.js +123 -61
- package/dist/core/state-db-scope.js +2 -4
- package/dist/core/state-db.js +126 -692
- package/dist/core/time.js +0 -20
- package/dist/core/type-presentation.js +1 -9
- package/dist/core/write-source.js +294 -1005
- package/dist/execution/input-contract.js +1 -1
- package/dist/execution/resolved-request.js +135 -689
- package/dist/execution/source.js +63 -257
- package/dist/execution/target-ref.js +1 -1
- package/dist/indexer/bundle-identity-guard.js +2 -2
- package/dist/indexer/db/llm-cache.js +2 -2
- package/dist/indexer/ensure-index.js +77 -73
- package/dist/indexer/index-rebuild-lock.js +3 -11
- package/dist/indexer/index-writer-lock.js +8 -17
- package/dist/indexer/index-written-assets.js +141 -154
- package/dist/indexer/indexer.js +400 -1124
- package/dist/indexer/links/declared-links.js +90 -0
- package/dist/indexer/materialize-embeddings.js +60 -397
- package/dist/indexer/passes/memory-inference.js +96 -90
- package/dist/indexer/passes/metadata.js +132 -219
- package/dist/indexer/read-preflight.js +0 -7
- package/dist/indexer/scan/doc-to-entry.js +2 -3
- package/dist/indexer/scan/drain-dir.js +1 -1
- package/dist/indexer/search/db-search.js +190 -590
- package/dist/indexer/search/fts-query.js +30 -41
- package/dist/indexer/search/ranking.js +28 -154
- package/dist/indexer/search/search-attribution.js +12 -32
- package/dist/indexer/search/search-fields.js +11 -15
- package/dist/indexer/search/search-hit-enrichers.js +54 -85
- package/dist/indexer/search/search-source.js +1 -4
- package/dist/indexer/usage/usage-events.js +36 -7
- package/dist/indexer/walk/walker.js +3 -4
- package/dist/integrations/agent/engine-fallback.js +23 -40
- package/dist/integrations/agent/engine-resolution.js +93 -183
- package/dist/integrations/agent/execution.js +507 -0
- package/dist/integrations/agent/model-map.js +28 -156
- package/dist/integrations/agent/request-lowering.js +66 -141
- package/dist/integrations/agent/runner-dispatch.js +143 -321
- package/dist/integrations/agent/runner.js +54 -14
- package/dist/integrations/lockfile.js +53 -101
- package/dist/llm/client.js +18 -6
- package/dist/llm/embedders/deterministic.js +2 -3
- package/dist/llm/embedders/profile.js +71 -0
- package/dist/llm/embedders/remote.js +11 -17
- package/dist/llm/feature-gate.js +0 -8
- package/dist/llm/index-passes.js +3 -5
- package/dist/llm/memory-infer.js +1 -2
- package/dist/llm/structured-call.js +5 -24
- package/dist/output/generic-render.js +23 -11
- package/dist/output/html-render.js +13 -10
- package/dist/output/render-registry.js +3 -32
- package/dist/output/shapes/helpers.js +25 -38
- package/dist/output/shapes/passthrough.js +1 -9
- package/dist/{indexer/graph/graph-types.js → output/text/bundle-rename.js} +4 -1
- package/dist/output/text/command-format.js +69 -31
- package/dist/output/text/helpers.js +1 -1
- package/dist/output/text/migrate.js +5 -14
- package/dist/output/text/proposal-format.js +48 -3
- package/dist/output/text/show-format.js +13 -17
- package/dist/output/text/workflow-format.js +0 -32
- package/dist/output/text.js +2 -0
- package/dist/registry/factory.js +4 -19
- package/dist/registry/network.js +66 -220
- package/dist/registry/providers/index.js +0 -2
- package/dist/registry/providers/skills-sh.js +3 -14
- package/dist/registry/providers/static-index.js +24 -26
- package/dist/registry/resolve.js +55 -131
- package/dist/scripts/akm-migrate-node.js +42948 -92369
- package/dist/scripts/akm-migrate.js +42935 -92354
- package/dist/setup/registry-stash-loader.js +4 -13
- package/dist/setup/semantic-assets.js +3 -44
- package/dist/setup/setup.js +1 -1
- package/dist/setup/steps/connection.js +5 -6
- package/dist/setup/steps/platforms.js +2 -2
- package/dist/setup/steps/tasks.js +25 -15
- package/dist/sources/provider-factory.js +17 -18
- package/dist/sources/providers/filesystem.js +2 -3
- package/dist/sources/providers/git-install.js +7 -1
- package/dist/sources/providers/git-provider.js +0 -3
- package/dist/sources/providers/git-stash.js +83 -21
- package/dist/sources/providers/npm.js +2 -4
- package/dist/sources/providers/provider-utils.js +5 -10
- package/dist/sources/providers/website.js +0 -2
- package/dist/sources/snapshot-fetchers/website-ingest.js +1 -1
- package/dist/sources/website-url.js +2 -2
- package/dist/storage/database.js +9 -35
- package/dist/storage/repositories/improve-ledger-repository.js +209 -0
- package/dist/storage/repositories/index-connection.js +39 -72
- package/dist/storage/repositories/index-entries-repository.js +131 -129
- package/dist/storage/repositories/index-entry-mapper.js +1 -2
- package/dist/storage/repositories/index-entry-schema.js +101 -268
- package/dist/storage/repositories/index-fts-repository.js +86 -256
- package/dist/storage/repositories/index-links-repository.js +143 -0
- package/dist/storage/repositories/index-llm-cache-repository.js +7 -9
- package/dist/storage/repositories/index-meta-repository.js +6 -4
- package/dist/storage/repositories/index-schema.js +257 -325
- package/dist/storage/repositories/index-utility-repository.js +8 -29
- package/dist/storage/repositories/index-vec-repository.js +133 -414
- package/dist/storage/repositories/outcome-repository.js +2 -1
- package/dist/storage/repositories/proposals-repository.js +104 -1
- package/dist/storage/repositories/registry-index-cache-repository.js +100 -0
- package/dist/storage/repositories/salience-repository.js +1 -19
- package/dist/storage/repositories/task-history-repository.js +26 -4
- package/dist/storage/repositories/workflow-runs-repository.js +53 -244
- package/dist/storage/sqlite-migrations.js +136 -0
- package/dist/storage/sqlite-pragmas.js +11 -9
- package/dist/storage/sqlite-transaction.js +170 -0
- package/dist/storage/state-db-integrity.js +130 -0
- package/dist/tasks/activation-config.js +134 -62
- package/dist/tasks/backends/cron.js +191 -302
- package/dist/tasks/backends/exec-utils.js +2 -5
- package/dist/tasks/backends/launchd.js +141 -748
- package/dist/tasks/backends/schtasks.js +119 -623
- package/dist/tasks/prepare/prepare-support.js +5 -15
- package/dist/tasks/prepare/prepare.js +0 -2
- package/dist/tasks/resolve-akm-bin.js +20 -79
- package/dist/tasks/run/attempt-lifecycle.js +0 -1
- package/dist/tasks/run/load-task.js +1 -1
- package/dist/tasks/scheduler-binding.js +20 -238
- package/dist/tasks/scheduler-invocation.js +136 -244
- package/dist/tasks/scheduler-lock.js +53 -0
- package/dist/tasks/scheduler-sync.js +368 -679
- package/dist/tasks/source/parse-task-source.js +55 -9
- package/dist/tasks/source/task-source-v3-frozen.js +3 -4
- package/dist/tasks/source/task-to-v4.js +464 -88
- package/dist/workflows/authoring/authoring.js +3 -12
- package/dist/workflows/compile.js +211 -0
- package/dist/workflows/concurrency-policy.js +13 -74
- package/dist/workflows/exec/child-invocation.js +3 -17
- package/dist/workflows/exec/child-workflow.js +32 -141
- package/dist/workflows/exec/dispatch-redaction.js +13 -53
- package/dist/workflows/exec/environment.js +98 -0
- package/dist/workflows/exec/exec-unit.js +33 -140
- package/dist/workflows/exec/frozen-judge.js +7 -59
- package/dist/workflows/exec/native-executor.js +82 -341
- package/dist/workflows/exec/param-secrets.js +29 -47
- package/dist/workflows/exec/run-workflow.js +154 -387
- package/dist/workflows/exec/scheduler.js +9 -36
- package/dist/workflows/exec/step-work.js +127 -430
- package/dist/workflows/exec/unit-dispatch.js +11 -63
- package/dist/workflows/exec/unit-writer.js +8 -52
- package/dist/workflows/exec/worktree.js +39 -273
- package/dist/workflows/freeze/child-output-references.js +4 -15
- package/dist/workflows/freeze/environment.js +99 -92
- package/dist/workflows/freeze/freeze.js +172 -0
- package/dist/workflows/freeze/step-values.js +19 -21
- package/dist/workflows/freeze/targets/child-workflow.js +23 -92
- package/dist/workflows/freeze/targets/command.js +10 -33
- package/dist/workflows/freeze/targets/script.js +5 -12
- package/dist/workflows/freeze/targets/shell.js +3 -6
- package/dist/workflows/freeze/targets/task.js +25 -80
- package/dist/workflows/freeze/task-bindings.js +20 -67
- package/dist/workflows/{source-ir/github-yaml.js → github-yaml.js} +88 -206
- package/dist/workflows/ir/params.js +6 -51
- package/dist/workflows/ir/plan-hash.js +2 -34
- package/dist/workflows/parser.js +140 -43
- package/dist/{commands/improve/consolidate/types.js → workflows/plan.js} +2 -1
- package/dist/workflows/renderer.js +36 -69
- package/dist/workflows/resource-limits.js +12 -120
- package/dist/workflows/runtime/agent-identity.js +8 -40
- package/dist/workflows/runtime/run-outputs.js +3 -6
- package/dist/workflows/runtime/run-plan.js +316 -0
- package/dist/workflows/runtime/runs.js +48 -200
- package/dist/workflows/runtime/workflow-asset-loader.js +24 -57
- package/dist/workflows/{source-ir/semantics.js → source-semantics.js} +16 -20
- package/dist/workflows/validate-summary.js +2 -7
- package/docs/integration/bundling-akm.md +49 -42
- package/docs/migration/README.md +1 -0
- package/docs/migration/release-notes/0.9.17.md +43 -0
- package/docs/migration/v0.9.1-to-v0.9.2.md +23 -7
- package/docs/reference/cli.md +232 -135
- package/docs/reference/configuration.md +71 -57
- package/docs/reference/data-and-telemetry.md +20 -21
- package/docs/reference/tasks.md +105 -39
- package/docs/reference/workflow-schema.md +14 -18
- package/docs/reference/workflows.md +6 -9
- package/package.json +1 -1
- package/schemas/akm-config.json +115 -738
- package/schemas/akm-workflow.json +1 -0
- package/dist/assets/improve-strategies/graph-refresh.json +0 -15
- package/dist/assets/prompts/contradiction-judge.md +0 -33
- package/dist/assets/prompts/graph-extract-system.md +0 -1
- package/dist/assets/prompts/graph-extract-user-prompt.md +0 -35
- package/dist/assets/prompts/metadata-enhance-system.md +0 -1
- package/dist/assets/tasks/improve/akm-graph-refresh-weekly.yml +0 -4
- package/dist/commands/health/advisories.js +0 -150
- package/dist/commands/health/metrics.js +0 -329
- package/dist/commands/health/surfaces.js +0 -102
- package/dist/commands/improve/anti-collapse.js +0 -83
- package/dist/commands/improve/collapse-detector.js +0 -432
- package/dist/commands/improve/consolidate/eligibility.js +0 -48
- package/dist/commands/improve/consolidate/merge.js +0 -149
- package/dist/commands/improve/distill/promote-memory.js +0 -291
- package/dist/commands/improve/distill/quality-gate.js +0 -337
- package/dist/commands/improve/eval-cases.js +0 -52
- package/dist/commands/improve/memory/memory-contradiction-detect.js +0 -291
- package/dist/commands/improve/proposal-envelope.js +0 -31
- package/dist/commands/improve/run-context.js +0 -123
- package/dist/commands/improve/shared.js +0 -31
- package/dist/commands/improve/source-identity.js +0 -28
- package/dist/commands/improve/triage.js +0 -96
- package/dist/commands/proposal/drain-policies.js +0 -151
- package/dist/commands/sources/update-transaction.js +0 -220
- package/dist/core/action-contributors.js +0 -28
- package/dist/core/config/config-version-shim.js +0 -101
- package/dist/core/fs-txn.js +0 -405
- package/dist/core/lexical-score.js +0 -25
- package/dist/core/maintenance-barrier.js +0 -167
- package/dist/execution/executable-identity.js +0 -105
- package/dist/execution/guarded-source.js +0 -427
- package/dist/indexer/db/graph-db.js +0 -444
- package/dist/indexer/graph/graph-boost.js +0 -427
- package/dist/indexer/graph/graph-dedup.js +0 -95
- package/dist/indexer/graph/graph-extraction.js +0 -1108
- package/dist/indexer/search/name-match.js +0 -35
- package/dist/indexer/search/ranking-contributors.js +0 -515
- package/dist/indexer/search/ranking-types.js +0 -4
- package/dist/indexer/walk/project-context.js +0 -192
- package/dist/integrations/agent/execution-cascade.js +0 -566
- package/dist/integrations/agent/execution-definitions.js +0 -202
- package/dist/integrations/agent/execution-lowering.js +0 -841
- package/dist/integrations/agent/execution-preparation.js +0 -98
- package/dist/integrations/agent/inline-execution.js +0 -74
- package/dist/llm/graph-extract.js +0 -728
- package/dist/llm/metadata-enhance.js +0 -96
- package/dist/registry/create-provider-registry.js +0 -29
- package/dist/registry/pinned-request-helper.js +0 -247
- package/dist/registry/pinned-transport.js +0 -717
- package/dist/sources/providers/index.js +0 -14
- package/dist/storage/engines/sqlite-migrations.js +0 -271
- package/dist/storage/repositories/canaries-repository.js +0 -107
- package/dist/storage/repositories/embedding-salvage-repository.js +0 -184
- package/dist/storage/repositories/registry-cache.js +0 -113
- package/dist/tasks/scheduler-sync-preview.js +0 -52
- package/dist/tasks/source/task-to-v3.js +0 -507
- package/dist/workflows/freeze/resolve-steps.js +0 -86
- package/dist/workflows/freeze/source-freeze.js +0 -64
- package/dist/workflows/ir/compile.js +0 -321
- package/dist/workflows/ir/environment-v4.js +0 -330
- package/dist/workflows/ir/freeze-v4.js +0 -153
- package/dist/workflows/ir/schema-v4.js +0 -745
- package/dist/workflows/ir/schema.js +0 -354
- package/dist/workflows/program/schema.js +0 -77
- package/dist/workflows/runtime/checkin.js +0 -57
- package/dist/workflows/runtime/plan-classifier.js +0 -196
- package/dist/workflows/runtime/unit-checkin.js +0 -45
- package/dist/workflows/runtime/unit-phases.js +0 -20
- package/dist/workflows/schema.js +0 -4
- package/dist/workflows/source-ir/compile.js +0 -200
- package/dist/workflows/source-ir/program.js +0 -50
- package/dist/workflows/source-ir/result.js +0 -26
- package/dist/workflows/source-ir/schema.js +0 -786
- package/dist/workflows/source-ir/triggers.js +0 -79
- package/dist/workflows/source-ir/uses.js +0 -40
- package/dist/workflows/validator.js +0 -60
|
@@ -1,444 +0,0 @@
|
|
|
1
|
-
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
|
-
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
|
-
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
|
-
import { rethrowIfDataDirUnreadable, rethrowIfTestIsolationError } from "../../core/errors.js";
|
|
5
|
-
import { isPathAbsent } from "../../core/path-access.js";
|
|
6
|
-
import { getDbPath } from "../../core/paths.js";
|
|
7
|
-
import { closeDatabase, openExistingDatabase } from "../../storage/repositories/index-connection.js";
|
|
8
|
-
function withReadableGraphDb(db, fn) {
|
|
9
|
-
if (db)
|
|
10
|
-
return fn(db);
|
|
11
|
-
const dbPath = getDbPath();
|
|
12
|
-
// `GRAPH_DB_MISSING` is the loaders' "nothing extracted yet" sentinel — every
|
|
13
|
-
// caller below turns it into `null`/`[]`. Reserve it for a genuinely ABSENT
|
|
14
|
-
// index: an index that exists and cannot be read must reach the caller as the
|
|
15
|
-
// ConfigError `openExistingDatabase` raises, not as "no graph data" (#791).
|
|
16
|
-
if (isPathAbsent(dbPath))
|
|
17
|
-
throw new Error("GRAPH_DB_MISSING");
|
|
18
|
-
const opened = openExistingDatabase(dbPath);
|
|
19
|
-
try {
|
|
20
|
-
return fn(opened);
|
|
21
|
-
}
|
|
22
|
-
finally {
|
|
23
|
-
closeDatabase(opened);
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
function uniqueSorted(values) {
|
|
27
|
-
return [...new Set(values)].sort((a, b) => a.localeCompare(b));
|
|
28
|
-
}
|
|
29
|
-
function normalizeEntity(value) {
|
|
30
|
-
return value.trim().toLowerCase();
|
|
31
|
-
}
|
|
32
|
-
/**
|
|
33
|
-
* Persist (or update) a graph snapshot for a stash root.
|
|
34
|
-
*
|
|
35
|
-
* #624-P1: keyed on (stash_root, file_path, body_hash) — NOT entries.id. Graph
|
|
36
|
-
* rows are self-keyed by path, so they survive an entries delete + reinsert
|
|
37
|
-
* (a reindex) when body_hash is unchanged. Unchanged files (matching body_hash)
|
|
38
|
-
* only have their file-meta refreshed; files whose body_hash changed have their
|
|
39
|
-
* old row + child rows deleted and the new content inserted; files in DB but
|
|
40
|
-
* absent from the new snapshot are deleted. There is no entry_id resolution and
|
|
41
|
-
* no orphan-skip — a graph file no longer needs a matching entries row.
|
|
42
|
-
*/
|
|
43
|
-
export function replaceStoredGraph(db, graph) {
|
|
44
|
-
const upsertMeta = db.prepare(`INSERT INTO graph_meta (
|
|
45
|
-
stash_root,
|
|
46
|
-
schema_version,
|
|
47
|
-
generated_at,
|
|
48
|
-
considered_files,
|
|
49
|
-
extracted_files,
|
|
50
|
-
entity_count,
|
|
51
|
-
relation_count,
|
|
52
|
-
extraction_coverage,
|
|
53
|
-
density,
|
|
54
|
-
extractor_id,
|
|
55
|
-
extraction_run_id,
|
|
56
|
-
model,
|
|
57
|
-
prompt_version,
|
|
58
|
-
batch_size,
|
|
59
|
-
cache_hits,
|
|
60
|
-
cache_misses,
|
|
61
|
-
truncation_count,
|
|
62
|
-
failure_count
|
|
63
|
-
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
64
|
-
ON CONFLICT(stash_root) DO UPDATE SET
|
|
65
|
-
schema_version = excluded.schema_version,
|
|
66
|
-
generated_at = excluded.generated_at,
|
|
67
|
-
considered_files = excluded.considered_files,
|
|
68
|
-
extracted_files = excluded.extracted_files,
|
|
69
|
-
entity_count = excluded.entity_count,
|
|
70
|
-
relation_count = excluded.relation_count,
|
|
71
|
-
extraction_coverage = excluded.extraction_coverage,
|
|
72
|
-
density = excluded.density,
|
|
73
|
-
extractor_id = excluded.extractor_id,
|
|
74
|
-
extraction_run_id = excluded.extraction_run_id,
|
|
75
|
-
model = excluded.model,
|
|
76
|
-
prompt_version = excluded.prompt_version,
|
|
77
|
-
batch_size = excluded.batch_size,
|
|
78
|
-
cache_hits = excluded.cache_hits,
|
|
79
|
-
cache_misses = excluded.cache_misses,
|
|
80
|
-
truncation_count = excluded.truncation_count,
|
|
81
|
-
failure_count = excluded.failure_count`);
|
|
82
|
-
const selectExisting = db.prepare("SELECT file_path, body_hash, file_order FROM graph_files WHERE stash_root = ?");
|
|
83
|
-
const deleteFile = db.prepare("DELETE FROM graph_files WHERE stash_root = ? AND file_path = ? AND body_hash = ?");
|
|
84
|
-
const deleteEntities = db.prepare("DELETE FROM graph_file_entities WHERE stash_root = ? AND file_path = ? AND body_hash = ?");
|
|
85
|
-
const deleteRelations = db.prepare("DELETE FROM graph_file_relations WHERE stash_root = ? AND file_path = ? AND body_hash = ?");
|
|
86
|
-
const insertFile = db.prepare(`INSERT INTO graph_files (
|
|
87
|
-
stash_root, file_path, file_order, file_type, body_hash, confidence, status, reason, extraction_run_id
|
|
88
|
-
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`);
|
|
89
|
-
const updateFileMeta = db.prepare(`UPDATE graph_files
|
|
90
|
-
SET file_order = ?, file_type = ?, confidence = ?, status = ?, reason = ?, extraction_run_id = ?
|
|
91
|
-
WHERE stash_root = ? AND file_path = ? AND body_hash = ?`);
|
|
92
|
-
const insertEntity = db.prepare(`INSERT INTO graph_file_entities (stash_root, file_path, body_hash, entity_order, entity_norm, entity)
|
|
93
|
-
VALUES (?, ?, ?, ?, ?, ?)`);
|
|
94
|
-
const insertRelation = db.prepare(`INSERT INTO graph_file_relations (
|
|
95
|
-
stash_root, file_path, body_hash, relation_order, from_entity_norm, from_entity, to_entity_norm, to_entity, relation_type, confidence
|
|
96
|
-
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`);
|
|
97
|
-
const quality = graph.quality;
|
|
98
|
-
const telemetry = graph.telemetry;
|
|
99
|
-
db.transaction(() => {
|
|
100
|
-
upsertMeta.run(graph.stashRoot, graph.schemaVersion, graph.generatedAt, quality?.consideredFiles ?? graph.files.length, quality?.extractedFiles ?? graph.files.length, quality?.entityCount ?? graph.entities?.length ?? 0, quality?.relationCount ?? graph.relations?.length ?? 0, quality?.extractionCoverage ?? 0, quality?.density ?? 0, telemetry?.extractorId ?? null, telemetry?.extractionRunId ?? null, telemetry?.model ?? null, telemetry?.promptVersion ?? null, telemetry?.batchSize ?? null, telemetry?.cacheHits ?? 0, telemetry?.cacheMisses ?? 0, telemetry?.truncationCount ?? 0, telemetry?.failureCount ?? 0);
|
|
101
|
-
// Build a snapshot of existing rows for incremental compare. The unique
|
|
102
|
-
// index idx_graph_files_path guarantees at most one row per file_path.
|
|
103
|
-
const existingRows = selectExisting.all(graph.stashRoot);
|
|
104
|
-
const existingByPath = new Map();
|
|
105
|
-
for (const row of existingRows)
|
|
106
|
-
existingByPath.set(row.file_path, row);
|
|
107
|
-
const presentPaths = new Set();
|
|
108
|
-
for (const [fileOrder, node] of graph.files.entries()) {
|
|
109
|
-
// body_hash is part of the PK; default to a sentinel for inputs (test
|
|
110
|
-
// fixtures, legacy imports) that don't supply one. The sentinel never
|
|
111
|
-
// equals a real hash so subsequent staleness checks always re-extract —
|
|
112
|
-
// correct behaviour for "unknown" bodies. Distinct files in one stash
|
|
113
|
-
// are still keyed apart by file_path, so the empty sentinel is safe.
|
|
114
|
-
const bodyHash = node.bodyHash && node.bodyHash.length > 0 ? node.bodyHash : "";
|
|
115
|
-
presentPaths.add(node.path);
|
|
116
|
-
const existing = existingByPath.get(node.path);
|
|
117
|
-
if (existing && existing.body_hash === bodyHash) {
|
|
118
|
-
// Body unchanged — only fix up file_order/confidence in case they drifted.
|
|
119
|
-
updateFileMeta.run(fileOrder, node.type, node.confidence ?? null, node.status ?? (node.entities.length > 0 ? "extracted" : "empty"), node.reason ?? (node.entities.length > 0 ? "none" : "no_graph_content"), node.extractionRunId ?? telemetry?.extractionRunId ?? null, graph.stashRoot, node.path, bodyHash);
|
|
120
|
-
continue;
|
|
121
|
-
}
|
|
122
|
-
if (existing) {
|
|
123
|
-
// Stale row (different body_hash for this path). Delete the old row by
|
|
124
|
-
// its OLD body_hash; child rows cascade, but explicit DELETE keeps the
|
|
125
|
-
// order deterministic and is safe regardless of the FK pragma.
|
|
126
|
-
deleteEntities.run(graph.stashRoot, existing.file_path, existing.body_hash);
|
|
127
|
-
deleteRelations.run(graph.stashRoot, existing.file_path, existing.body_hash);
|
|
128
|
-
deleteFile.run(graph.stashRoot, existing.file_path, existing.body_hash);
|
|
129
|
-
}
|
|
130
|
-
insertFile.run(graph.stashRoot, node.path, fileOrder, node.type, bodyHash, node.confidence ?? null, node.status ?? (node.entities.length > 0 ? "extracted" : "empty"), node.reason ?? (node.entities.length > 0 ? "none" : "no_graph_content"), node.extractionRunId ?? telemetry?.extractionRunId ?? null);
|
|
131
|
-
for (const [entityOrder, entity] of node.entities.entries()) {
|
|
132
|
-
insertEntity.run(graph.stashRoot, node.path, bodyHash, entityOrder, normalizeEntity(entity), entity);
|
|
133
|
-
}
|
|
134
|
-
for (const [relationOrder, relation] of node.relations.entries()) {
|
|
135
|
-
insertRelation.run(graph.stashRoot, node.path, bodyHash, relationOrder, normalizeEntity(relation.from), relation.from, normalizeEntity(relation.to), relation.to, relation.type ?? null, relation.confidence ?? null);
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
// Delete files present in DB but absent from the new snapshot. Child
|
|
139
|
-
// tables CASCADE on the composite key; explicit DELETE keeps it determinstic.
|
|
140
|
-
for (const row of existingRows) {
|
|
141
|
-
if (!presentPaths.has(row.file_path)) {
|
|
142
|
-
deleteEntities.run(graph.stashRoot, row.file_path, row.body_hash);
|
|
143
|
-
deleteRelations.run(graph.stashRoot, row.file_path, row.body_hash);
|
|
144
|
-
deleteFile.run(graph.stashRoot, row.file_path, row.body_hash);
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
})();
|
|
148
|
-
}
|
|
149
|
-
export function deleteStoredGraph(db, stashPath) {
|
|
150
|
-
db.transaction(() => {
|
|
151
|
-
// Child rows cascade via the composite (stash_root, file_path, body_hash)
|
|
152
|
-
// FK; deleting graph_files clears them. This is the explicit full-clear
|
|
153
|
-
// path for a stash (entries-delete no longer wipes graph data — see #624-P1).
|
|
154
|
-
db.prepare("DELETE FROM graph_files WHERE stash_root = ?").run(stashPath);
|
|
155
|
-
db.prepare("DELETE FROM graph_meta WHERE stash_root = ?").run(stashPath);
|
|
156
|
-
})();
|
|
157
|
-
}
|
|
158
|
-
/**
|
|
159
|
-
* #624-P1 — does any graph data exist for a file_path under a stash root?
|
|
160
|
-
* Consumed by show/curate flows (P3) but defined here so the schema and its
|
|
161
|
-
* accessors land together.
|
|
162
|
-
*/
|
|
163
|
-
export function hasGraphData(db, stashRoot, filePath) {
|
|
164
|
-
try {
|
|
165
|
-
const row = db
|
|
166
|
-
.prepare("SELECT 1 AS present FROM graph_files WHERE stash_root = ? AND file_path = ? LIMIT 1")
|
|
167
|
-
.get(stashRoot, filePath);
|
|
168
|
-
return row !== undefined;
|
|
169
|
-
}
|
|
170
|
-
catch {
|
|
171
|
-
return false;
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
/**
|
|
175
|
-
* #624-P3 — enqueue a file for lazy graph extraction. Idempotent on the
|
|
176
|
-
* (stash_root, file_path) PK: a second enqueue refreshes body_hash + queued_at
|
|
177
|
-
* and keeps the HIGHER priority. Non-blocking, no LLM call — the queued row is
|
|
178
|
-
* drained later by the graph-extraction pass. Tolerant of a missing table /
|
|
179
|
-
* db error (best-effort), but never masks the bun-test isolation guard.
|
|
180
|
-
*/
|
|
181
|
-
export function enqueueGraphExtraction(db, stashRoot, filePath, bodyHash, priority = 0) {
|
|
182
|
-
try {
|
|
183
|
-
db.prepare(`INSERT INTO graph_extraction_queue (stash_root, file_path, body_hash, priority)
|
|
184
|
-
VALUES (?, ?, ?, ?)
|
|
185
|
-
ON CONFLICT(stash_root, file_path) DO UPDATE SET
|
|
186
|
-
body_hash = excluded.body_hash,
|
|
187
|
-
priority = MAX(graph_extraction_queue.priority, excluded.priority),
|
|
188
|
-
queued_at = datetime('now')`).run(stashRoot, filePath, bodyHash, priority);
|
|
189
|
-
}
|
|
190
|
-
catch (err) {
|
|
191
|
-
rethrowIfTestIsolationError(err);
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
/**
|
|
195
|
-
* #624-P3 — drain up to `limit` queued files for a stash, highest-priority
|
|
196
|
-
* first (then oldest queued_at). The returned rows are DELETED from the queue
|
|
197
|
-
* in the SAME transaction (SELECT-then-DELETE-by-PK), so a drain is exactly
|
|
198
|
-
* once. Tolerant of a missing table / db error (returns []), but never masks
|
|
199
|
-
* the bun-test isolation guard.
|
|
200
|
-
*/
|
|
201
|
-
export function drainExtractionQueue(db, stashRoot, limit) {
|
|
202
|
-
try {
|
|
203
|
-
return db.transaction(() => {
|
|
204
|
-
const rows = db
|
|
205
|
-
.prepare(`SELECT file_path, body_hash, priority
|
|
206
|
-
FROM graph_extraction_queue
|
|
207
|
-
WHERE stash_root = ?
|
|
208
|
-
ORDER BY priority DESC, queued_at ASC
|
|
209
|
-
LIMIT ?`)
|
|
210
|
-
.all(stashRoot, limit);
|
|
211
|
-
const del = db.prepare("DELETE FROM graph_extraction_queue WHERE stash_root = ? AND file_path = ?");
|
|
212
|
-
for (const row of rows)
|
|
213
|
-
del.run(stashRoot, row.file_path);
|
|
214
|
-
return rows.map((row) => ({ filePath: row.file_path, bodyHash: row.body_hash, priority: row.priority }));
|
|
215
|
-
})();
|
|
216
|
-
}
|
|
217
|
-
catch (err) {
|
|
218
|
-
rethrowIfTestIsolationError(err);
|
|
219
|
-
return [];
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
/** Read queued graph work without claiming or deleting it. */
|
|
223
|
-
export function peekExtractionQueue(db, stashRoot, limit) {
|
|
224
|
-
try {
|
|
225
|
-
const rows = db
|
|
226
|
-
.prepare(`SELECT file_path, body_hash, priority
|
|
227
|
-
FROM graph_extraction_queue
|
|
228
|
-
WHERE stash_root = ?
|
|
229
|
-
ORDER BY priority DESC, queued_at ASC
|
|
230
|
-
LIMIT ?`)
|
|
231
|
-
.all(stashRoot, limit);
|
|
232
|
-
return rows.map((row) => ({ filePath: row.file_path, bodyHash: row.body_hash, priority: row.priority }));
|
|
233
|
-
}
|
|
234
|
-
catch (err) {
|
|
235
|
-
rethrowIfTestIsolationError(err);
|
|
236
|
-
return [];
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
/**
|
|
240
|
-
* Acknowledge the exact queued revision that was classified and handled.
|
|
241
|
-
* A concurrent re-enqueue with a new body hash therefore survives.
|
|
242
|
-
*/
|
|
243
|
-
export function acknowledgeExtractionQueueEntry(db, stashRoot, filePath, bodyHash) {
|
|
244
|
-
try {
|
|
245
|
-
const result = db
|
|
246
|
-
.prepare("DELETE FROM graph_extraction_queue WHERE stash_root = ? AND file_path = ? AND body_hash = ?")
|
|
247
|
-
.run(stashRoot, filePath, bodyHash);
|
|
248
|
-
return result.changes > 0;
|
|
249
|
-
}
|
|
250
|
-
catch (err) {
|
|
251
|
-
rethrowIfTestIsolationError(err);
|
|
252
|
-
return false;
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
/**
|
|
256
|
-
* Scoped loader — graph_files rows without entities/relations. Used for
|
|
257
|
-
* orphan detection and entity overview commands.
|
|
258
|
-
*/
|
|
259
|
-
export function loadGraphFilesOnly(stashPath, db) {
|
|
260
|
-
try {
|
|
261
|
-
return withReadableGraphDb(db, (readDb) => {
|
|
262
|
-
const rows = readDb
|
|
263
|
-
.prepare(`SELECT file_path, file_type, body_hash, confidence, status, reason
|
|
264
|
-
FROM graph_files
|
|
265
|
-
WHERE stash_root = ?
|
|
266
|
-
ORDER BY file_order`)
|
|
267
|
-
.all(stashPath);
|
|
268
|
-
return rows.map((row) => ({
|
|
269
|
-
path: row.file_path,
|
|
270
|
-
type: row.file_type,
|
|
271
|
-
bodyHash: row.body_hash,
|
|
272
|
-
...(typeof row.confidence === "number" ? { confidence: row.confidence } : {}),
|
|
273
|
-
...(row.status ? { status: row.status } : {}),
|
|
274
|
-
...(row.reason ? { reason: row.reason } : {}),
|
|
275
|
-
}));
|
|
276
|
-
});
|
|
277
|
-
}
|
|
278
|
-
catch (err) {
|
|
279
|
-
// Never mask the bun-test isolation guard as "no stored graph files",
|
|
280
|
-
// and never mask an index we are not allowed to read as one with no
|
|
281
|
-
// graph in it (#791) — `GRAPH_DB_MISSING` above is the only "absent".
|
|
282
|
-
rethrowIfTestIsolationError(err);
|
|
283
|
-
rethrowIfDataDirUnreadable(err);
|
|
284
|
-
return [];
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
export function loadStoredGraphMeta(stashPath, db) {
|
|
288
|
-
try {
|
|
289
|
-
return withReadableGraphDb(db, (readDb) => {
|
|
290
|
-
const row = readDb
|
|
291
|
-
.prepare(`SELECT
|
|
292
|
-
stash_root,
|
|
293
|
-
schema_version,
|
|
294
|
-
generated_at,
|
|
295
|
-
considered_files,
|
|
296
|
-
extracted_files,
|
|
297
|
-
entity_count,
|
|
298
|
-
relation_count,
|
|
299
|
-
extraction_coverage,
|
|
300
|
-
density,
|
|
301
|
-
extractor_id,
|
|
302
|
-
extraction_run_id,
|
|
303
|
-
model,
|
|
304
|
-
prompt_version,
|
|
305
|
-
batch_size,
|
|
306
|
-
cache_hits,
|
|
307
|
-
cache_misses,
|
|
308
|
-
truncation_count,
|
|
309
|
-
failure_count
|
|
310
|
-
FROM graph_meta
|
|
311
|
-
WHERE stash_root = ?`)
|
|
312
|
-
.get(stashPath);
|
|
313
|
-
if (!row)
|
|
314
|
-
return null;
|
|
315
|
-
return {
|
|
316
|
-
stashPath: row.stash_root,
|
|
317
|
-
graphPath: getDbPath(),
|
|
318
|
-
schemaVersion: row.schema_version,
|
|
319
|
-
generatedAt: row.generated_at,
|
|
320
|
-
quality: {
|
|
321
|
-
consideredFiles: row.considered_files,
|
|
322
|
-
extractedFiles: row.extracted_files,
|
|
323
|
-
entityCount: row.entity_count,
|
|
324
|
-
relationCount: row.relation_count,
|
|
325
|
-
extractionCoverage: row.extraction_coverage,
|
|
326
|
-
density: row.density,
|
|
327
|
-
},
|
|
328
|
-
telemetry: {
|
|
329
|
-
...(row.extractor_id ? { extractorId: row.extractor_id } : {}),
|
|
330
|
-
...(row.extraction_run_id ? { extractionRunId: row.extraction_run_id } : {}),
|
|
331
|
-
...(row.model ? { model: row.model } : {}),
|
|
332
|
-
...(row.prompt_version ? { promptVersion: row.prompt_version } : {}),
|
|
333
|
-
...(typeof row.batch_size === "number" ? { batchSize: row.batch_size } : {}),
|
|
334
|
-
cacheHits: row.cache_hits,
|
|
335
|
-
cacheMisses: row.cache_misses,
|
|
336
|
-
truncationCount: row.truncation_count,
|
|
337
|
-
failureCount: row.failure_count,
|
|
338
|
-
// `retry_attempts` is not persisted to the graph-meta table (it is
|
|
339
|
-
// surfaced from the run's emitted telemetry into `akm health`, not
|
|
340
|
-
// from the reuse cache). Default to 0 so the loaded shape satisfies
|
|
341
|
-
// GraphExtractionTelemetry.
|
|
342
|
-
retryAttempts: 0,
|
|
343
|
-
},
|
|
344
|
-
};
|
|
345
|
-
});
|
|
346
|
-
}
|
|
347
|
-
catch (err) {
|
|
348
|
-
// Never mask the bun-test isolation guard as "no stored graph meta",
|
|
349
|
-
// nor an unreadable index as one that simply has no graph (#791).
|
|
350
|
-
rethrowIfTestIsolationError(err);
|
|
351
|
-
rethrowIfDataDirUnreadable(err);
|
|
352
|
-
return null;
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
export function loadStoredGraphSnapshot(stashPath, db) {
|
|
356
|
-
try {
|
|
357
|
-
return withReadableGraphDb(db, (readDb) => {
|
|
358
|
-
const meta = loadStoredGraphMeta(stashPath, readDb);
|
|
359
|
-
if (!meta)
|
|
360
|
-
return null;
|
|
361
|
-
const fileRows = readDb
|
|
362
|
-
.prepare(`SELECT file_path, file_type, body_hash, confidence, status, reason, extraction_run_id
|
|
363
|
-
FROM graph_files
|
|
364
|
-
WHERE stash_root = ?
|
|
365
|
-
ORDER BY file_order`)
|
|
366
|
-
.all(stashPath);
|
|
367
|
-
const entityRows = readDb
|
|
368
|
-
.prepare(`SELECT gf.file_path AS file_path, gfe.entity AS entity
|
|
369
|
-
FROM graph_file_entities gfe
|
|
370
|
-
JOIN graph_files gf
|
|
371
|
-
ON gf.stash_root = gfe.stash_root
|
|
372
|
-
AND gf.file_path = gfe.file_path
|
|
373
|
-
AND gf.body_hash = gfe.body_hash
|
|
374
|
-
WHERE gf.stash_root = ?
|
|
375
|
-
ORDER BY gf.file_order, gfe.entity_order`)
|
|
376
|
-
.all(stashPath);
|
|
377
|
-
const relationRows = readDb
|
|
378
|
-
.prepare(`SELECT gf.file_path AS file_path,
|
|
379
|
-
gfr.from_entity AS from_entity,
|
|
380
|
-
gfr.to_entity AS to_entity,
|
|
381
|
-
gfr.relation_type AS relation_type,
|
|
382
|
-
gfr.confidence AS confidence
|
|
383
|
-
FROM graph_file_relations gfr
|
|
384
|
-
JOIN graph_files gf
|
|
385
|
-
ON gf.stash_root = gfr.stash_root
|
|
386
|
-
AND gf.file_path = gfr.file_path
|
|
387
|
-
AND gf.body_hash = gfr.body_hash
|
|
388
|
-
WHERE gf.stash_root = ?
|
|
389
|
-
ORDER BY gf.file_order, gfr.relation_order`)
|
|
390
|
-
.all(stashPath);
|
|
391
|
-
const entitiesByPath = new Map();
|
|
392
|
-
for (const row of entityRows) {
|
|
393
|
-
const bucket = entitiesByPath.get(row.file_path);
|
|
394
|
-
if (bucket)
|
|
395
|
-
bucket.push(row.entity);
|
|
396
|
-
else
|
|
397
|
-
entitiesByPath.set(row.file_path, [row.entity]);
|
|
398
|
-
}
|
|
399
|
-
const relationsByPath = new Map();
|
|
400
|
-
for (const row of relationRows) {
|
|
401
|
-
const relation = {
|
|
402
|
-
from: row.from_entity,
|
|
403
|
-
to: row.to_entity,
|
|
404
|
-
...(row.relation_type ? { type: row.relation_type } : {}),
|
|
405
|
-
...(typeof row.confidence === "number" ? { confidence: row.confidence } : {}),
|
|
406
|
-
};
|
|
407
|
-
const bucket = relationsByPath.get(row.file_path);
|
|
408
|
-
if (bucket)
|
|
409
|
-
bucket.push(relation);
|
|
410
|
-
else
|
|
411
|
-
relationsByPath.set(row.file_path, [relation]);
|
|
412
|
-
}
|
|
413
|
-
const files = fileRows.map((row) => ({
|
|
414
|
-
path: row.file_path,
|
|
415
|
-
type: row.file_type,
|
|
416
|
-
...(row.body_hash ? { bodyHash: row.body_hash } : {}),
|
|
417
|
-
entities: entitiesByPath.get(row.file_path) ?? [],
|
|
418
|
-
relations: relationsByPath.get(row.file_path) ?? [],
|
|
419
|
-
...(typeof row.confidence === "number" ? { confidence: row.confidence } : {}),
|
|
420
|
-
...(row.status ? { status: row.status } : {}),
|
|
421
|
-
...(row.reason ? { reason: row.reason } : {}),
|
|
422
|
-
...(row.extraction_run_id ? { extractionRunId: row.extraction_run_id } : {}),
|
|
423
|
-
}));
|
|
424
|
-
return {
|
|
425
|
-
stashPath: meta.stashPath,
|
|
426
|
-
graphPath: meta.graphPath,
|
|
427
|
-
schemaVersion: meta.schemaVersion,
|
|
428
|
-
generatedAt: meta.generatedAt,
|
|
429
|
-
...(meta.quality ? { quality: meta.quality } : {}),
|
|
430
|
-
...(meta.telemetry ? { telemetry: meta.telemetry } : {}),
|
|
431
|
-
files,
|
|
432
|
-
entities: uniqueSorted(files.flatMap((file) => file.entities)),
|
|
433
|
-
relations: files.flatMap((file) => file.relations),
|
|
434
|
-
};
|
|
435
|
-
});
|
|
436
|
-
}
|
|
437
|
-
catch (err) {
|
|
438
|
-
// Never mask the bun-test isolation guard as "no stored graph snapshot",
|
|
439
|
-
// nor an unreadable index as one that simply has no graph (#791).
|
|
440
|
-
rethrowIfTestIsolationError(err);
|
|
441
|
-
rethrowIfDataDirUnreadable(err);
|
|
442
|
-
return null;
|
|
443
|
-
}
|
|
444
|
-
}
|