@unbrained/pm-cli 2026.9.7 → 2026.9.8
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/.agents/skills/pm-developer/SKILL.md +12 -4
- package/.agents/skills/pm-developer/references/MULTI_AGENT_MERGE.md +19 -10
- package/.agents/skills/pm-extensions/SKILL.md +6 -0
- package/.agents/skills/pm-sdk/SKILL.md +11 -2
- package/.agents/skills/pm-user/SKILL.md +5 -0
- package/.agents/skills/pm-user/references/ECOSYSTEM_PLANNING.md +95 -0
- package/.claude-plugin/marketplace.json +2 -2
- package/CHANGELOG.md +211 -181
- package/dist/cli/after-command-context-usage.js +1 -48
- package/dist/cli/argv-utils.js +1 -40
- package/dist/cli/bootstrap-args.js +1 -9
- package/dist/cli/bundle-integrity.js +2 -110
- package/dist/cli/commander-usage.js +11 -771
- package/dist/cli/commands/activity.js +1 -9
- package/dist/cli/commands/aggregate.js +1 -5
- package/dist/cli/commands/append.js +1 -5
- package/dist/cli/commands/claim.js +1 -5
- package/dist/cli/commands/close-many.js +1 -5
- package/dist/cli/commands/close.js +1 -9
- package/dist/cli/commands/comments.js +1 -5
- package/dist/cli/commands/config.js +1 -9
- package/dist/cli/commands/context.js +1 -9
- package/dist/cli/commands/contracts.js +1 -5
- package/dist/cli/commands/copy.js +1 -9
- package/dist/cli/commands/create.js +1 -9
- package/dist/cli/commands/delete.js +1 -9
- package/dist/cli/commands/deps.js +1 -9
- package/dist/cli/commands/docs.js +1 -9
- package/dist/cli/commands/duplicates.js +1 -9
- package/dist/cli/commands/eval.js +1 -9
- package/dist/cli/commands/extension/describe.js +1 -5
- package/dist/cli/commands/extension/scaffold.js +1 -5
- package/dist/cli/commands/extension/shared.js +1 -5
- package/dist/cli/commands/extension.js +1 -9
- package/dist/cli/commands/files.js +1 -9
- package/dist/cli/commands/focus.js +1 -9
- package/dist/cli/commands/gc.js +1 -9
- package/dist/cli/commands/get.js +1 -9
- package/dist/cli/commands/graph.js +1 -10
- package/dist/cli/commands/health.js +1 -9
- package/dist/cli/commands/history-compact.js +1 -10
- package/dist/cli/commands/history-redact.js +1 -11
- package/dist/cli/commands/history-repair.js +1 -10
- package/dist/cli/commands/history.js +1 -5
- package/dist/cli/commands/index.js +1 -58
- package/dist/cli/commands/init-agent-guidance.js +1 -9
- package/dist/cli/commands/init.js +1 -9
- package/dist/cli/commands/learnings.js +1 -5
- package/dist/cli/commands/lifecycle-transitions.js +1 -5
- package/dist/cli/commands/list.js +1 -9
- package/dist/cli/commands/merge.js +1 -11
- package/dist/cli/commands/next.js +1 -9
- package/dist/cli/commands/notes.js +1 -5
- package/dist/cli/commands/plan.js +1 -9
- package/dist/cli/commands/profile.js +1 -9
- package/dist/cli/commands/restore.js +1 -9
- package/dist/cli/commands/scheduling-shortcuts.js +1 -9
- package/dist/cli/commands/schema.js +1 -10
- package/dist/cli/commands/search.js +1 -9
- package/dist/cli/commands/stats.js +1 -9
- package/dist/cli/commands/telemetry.js +1 -9
- package/dist/cli/commands/test-all.js +1 -9
- package/dist/cli/commands/test-runs.js +1 -9
- package/dist/cli/commands/test.js +1 -9
- package/dist/cli/commands/update-many.js +1 -5
- package/dist/cli/commands/update.js +1 -9
- package/dist/cli/commands/upgrade.js +1 -5
- package/dist/cli/commands/validate.js +1 -15
- package/dist/cli/context-intent-invocation.js +1 -20
- package/dist/cli/description-stdin.js +1 -17
- package/dist/cli/error-guidance.js +1 -1353
- package/dist/cli/extension-command-help.js +5 -636
- package/dist/cli/extension-command-options.js +1 -427
- package/dist/cli/extension-recovery.js +1 -126
- package/dist/cli/help-content.js +2 -1001
- package/dist/cli/help-json-payload.js +4 -570
- package/dist/cli/main.d.ts +4 -0
- package/dist/cli/main.js +5 -2573
- package/dist/cli/migration-gates.js +1 -289
- package/dist/cli/public.js +1 -20
- package/dist/cli/register-annotations.js +1 -270
- package/dist/cli/register-assurance.js +1 -62
- package/dist/cli/register-files-lookup.js +1 -56
- package/dist/cli/register-history-activity.d.ts +8 -0
- package/dist/cli/register-history-activity.js +2 -0
- package/dist/cli/register-history-author.js +1 -38
- package/dist/cli/register-history-maintenance.d.ts +9 -0
- package/dist/cli/register-history-maintenance.js +2 -0
- package/dist/cli/register-list-query.js +10 -943
- package/dist/cli/register-mutation-options.js +1 -9
- package/dist/cli/register-mutation.js +19 -1893
- package/dist/cli/register-operations.js +1 -920
- package/dist/cli/register-setup.js +1 -716
- package/dist/cli/register-structured-mutation.js +1 -196
- package/dist/cli/registration-helpers.js +1 -5
- package/dist/cli/runtime-compatibility-boundary.js +4 -42
- package/dist/cli/schema-registration-helpers.js +1 -73
- package/dist/cli/search-refresh.js +1 -13
- package/dist/cli/stats-analytics-json.js +1 -68
- package/dist/cli/telemetry-flush.js +1 -10
- package/dist/cli-bundle/bundle-manifest.json +164 -156
- package/dist/cli-bundle/chunks/chunk-3BZZA6A3.js +5 -0
- package/dist/cli-bundle/chunks/chunk-AMRDVX36.js +235 -0
- package/dist/cli-bundle/chunks/chunk-DAM4CBBR.js +2202 -0
- package/dist/cli-bundle/chunks/{chunk-WYRZZ5ZE.js → chunk-DEZPZOQ7.js} +2 -2
- package/dist/cli-bundle/chunks/chunk-FLDWYEND.js +77 -0
- package/dist/cli-bundle/chunks/{chunk-NPN5I67J.js → chunk-G5ADGQ2D.js} +3 -3
- package/dist/cli-bundle/chunks/chunk-JAAEYHUA.js +2 -0
- package/dist/cli-bundle/chunks/{chunk-JX4DH4WC.js → chunk-KR3RP4FH.js} +3 -3
- package/dist/cli-bundle/chunks/chunk-LEZOUXG6.js +2 -0
- package/dist/cli-bundle/chunks/chunk-NSAPNEYH.js +2 -0
- package/dist/cli-bundle/chunks/chunk-QOEKOECV.js +29 -0
- package/dist/cli-bundle/chunks/chunk-RHSFOMHU.js +2 -0
- package/dist/cli-bundle/chunks/chunk-XOD2PCB6.js +20 -0
- package/dist/cli-bundle/chunks/{chunk-JT6XF6GE.js → chunk-YVEQ2AMO.js} +4 -4
- package/dist/cli-bundle/chunks/register-list-query-KSK3R63M.js +11 -0
- package/dist/cli-bundle/chunks/register-mutation-IQ5C7U6O.js +20 -0
- package/dist/cli-bundle/chunks/{register-operations-I5W3KMGB.js → register-operations-DWVHR2NC.js} +2 -2
- package/dist/cli-bundle/chunks/register-setup-BQ5SVD4B.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-3WRPWLA7.js +3 -0
- package/dist/cli-bundle/focused-chunks/chunk-7MBUII7U.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-COPBO5HW.js +8 -0
- package/dist/cli-bundle/focused-chunks/chunk-DUN4IXYN.js +20 -0
- package/dist/cli-bundle/focused-chunks/{chunk-LIJIA4TY.js → chunk-EE5QSM4Z.js} +3 -3
- package/dist/cli-bundle/focused-chunks/chunk-HJVARYM3.js +6 -0
- package/dist/cli-bundle/focused-chunks/chunk-IAUOUGVR.js +177 -0
- package/dist/cli-bundle/focused-chunks/chunk-KOOMJ54F.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-MZDXX7JY.js +56 -0
- package/dist/cli-bundle/focused-chunks/{chunk-M6PBRFSH.js → chunk-OPFHFGDD.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-QHNETP77.js +9 -0
- package/dist/cli-bundle/focused-chunks/{chunk-3BZEOXLT.js → chunk-RMWES4M6.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-RXT4P5QH.js +10 -0
- package/dist/cli-bundle/focused-chunks/chunk-SDOL6FM2.js +12 -0
- package/dist/cli-bundle/focused-chunks/chunk-SQV4AAUC.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-PEFABF7E.js → chunk-WE3IUNIW.js} +3 -3
- package/dist/cli-bundle/focused-chunks/chunk-YALOUBWJ.js +2 -0
- package/dist/cli-bundle/main.js +20 -20
- package/dist/cli-bundle/sdk-authoring.js +1 -1
- package/dist/cli-bundle/sdk-contracts.js +2 -2
- package/dist/cli-bundle/sdk-core.js +29 -29
- package/dist/cli-bundle/sdk-governance.js +1 -1
- package/dist/cli-bundle/sdk-graph.js +1 -1
- package/dist/cli-bundle/sdk-merge.js +42 -42
- package/dist/cli-bundle/sdk-query.js +1 -1
- package/dist/cli-bundle/sdk-runtime.js +1 -1
- package/dist/cli-bundle/sdk-testing.js +1 -1
- package/dist/cli-bundle/sdk.js +11 -11
- package/dist/cli.js +1 -104
- package/dist/core/checkpoint/checkpoint-gc.js +1 -169
- package/dist/core/checkpoint/mutation-checkpoint.js +2 -133
- package/dist/core/config/nested-settings.js +1 -534
- package/dist/core/config/positional-value.js +1 -109
- package/dist/core/diagnostics/remediation.js +1 -506
- package/dist/core/extensions/activation-summary-markdown.js +2 -145
- package/dist/core/extensions/activation-summary.js +1 -92
- package/dist/core/extensions/activation-transaction.js +1 -46
- package/dist/core/extensions/capability-usage.js +1 -173
- package/dist/core/extensions/command-hook-context.js +1 -13
- package/dist/core/extensions/command-metadata-contract.js +1 -22
- package/dist/core/extensions/command-visibility-tier.js +1 -29
- package/dist/core/extensions/contribution-inventory.js +1 -173
- package/dist/core/extensions/exporter-output-contract.js +1 -66
- package/dist/core/extensions/extension-candidate.js +1 -18
- package/dist/core/extensions/extension-capability-aliases.js +1 -158
- package/dist/core/extensions/extension-hook-runtime.js +1 -699
- package/dist/core/extensions/extension-policy.js +1 -599
- package/dist/core/extensions/extension-registries.js +1 -62
- package/dist/core/extensions/extension-runtime-helpers.js +1 -33
- package/dist/core/extensions/extension-types.js +1 -102
- package/dist/core/extensions/flag-definition-validation.js +1 -52
- package/dist/core/extensions/flag-value-types.js +1 -64
- package/dist/core/extensions/index.js +1 -526
- package/dist/core/extensions/item-field-types.js +1 -39
- package/dist/core/extensions/item-fields.js +1 -261
- package/dist/core/extensions/loader.js +1 -2223
- package/dist/core/extensions/manifest-schema.js +1 -69
- package/dist/core/extensions/module-graph-snapshot.js +1 -33
- package/dist/core/extensions/preflight-ownership.js +1 -41
- package/dist/core/extensions/registration-validation.js +1 -82
- package/dist/core/extensions/registration-values.js +1 -209
- package/dist/core/extensions/reserved-host-flags.js +1 -36
- package/dist/core/extensions/runtime-registrations.js +1 -67
- package/dist/core/extensions/service-ownership.js +1 -19
- package/dist/core/extensions/version-compat.js +1 -216
- package/dist/core/fs/fs-utils.js +2 -158
- package/dist/core/fs/host-environment-errors.js +1 -141
- package/dist/core/fs/index.js +1 -9
- package/dist/core/fs/path-utils.js +1 -17
- package/dist/core/governance/content-fields.js +1 -160
- package/dist/core/governance/issue-codes.js +1 -151
- package/dist/core/governance/metadata-coverage.js +1 -358
- package/dist/core/history/drift-cache.js +3 -72
- package/dist/core/history/drift-scan.js +1 -342
- package/dist/core/history/event-classification.js +1 -109
- package/dist/core/history/event-index.js +8 -784
- package/dist/core/history/history-compact-bulk.js +1 -104
- package/dist/core/history/history-diff.js +1 -158
- package/dist/core/history/history-rewrite.d.ts +6 -1
- package/dist/core/history/history-rewrite.js +1 -107
- package/dist/core/history/history-storage-stats.js +1 -102
- package/dist/core/history/history-stream-policy.js +1 -62
- package/dist/core/history/history.js +2 -617
- package/dist/core/history/identity.js +1 -30
- package/dist/core/history/index.js +1 -9
- package/dist/core/history/projection.js +1 -196
- package/dist/core/history/read.d.ts +9 -0
- package/dist/core/history/read.js +1 -57
- package/dist/core/history/replay.js +2 -439
- package/dist/core/history/version-address.js +1 -32
- package/dist/core/history/workspace-history.js +2 -433
- package/dist/core/io/body-file.js +1 -62
- package/dist/core/io/bulk-ids-input.js +1 -112
- package/dist/core/item/actionability.js +1 -327
- package/dist/core/item/dependency-reference.js +1 -20
- package/dist/core/item/id.js +1 -112
- package/dist/core/item/index.js +1 -12
- package/dist/core/item/item-format-version.js +1 -78
- package/dist/core/item/item-format.js +5 -1473
- package/dist/core/item/item-record.js +1 -23
- package/dist/core/item/item-type-definition.js +1 -133
- package/dist/core/item/parent-reference-policy.js +1 -57
- package/dist/core/item/parse.js +2 -603
- package/dist/core/item/plan-lifecycle.js +1 -19
- package/dist/core/item/priority.js +1 -61
- package/dist/core/item/sprint-release-format.js +1 -38
- package/dist/core/item/status-filter.js +1 -115
- package/dist/core/item/status.js +1 -43
- package/dist/core/item/toon-decode.js +1 -29
- package/dist/core/item/type-registry.js +1 -715
- package/dist/core/item/type-synonyms.js +1 -38
- package/dist/core/lock/index.js +1 -9
- package/dist/core/lock/lock-gc.js +1 -240
- package/dist/core/lock/lock.js +3 -590
- package/dist/core/output/mutation-projection.js +1 -217
- package/dist/core/output/output-control.js +1 -25
- package/dist/core/output/output.js +11 -494
- package/dist/core/output/query-summary.js +1 -58
- package/dist/core/output/tabular.js +1 -77
- package/dist/core/packages/manifest.js +1 -244
- package/dist/core/packages/root.js +1 -84
- package/dist/core/profile/profile-describe.js +1 -83
- package/dist/core/profile/profile-lint.js +1 -415
- package/dist/core/profile/profile-plan.js +0 -0
- package/dist/core/profile/profile-presets.js +1 -370
- package/dist/core/reproducibility/context.js +1 -82
- package/dist/core/schema/fields-file.js +2 -288
- package/dist/core/schema/item-types-file.js +2 -296
- package/dist/core/schema/runtime-field-filters.js +1 -49
- package/dist/core/schema/runtime-field-values.js +1 -313
- package/dist/core/schema/runtime-schema.js +2 -826
- package/dist/core/schema/status-defs-file.js +2 -227
- package/dist/core/schema/status-token.js +1 -31
- package/dist/core/schema/type-inference.js +1 -95
- package/dist/core/schema/type-presets.js +1 -87
- package/dist/core/schema/type-workflows.js +1 -104
- package/dist/core/search/background-refresh.js +2 -286
- package/dist/core/search/bm25.js +1 -146
- package/dist/core/search/cache.js +2 -534
- package/dist/core/search/corpus.js +1 -311
- package/dist/core/search/embedding-batches.js +1 -163
- package/dist/core/search/eval.js +1 -225
- package/dist/core/search/http-client.js +1 -75
- package/dist/core/search/providers.js +1 -242
- package/dist/core/search/relevance.js +1 -244
- package/dist/core/search/semantic-defaults.js +1 -199
- package/dist/core/search/staleness.js +1 -30
- package/dist/core/search/vector-stores.js +2 -664
- package/dist/core/search/vectorization-metadata.js +1 -81
- package/dist/core/sentry/helpers.js +1 -272
- package/dist/core/sentry/instrument.js +1 -387
- package/dist/core/session/session-state.js +1 -260
- package/dist/core/shared/agent-session-context.js +1 -133
- package/dist/core/shared/author.js +1 -1172
- package/dist/core/shared/command-types.js +1 -4
- package/dist/core/shared/conflict-markers.js +1 -31
- package/dist/core/shared/constants.js +1 -405
- package/dist/core/shared/errors.js +1 -20
- package/dist/core/shared/html-entity-decode.js +1 -131
- package/dist/core/shared/index.js +1 -12
- package/dist/core/shared/item-metadata-contract.js +1 -89
- package/dist/core/shared/lazy-module.js +1 -16
- package/dist/core/shared/levenshtein.js +1 -61
- package/dist/core/shared/memo.js +1 -19
- package/dist/core/shared/numeric-parsers.js +1 -20
- package/dist/core/shared/option-alias-visibility.js +1 -67
- package/dist/core/shared/primitives.js +1 -127
- package/dist/core/shared/serial-queue.js +1 -79
- package/dist/core/shared/serialization.js +1 -210
- package/dist/core/shared/split-comma-list.js +1 -30
- package/dist/core/shared/text-normalization.js +1 -38
- package/dist/core/shared/time.js +1 -306
- package/dist/core/store/index.js +1 -12
- package/dist/core/store/item-format-migration.js +1 -125
- package/dist/core/store/item-metadata-cache.js +1 -1116
- package/dist/core/store/item-metadata-query-index.js +9 -394
- package/dist/core/store/item-metadata-read-work.js +1 -43
- package/dist/core/store/item-store.js +1 -693
- package/dist/core/store/paths.d.ts +1 -1
- package/dist/core/store/paths.js +1 -214
- package/dist/core/store/settings-read-cache.js +1 -85
- package/dist/core/store/settings-validator.js +1 -421
- package/dist/core/store/settings.js +3 -1309
- package/dist/core/store/tracker-preflight.js +1 -141
- package/dist/core/telemetry/consent.js +5 -108
- package/dist/core/telemetry/observability.js +1 -246
- package/dist/core/telemetry/runtime.js +4 -1988
- package/dist/core/test/background-runs.js +4 -945
- package/dist/core/test/item-test-run-tracking.js +1 -63
- package/dist/core/test/run-selectors.js +1 -120
- package/dist/core/validate/estimate-defaults.js +1 -89
- package/dist/core/validate/fix-planning.js +1 -189
- package/dist/core/validate/linked-artifact-reference.js +1 -36
- package/dist/core/validate/missing-by-type.js +1 -34
- package/dist/core/validate/missing-link-owners.js +1 -95
- package/dist/core/validate/stale-file-classification.js +1 -82
- package/dist/mcp/http-server.js +5 -448
- package/dist/mcp/legacy-adapter.js +1 -77
- package/dist/mcp/runtime-capabilities.js +1 -200
- package/dist/mcp/server.js +4 -1233
- package/dist/mcp/tool-definitions.js +1 -804
- package/dist/sdk/actionability.js +1 -13
- package/dist/sdk/agent/closed-domain-contracts.js +1 -161
- package/dist/sdk/agent/command-recovery.js +1 -59
- package/dist/sdk/agent/command-suggestions.js +1 -66
- package/dist/sdk/agent/create-option-policy.js +1 -31
- package/dist/sdk/agent/identity-config.js +1 -106
- package/dist/sdk/agent/item-addressing.js +1 -207
- package/dist/sdk/agent/refusal-closure-census.js +1 -151
- package/dist/sdk/agent/refusal-closure.js +1 -133
- package/dist/sdk/agent/refusal-corpus-contracts.js +1 -193
- package/dist/sdk/agent/refusal-reachability.js +1 -593
- package/dist/sdk/agent/subcommand-recovery.js +1 -83
- package/dist/sdk/agent/task-transcript-contracts.js +1 -197
- package/dist/sdk/agent/tracker-preflight-contracts.js +1 -126
- package/dist/sdk/agent-capability-contracts.js +1 -428
- package/dist/sdk/agent-session-context.js +1 -9
- package/dist/sdk/annotations.js +1 -448
- package/dist/sdk/author-attribution.js +1 -468
- package/dist/sdk/authoring.js +1 -20
- package/dist/sdk/cli-bootstrap.js +1 -838
- package/dist/sdk/cli-contracts/agent-output-contracts.d.ts +1 -1
- package/dist/sdk/cli-contracts/agent-output-contracts.js +4 -476
- package/dist/sdk/cli-contracts/bootstrap-command-scanner.js +1 -79
- package/dist/sdk/cli-contracts/command-aliases.d.ts +4 -0
- package/dist/sdk/cli-contracts/command-aliases.js +1 -107
- package/dist/sdk/cli-contracts/command-exit-contracts.js +1 -151
- package/dist/sdk/cli-contracts/commander-mutation-options.js +1 -1081
- package/dist/sdk/cli-contracts/commander-types.js +1 -159
- package/dist/sdk/cli-contracts/completeness.js +1 -393
- package/dist/sdk/cli-contracts/enum-contracts.js +1 -222
- package/dist/sdk/cli-contracts/flag-contracts.js +1 -1947
- package/dist/sdk/cli-contracts/flag-lexicon-contracts.js +1 -347
- package/dist/sdk/cli-contracts/grammar-contracts.js +1 -986
- package/dist/sdk/cli-contracts/registration-helpers.js +7 -990
- package/dist/sdk/cli-contracts/runtime-contracts.d.ts +5 -0
- package/dist/sdk/cli-contracts/runtime-contracts.js +1 -2090
- package/dist/sdk/cli-contracts/schemas/assurance-definition.js +1 -324
- package/dist/sdk/cli-contracts/string-lists.js +1 -16
- package/dist/sdk/cli-contracts/tool-option-contracts.js +1 -461
- package/dist/sdk/cli-contracts/tool-parameter-tables.js +1 -2167
- package/dist/sdk/cli-contracts/tool-schema.d.ts +3 -1
- package/dist/sdk/cli-contracts/tool-schema.js +1 -1664
- package/dist/sdk/cli-contracts/typed-action-inputs.js +1 -4
- package/dist/sdk/cli-contracts.d.ts +1 -1
- package/dist/sdk/cli-contracts.js +1 -17
- package/dist/sdk/cli-program.js +1 -49
- package/dist/sdk/command-line.d.ts +2 -5
- package/dist/sdk/command-line.js +1 -78
- package/dist/sdk/comments.js +1 -133
- package/dist/sdk/compile-cache.js +1 -73
- package/dist/sdk/completion.js +157 -837
- package/dist/sdk/compose.js +1 -1090
- package/dist/sdk/config.js +1 -1204
- package/dist/sdk/context/recency.js +1 -33
- package/dist/sdk/context/semantic-session-attribution.js +1 -82
- package/dist/sdk/context/usage-egress.js +1 -29
- package/dist/sdk/context/usage-ledger.js +3 -185
- package/dist/sdk/context-intent-contracts.js +1 -709
- package/dist/sdk/context-intent-runtime.js +1 -115
- package/dist/sdk/context-packing.js +1 -218
- package/dist/sdk/context-relevance.js +1 -503
- package/dist/sdk/context-signal-store.js +2 -426
- package/dist/sdk/context-usage.js +1 -367
- package/dist/sdk/contracts.js +1 -23
- package/dist/sdk/core-governance.js +1 -14
- package/dist/sdk/core.js +1 -14
- package/dist/sdk/corpus-shape.js +1 -401
- package/dist/sdk/define.js +1 -220
- package/dist/sdk/dependencies.js +1 -718
- package/dist/sdk/dependency-flag-validation.js +1 -156
- package/dist/sdk/dependency-provenance.js +1 -135
- package/dist/sdk/docs.js +1 -14
- package/dist/sdk/duplicates.js +1 -40
- package/dist/sdk/environment/agent-environment.js +1 -466
- package/dist/sdk/environment/host-environment-errors.js +1 -8
- package/dist/sdk/environment/project-runtime-compatibility.js +1 -481
- package/dist/sdk/environment/source-context.js +1 -28
- package/dist/sdk/environment/tracker-preflight.js +1 -9
- package/dist/sdk/error-code-catalog.js +1 -153
- package/dist/sdk/error-runtime.js +1 -58
- package/dist/sdk/errors.js +1 -58
- package/dist/sdk/eval.js +1 -190
- package/dist/sdk/extension/author-manifest.js +1 -92
- package/dist/sdk/extension/bundled-catalog.js +1 -332
- package/dist/sdk/extension/concurrency.js +1 -25
- package/dist/sdk/extension/copy-scope.d.ts +2 -0
- package/dist/sdk/extension/copy-scope.js +2 -0
- package/dist/sdk/extension/custom-field-collisions.js +1 -30
- package/dist/sdk/extension/describe.js +3 -189
- package/dist/sdk/extension/doctor.js +1 -606
- package/dist/sdk/extension/install-plan.d.ts +69 -0
- package/dist/sdk/extension/install-plan.js +2 -0
- package/dist/sdk/extension/install-receipts.d.ts +7 -0
- package/dist/sdk/extension/install-receipts.js +2 -0
- package/dist/sdk/extension/install-runtime.js +3 -313
- package/dist/sdk/extension/install-snapshot.js +1 -66
- package/dist/sdk/extension/install-sources.js +5 -1057
- package/dist/sdk/extension/managed-state.js +2 -252
- package/dist/sdk/extension/migrations.js +2 -174
- package/dist/sdk/extension/output-ownership.js +1 -25
- package/dist/sdk/extension/runtime-summary.js +1 -18
- package/dist/sdk/extension/scaffold.js +4 -2308
- package/dist/sdk/extension/shared.js +1 -147
- package/dist/sdk/extension/source-resolution.js +1 -65
- package/dist/sdk/extension/update-check.js +1 -67
- package/dist/sdk/extension-command-context.js +1 -44
- package/dist/sdk/extension-contracts.js +1 -73
- package/dist/sdk/extension.d.ts +7 -2
- package/dist/sdk/extension.js +1 -2196
- package/dist/sdk/files.js +1 -535
- package/dist/sdk/flag-invocation-contracts.d.ts +0 -5
- package/dist/sdk/flag-invocation-contracts.js +1 -344
- package/dist/sdk/generated/generated-error-code-catalog-part-1.js +1 -2224
- package/dist/sdk/generated/generated-error-code-catalog-part-2.js +1 -2236
- package/dist/sdk/generated-error-code-catalog.js +1 -16
- package/dist/sdk/governance/assurance-action-contracts.js +1 -4
- package/dist/sdk/governance/assurance-action.js +1 -411
- package/dist/sdk/governance/assurance-limits.js +1 -10
- package/dist/sdk/governance/assurance-mutation-error.js +1 -81
- package/dist/sdk/governance/assurance-presets.js +1 -135
- package/dist/sdk/governance/assurance-runtime.js +1 -238
- package/dist/sdk/governance/assurance.js +4 -1182
- package/dist/sdk/governance/boundary-fixtures.js +1 -200
- package/dist/sdk/governance/coverage-assurance.js +1 -60
- package/dist/sdk/governance/defect-recurrence-coverage.js +1 -188
- package/dist/sdk/governance/defect-recurrence-graph.js +1 -120
- package/dist/sdk/governance/defect-recurrence-signals.js +1 -24
- package/dist/sdk/governance/defect-recurrence.js +1 -623
- package/dist/sdk/governance/extension-host-version.js +1 -115
- package/dist/sdk/governance/gc.js +1 -368
- package/dist/sdk/governance/health.js +1 -2367
- package/dist/sdk/governance/hierarchy-validation.js +1 -108
- package/dist/sdk/governance/linked-file-report.js +1 -71
- package/dist/sdk/governance/merge-receipt-history.js +1 -206
- package/dist/sdk/governance/provenance-health.js +1 -282
- package/dist/sdk/governance/reindex.js +4 -761
- package/dist/sdk/governance/stale-work.js +1 -82
- package/dist/sdk/governance/status-role-diagnostics.js +1 -35
- package/dist/sdk/governance/storage-integrity.js +1 -280
- package/dist/sdk/governance/tracked-runtime-cache.js +1 -106
- package/dist/sdk/governance/upgrade.js +2 -327
- package/dist/sdk/governance/validate-history-drift.js +1 -81
- package/dist/sdk/governance/validate-item-reader.js +1 -17
- package/dist/sdk/governance/validate-normalization.js +1 -36
- package/dist/sdk/governance/validate.js +1 -2261
- package/dist/sdk/governance/workspace-position.js +1 -163
- package/dist/sdk/governance.d.ts +1 -0
- package/dist/sdk/governance.js +1 -31
- package/dist/sdk/graph/adapter.js +1 -181
- package/dist/sdk/graph/analytics.js +1 -474
- package/dist/sdk/graph/assembly.js +1 -377
- package/dist/sdk/graph/cache.js +1 -160
- package/dist/sdk/graph/centrality.js +1 -258
- package/dist/sdk/graph/conformance.js +1 -130
- package/dist/sdk/graph/deadline-scheduling.d.ts +90 -0
- package/dist/sdk/graph/deadline-scheduling.js +2 -0
- package/dist/sdk/graph/durable-cache.d.ts +1 -1
- package/dist/sdk/graph/durable-cache.js +1 -361
- package/dist/sdk/graph/governance-contracts.js +1 -34
- package/dist/sdk/graph/governance.d.ts +13 -1
- package/dist/sdk/graph/governance.js +1 -735
- package/dist/sdk/graph/hierarchy-integrity.js +1 -310
- package/dist/sdk/graph/index.d.ts +3 -2
- package/dist/sdk/graph/index.js +1 -26
- package/dist/sdk/graph/lifecycle-coverage.d.ts +32 -0
- package/dist/sdk/graph/lifecycle-coverage.js +2 -0
- package/dist/sdk/graph/mutation-advisory.js +1 -176
- package/dist/sdk/graph/remediation.js +1 -197
- package/dist/sdk/graph/run.d.ts +15 -1
- package/dist/sdk/graph/run.js +1 -768
- package/dist/sdk/graph/scheduling.js +1 -124
- package/dist/sdk/graph/traversal.js +1 -284
- package/dist/sdk/graph/workspace-relationship-kind-registry.js +1 -27
- package/dist/sdk/graph.js +1 -15
- package/dist/sdk/guide-topics.js +1 -707
- package/dist/sdk/guide.js +1 -279
- package/dist/sdk/history/maintenance.d.ts +71 -0
- package/dist/sdk/history/maintenance.js +2 -0
- package/dist/sdk/history/salvage.js +2 -247
- package/dist/sdk/history/subject.d.ts +19 -0
- package/dist/sdk/history/subject.js +2 -0
- package/dist/sdk/history-analytics.js +1 -282
- package/dist/sdk/history-compact.js +1 -527
- package/dist/sdk/history-mcp.js +1 -68
- package/dist/sdk/history-provenance.js +1 -182
- package/dist/sdk/history-read.js +1 -96
- package/dist/sdk/history-redact.d.ts +1 -14
- package/dist/sdk/history-redact.js +1 -643
- package/dist/sdk/history-repair.d.ts +5 -0
- package/dist/sdk/history-repair.js +1 -657
- package/dist/sdk/improvement-ledger-validation.js +1 -62
- package/dist/sdk/improvement-ledger.js +2 -257
- package/dist/sdk/index.d.ts +4 -0
- package/dist/sdk/index.js +1 -183
- package/dist/sdk/init-agent-guidance.js +2 -496
- package/dist/sdk/init.js +2 -820
- package/dist/sdk/invocation-author.js +1 -39
- package/dist/sdk/item-children.js +1 -90
- package/dist/sdk/item-metadata-index.js +1 -15
- package/dist/sdk/item-schedule.js +1 -27
- package/dist/sdk/item-transaction.js +1 -396
- package/dist/sdk/learnings.js +1 -29
- package/dist/sdk/lifecycle/append.js +2 -53
- package/dist/sdk/lifecycle/claim.d.ts +2 -0
- package/dist/sdk/lifecycle/claim.js +1 -242
- package/dist/sdk/lifecycle/close-many.js +1 -438
- package/dist/sdk/lifecycle/close.js +1 -468
- package/dist/sdk/lifecycle/copy.js +1 -212
- package/dist/sdk/lifecycle/create.js +1 -1949
- package/dist/sdk/lifecycle/delete.js +1 -45
- package/dist/sdk/lifecycle/event-validation-messages.js +1 -91
- package/dist/sdk/lifecycle/focus.js +1 -91
- package/dist/sdk/lifecycle/hierarchy-mutation-lock.js +1 -24
- package/dist/sdk/lifecycle/legacy-none-tokens.js +1 -149
- package/dist/sdk/lifecycle/lifecycle-transitions.js +1 -40
- package/dist/sdk/lifecycle/mcp-actions.d.ts +2 -0
- package/dist/sdk/lifecycle/mcp-actions.js +1 -51
- package/dist/sdk/lifecycle/metadata-normalizers.js +1 -46
- package/dist/sdk/lifecycle/mutation-command-options.js +1 -9
- package/dist/sdk/lifecycle/plan.js +1 -1606
- package/dist/sdk/lifecycle/recurrence-parsers.js +1 -147
- package/dist/sdk/lifecycle/reopen.js +1 -68
- package/dist/sdk/lifecycle/repeatable-metadata-parsers.js +1 -143
- package/dist/sdk/lifecycle/restore.d.ts +1 -0
- package/dist/sdk/lifecycle/restore.js +1 -330
- package/dist/sdk/lifecycle/shared-unset-fields.js +1 -295
- package/dist/sdk/lifecycle/update-many.js +1 -861
- package/dist/sdk/lifecycle/update.js +1 -2136
- package/dist/sdk/lifecycle-completion.js +1 -92
- package/dist/sdk/lifecycle-policy.js +1 -120
- package/dist/sdk/linked-artifacts.js +1 -530
- package/dist/sdk/mcp/apps.js +4 -133
- package/dist/sdk/mcp/authorization.js +1 -404
- package/dist/sdk/mcp/discovery.js +1 -494
- package/dist/sdk/mcp/interactions.js +1 -336
- package/dist/sdk/mcp/protocol.d.ts +7 -0
- package/dist/sdk/mcp/protocol.js +1 -184
- package/dist/sdk/mcp/skills.js +1 -389
- package/dist/sdk/mcp/subscriptions.js +1 -211
- package/dist/sdk/mcp/tasks.js +2 -430
- package/dist/sdk/mcp/transport.js +1 -260
- package/dist/sdk/merge/abandoned-receipts.js +1 -46
- package/dist/sdk/merge/driver.js +1 -212
- package/dist/sdk/merge/index.js +1 -16
- package/dist/sdk/merge/install.js +3 -561
- package/dist/sdk/merge/receipt-file-boundary.js +1 -46
- package/dist/sdk/merge/receipt-operation.js +1 -96
- package/dist/sdk/merge/receipt-schema.js +1 -397
- package/dist/sdk/merge/receipts.js +4 -525
- package/dist/sdk/merge/reconcile.js +1 -352
- package/dist/sdk/merge/three-way.js +3 -775
- package/dist/sdk/merge.js +1 -10
- package/dist/sdk/mutation-events.js +1 -292
- package/dist/sdk/mutation-guard.js +1 -216
- package/dist/sdk/notes.js +1 -139
- package/dist/sdk/output-contracts.js +1 -172
- package/dist/sdk/output-projection.js +1 -430
- package/dist/sdk/output-token-accounting.js +1 -140
- package/dist/sdk/output.js +1 -64
- package/dist/sdk/ownership-source.js +1 -21
- package/dist/sdk/package-import-adapters.js +1 -442
- package/dist/sdk/package-migrations.js +1 -20
- package/dist/sdk/package-runtime-options.js +1 -80
- package/dist/sdk/pagination.js +1 -162
- package/dist/sdk/profile.js +1 -454
- package/dist/sdk/provenance.js +1 -258
- package/dist/sdk/public-surface.json +1 -1
- package/dist/sdk/query/activity.js +1 -401
- package/dist/sdk/query/aggregate.d.ts +16 -0
- package/dist/sdk/query/aggregate.js +1 -390
- package/dist/sdk/query/calendar.js +1 -964
- package/dist/sdk/query/complete-list.js +1 -215
- package/dist/sdk/query/context.js +1 -1702
- package/dist/sdk/query/duplicate-candidates.js +1 -70
- package/dist/sdk/query/get.js +1 -450
- package/dist/sdk/query/history.js +1 -186
- package/dist/sdk/query/item-filter-options.js +1 -9
- package/dist/sdk/query/light-metadata.js +1 -18
- package/dist/sdk/query/list-filter-shared.js +1 -81
- package/dist/sdk/query/list.js +1 -1304
- package/dist/sdk/query/multi-value-filters.js +1 -78
- package/dist/sdk/query/next.js +1 -513
- package/dist/sdk/query/parsers.js +1 -44
- package/dist/sdk/query/projection-contracts.js +1 -184
- package/dist/sdk/query/search-contracts.js +1 -230
- package/dist/sdk/query/search-pagination.js +1 -35
- package/dist/sdk/query/search-rendering.js +1 -105
- package/dist/sdk/query/search.js +2 -1987
- package/dist/sdk/query.js +1 -35
- package/dist/sdk/read-output/continuation.js +1 -194
- package/dist/sdk/read-output-budget.js +1 -135
- package/dist/sdk/read-output-contracts.js +1 -1225
- package/dist/sdk/read-output-rows.js +1 -186
- package/dist/sdk/read-output-session.js +1 -208
- package/dist/sdk/relationship-analytics.js +1 -410
- package/dist/sdk/relationship-context.js +1 -284
- package/dist/sdk/relationship-history.js +4 -519
- package/dist/sdk/relationship-kinds/contract.js +1 -22
- package/dist/sdk/relationship-migration.js +1 -77
- package/dist/sdk/relationships.js +1 -579
- package/dist/sdk/reproducibility/process.js +1 -87
- package/dist/sdk/runtime-action-aliases.js +1 -59
- package/dist/sdk/runtime-extended-actions.js +1 -177
- package/dist/sdk/runtime-input.js +1 -614
- package/dist/sdk/runtime-primitives.js +1 -84
- package/dist/sdk/runtime-public-contracts.js +1 -4
- package/dist/sdk/runtime-stats-options.js +1 -38
- package/dist/sdk/runtime.js +1 -1928
- package/dist/sdk/scheduling-shortcuts.js +1 -63
- package/dist/sdk/schema-migration.js +3 -856
- package/dist/sdk/schema.js +1 -1376
- package/dist/sdk/search-refresh-worker.js +1 -18
- package/dist/sdk/similarity-scoring.js +1 -53
- package/dist/sdk/similarity.js +1 -326
- package/dist/sdk/start-task-status.js +1 -14
- package/dist/sdk/stats.js +1 -270
- package/dist/sdk/structured-mutations.js +1 -580
- package/dist/sdk/telemetry-flush.js +1 -13
- package/dist/sdk/telemetry.js +1 -405
- package/dist/sdk/templates.js +2 -292
- package/dist/sdk/test/batch.js +2 -509
- package/dist/sdk/test/entry.js +1 -70
- package/dist/sdk/test/execution.js +6 -2211
- package/dist/sdk/test/linked-command-detection.js +1 -546
- package/dist/sdk/test/measurements.js +1 -91
- package/dist/sdk/test/parsers.js +1 -545
- package/dist/sdk/test/runs.js +1 -193
- package/dist/sdk/test/trust.js +2 -206
- package/dist/sdk/testing.js +4 -1391
- package/dist/sdk/traceability/runtime-files-lookup.js +1 -32
- package/dist/sdk/traceability/source-traceability.js +1 -292
- package/dist/sdk/tracker-root-discovery.js +1 -9
- package/dist/sdk/workspace-contracts-cache.js +1 -28
- package/dist/sdk/workspace-contracts.js +1 -33
- package/dist/sdk/workspace-memory.js +2 -318
- package/dist/sdk/workspace-recipe.js +1 -71
- package/dist/sdk/workspace-snapshot.js +4 -613
- package/dist/sdk/workspace-transaction-gc.js +1 -149
- package/dist/sdk/workspace-transaction.js +2 -363
- package/dist/sdk/workspace.js +3 -127
- package/dist/types/index.js +1 -9
- package/dist/types.js +1 -245
- package/docs/AGENT_GUIDE.md +1 -1
- package/docs/CONTEXT_ALGORITHM_PORTFOLIO.md +167 -0
- package/docs/DIAGNOSTIC_OUTPUT_CONTRACTS.md +9 -3
- package/docs/EXTENSIONS.md +1 -0
- package/docs/HISTORY_MAINTENANCE.md +125 -0
- package/docs/MCP_2026_07_28_CONFORMANCE.md +20 -10
- package/docs/PACKAGE_EVIDENCE.md +92 -0
- package/docs/PLANNING_MEASUREMENTS.md +183 -0
- package/docs/README.md +3 -0
- package/docs/SCRIPTING.md +21 -0
- package/docs/TESTING.md +23 -0
- package/docs/generated/FLAG_LEXICON_BUDGETS.md +5 -5
- package/docs/generated/REFUSAL_CLOSURE_CENSUS.md +2 -2
- package/marketplace.json +2 -2
- package/package.json +1 -1
- package/packages/pm-beads/package.json +1 -1
- package/packages/pm-calendar/package.json +1 -1
- package/packages/pm-command-kit/package.json +1 -1
- package/packages/pm-digital-twin/package.json +1 -1
- package/packages/pm-governance-audit/package.json +1 -1
- package/packages/pm-guide-shell/package.json +1 -1
- package/packages/pm-kanban/package.json +1 -1
- package/packages/pm-lifecycle-hooks/package.json +1 -1
- package/packages/pm-linked-test-adapters/package.json +1 -1
- package/packages/pm-search-advanced/package.json +1 -1
- package/packages/pm-templates/package.json +1 -1
- package/packages/pm-todos/package.json +1 -1
- package/packages/pm-vcs/package.json +1 -1
- package/plugins/pm-claude/.claude-plugin/plugin.json +1 -1
- package/plugins/pm-codex/.codex-plugin/plugin.json +1 -1
- package/scripts/finalize-build.mjs +45 -3
- package/dist/cli-bundle/chunks/chunk-AZDFJGH6.js +0 -9
- package/dist/cli-bundle/chunks/chunk-BAX2BYUW.js +0 -2111
- package/dist/cli-bundle/chunks/chunk-CKOL5U7J.js +0 -77
- package/dist/cli-bundle/chunks/chunk-OF76PSDQ.js +0 -5
- package/dist/cli-bundle/chunks/chunk-QUWFABDM.js +0 -232
- package/dist/cli-bundle/chunks/chunk-QWRRFYK3.js +0 -2
- package/dist/cli-bundle/chunks/chunk-RWWBOWJ5.js +0 -2
- package/dist/cli-bundle/chunks/chunk-WGAOYSYH.js +0 -40
- package/dist/cli-bundle/chunks/chunk-WI2AYPA7.js +0 -2
- package/dist/cli-bundle/chunks/register-list-query-5JL52D33.js +0 -11
- package/dist/cli-bundle/chunks/register-mutation-ZPG7KMVP.js +0 -20
- package/dist/cli-bundle/chunks/register-setup-H4SVAVX7.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-AL5ON6K6.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-CHC2IDXA.js +0 -6
- package/dist/cli-bundle/focused-chunks/chunk-CK6QFAPZ.js +0 -20
- package/dist/cli-bundle/focused-chunks/chunk-EZR3GHFE.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-H2WJWK7L.js +0 -56
- package/dist/cli-bundle/focused-chunks/chunk-NTPY5GSO.js +0 -3
- package/dist/cli-bundle/focused-chunks/chunk-P5O7MP5Y.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-PDMW2E36.js +0 -177
- package/dist/cli-bundle/focused-chunks/chunk-QTVCLMSZ.js +0 -6
- package/dist/cli-bundle/focused-chunks/chunk-QTZRBUYA.js +0 -8
- package/dist/cli-bundle/focused-chunks/chunk-SGQST3PQ.js +0 -12
- package/dist/cli-bundle/focused-chunks/chunk-UKHASMMP.js +0 -10
- package/dist/cli-bundle/focused-chunks/chunk-ZPEKQHOC.js +0 -2
|
@@ -1,665 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
import { mkdir, readFile, stat, unlink } from "node:fs/promises";
|
|
4
|
-
import { basename, dirname, isAbsolute, join, resolve } from "node:path";
|
|
5
|
-
import { executeSearchJsonRequest, normalizeSearchHttpTimeoutMs, resolveSearchHttpFetcher, } from "./http-client.js";
|
|
6
|
-
import { isFiniteNumberArray, toErrorMessage, toNonEmptyString, trimTrailingSlashes, } from "../shared/primitives.js";
|
|
7
|
-
import { isFileMissingError, writeFileAtomic } from "../fs/fs-utils.js";
|
|
8
|
-
const DEFAULT_COLLECTION = "pm_items";
|
|
9
|
-
const COLLECTION_SANITIZE_PATTERN = /[^a-zA-Z0-9_-]/g;
|
|
10
|
-
const MAX_COLLECTION_NAME_LENGTH = 128;
|
|
11
|
-
const LANCE_DB_LOCAL_SNAPSHOT_DIR = ".pm-cli-local-vectors";
|
|
12
|
-
const LANCE_DB_LOCAL_SNAPSHOT_VERSION = 1;
|
|
13
|
-
const lanceDbLocalTables = new Map();
|
|
14
|
-
function resolveStoreCollectionName(store) {
|
|
15
|
-
const candidate = toNonEmptyString(store.collection_name) ?? DEFAULT_COLLECTION;
|
|
16
|
-
return candidate
|
|
17
|
-
.replaceAll(COLLECTION_SANITIZE_PATTERN, "_")
|
|
18
|
-
.slice(0, MAX_COLLECTION_NAME_LENGTH);
|
|
19
|
-
}
|
|
20
|
-
function normalizeVector(value) {
|
|
21
|
-
if (!isFiniteNumberArray(value) || value.length === 0) {
|
|
22
|
-
throw new Error("Vector values must be a non-empty numeric array");
|
|
23
|
-
}
|
|
24
|
-
return [...value];
|
|
25
|
-
}
|
|
26
|
-
function normalizeLimit(value) {
|
|
27
|
-
if (!Number.isFinite(value) || value <= 0) {
|
|
28
|
-
throw new Error("Vector query limit must be a positive number");
|
|
29
|
-
}
|
|
30
|
-
return Math.floor(value);
|
|
31
|
-
}
|
|
32
|
-
function normalizeQdrantQueryResponse(payload) {
|
|
33
|
-
const result = payload.result;
|
|
34
|
-
if (!Array.isArray(result)) {
|
|
35
|
-
throw new TypeError("Qdrant query response must include a result array");
|
|
36
|
-
}
|
|
37
|
-
const hits = result.map((entry, index) => {
|
|
38
|
-
const idValue = entry.id;
|
|
39
|
-
const idCandidate = typeof idValue === "number" ? String(idValue) : idValue;
|
|
40
|
-
const id = toNonEmptyString(idCandidate);
|
|
41
|
-
if (!id) {
|
|
42
|
-
throw new Error(`Qdrant query response entry at index ${index} is missing a non-empty id`);
|
|
43
|
-
}
|
|
44
|
-
const score = entry.score;
|
|
45
|
-
if (typeof score !== "number" || !Number.isFinite(score)) {
|
|
46
|
-
throw new TypeError(`Qdrant query response entry at index ${index} is missing a finite numeric score`);
|
|
47
|
-
}
|
|
48
|
-
const payloadValue = entry.payload;
|
|
49
|
-
if (payloadValue !== undefined &&
|
|
50
|
-
(typeof payloadValue !== "object" ||
|
|
51
|
-
payloadValue === null ||
|
|
52
|
-
Array.isArray(payloadValue))) {
|
|
53
|
-
throw new Error(`Qdrant query response entry at index ${index} must provide payload as an object when set`);
|
|
54
|
-
}
|
|
55
|
-
return {
|
|
56
|
-
id,
|
|
57
|
-
score,
|
|
58
|
-
...(payloadValue
|
|
59
|
-
? { payload: payloadValue }
|
|
60
|
-
: {}),
|
|
61
|
-
};
|
|
62
|
-
});
|
|
63
|
-
hits.sort((left, right) => {
|
|
64
|
-
if (left.score !== right.score) {
|
|
65
|
-
return right.score - left.score;
|
|
66
|
-
}
|
|
67
|
-
return left.id.localeCompare(right.id);
|
|
68
|
-
});
|
|
69
|
-
return hits;
|
|
70
|
-
}
|
|
71
|
-
function normalizeQdrantUpsertResponse(payload) {
|
|
72
|
-
const nestedStatus = toNonEmptyString(payload.result?.status);
|
|
73
|
-
if (nestedStatus) {
|
|
74
|
-
return { status: nestedStatus };
|
|
75
|
-
}
|
|
76
|
-
const topLevelStatus = toNonEmptyString(payload.status);
|
|
77
|
-
if (topLevelStatus) {
|
|
78
|
-
return { status: topLevelStatus };
|
|
79
|
-
}
|
|
80
|
-
throw new Error("Qdrant upsert response must include status metadata");
|
|
81
|
-
}
|
|
82
|
-
async function executeRemoteVectorPlan(endpoint, plan, timeoutMs, fetcher, requestKind) {
|
|
83
|
-
return await executeSearchJsonRequest({
|
|
84
|
-
endpoint,
|
|
85
|
-
method: plan.method,
|
|
86
|
-
headers: plan.headers,
|
|
87
|
-
body: plan.body,
|
|
88
|
-
timeoutMs,
|
|
89
|
-
fetcher,
|
|
90
|
-
requestLabel: `Vector ${requestKind} request`,
|
|
91
|
-
responseLabel: `Vector ${requestKind} response`,
|
|
92
|
-
});
|
|
93
|
-
}
|
|
94
|
-
function resolveQdrantStore(settings) {
|
|
95
|
-
const url = toNonEmptyString(settings.vector_store?.qdrant?.url);
|
|
96
|
-
if (!url) {
|
|
97
|
-
return null;
|
|
98
|
-
}
|
|
99
|
-
const collectionName = toNonEmptyString(settings.vector_store?.collection_name);
|
|
100
|
-
const apiKey = toNonEmptyString(settings.vector_store?.qdrant?.api_key);
|
|
101
|
-
return {
|
|
102
|
-
name: "qdrant",
|
|
103
|
-
url,
|
|
104
|
-
...(collectionName && collectionName !== DEFAULT_COLLECTION
|
|
105
|
-
? { collection_name: collectionName }
|
|
106
|
-
: {}),
|
|
107
|
-
...(apiKey ? { api_key: apiKey } : {}),
|
|
108
|
-
};
|
|
109
|
-
}
|
|
110
|
-
/** Derive the workspace root a workspace-relative store path is anchored to. A conventional pm root (`<workspace>/.agents/pm`) maps to `<workspace>`; an explicit bare root (`--path <dir>`) anchors to the root itself. */
|
|
111
|
-
function resolveWorkspaceRootFromPmRoot(pmRoot) {
|
|
112
|
-
const resolved = resolve(pmRoot);
|
|
113
|
-
const parent = dirname(resolved);
|
|
114
|
-
if (basename(resolved) === "pm" && basename(parent) === ".agents") {
|
|
115
|
-
return dirname(parent);
|
|
116
|
-
}
|
|
117
|
-
return resolved;
|
|
118
|
-
}
|
|
119
|
-
/** Anchor a relative lancedb path (settings store workspace-relative paths such as the `.agents/pm/search/lancedb/` default) to the pm workspace root instead of the process cwd. Without this, any pm invocation from a workspace subdirectory (including detached background refresh children inheriting the parent cwd) silently creates a second vector store under that subdirectory. */
|
|
120
|
-
function anchorLanceDbStorePath(storePath, pmRoot) {
|
|
121
|
-
if (!pmRoot || isAbsolute(storePath)) {
|
|
122
|
-
return storePath;
|
|
123
|
-
}
|
|
124
|
-
return resolve(resolveWorkspaceRootFromPmRoot(pmRoot), storePath);
|
|
125
|
-
}
|
|
126
|
-
function resolveLanceDbStore(settings, pmRoot) {
|
|
127
|
-
const lancedbPath = toNonEmptyString(settings.vector_store?.lancedb?.path);
|
|
128
|
-
if (!lancedbPath) {
|
|
129
|
-
return null;
|
|
130
|
-
}
|
|
131
|
-
const collectionName = toNonEmptyString(settings.vector_store?.collection_name);
|
|
132
|
-
return {
|
|
133
|
-
name: "lancedb",
|
|
134
|
-
path: anchorLanceDbStorePath(lancedbPath, pmRoot),
|
|
135
|
-
...(collectionName && collectionName !== DEFAULT_COLLECTION
|
|
136
|
-
? { collection_name: collectionName }
|
|
137
|
-
: {}),
|
|
138
|
-
};
|
|
139
|
-
}
|
|
140
|
-
function normalizeVectorRecords(records) {
|
|
141
|
-
if (!Array.isArray(records) || records.length === 0) {
|
|
142
|
-
throw new Error("Vector upsert records must include at least one entry");
|
|
143
|
-
}
|
|
144
|
-
return records.map((record, index) => {
|
|
145
|
-
const id = toNonEmptyString(record.id);
|
|
146
|
-
if (!id) {
|
|
147
|
-
throw new Error(`Vector upsert record at index ${index} is missing a non-empty id`);
|
|
148
|
-
}
|
|
149
|
-
const vector = normalizeVector(record.vector);
|
|
150
|
-
const payload = record.payload;
|
|
151
|
-
if (payload !== undefined &&
|
|
152
|
-
(typeof payload !== "object" ||
|
|
153
|
-
payload === null ||
|
|
154
|
-
Array.isArray(payload))) {
|
|
155
|
-
throw new Error(`Vector upsert record at index ${index} must provide payload as an object when set`);
|
|
156
|
-
}
|
|
157
|
-
return {
|
|
158
|
-
id,
|
|
159
|
-
vector,
|
|
160
|
-
...(payload ? { payload } : {}),
|
|
161
|
-
};
|
|
162
|
-
});
|
|
163
|
-
}
|
|
164
|
-
function normalizeVectorDeleteIds(ids) {
|
|
165
|
-
if (!Array.isArray(ids) || ids.length === 0) {
|
|
166
|
-
throw new Error("Vector delete ids must include at least one entry");
|
|
167
|
-
}
|
|
168
|
-
const normalizedIds = ids
|
|
169
|
-
.map((id, index) => {
|
|
170
|
-
const normalized = toNonEmptyString(id);
|
|
171
|
-
if (!normalized) {
|
|
172
|
-
throw new Error(`Vector delete id at index ${index} is missing a non-empty value`);
|
|
173
|
-
}
|
|
174
|
-
return normalized;
|
|
175
|
-
})
|
|
176
|
-
.sort((left, right) => left.localeCompare(right));
|
|
177
|
-
const uniqueIds = [];
|
|
178
|
-
for (const id of normalizedIds) {
|
|
179
|
-
if (uniqueIds.at(-1) !== id) {
|
|
180
|
-
uniqueIds.push(id);
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
return uniqueIds;
|
|
184
|
-
}
|
|
185
|
-
function resolveQdrantDeleteTarget(upsertTarget) {
|
|
186
|
-
return upsertTarget.replace(/\/points\?wait=true$/, "/points/delete?wait=true");
|
|
187
|
-
}
|
|
188
|
-
function resolveQdrantCollectionTarget(upsertTarget) {
|
|
189
|
-
return upsertTarget.replace(/\/points\?wait=true$/, "");
|
|
190
|
-
}
|
|
191
|
-
function buildQdrantJsonHeaders(store) {
|
|
192
|
-
return {
|
|
193
|
-
"content-type": "application/json",
|
|
194
|
-
...(store.api_key ? { "api-key": store.api_key } : {}),
|
|
195
|
-
};
|
|
196
|
-
}
|
|
197
|
-
function getLanceDbLocalTableKey(storePath, table) {
|
|
198
|
-
return getLanceDbSnapshotPath(storePath, table);
|
|
199
|
-
}
|
|
200
|
-
function getLanceDbSnapshotPath(storePath, table) {
|
|
201
|
-
return join(resolve(storePath), LANCE_DB_LOCAL_SNAPSHOT_DIR, `${table}.json`);
|
|
202
|
-
}
|
|
203
|
-
function normalizeSnapshotRecord(entry, index, snapshotPath) {
|
|
204
|
-
const id = toNonEmptyString(entry.id);
|
|
205
|
-
if (!id) {
|
|
206
|
-
throw new Error(`LanceDB local snapshot '${snapshotPath}' record at index ${index} is missing a non-empty id`);
|
|
207
|
-
}
|
|
208
|
-
const vector = normalizeVector(entry.vector);
|
|
209
|
-
const payload = entry.payload;
|
|
210
|
-
if (payload !== undefined &&
|
|
211
|
-
(typeof payload !== "object" || payload === null || Array.isArray(payload))) {
|
|
212
|
-
throw new Error(`LanceDB local snapshot '${snapshotPath}' record '${id}' must provide payload as an object when set`);
|
|
213
|
-
}
|
|
214
|
-
return {
|
|
215
|
-
id,
|
|
216
|
-
vector,
|
|
217
|
-
...(payload ? { payload: payload } : {}),
|
|
218
|
-
};
|
|
219
|
-
}
|
|
220
|
-
function parseLanceDbSnapshot(snapshotPath, expectedTable, raw) {
|
|
221
|
-
let parsed;
|
|
222
|
-
try {
|
|
223
|
-
parsed = JSON.parse(raw);
|
|
224
|
-
}
|
|
225
|
-
catch (error) {
|
|
226
|
-
throw new Error(`LanceDB local snapshot at '${snapshotPath}' is not valid JSON: ${toErrorMessage(error)}`);
|
|
227
|
-
}
|
|
228
|
-
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
229
|
-
throw new Error(`LanceDB local snapshot at '${snapshotPath}' must be a JSON object`);
|
|
230
|
-
}
|
|
231
|
-
const version = parsed.version;
|
|
232
|
-
if (version !== LANCE_DB_LOCAL_SNAPSHOT_VERSION) {
|
|
233
|
-
throw new Error(`LanceDB local snapshot at '${snapshotPath}' must include version=${LANCE_DB_LOCAL_SNAPSHOT_VERSION}`);
|
|
234
|
-
}
|
|
235
|
-
const table = toNonEmptyString(parsed.table);
|
|
236
|
-
if (!table) {
|
|
237
|
-
throw new Error(`LanceDB local snapshot at '${snapshotPath}' must include a non-empty table value`);
|
|
238
|
-
}
|
|
239
|
-
if (table !== expectedTable) {
|
|
240
|
-
throw new Error(`LanceDB local snapshot at '${snapshotPath}' table mismatch: expected '${expectedTable}', received '${table}'`);
|
|
241
|
-
}
|
|
242
|
-
const recordsValue = parsed.records;
|
|
243
|
-
if (!Array.isArray(recordsValue)) {
|
|
244
|
-
throw new TypeError(`LanceDB local snapshot at '${snapshotPath}' must include a records array`);
|
|
245
|
-
}
|
|
246
|
-
const tableRecords = new Map();
|
|
247
|
-
for (let index = 0; index < recordsValue.length; index += 1) {
|
|
248
|
-
const record = normalizeSnapshotRecord(recordsValue[index], index, snapshotPath);
|
|
249
|
-
tableRecords.set(record.id, record);
|
|
250
|
-
}
|
|
251
|
-
return tableRecords;
|
|
252
|
-
}
|
|
253
|
-
async function readLanceDbSnapshotStats(snapshotPath) {
|
|
254
|
-
try {
|
|
255
|
-
const stats = await stat(snapshotPath);
|
|
256
|
-
return { mtimeMs: stats.mtimeMs, size: stats.size };
|
|
257
|
-
}
|
|
258
|
-
catch (error) {
|
|
259
|
-
if (!isFileMissingError(error)) {
|
|
260
|
-
throw error;
|
|
261
|
-
}
|
|
262
|
-
return null;
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
function resolveMissingLanceDbSnapshotCache(key, cached) {
|
|
266
|
-
if (!cached) {
|
|
267
|
-
return null;
|
|
268
|
-
}
|
|
269
|
-
if (cached.mtimeMs === null &&
|
|
270
|
-
cached.size === null &&
|
|
271
|
-
cached.records.size === 0) {
|
|
272
|
-
return cached.records;
|
|
273
|
-
}
|
|
274
|
-
const loaded = new Map();
|
|
275
|
-
lanceDbLocalTables.set(key, { records: loaded, mtimeMs: null, size: null });
|
|
276
|
-
return loaded;
|
|
277
|
-
}
|
|
278
|
-
function cachedLanceDbSnapshotMatches(cached, snapshotStats) {
|
|
279
|
-
return (cached !== undefined &&
|
|
280
|
-
snapshotStats !== null &&
|
|
281
|
-
cached.mtimeMs === snapshotStats.mtimeMs &&
|
|
282
|
-
cached.size === snapshotStats.size);
|
|
283
|
-
}
|
|
284
|
-
async function loadLanceDbLocalTable(storePath, table) {
|
|
285
|
-
const key = getLanceDbLocalTableKey(storePath, table);
|
|
286
|
-
const snapshotPath = getLanceDbSnapshotPath(storePath, table);
|
|
287
|
-
const snapshotStats = await readLanceDbSnapshotStats(snapshotPath);
|
|
288
|
-
const cached = lanceDbLocalTables.get(key);
|
|
289
|
-
if (!snapshotStats) {
|
|
290
|
-
const resolved = resolveMissingLanceDbSnapshotCache(key, cached);
|
|
291
|
-
if (resolved) {
|
|
292
|
-
return resolved;
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
if (cachedLanceDbSnapshotMatches(cached, snapshotStats)) {
|
|
296
|
-
return cached.records;
|
|
297
|
-
}
|
|
298
|
-
let loaded = new Map();
|
|
299
|
-
try {
|
|
300
|
-
const raw = await readFile(snapshotPath, "utf8");
|
|
301
|
-
loaded = parseLanceDbSnapshot(snapshotPath, table, raw);
|
|
302
|
-
}
|
|
303
|
-
catch (error) {
|
|
304
|
-
if (!isFileMissingError(error)) {
|
|
305
|
-
throw error;
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
lanceDbLocalTables.set(key, {
|
|
309
|
-
records: loaded,
|
|
310
|
-
mtimeMs: snapshotStats?.mtimeMs ?? null,
|
|
311
|
-
size: snapshotStats?.size ?? null,
|
|
312
|
-
});
|
|
313
|
-
return loaded;
|
|
314
|
-
}
|
|
315
|
-
function buildSnapshotRecords(table) {
|
|
316
|
-
const records = [...table.values()];
|
|
317
|
-
records.sort((left, right) => left.id.localeCompare(right.id));
|
|
318
|
-
return records.map((record) => ({
|
|
319
|
-
id: record.id,
|
|
320
|
-
vector: [...record.vector],
|
|
321
|
-
...(record.payload ? { payload: record.payload } : {}),
|
|
322
|
-
}));
|
|
323
|
-
}
|
|
324
|
-
async function removeSnapshotFile(snapshotPath) {
|
|
325
|
-
try {
|
|
326
|
-
await unlink(snapshotPath);
|
|
327
|
-
}
|
|
328
|
-
catch (error) {
|
|
329
|
-
if (!isFileMissingError(error)) {
|
|
330
|
-
throw new Error(`LanceDB local snapshot delete failed at '${snapshotPath}': ${toErrorMessage(error)}`);
|
|
331
|
-
}
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
|
-
async function persistLanceDbLocalTable(storePath, tableName, table) {
|
|
335
|
-
const snapshotPath = getLanceDbSnapshotPath(storePath, tableName);
|
|
336
|
-
if (table.size === 0) {
|
|
337
|
-
await removeSnapshotFile(snapshotPath);
|
|
338
|
-
return;
|
|
339
|
-
}
|
|
340
|
-
const snapshotDir = dirname(snapshotPath);
|
|
341
|
-
try {
|
|
342
|
-
await mkdir(snapshotDir, { recursive: true });
|
|
343
|
-
}
|
|
344
|
-
catch (error) {
|
|
345
|
-
throw new Error(`LanceDB local snapshot directory create failed at '${snapshotDir}': ${toErrorMessage(error)}`);
|
|
346
|
-
}
|
|
347
|
-
// Serialize compactly: the snapshot is an internal, gitignored cache re-read via
|
|
348
|
-
// JSON.parse (whitespace-agnostic). Pretty-printing put every embedding float on its
|
|
349
|
-
// own indented line, roughly doubling file size and parse/serialize cost — a real
|
|
350
|
-
// per-mutation latency tax on large indexes. Compact JSON keeps it instant.
|
|
351
|
-
const serialized = `${JSON.stringify({
|
|
352
|
-
version: LANCE_DB_LOCAL_SNAPSHOT_VERSION,
|
|
353
|
-
table: tableName,
|
|
354
|
-
records: buildSnapshotRecords(table),
|
|
355
|
-
})}\n`;
|
|
356
|
-
try {
|
|
357
|
-
await writeFileAtomic(snapshotPath, serialized);
|
|
358
|
-
}
|
|
359
|
-
catch (error) {
|
|
360
|
-
throw new Error(`LanceDB local snapshot write failed at '${snapshotPath}': ${toErrorMessage(error)}`);
|
|
361
|
-
}
|
|
362
|
-
}
|
|
363
|
-
async function resetLanceDbLocalTable(storePath, tableName) {
|
|
364
|
-
const key = getLanceDbLocalTableKey(storePath, tableName);
|
|
365
|
-
const snapshotPath = getLanceDbSnapshotPath(storePath, tableName);
|
|
366
|
-
await removeSnapshotFile(snapshotPath);
|
|
367
|
-
lanceDbLocalTables.delete(key);
|
|
368
|
-
}
|
|
369
|
-
function l2Norm(vector) {
|
|
370
|
-
let sumSq = 0;
|
|
371
|
-
for (let index = 0; index < vector.length; index += 1) {
|
|
372
|
-
sumSq += vector[index] * vector[index];
|
|
373
|
-
}
|
|
374
|
-
return Math.sqrt(sumSq);
|
|
375
|
-
}
|
|
376
|
-
function cosineSimilarity(left, right) {
|
|
377
|
-
let dotProd = 0;
|
|
378
|
-
for (let index = 0; index < left.length; index += 1) {
|
|
379
|
-
dotProd += left[index] * right[index];
|
|
380
|
-
}
|
|
381
|
-
const leftNorm = l2Norm(left);
|
|
382
|
-
const rightNorm = l2Norm(right);
|
|
383
|
-
if (leftNorm === 0 || rightNorm === 0) {
|
|
384
|
-
return 0;
|
|
385
|
-
}
|
|
386
|
-
return dotProd / (leftNorm * rightNorm);
|
|
387
|
-
}
|
|
388
|
-
/** Implements resolve vector stores for the public runtime surface of this module. */
|
|
389
|
-
export function resolveVectorStores(settings, pmRoot) {
|
|
390
|
-
const qdrant = resolveQdrantStore(settings);
|
|
391
|
-
const lancedb = resolveLanceDbStore(settings, pmRoot);
|
|
392
|
-
const available = [qdrant, lancedb].filter((entry) => entry !== null);
|
|
393
|
-
// Honor `settings.vector_store.adapter` when set: if both built-in stores
|
|
394
|
-
// are configured, the preferred adapter wins; otherwise fall back to the
|
|
395
|
-
// first available entry (preserves the previous tie-break: qdrant > lancedb).
|
|
396
|
-
// Match case-insensitively so "Qdrant" / "LanceDB" / "lancedb" all work.
|
|
397
|
-
const preferredName = toNonEmptyString(settings.vector_store
|
|
398
|
-
?.adapter);
|
|
399
|
-
const preferredKey = preferredName ? preferredName.toLowerCase() : null;
|
|
400
|
-
const preferred = preferredKey
|
|
401
|
-
? available.find((entry) => entry.name === preferredKey)
|
|
402
|
-
: undefined;
|
|
403
|
-
return {
|
|
404
|
-
active: preferred ?? available[0] ?? null,
|
|
405
|
-
available,
|
|
406
|
-
};
|
|
407
|
-
}
|
|
408
|
-
/** Implements resolve vector store request target for the public runtime surface of this module. */
|
|
409
|
-
export function resolveVectorStoreRequestTarget(store) {
|
|
410
|
-
const collectionName = resolveStoreCollectionName(store);
|
|
411
|
-
if (store.name === "qdrant") {
|
|
412
|
-
const baseUrl = trimTrailingSlashes(store.url);
|
|
413
|
-
const encodedCollection = encodeURIComponent(collectionName);
|
|
414
|
-
return {
|
|
415
|
-
store: "qdrant",
|
|
416
|
-
query_target: `${baseUrl}/collections/${encodedCollection}/points/search`,
|
|
417
|
-
upsert_target: `${baseUrl}/collections/${encodedCollection}/points?wait=true`,
|
|
418
|
-
};
|
|
419
|
-
}
|
|
420
|
-
const encodedPath = encodeURIComponent(store.path);
|
|
421
|
-
const encodedCollection = encodeURIComponent(collectionName);
|
|
422
|
-
return {
|
|
423
|
-
store: "lancedb",
|
|
424
|
-
query_target: `lancedb://${encodedPath}#${encodedCollection}`,
|
|
425
|
-
upsert_target: `lancedb://${encodedPath}#${encodedCollection}`,
|
|
426
|
-
};
|
|
427
|
-
}
|
|
428
|
-
/** Implements build vector query plan for the public runtime surface of this module. */
|
|
429
|
-
export function buildVectorQueryPlan(store, vector, limit) {
|
|
430
|
-
const target = resolveVectorStoreRequestTarget(store);
|
|
431
|
-
const normalizedVector = normalizeVector(vector);
|
|
432
|
-
const normalizedLimit = normalizeLimit(limit);
|
|
433
|
-
if (store.name === "qdrant") {
|
|
434
|
-
return {
|
|
435
|
-
target,
|
|
436
|
-
method: "POST",
|
|
437
|
-
headers: buildQdrantJsonHeaders(store),
|
|
438
|
-
body: {
|
|
439
|
-
vector: normalizedVector,
|
|
440
|
-
limit: normalizedLimit,
|
|
441
|
-
with_payload: true,
|
|
442
|
-
},
|
|
443
|
-
};
|
|
444
|
-
}
|
|
445
|
-
return {
|
|
446
|
-
target,
|
|
447
|
-
method: "LOCAL",
|
|
448
|
-
headers: {},
|
|
449
|
-
body: {
|
|
450
|
-
table: resolveStoreCollectionName(store),
|
|
451
|
-
vector: normalizedVector,
|
|
452
|
-
limit: normalizedLimit,
|
|
453
|
-
},
|
|
454
|
-
};
|
|
455
|
-
}
|
|
456
|
-
/** Implements build vector upsert plan for the public runtime surface of this module. */
|
|
457
|
-
export function buildVectorUpsertPlan(store, records) {
|
|
458
|
-
const target = resolveVectorStoreRequestTarget(store);
|
|
459
|
-
const normalizedRecords = normalizeVectorRecords(records);
|
|
460
|
-
if (store.name === "qdrant") {
|
|
461
|
-
return {
|
|
462
|
-
target,
|
|
463
|
-
method: "POST",
|
|
464
|
-
headers: buildQdrantJsonHeaders(store),
|
|
465
|
-
body: {
|
|
466
|
-
points: normalizedRecords,
|
|
467
|
-
},
|
|
468
|
-
};
|
|
469
|
-
}
|
|
470
|
-
return {
|
|
471
|
-
target,
|
|
472
|
-
method: "LOCAL",
|
|
473
|
-
headers: {},
|
|
474
|
-
body: {
|
|
475
|
-
table: resolveStoreCollectionName(store),
|
|
476
|
-
records: normalizedRecords,
|
|
477
|
-
},
|
|
478
|
-
};
|
|
479
|
-
}
|
|
480
|
-
/** Implements build vector delete plan for the public runtime surface of this module. */
|
|
481
|
-
export function buildVectorDeletePlan(store, ids) {
|
|
482
|
-
const target = resolveVectorStoreRequestTarget(store);
|
|
483
|
-
const normalizedIds = normalizeVectorDeleteIds(ids);
|
|
484
|
-
if (store.name === "qdrant") {
|
|
485
|
-
return {
|
|
486
|
-
target,
|
|
487
|
-
method: "POST",
|
|
488
|
-
headers: buildQdrantJsonHeaders(store),
|
|
489
|
-
body: {
|
|
490
|
-
points: normalizedIds,
|
|
491
|
-
},
|
|
492
|
-
};
|
|
493
|
-
}
|
|
494
|
-
return {
|
|
495
|
-
target,
|
|
496
|
-
method: "LOCAL",
|
|
497
|
-
headers: {},
|
|
498
|
-
body: {
|
|
499
|
-
table: resolveStoreCollectionName(store),
|
|
500
|
-
ids: normalizedIds,
|
|
501
|
-
},
|
|
502
|
-
};
|
|
503
|
-
}
|
|
504
|
-
/** Implements execute vector query for the public runtime surface of this module. */
|
|
505
|
-
export async function executeVectorQuery(store, vector, limit, options = {}) {
|
|
506
|
-
const plan = buildVectorQueryPlan(store, vector, limit);
|
|
507
|
-
if (plan.method === "LOCAL") {
|
|
508
|
-
const lanceDbStore = store;
|
|
509
|
-
const queryBody = plan.body;
|
|
510
|
-
const table = await loadLanceDbLocalTable(lanceDbStore.path, queryBody.table);
|
|
511
|
-
if (table.size === 0) {
|
|
512
|
-
return [];
|
|
513
|
-
}
|
|
514
|
-
const queryVector = normalizeVector(queryBody.vector);
|
|
515
|
-
const queryLimit = normalizeLimit(queryBody.limit);
|
|
516
|
-
const hits = [];
|
|
517
|
-
let dimensionMismatchCount = 0;
|
|
518
|
-
for (const record of table.values()) {
|
|
519
|
-
if (record.vector.length !== queryVector.length) {
|
|
520
|
-
dimensionMismatchCount++;
|
|
521
|
-
continue;
|
|
522
|
-
}
|
|
523
|
-
hits.push({
|
|
524
|
-
id: record.id,
|
|
525
|
-
score: cosineSimilarity(queryVector, record.vector),
|
|
526
|
-
...(record.payload ? { payload: record.payload } : {}),
|
|
527
|
-
});
|
|
528
|
-
}
|
|
529
|
-
if (dimensionMismatchCount > 0 && options.warnings) {
|
|
530
|
-
options.warnings.push(`vector_dimension_mismatch:${dimensionMismatchCount} records skipped (expected ${queryVector.length} dimensions)`);
|
|
531
|
-
}
|
|
532
|
-
hits.sort((left, right) => {
|
|
533
|
-
if (left.score !== right.score) {
|
|
534
|
-
return right.score - left.score;
|
|
535
|
-
}
|
|
536
|
-
return left.id.localeCompare(right.id);
|
|
537
|
-
});
|
|
538
|
-
return hits.slice(0, queryLimit);
|
|
539
|
-
}
|
|
540
|
-
const timeoutMs = normalizeSearchHttpTimeoutMs(options.timeout_ms, "Vector request");
|
|
541
|
-
const fetcher = resolveSearchHttpFetcher(options.fetcher, "Vector request");
|
|
542
|
-
const payload = await executeRemoteVectorPlan(plan.target.query_target, {
|
|
543
|
-
method: "POST",
|
|
544
|
-
headers: plan.headers,
|
|
545
|
-
body: plan.body,
|
|
546
|
-
}, timeoutMs, fetcher, "query");
|
|
547
|
-
return normalizeQdrantQueryResponse(payload);
|
|
548
|
-
}
|
|
549
|
-
/** Implements execute vector upsert for the public runtime surface of this module. */
|
|
550
|
-
export async function executeVectorUpsert(store, records, options = {}) {
|
|
551
|
-
const plan = buildVectorUpsertPlan(store, records);
|
|
552
|
-
if (plan.method === "LOCAL") {
|
|
553
|
-
const lanceDbStore = store;
|
|
554
|
-
const upsertBody = plan.body;
|
|
555
|
-
const key = getLanceDbLocalTableKey(lanceDbStore.path, upsertBody.table);
|
|
556
|
-
const table = await loadLanceDbLocalTable(lanceDbStore.path, upsertBody.table);
|
|
557
|
-
for (const record of upsertBody.records) {
|
|
558
|
-
table.set(record.id, record);
|
|
559
|
-
}
|
|
560
|
-
await persistLanceDbLocalTable(lanceDbStore.path, upsertBody.table, table);
|
|
561
|
-
const snapshotPath = getLanceDbSnapshotPath(lanceDbStore.path, upsertBody.table);
|
|
562
|
-
const snapshotStats = await stat(snapshotPath);
|
|
563
|
-
lanceDbLocalTables.set(key, {
|
|
564
|
-
records: table,
|
|
565
|
-
mtimeMs: snapshotStats.mtimeMs,
|
|
566
|
-
size: snapshotStats.size,
|
|
567
|
-
});
|
|
568
|
-
return { status: "ok" };
|
|
569
|
-
}
|
|
570
|
-
const timeoutMs = normalizeSearchHttpTimeoutMs(options.timeout_ms, "Vector request");
|
|
571
|
-
const fetcher = resolveSearchHttpFetcher(options.fetcher, "Vector request");
|
|
572
|
-
const payload = await executeRemoteVectorPlan(plan.target.upsert_target, {
|
|
573
|
-
method: "POST",
|
|
574
|
-
headers: plan.headers,
|
|
575
|
-
body: plan.body,
|
|
576
|
-
}, timeoutMs, fetcher, "upsert");
|
|
577
|
-
return normalizeQdrantUpsertResponse(payload);
|
|
578
|
-
}
|
|
579
|
-
/** Implements execute vector delete for the public runtime surface of this module. */
|
|
580
|
-
export async function executeVectorDelete(store, ids, options = {}) {
|
|
581
|
-
const plan = buildVectorDeletePlan(store, ids);
|
|
582
|
-
if (plan.method === "LOCAL") {
|
|
583
|
-
const lanceDbStore = store;
|
|
584
|
-
const deleteBody = plan.body;
|
|
585
|
-
const key = getLanceDbLocalTableKey(lanceDbStore.path, deleteBody.table);
|
|
586
|
-
const table = await loadLanceDbLocalTable(lanceDbStore.path, deleteBody.table);
|
|
587
|
-
if (table.size === 0) {
|
|
588
|
-
return { status: "ok" };
|
|
589
|
-
}
|
|
590
|
-
for (const id of deleteBody.ids) {
|
|
591
|
-
table.delete(id);
|
|
592
|
-
}
|
|
593
|
-
await persistLanceDbLocalTable(lanceDbStore.path, deleteBody.table, table);
|
|
594
|
-
if (table.size === 0) {
|
|
595
|
-
lanceDbLocalTables.delete(key);
|
|
596
|
-
}
|
|
597
|
-
else {
|
|
598
|
-
const snapshotPath = getLanceDbSnapshotPath(lanceDbStore.path, deleteBody.table);
|
|
599
|
-
const snapshotStats = await stat(snapshotPath);
|
|
600
|
-
lanceDbLocalTables.set(key, {
|
|
601
|
-
records: table,
|
|
602
|
-
mtimeMs: snapshotStats.mtimeMs,
|
|
603
|
-
size: snapshotStats.size,
|
|
604
|
-
});
|
|
605
|
-
}
|
|
606
|
-
return { status: "ok" };
|
|
607
|
-
}
|
|
608
|
-
const timeoutMs = normalizeSearchHttpTimeoutMs(options.timeout_ms, "Vector request");
|
|
609
|
-
const fetcher = resolveSearchHttpFetcher(options.fetcher, "Vector request");
|
|
610
|
-
const payload = await executeRemoteVectorPlan(resolveQdrantDeleteTarget(plan.target.upsert_target), {
|
|
611
|
-
method: "POST",
|
|
612
|
-
headers: plan.headers,
|
|
613
|
-
body: plan.body,
|
|
614
|
-
}, timeoutMs, fetcher, "delete");
|
|
615
|
-
return normalizeQdrantUpsertResponse(payload);
|
|
616
|
-
}
|
|
617
|
-
/** Implements execute vector reset for the public runtime surface of this module. */
|
|
618
|
-
export async function executeVectorReset(store, knownIds = [], options = {}, vectorDimension) {
|
|
619
|
-
if (store.name === "lancedb") {
|
|
620
|
-
await resetLanceDbLocalTable(store.path, resolveStoreCollectionName(store));
|
|
621
|
-
return { status: "ok" };
|
|
622
|
-
}
|
|
623
|
-
if (vectorDimension !== undefined) {
|
|
624
|
-
if (!Number.isInteger(vectorDimension) || vectorDimension <= 0) {
|
|
625
|
-
throw new Error("Vector reset dimension must be a positive integer when provided");
|
|
626
|
-
}
|
|
627
|
-
const target = resolveVectorStoreRequestTarget(store);
|
|
628
|
-
const collectionTarget = resolveQdrantCollectionTarget(target.upsert_target);
|
|
629
|
-
const timeoutMs = normalizeSearchHttpTimeoutMs(options.timeout_ms, "Vector request");
|
|
630
|
-
const fetcher = resolveSearchHttpFetcher(options.fetcher, "Vector request");
|
|
631
|
-
const headers = buildQdrantJsonHeaders(store);
|
|
632
|
-
try {
|
|
633
|
-
await executeRemoteVectorPlan(collectionTarget, {
|
|
634
|
-
method: "DELETE",
|
|
635
|
-
headers,
|
|
636
|
-
body: {},
|
|
637
|
-
}, timeoutMs, fetcher, "delete");
|
|
638
|
-
}
|
|
639
|
-
catch (error) {
|
|
640
|
-
if (!toErrorMessage(error).includes("failed with status 404")) {
|
|
641
|
-
throw error;
|
|
642
|
-
}
|
|
643
|
-
}
|
|
644
|
-
const payload = await executeRemoteVectorPlan(collectionTarget, {
|
|
645
|
-
method: "PUT",
|
|
646
|
-
headers,
|
|
647
|
-
body: {
|
|
648
|
-
vectors: {
|
|
649
|
-
size: vectorDimension,
|
|
650
|
-
distance: "Cosine",
|
|
651
|
-
},
|
|
652
|
-
},
|
|
653
|
-
}, timeoutMs, fetcher, "upsert");
|
|
654
|
-
return normalizeQdrantUpsertResponse(payload);
|
|
655
|
-
}
|
|
656
|
-
const idsToDelete = knownIds
|
|
657
|
-
.map((id) => id.trim())
|
|
658
|
-
.filter((id) => id.length > 0);
|
|
659
|
-
if (idsToDelete.length === 0) {
|
|
660
|
-
return { status: "ok" };
|
|
661
|
-
}
|
|
662
|
-
return await executeVectorDelete(store, idsToDelete, options);
|
|
663
|
-
}
|
|
1
|
+
!(function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="887ac66e-679f-5a07-a6a2-8a19a4007198")}catch(e2){}})();import{mkdir,readFile,stat,unlink}from"node:fs/promises";import{basename,dirname,isAbsolute,join,resolve}from"node:path";import{executeSearchJsonRequest,normalizeSearchHttpTimeoutMs,resolveSearchHttpFetcher}from"./http-client.js";import{isFiniteNumberArray,toErrorMessage,toNonEmptyString,trimTrailingSlashes}from"../shared/primitives.js";import{isFileMissingError,writeFileAtomic}from"../fs/fs-utils.js";const DEFAULT_COLLECTION="pm_items";const COLLECTION_SANITIZE_PATTERN=/[^a-zA-Z0-9_-]/g;const MAX_COLLECTION_NAME_LENGTH=128;const LANCE_DB_LOCAL_SNAPSHOT_DIR=".pm-cli-local-vectors";const LANCE_DB_LOCAL_SNAPSHOT_VERSION=1;const lanceDbLocalTables=new Map;function resolveStoreCollectionName(store){const candidate=toNonEmptyString(store.collection_name)??DEFAULT_COLLECTION;return candidate.replaceAll(COLLECTION_SANITIZE_PATTERN,"_").slice(0,MAX_COLLECTION_NAME_LENGTH)}function normalizeVector(value){if(!isFiniteNumberArray(value)||value.length===0){throw new Error("Vector values must be a non-empty numeric array")}return[...value]}function normalizeLimit(value){if(!Number.isFinite(value)||value<=0){throw new Error("Vector query limit must be a positive number")}return Math.floor(value)}function normalizeQdrantQueryResponse(payload){const result=payload.result;if(!Array.isArray(result)){throw new TypeError("Qdrant query response must include a result array")}const hits=result.map((entry,index)=>{const idValue=entry.id;const idCandidate=typeof idValue==="number"?String(idValue):idValue;const id=toNonEmptyString(idCandidate);if(!id){throw new Error(`Qdrant query response entry at index ${index} is missing a non-empty id`)}const score=entry.score;if(typeof score!=="number"||!Number.isFinite(score)){throw new TypeError(`Qdrant query response entry at index ${index} is missing a finite numeric score`)}const payloadValue=entry.payload;if(payloadValue!==void 0&&(typeof payloadValue!=="object"||payloadValue===null||Array.isArray(payloadValue))){throw new Error(`Qdrant query response entry at index ${index} must provide payload as an object when set`)}return{id,score,...payloadValue?{payload:payloadValue}:{}}});hits.sort((left,right)=>{if(left.score!==right.score){return right.score-left.score}return left.id.localeCompare(right.id)});return hits}function normalizeQdrantUpsertResponse(payload){const nestedStatus=toNonEmptyString(payload.result?.status);if(nestedStatus){return{status:nestedStatus}}const topLevelStatus=toNonEmptyString(payload.status);if(topLevelStatus){return{status:topLevelStatus}}throw new Error("Qdrant upsert response must include status metadata")}async function executeRemoteVectorPlan(endpoint,plan,timeoutMs,fetcher,requestKind){return await executeSearchJsonRequest({endpoint,method:plan.method,headers:plan.headers,body:plan.body,timeoutMs,fetcher,requestLabel:`Vector ${requestKind} request`,responseLabel:`Vector ${requestKind} response`})}function resolveQdrantStore(settings){const url=toNonEmptyString(settings.vector_store?.qdrant?.url);if(!url){return null}const collectionName=toNonEmptyString(settings.vector_store?.collection_name);const apiKey=toNonEmptyString(settings.vector_store?.qdrant?.api_key);return{name:"qdrant",url,...collectionName&&collectionName!==DEFAULT_COLLECTION?{collection_name:collectionName}:{},...apiKey?{api_key:apiKey}:{}}}function resolveWorkspaceRootFromPmRoot(pmRoot){const resolved=resolve(pmRoot);const parent=dirname(resolved);if(basename(resolved)==="pm"&&basename(parent)===".agents"){return dirname(parent)}return resolved}function anchorLanceDbStorePath(storePath,pmRoot){if(!pmRoot||isAbsolute(storePath)){return storePath}return resolve(resolveWorkspaceRootFromPmRoot(pmRoot),storePath)}function resolveLanceDbStore(settings,pmRoot){const lancedbPath=toNonEmptyString(settings.vector_store?.lancedb?.path);if(!lancedbPath){return null}const collectionName=toNonEmptyString(settings.vector_store?.collection_name);return{name:"lancedb",path:anchorLanceDbStorePath(lancedbPath,pmRoot),...collectionName&&collectionName!==DEFAULT_COLLECTION?{collection_name:collectionName}:{}}}function normalizeVectorRecords(records){if(!Array.isArray(records)||records.length===0){throw new Error("Vector upsert records must include at least one entry")}return records.map((record,index)=>{const id=toNonEmptyString(record.id);if(!id){throw new Error(`Vector upsert record at index ${index} is missing a non-empty id`)}const vector=normalizeVector(record.vector);const payload=record.payload;if(payload!==void 0&&(typeof payload!=="object"||payload===null||Array.isArray(payload))){throw new Error(`Vector upsert record at index ${index} must provide payload as an object when set`)}return{id,vector,...payload?{payload}:{}}})}function normalizeVectorDeleteIds(ids){if(!Array.isArray(ids)||ids.length===0){throw new Error("Vector delete ids must include at least one entry")}const normalizedIds=ids.map((id,index)=>{const normalized=toNonEmptyString(id);if(!normalized){throw new Error(`Vector delete id at index ${index} is missing a non-empty value`)}return normalized}).sort((left,right)=>left.localeCompare(right));const uniqueIds=[];for(const id of normalizedIds){if(uniqueIds.at(-1)!==id){uniqueIds.push(id)}}return uniqueIds}function resolveQdrantDeleteTarget(upsertTarget){return upsertTarget.replace(/\/points\?wait=true$/,"/points/delete?wait=true")}function resolveQdrantCollectionTarget(upsertTarget){return upsertTarget.replace(/\/points\?wait=true$/,"")}function buildQdrantJsonHeaders(store){return{"content-type":"application/json",...store.api_key?{"api-key":store.api_key}:{}}}function getLanceDbLocalTableKey(storePath,table){return getLanceDbSnapshotPath(storePath,table)}function getLanceDbSnapshotPath(storePath,table){return join(resolve(storePath),LANCE_DB_LOCAL_SNAPSHOT_DIR,`${table}.json`)}function normalizeSnapshotRecord(entry,index,snapshotPath){const id=toNonEmptyString(entry.id);if(!id){throw new Error(`LanceDB local snapshot '${snapshotPath}' record at index ${index} is missing a non-empty id`)}const vector=normalizeVector(entry.vector);const payload=entry.payload;if(payload!==void 0&&(typeof payload!=="object"||payload===null||Array.isArray(payload))){throw new Error(`LanceDB local snapshot '${snapshotPath}' record '${id}' must provide payload as an object when set`)}return{id,vector,...payload?{payload}:{}}}function parseLanceDbSnapshot(snapshotPath,expectedTable,raw){let parsed;try{parsed=JSON.parse(raw)}catch(error){throw new Error(`LanceDB local snapshot at '${snapshotPath}' is not valid JSON: ${toErrorMessage(error)}`)}if(typeof parsed!=="object"||parsed===null||Array.isArray(parsed)){throw new Error(`LanceDB local snapshot at '${snapshotPath}' must be a JSON object`)}const version=parsed.version;if(version!==LANCE_DB_LOCAL_SNAPSHOT_VERSION){throw new Error(`LanceDB local snapshot at '${snapshotPath}' must include version=${LANCE_DB_LOCAL_SNAPSHOT_VERSION}`)}const table=toNonEmptyString(parsed.table);if(!table){throw new Error(`LanceDB local snapshot at '${snapshotPath}' must include a non-empty table value`)}if(table!==expectedTable){throw new Error(`LanceDB local snapshot at '${snapshotPath}' table mismatch: expected '${expectedTable}', received '${table}'`)}const recordsValue=parsed.records;if(!Array.isArray(recordsValue)){throw new TypeError(`LanceDB local snapshot at '${snapshotPath}' must include a records array`)}const tableRecords=new Map;for(let index=0;index<recordsValue.length;index+=1){const record=normalizeSnapshotRecord(recordsValue[index],index,snapshotPath);tableRecords.set(record.id,record)}return tableRecords}async function readLanceDbSnapshotStats(snapshotPath){try{const stats=await stat(snapshotPath);return{mtimeMs:stats.mtimeMs,size:stats.size}}catch(error){if(!isFileMissingError(error)){throw error}return null}}function resolveMissingLanceDbSnapshotCache(key,cached){if(!cached){return null}if(cached.mtimeMs===null&&cached.size===null&&cached.records.size===0){return cached.records}const loaded=new Map;lanceDbLocalTables.set(key,{records:loaded,mtimeMs:null,size:null});return loaded}function cachedLanceDbSnapshotMatches(cached,snapshotStats){return cached!==void 0&&snapshotStats!==null&&cached.mtimeMs===snapshotStats.mtimeMs&&cached.size===snapshotStats.size}async function loadLanceDbLocalTable(storePath,table){const key=getLanceDbLocalTableKey(storePath,table);const snapshotPath=getLanceDbSnapshotPath(storePath,table);const snapshotStats=await readLanceDbSnapshotStats(snapshotPath);const cached=lanceDbLocalTables.get(key);if(!snapshotStats){const resolved=resolveMissingLanceDbSnapshotCache(key,cached);if(resolved){return resolved}}if(cachedLanceDbSnapshotMatches(cached,snapshotStats)){return cached.records}let loaded=new Map;try{const raw=await readFile(snapshotPath,"utf8");loaded=parseLanceDbSnapshot(snapshotPath,table,raw)}catch(error){if(!isFileMissingError(error)){throw error}}lanceDbLocalTables.set(key,{records:loaded,mtimeMs:snapshotStats?.mtimeMs??null,size:snapshotStats?.size??null});return loaded}function buildSnapshotRecords(table){const records=[...table.values()];records.sort((left,right)=>left.id.localeCompare(right.id));return records.map(record=>({id:record.id,vector:[...record.vector],...record.payload?{payload:record.payload}:{}}))}async function removeSnapshotFile(snapshotPath){try{await unlink(snapshotPath)}catch(error){if(!isFileMissingError(error)){throw new Error(`LanceDB local snapshot delete failed at '${snapshotPath}': ${toErrorMessage(error)}`)}}}async function persistLanceDbLocalTable(storePath,tableName,table){const snapshotPath=getLanceDbSnapshotPath(storePath,tableName);if(table.size===0){await removeSnapshotFile(snapshotPath);return}const snapshotDir=dirname(snapshotPath);try{await mkdir(snapshotDir,{recursive:true})}catch(error){throw new Error(`LanceDB local snapshot directory create failed at '${snapshotDir}': ${toErrorMessage(error)}`)}const serialized=`${JSON.stringify({version:LANCE_DB_LOCAL_SNAPSHOT_VERSION,table:tableName,records:buildSnapshotRecords(table)})}
|
|
2
|
+
`;try{await writeFileAtomic(snapshotPath,serialized)}catch(error){throw new Error(`LanceDB local snapshot write failed at '${snapshotPath}': ${toErrorMessage(error)}`)}}async function resetLanceDbLocalTable(storePath,tableName){const key=getLanceDbLocalTableKey(storePath,tableName);const snapshotPath=getLanceDbSnapshotPath(storePath,tableName);await removeSnapshotFile(snapshotPath);lanceDbLocalTables.delete(key)}function l2Norm(vector){let sumSq=0;for(let index=0;index<vector.length;index+=1){sumSq+=vector[index]*vector[index]}return Math.sqrt(sumSq)}function cosineSimilarity(left,right){let dotProd=0;for(let index=0;index<left.length;index+=1){dotProd+=left[index]*right[index]}const leftNorm=l2Norm(left);const rightNorm=l2Norm(right);if(leftNorm===0||rightNorm===0){return 0}return dotProd/(leftNorm*rightNorm)}function resolveVectorStores(settings,pmRoot){const qdrant=resolveQdrantStore(settings);const lancedb=resolveLanceDbStore(settings,pmRoot);const available=[qdrant,lancedb].filter(entry=>entry!==null);const preferredName=toNonEmptyString(settings.vector_store?.adapter);const preferredKey=preferredName?preferredName.toLowerCase():null;const preferred=preferredKey?available.find(entry=>entry.name===preferredKey):void 0;return{active:preferred??available[0]??null,available}}function resolveVectorStoreRequestTarget(store){const collectionName=resolveStoreCollectionName(store);if(store.name==="qdrant"){const baseUrl=trimTrailingSlashes(store.url);const encodedCollection2=encodeURIComponent(collectionName);return{store:"qdrant",query_target:`${baseUrl}/collections/${encodedCollection2}/points/search`,upsert_target:`${baseUrl}/collections/${encodedCollection2}/points?wait=true`}}const encodedPath=encodeURIComponent(store.path);const encodedCollection=encodeURIComponent(collectionName);return{store:"lancedb",query_target:`lancedb://${encodedPath}#${encodedCollection}`,upsert_target:`lancedb://${encodedPath}#${encodedCollection}`}}function buildVectorQueryPlan(store,vector,limit){const target=resolveVectorStoreRequestTarget(store);const normalizedVector=normalizeVector(vector);const normalizedLimit=normalizeLimit(limit);if(store.name==="qdrant"){return{target,method:"POST",headers:buildQdrantJsonHeaders(store),body:{vector:normalizedVector,limit:normalizedLimit,with_payload:true}}}return{target,method:"LOCAL",headers:{},body:{table:resolveStoreCollectionName(store),vector:normalizedVector,limit:normalizedLimit}}}function buildVectorUpsertPlan(store,records){const target=resolveVectorStoreRequestTarget(store);const normalizedRecords=normalizeVectorRecords(records);if(store.name==="qdrant"){return{target,method:"POST",headers:buildQdrantJsonHeaders(store),body:{points:normalizedRecords}}}return{target,method:"LOCAL",headers:{},body:{table:resolveStoreCollectionName(store),records:normalizedRecords}}}function buildVectorDeletePlan(store,ids){const target=resolveVectorStoreRequestTarget(store);const normalizedIds=normalizeVectorDeleteIds(ids);if(store.name==="qdrant"){return{target,method:"POST",headers:buildQdrantJsonHeaders(store),body:{points:normalizedIds}}}return{target,method:"LOCAL",headers:{},body:{table:resolveStoreCollectionName(store),ids:normalizedIds}}}async function executeVectorQuery(store,vector,limit,options={}){const plan=buildVectorQueryPlan(store,vector,limit);if(plan.method==="LOCAL"){const lanceDbStore=store;const queryBody=plan.body;const table=await loadLanceDbLocalTable(lanceDbStore.path,queryBody.table);if(table.size===0){return[]}const queryVector=normalizeVector(queryBody.vector);const queryLimit=normalizeLimit(queryBody.limit);const hits=[];let dimensionMismatchCount=0;for(const record of table.values()){if(record.vector.length!==queryVector.length){dimensionMismatchCount++;continue}hits.push({id:record.id,score:cosineSimilarity(queryVector,record.vector),...record.payload?{payload:record.payload}:{}})}if(dimensionMismatchCount>0&&options.warnings){options.warnings.push(`vector_dimension_mismatch:${dimensionMismatchCount} records skipped (expected ${queryVector.length} dimensions)`)}hits.sort((left,right)=>{if(left.score!==right.score){return right.score-left.score}return left.id.localeCompare(right.id)});return hits.slice(0,queryLimit)}const timeoutMs=normalizeSearchHttpTimeoutMs(options.timeout_ms,"Vector request");const fetcher=resolveSearchHttpFetcher(options.fetcher,"Vector request");const payload=await executeRemoteVectorPlan(plan.target.query_target,{method:"POST",headers:plan.headers,body:plan.body},timeoutMs,fetcher,"query");return normalizeQdrantQueryResponse(payload)}async function executeVectorUpsert(store,records,options={}){const plan=buildVectorUpsertPlan(store,records);if(plan.method==="LOCAL"){const lanceDbStore=store;const upsertBody=plan.body;const key=getLanceDbLocalTableKey(lanceDbStore.path,upsertBody.table);const table=await loadLanceDbLocalTable(lanceDbStore.path,upsertBody.table);for(const record of upsertBody.records){table.set(record.id,record)}await persistLanceDbLocalTable(lanceDbStore.path,upsertBody.table,table);const snapshotPath=getLanceDbSnapshotPath(lanceDbStore.path,upsertBody.table);const snapshotStats=await stat(snapshotPath);lanceDbLocalTables.set(key,{records:table,mtimeMs:snapshotStats.mtimeMs,size:snapshotStats.size});return{status:"ok"}}const timeoutMs=normalizeSearchHttpTimeoutMs(options.timeout_ms,"Vector request");const fetcher=resolveSearchHttpFetcher(options.fetcher,"Vector request");const payload=await executeRemoteVectorPlan(plan.target.upsert_target,{method:"POST",headers:plan.headers,body:plan.body},timeoutMs,fetcher,"upsert");return normalizeQdrantUpsertResponse(payload)}async function executeVectorDelete(store,ids,options={}){const plan=buildVectorDeletePlan(store,ids);if(plan.method==="LOCAL"){const lanceDbStore=store;const deleteBody=plan.body;const key=getLanceDbLocalTableKey(lanceDbStore.path,deleteBody.table);const table=await loadLanceDbLocalTable(lanceDbStore.path,deleteBody.table);if(table.size===0){return{status:"ok"}}for(const id of deleteBody.ids){table.delete(id)}await persistLanceDbLocalTable(lanceDbStore.path,deleteBody.table,table);if(table.size===0){lanceDbLocalTables.delete(key)}else{const snapshotPath=getLanceDbSnapshotPath(lanceDbStore.path,deleteBody.table);const snapshotStats=await stat(snapshotPath);lanceDbLocalTables.set(key,{records:table,mtimeMs:snapshotStats.mtimeMs,size:snapshotStats.size})}return{status:"ok"}}const timeoutMs=normalizeSearchHttpTimeoutMs(options.timeout_ms,"Vector request");const fetcher=resolveSearchHttpFetcher(options.fetcher,"Vector request");const payload=await executeRemoteVectorPlan(resolveQdrantDeleteTarget(plan.target.upsert_target),{method:"POST",headers:plan.headers,body:plan.body},timeoutMs,fetcher,"delete");return normalizeQdrantUpsertResponse(payload)}async function executeVectorReset(store,knownIds=[],options={},vectorDimension){if(store.name==="lancedb"){await resetLanceDbLocalTable(store.path,resolveStoreCollectionName(store));return{status:"ok"}}if(vectorDimension!==void 0){if(!Number.isInteger(vectorDimension)||vectorDimension<=0){throw new Error("Vector reset dimension must be a positive integer when provided")}const target=resolveVectorStoreRequestTarget(store);const collectionTarget=resolveQdrantCollectionTarget(target.upsert_target);const timeoutMs=normalizeSearchHttpTimeoutMs(options.timeout_ms,"Vector request");const fetcher=resolveSearchHttpFetcher(options.fetcher,"Vector request");const headers=buildQdrantJsonHeaders(store);try{await executeRemoteVectorPlan(collectionTarget,{method:"DELETE",headers,body:{}},timeoutMs,fetcher,"delete")}catch(error){if(!toErrorMessage(error).includes("failed with status 404")){throw error}}const payload=await executeRemoteVectorPlan(collectionTarget,{method:"PUT",headers,body:{vectors:{size:vectorDimension,distance:"Cosine"}}},timeoutMs,fetcher,"upsert");return normalizeQdrantUpsertResponse(payload)}const idsToDelete=knownIds.map(id=>id.trim()).filter(id=>id.length>0);if(idsToDelete.length===0){return{status:"ok"}}return await executeVectorDelete(store,idsToDelete,options)}export{buildVectorDeletePlan,buildVectorQueryPlan,buildVectorUpsertPlan,executeVectorDelete,executeVectorQuery,executeVectorReset,executeVectorUpsert,resolveVectorStoreRequestTarget,resolveVectorStores};
|
|
664
3
|
//# sourceMappingURL=vector-stores.js.map
|
|
665
|
-
//# debugId=98c8d03c-bdde-5ac4-b80d-395d885f7442
|