@unbrained/pm-cli 2026.9.6 → 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 +218 -182
- 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/RELEASING.md +1 -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,495 +1,2 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @module sdk/mcp/discovery
|
|
3
|
-
*
|
|
4
|
-
* Provides the deterministic, token-bounded progressive tool discovery
|
|
5
|
-
* contract shared by MCP servers, embedded hosts, and agent integrations.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
!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]="4853ebbf-f28a-55f1-b306-aa75cb9355ae")}catch(e){}}();
|
|
9
|
-
import { createHash, createHmac, randomBytes, timingSafeEqual, } from "node:crypto";
|
|
10
|
-
import { PM_COMMAND_CAPABILITY_CONTRACTS, PM_MCP_TOOL_COMMAND_CONTRACTS, resolvePmCommandCapabilityFamily, resolvePmCommandVisibilityTier, } from "../agent-capability-contracts.js";
|
|
11
|
-
import { PmCliError } from "../runtime-primitives.js";
|
|
12
|
-
/** Namespaced MCP extension that opts a client into progressive tool discovery. */
|
|
13
|
-
export const PM_MCP_PROGRESSIVE_DISCOVERY_EXTENSION = "dev.unbrained.pm/progressive-tool-discovery";
|
|
14
|
-
/** Versioned server capability advertised for progressive tool discovery. */
|
|
15
|
-
export const PM_MCP_PROGRESSIVE_DISCOVERY_SERVER_CAPABILITY = Object.freeze({
|
|
16
|
-
version: 1,
|
|
17
|
-
discoveryTool: "pm_discover",
|
|
18
|
-
canonicalResult: "structuredContent.result",
|
|
19
|
-
compatibilityText: "pointer",
|
|
20
|
-
});
|
|
21
|
-
/** Small stable tool catalog returned to clients that negotiate the extension. */
|
|
22
|
-
export const PM_MCP_ENTRY_TOOL_NAMES = Object.freeze([
|
|
23
|
-
"pm_discover",
|
|
24
|
-
"pm_next",
|
|
25
|
-
"pm_context",
|
|
26
|
-
"pm_search",
|
|
27
|
-
"pm_get",
|
|
28
|
-
]);
|
|
29
|
-
const DISCOVERY_WEIGHTS = Object.freeze({
|
|
30
|
-
lexical: 0.4,
|
|
31
|
-
semantic: 0.2,
|
|
32
|
-
graph: 0.1,
|
|
33
|
-
permission: 0.15,
|
|
34
|
-
freshness: 0.05,
|
|
35
|
-
usage: 0.1,
|
|
36
|
-
});
|
|
37
|
-
const DISCOVERY_CACHE_INVALIDATIONS = Object.freeze([
|
|
38
|
-
"profile_changed",
|
|
39
|
-
"tool_contract_changed",
|
|
40
|
-
"workspace_extension_changed",
|
|
41
|
-
"authorization_changed",
|
|
42
|
-
"ranking_signal_changed",
|
|
43
|
-
"cursor_integrity_key_rotated",
|
|
44
|
-
]);
|
|
45
|
-
const TIER_RANK = {
|
|
46
|
-
core: 0,
|
|
47
|
-
standard: 1,
|
|
48
|
-
full: 2,
|
|
49
|
-
internal: 3,
|
|
50
|
-
};
|
|
51
|
-
const SELECTABLE_TIERS = Object.freeze([
|
|
52
|
-
"core",
|
|
53
|
-
"standard",
|
|
54
|
-
"full",
|
|
55
|
-
]);
|
|
56
|
-
const MCP_TOOL_PROFILES = new Set([
|
|
57
|
-
"core",
|
|
58
|
-
"standard",
|
|
59
|
-
"full",
|
|
60
|
-
"custom",
|
|
61
|
-
]);
|
|
62
|
-
const CAPABILITY_FAMILIES = new Set(PM_COMMAND_CAPABILITY_CONTRACTS.map(({ family }) => family));
|
|
63
|
-
const PROCESS_CURSOR_INTEGRITY_KEY = randomBytes(32);
|
|
64
|
-
/** Validate a discovery string with the Unicode code-point semantics used by JSON Schema. */
|
|
65
|
-
function boundedDiscoveryString(value, field) {
|
|
66
|
-
if (typeof value !== "string") {
|
|
67
|
-
throw new PmCliError(`pm tool discovery ${field} must be a string of at most 4096 Unicode characters.`, 64);
|
|
68
|
-
}
|
|
69
|
-
const iterator = value[Symbol.iterator]();
|
|
70
|
-
let count = 0;
|
|
71
|
-
for (let next = iterator.next(); !next.done; next = iterator.next()) {
|
|
72
|
-
count += 1;
|
|
73
|
-
if (count > 4_096) {
|
|
74
|
-
throw new PmCliError(`pm tool discovery ${field} must be a string of at most 4096 Unicode characters.`, 64);
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
return value;
|
|
78
|
-
}
|
|
79
|
-
function discoveryLimit(value) {
|
|
80
|
-
if (!Number.isInteger(value) || Number(value) < 1 || Number(value) > 100) {
|
|
81
|
-
throw new PmCliError("pm tool discovery limit must be from 1 through 100.", 64);
|
|
82
|
-
}
|
|
83
|
-
return Number(value);
|
|
84
|
-
}
|
|
85
|
-
function discoveryOutputBudget(value) {
|
|
86
|
-
if (value !== "unbounded" &&
|
|
87
|
-
(!Number.isInteger(value) || Number(value) < 128)) {
|
|
88
|
-
throw new PmCliError("pm tool discovery outputBudget must be unbounded or an integer of at least 128.", 64);
|
|
89
|
-
}
|
|
90
|
-
return value === "unbounded" ? value : Number(value);
|
|
91
|
-
}
|
|
92
|
-
function discoveryIncludeSchema(value) {
|
|
93
|
-
if (value !== undefined && typeof value !== "boolean") {
|
|
94
|
-
throw new PmCliError("pm tool discovery includeSchema must be a boolean.", 64);
|
|
95
|
-
}
|
|
96
|
-
return value === true;
|
|
97
|
-
}
|
|
98
|
-
function validateDiscoveryOptionsContainer(value) {
|
|
99
|
-
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
100
|
-
throw new PmCliError("pm tool discovery options must be an object.", 64);
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
/** Reject malformed candidate catalogs supplied by untyped SDK consumers. */
|
|
104
|
-
function validateDiscoveryCandidates(candidates) {
|
|
105
|
-
if (!Array.isArray(candidates)) {
|
|
106
|
-
throw new PmCliError("pm tool discovery candidates must be an array.", 64);
|
|
107
|
-
}
|
|
108
|
-
for (const [index, candidate] of candidates.entries()) {
|
|
109
|
-
if (candidate === null ||
|
|
110
|
-
typeof candidate !== "object" ||
|
|
111
|
-
Array.isArray(candidate)) {
|
|
112
|
-
throw new PmCliError(`pm tool discovery candidate ${index} must be an object.`, 64);
|
|
113
|
-
}
|
|
114
|
-
if (typeof candidate.name !== "string" ||
|
|
115
|
-
candidate.name.trim().length === 0) {
|
|
116
|
-
throw new PmCliError(`pm tool discovery candidate ${index} name must be a non-empty string.`, 64);
|
|
117
|
-
}
|
|
118
|
-
if (typeof candidate.description !== "string" ||
|
|
119
|
-
candidate.description.trim().length === 0) {
|
|
120
|
-
throw new PmCliError(`pm tool discovery candidate ${index} description must be a non-empty string.`, 64);
|
|
121
|
-
}
|
|
122
|
-
if (candidate.inputSchema === null ||
|
|
123
|
-
typeof candidate.inputSchema !== "object" ||
|
|
124
|
-
Array.isArray(candidate.inputSchema)) {
|
|
125
|
-
throw new PmCliError(`pm tool discovery candidate ${index} inputSchema must be an object.`, 64);
|
|
126
|
-
}
|
|
127
|
-
if (candidate.authorized !== undefined &&
|
|
128
|
-
typeof candidate.authorized !== "boolean") {
|
|
129
|
-
throw new PmCliError(`pm tool discovery candidate ${index} authorized must be a boolean.`, 64);
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
/** Parse untrusted adapter input without discarding malformed discovery values. */
|
|
134
|
-
export function parsePmToolDiscoveryOptions(input) {
|
|
135
|
-
validateDiscoveryOptionsContainer(input);
|
|
136
|
-
if (input.family !== undefined &&
|
|
137
|
-
(typeof input.family !== "string" || !CAPABILITY_FAMILIES.has(input.family))) {
|
|
138
|
-
throw new PmCliError("pm tool discovery family must be a declared capability family.", 64);
|
|
139
|
-
}
|
|
140
|
-
if (input.tier !== undefined &&
|
|
141
|
-
(typeof input.tier !== "string" || !SELECTABLE_TIERS.includes(input.tier))) {
|
|
142
|
-
throw new PmCliError("pm tool discovery tier must be core, standard, or full.", 64);
|
|
143
|
-
}
|
|
144
|
-
return {
|
|
145
|
-
...(input.query !== undefined
|
|
146
|
-
? { query: boundedDiscoveryString(input.query, "query") }
|
|
147
|
-
: {}),
|
|
148
|
-
...(input.family !== undefined
|
|
149
|
-
? { family: input.family }
|
|
150
|
-
: {}),
|
|
151
|
-
...(input.tier !== undefined
|
|
152
|
-
? {
|
|
153
|
-
tier: input.tier,
|
|
154
|
-
}
|
|
155
|
-
: {}),
|
|
156
|
-
...(input.limit !== undefined
|
|
157
|
-
? { limit: discoveryLimit(input.limit) }
|
|
158
|
-
: {}),
|
|
159
|
-
...(input.cursor !== undefined
|
|
160
|
-
? { cursor: boundedDiscoveryString(input.cursor, "cursor") }
|
|
161
|
-
: {}),
|
|
162
|
-
...(input.includeSchema !== undefined
|
|
163
|
-
? { includeSchema: discoveryIncludeSchema(input.includeSchema) }
|
|
164
|
-
: {}),
|
|
165
|
-
...(input.outputBudget !== undefined
|
|
166
|
-
? { outputBudget: discoveryOutputBudget(input.outputBudget) }
|
|
167
|
-
: {}),
|
|
168
|
-
};
|
|
169
|
-
}
|
|
170
|
-
function normalizedUnitInterval(value) {
|
|
171
|
-
if (value === undefined || !Number.isFinite(value))
|
|
172
|
-
return 0;
|
|
173
|
-
return Math.min(1, Math.max(0, value));
|
|
174
|
-
}
|
|
175
|
-
function normalizedSearchTokens(value) {
|
|
176
|
-
return [...new Set(value.toLowerCase().match(/[a-z0-9]+/gu) ?? [])].sort();
|
|
177
|
-
}
|
|
178
|
-
function lexicalRelevance(query, text) {
|
|
179
|
-
const queryTokens = normalizedSearchTokens(query);
|
|
180
|
-
if (queryTokens.length === 0)
|
|
181
|
-
return 0;
|
|
182
|
-
const targetTokens = new Set(normalizedSearchTokens(text));
|
|
183
|
-
const matched = queryTokens.filter((token) => targetTokens.has(token)).length;
|
|
184
|
-
const exactBonus = text.toLowerCase().includes(query.toLowerCase())
|
|
185
|
-
? 0.25
|
|
186
|
-
: 0;
|
|
187
|
-
return Math.min(1, matched / queryTokens.length + exactBonus);
|
|
188
|
-
}
|
|
189
|
-
function semanticRelevance(query, text) {
|
|
190
|
-
const queryTokens = normalizedSearchTokens(query);
|
|
191
|
-
if (queryTokens.length === 0)
|
|
192
|
-
return 0;
|
|
193
|
-
const target = text.toLowerCase();
|
|
194
|
-
const targetTokens = normalizedSearchTokens(text);
|
|
195
|
-
const related = queryTokens.filter((queryToken) => targetTokens.some((targetToken) => targetToken.startsWith(queryToken) ||
|
|
196
|
-
queryToken.startsWith(targetToken))).length;
|
|
197
|
-
const phraseBonus = target.includes(query.toLowerCase()) ? 0.2 : 0;
|
|
198
|
-
return Math.min(1, related / queryTokens.length + phraseBonus);
|
|
199
|
-
}
|
|
200
|
-
function hashDiscoveryValue(value) {
|
|
201
|
-
return createHash("sha256")
|
|
202
|
-
.update(JSON.stringify(value))
|
|
203
|
-
.digest("hex")
|
|
204
|
-
.slice(0, 24);
|
|
205
|
-
}
|
|
206
|
-
function cursorSignature(fingerprint, offset, integrityKey) {
|
|
207
|
-
return createHmac("sha256", integrityKey)
|
|
208
|
-
.update(JSON.stringify({ version: 1, fingerprint, offset }))
|
|
209
|
-
.digest("base64url");
|
|
210
|
-
}
|
|
211
|
-
function encodeDiscoveryCursor(fingerprint, offset, integrityKey) {
|
|
212
|
-
const cursor = {
|
|
213
|
-
version: 1,
|
|
214
|
-
offset,
|
|
215
|
-
signature: cursorSignature(fingerprint, offset, integrityKey),
|
|
216
|
-
};
|
|
217
|
-
return Buffer.from(JSON.stringify(cursor), "utf8").toString("base64url");
|
|
218
|
-
}
|
|
219
|
-
function decodeDiscoveryCursor(value, fingerprint, total, integrityKey) {
|
|
220
|
-
if (value === undefined)
|
|
221
|
-
return 0;
|
|
222
|
-
try {
|
|
223
|
-
const decoded = JSON.parse(Buffer.from(value, "base64url").toString("utf8"));
|
|
224
|
-
if (decoded.version !== 1 ||
|
|
225
|
-
!Number.isInteger(decoded.offset) ||
|
|
226
|
-
(decoded.offset ?? -1) < 0 ||
|
|
227
|
-
Number(decoded.offset) > total ||
|
|
228
|
-
typeof decoded.signature !== "string") {
|
|
229
|
-
throw new Error("cursor fields do not match the request");
|
|
230
|
-
}
|
|
231
|
-
const expectedSignature = Buffer.from(cursorSignature(fingerprint, decoded.offset, integrityKey), "base64url");
|
|
232
|
-
const suppliedSignature = Buffer.from(decoded.signature, "base64url");
|
|
233
|
-
if (suppliedSignature.length !== expectedSignature.length ||
|
|
234
|
-
!timingSafeEqual(suppliedSignature, expectedSignature)) {
|
|
235
|
-
throw new Error("cursor signature does not match the request");
|
|
236
|
-
}
|
|
237
|
-
return decoded.offset;
|
|
238
|
-
}
|
|
239
|
-
catch (error) {
|
|
240
|
-
throw new PmCliError("Invalid or stale pm tool discovery cursor; restart discovery without cursor.", 64, { reason: String(error) });
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
function appliedSignal(value, weight, source) {
|
|
244
|
-
return {
|
|
245
|
-
value: normalizedUnitInterval(value),
|
|
246
|
-
weight,
|
|
247
|
-
available: source !== "unavailable",
|
|
248
|
-
source,
|
|
249
|
-
};
|
|
250
|
-
}
|
|
251
|
-
function hostOrComputedSignal(hostValue, computedValue, weight) {
|
|
252
|
-
return appliedSignal(hostValue ?? computedValue, weight, hostValue === undefined ? "computed" : "host");
|
|
253
|
-
}
|
|
254
|
-
function buildRankedRow(candidate, query, includeSchema) {
|
|
255
|
-
const command = Object.hasOwn(PM_MCP_TOOL_COMMAND_CONTRACTS, candidate.name)
|
|
256
|
-
? PM_MCP_TOOL_COMMAND_CONTRACTS[candidate.name]
|
|
257
|
-
: "help";
|
|
258
|
-
const family = resolvePmCommandCapabilityFamily(command);
|
|
259
|
-
const searchableText = `${candidate.name} ${candidate.description} ${command} ${family}`;
|
|
260
|
-
const lexical = lexicalRelevance(query, searchableText);
|
|
261
|
-
const queryTokens = new Set(normalizedSearchTokens(query));
|
|
262
|
-
const signals = {
|
|
263
|
-
lexical: appliedSignal(lexical, DISCOVERY_WEIGHTS.lexical, "computed"),
|
|
264
|
-
semantic: hostOrComputedSignal(candidate.signals?.semantic, semanticRelevance(query, searchableText), DISCOVERY_WEIGHTS.semantic),
|
|
265
|
-
graph: hostOrComputedSignal(candidate.signals?.graph, queryTokens.has(family) || queryTokens.has(command) ? 1 : 0, DISCOVERY_WEIGHTS.graph),
|
|
266
|
-
permission: appliedSignal(1, DISCOVERY_WEIGHTS.permission, "authorization"),
|
|
267
|
-
freshness: hostOrComputedSignal(candidate.signals?.freshness, 1, DISCOVERY_WEIGHTS.freshness),
|
|
268
|
-
usage: hostOrComputedSignal(candidate.signals?.usage, PM_MCP_ENTRY_TOOL_NAMES.includes(candidate.name) ? 1 : 0, DISCOVERY_WEIGHTS.usage),
|
|
269
|
-
};
|
|
270
|
-
const score = Object.values(signals).reduce((total, signal) => total + signal.value * signal.weight, 0);
|
|
271
|
-
return {
|
|
272
|
-
name: candidate.name,
|
|
273
|
-
description: candidate.description,
|
|
274
|
-
command,
|
|
275
|
-
tier: resolvePmCommandVisibilityTier(command),
|
|
276
|
-
family,
|
|
277
|
-
score: Number(score.toFixed(6)),
|
|
278
|
-
signals,
|
|
279
|
-
...(includeSchema
|
|
280
|
-
? { input_schema: structuredClone(candidate.inputSchema) }
|
|
281
|
-
: {}),
|
|
282
|
-
};
|
|
283
|
-
}
|
|
284
|
-
/** Reject runtime filter values that bypass the public TypeScript unions. */
|
|
285
|
-
function validateDiscoveryFilters(options) {
|
|
286
|
-
if (options.cursorIntegrityKey !== undefined &&
|
|
287
|
-
(!(options.cursorIntegrityKey instanceof Uint8Array) ||
|
|
288
|
-
options.cursorIntegrityKey.byteLength < 32)) {
|
|
289
|
-
throw new PmCliError("pm tool discovery cursorIntegrityKey must contain at least 32 bytes.", 64);
|
|
290
|
-
}
|
|
291
|
-
if (options.tier !== undefined &&
|
|
292
|
-
(typeof options.tier !== "string" ||
|
|
293
|
-
!SELECTABLE_TIERS.includes(options.tier))) {
|
|
294
|
-
throw new PmCliError("pm tool discovery tier must be core, standard, or full.", 64);
|
|
295
|
-
}
|
|
296
|
-
if (options.family !== undefined &&
|
|
297
|
-
(typeof options.family !== "string" ||
|
|
298
|
-
!CAPABILITY_FAMILIES.has(options.family))) {
|
|
299
|
-
throw new PmCliError("pm tool discovery family must be a declared capability family.", 64);
|
|
300
|
-
}
|
|
301
|
-
if (options.profile !== undefined &&
|
|
302
|
-
(typeof options.profile !== "string" ||
|
|
303
|
-
!MCP_TOOL_PROFILES.has(options.profile))) {
|
|
304
|
-
throw new PmCliError("pm tool discovery profile must be core, standard, full, or custom.", 64);
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
function resolveDiscoveryRequest(options) {
|
|
308
|
-
const rawQuery = boundedDiscoveryString(options.query === undefined ? "" : options.query, "query");
|
|
309
|
-
const query = rawQuery.trim().replace(/\s+/gu, " ");
|
|
310
|
-
boundedDiscoveryString(options.cursor === undefined ? "" : options.cursor, "cursor");
|
|
311
|
-
const limit = discoveryLimit(options.limit === undefined ? 10 : options.limit);
|
|
312
|
-
const budget = discoveryOutputBudget(options.outputBudget === undefined ? 1_200 : options.outputBudget);
|
|
313
|
-
validateDiscoveryFilters(options);
|
|
314
|
-
return {
|
|
315
|
-
query,
|
|
316
|
-
includeSchema: discoveryIncludeSchema(options.includeSchema),
|
|
317
|
-
limit,
|
|
318
|
-
budget,
|
|
319
|
-
maximumTier: TIER_RANK[options.tier ?? "full"],
|
|
320
|
-
profile: options.profile === undefined ? "core" : options.profile,
|
|
321
|
-
};
|
|
322
|
-
}
|
|
323
|
-
/**
|
|
324
|
-
* Measure one result exactly while allowing callers to supply pre-serialized
|
|
325
|
-
* array contents, so budget selection stays linear in the returned row bytes.
|
|
326
|
-
*/
|
|
327
|
-
function estimateDiscoveryResultTokens(resultWithoutCost, budget, serializedToolRowsBytes) {
|
|
328
|
-
const toolRowsBytes = serializedToolRowsBytes ??
|
|
329
|
-
resultWithoutCost.tools.reduce((total, row, index) => total +
|
|
330
|
-
(index === 0 ? 0 : 1) +
|
|
331
|
-
Buffer.byteLength(JSON.stringify(row), "utf8"), 0);
|
|
332
|
-
const emptyToolsResult = { ...resultWithoutCost, tools: [] };
|
|
333
|
-
let estimatedTokens = 0;
|
|
334
|
-
for (let iteration = 0; iteration < 4; iteration += 1) {
|
|
335
|
-
const envelopeBytes = Buffer.byteLength(JSON.stringify({
|
|
336
|
-
...emptyToolsResult,
|
|
337
|
-
token_cost: {
|
|
338
|
-
estimated_tokens: estimatedTokens,
|
|
339
|
-
budget,
|
|
340
|
-
within_budget: true,
|
|
341
|
-
},
|
|
342
|
-
}), "utf8");
|
|
343
|
-
const nextEstimate = Math.ceil((envelopeBytes + toolRowsBytes) / 4);
|
|
344
|
-
if (nextEstimate === estimatedTokens)
|
|
345
|
-
break;
|
|
346
|
-
estimatedTokens = nextEstimate;
|
|
347
|
-
}
|
|
348
|
-
return estimatedTokens;
|
|
349
|
-
}
|
|
350
|
-
function rankedDiscoveryRows(candidates, options, request) {
|
|
351
|
-
return candidates
|
|
352
|
-
.filter((candidate) => candidate.authorized !== false)
|
|
353
|
-
.map((candidate) => buildRankedRow(candidate, request.query, request.includeSchema))
|
|
354
|
-
.filter((row) => row.tier !== "internal" &&
|
|
355
|
-
TIER_RANK[row.tier] <= request.maximumTier &&
|
|
356
|
-
(options.family === undefined || row.family === options.family))
|
|
357
|
-
.sort((left, right) => right.score - left.score ||
|
|
358
|
-
(left.name < right.name ? -1 : left.name > right.name ? 1 : 0));
|
|
359
|
-
}
|
|
360
|
-
function rowsWithinDiscoveryBudget(candidates, budget, buildResultWithoutCost) {
|
|
361
|
-
if (budget === "unbounded")
|
|
362
|
-
return [...candidates];
|
|
363
|
-
const selected = [];
|
|
364
|
-
let serializedToolRowsBytes = 0;
|
|
365
|
-
for (const [index, row] of candidates.entries()) {
|
|
366
|
-
const candidateRowsBytes = serializedToolRowsBytes +
|
|
367
|
-
(index === 0 ? 0 : 1) +
|
|
368
|
-
Buffer.byteLength(JSON.stringify(row), "utf8");
|
|
369
|
-
const estimatedTokens = estimateDiscoveryResultTokens(buildResultWithoutCost(index + 1), budget, candidateRowsBytes);
|
|
370
|
-
if (estimatedTokens > budget)
|
|
371
|
-
break;
|
|
372
|
-
selected.push(row);
|
|
373
|
-
serializedToolRowsBytes = candidateRowsBytes;
|
|
374
|
-
}
|
|
375
|
-
return selected;
|
|
376
|
-
}
|
|
377
|
-
/**
|
|
378
|
-
* Rank and page an authorized MCP tool catalog under an explicit token budget.
|
|
379
|
-
*
|
|
380
|
-
* Cursors fail closed when the query, filters, schemas, authorization-filtered
|
|
381
|
-
* catalog, or ranking inputs change. Host signals override documented local
|
|
382
|
-
* fallbacks without changing the public formula or hiding signal provenance.
|
|
383
|
-
*/
|
|
384
|
-
export function discoverPmTools(candidates, options = {}) {
|
|
385
|
-
validateDiscoveryCandidates(candidates);
|
|
386
|
-
validateDiscoveryOptionsContainer(options);
|
|
387
|
-
const request = resolveDiscoveryRequest(options);
|
|
388
|
-
const cursorIntegrityKey = options.cursorIntegrityKey ?? PROCESS_CURSOR_INTEGRITY_KEY;
|
|
389
|
-
const ranked = rankedDiscoveryRows(candidates, options, request);
|
|
390
|
-
const fingerprint = hashDiscoveryValue({
|
|
391
|
-
query: request.query,
|
|
392
|
-
family: options.family ?? null,
|
|
393
|
-
tier: options.tier ?? "full",
|
|
394
|
-
includeSchema: request.includeSchema,
|
|
395
|
-
profile: request.profile,
|
|
396
|
-
ranked,
|
|
397
|
-
});
|
|
398
|
-
const offset = decodeDiscoveryCursor(options.cursor, fingerprint, ranked.length, cursorIntegrityKey);
|
|
399
|
-
const pageCandidates = ranked.slice(offset, offset + request.limit);
|
|
400
|
-
const omitted = [];
|
|
401
|
-
if (!request.includeSchema) {
|
|
402
|
-
omitted.push({
|
|
403
|
-
name: "input_schema",
|
|
404
|
-
reason: "compact_projection",
|
|
405
|
-
restore_with: "Set includeSchema=true.",
|
|
406
|
-
});
|
|
407
|
-
}
|
|
408
|
-
if (offset + request.limit < ranked.length) {
|
|
409
|
-
omitted.push({
|
|
410
|
-
name: "tools",
|
|
411
|
-
reason: "limit",
|
|
412
|
-
restore_with: "Continue with next_cursor or increase limit.",
|
|
413
|
-
});
|
|
414
|
-
}
|
|
415
|
-
const base = {
|
|
416
|
-
result_type: "pm_tool_discovery",
|
|
417
|
-
contract_version: 1,
|
|
418
|
-
query: request.query,
|
|
419
|
-
profile: request.profile,
|
|
420
|
-
total: ranked.length,
|
|
421
|
-
ranking_policy: {
|
|
422
|
-
version: 1,
|
|
423
|
-
formula: "weighted_sum_then_name",
|
|
424
|
-
weights: DISCOVERY_WEIGHTS,
|
|
425
|
-
},
|
|
426
|
-
cache: {
|
|
427
|
-
key: hashDiscoveryValue({
|
|
428
|
-
fingerprint,
|
|
429
|
-
cursorIntegrityKey: createHash("sha256")
|
|
430
|
-
.update(cursorIntegrityKey)
|
|
431
|
-
.digest("hex"),
|
|
432
|
-
limit: request.limit,
|
|
433
|
-
offset,
|
|
434
|
-
budget: request.budget,
|
|
435
|
-
}),
|
|
436
|
-
ttl_ms: 30_000,
|
|
437
|
-
scope: "private",
|
|
438
|
-
invalidates_on: DISCOVERY_CACHE_INVALIDATIONS,
|
|
439
|
-
},
|
|
440
|
-
};
|
|
441
|
-
const buildResultWithoutCost = (selected, selectedCount = selected.length) => {
|
|
442
|
-
const endOffset = offset + selectedCount;
|
|
443
|
-
const hasMore = endOffset < ranked.length;
|
|
444
|
-
const resultOmissions = [...omitted];
|
|
445
|
-
if (selectedCount < pageCandidates.length) {
|
|
446
|
-
resultOmissions.push({
|
|
447
|
-
name: "tools",
|
|
448
|
-
reason: "token_budget",
|
|
449
|
-
restore_with: "Continue with next_cursor or increase outputBudget.",
|
|
450
|
-
});
|
|
451
|
-
}
|
|
452
|
-
const resultWithoutCost = {
|
|
453
|
-
...base,
|
|
454
|
-
tools: [...selected],
|
|
455
|
-
returned: selectedCount,
|
|
456
|
-
has_more: hasMore,
|
|
457
|
-
...(hasMore
|
|
458
|
-
? {
|
|
459
|
-
next_cursor: encodeDiscoveryCursor(fingerprint, endOffset, cursorIntegrityKey),
|
|
460
|
-
}
|
|
461
|
-
: {}),
|
|
462
|
-
omission_receipt: {
|
|
463
|
-
has_omissions: resultOmissions.length > 0,
|
|
464
|
-
omitted: resultOmissions,
|
|
465
|
-
},
|
|
466
|
-
};
|
|
467
|
-
return resultWithoutCost;
|
|
468
|
-
};
|
|
469
|
-
const buildResult = (selected) => {
|
|
470
|
-
const resultWithoutCost = buildResultWithoutCost(selected);
|
|
471
|
-
const estimatedTokens = estimateDiscoveryResultTokens(resultWithoutCost, request.budget);
|
|
472
|
-
return {
|
|
473
|
-
...resultWithoutCost,
|
|
474
|
-
token_cost: {
|
|
475
|
-
estimated_tokens: estimatedTokens,
|
|
476
|
-
budget: request.budget,
|
|
477
|
-
within_budget: request.budget === "unbounded" || estimatedTokens <= request.budget,
|
|
478
|
-
},
|
|
479
|
-
};
|
|
480
|
-
};
|
|
481
|
-
const selected = rowsWithinDiscoveryBudget(pageCandidates, request.budget, (selectedCount) => buildResultWithoutCost([], selectedCount));
|
|
482
|
-
const result = buildResult(selected);
|
|
483
|
-
if (pageCandidates.length > 0 && selected.length === 0) {
|
|
484
|
-
const oneRowCost = buildResult([pageCandidates[0]]).token_cost
|
|
485
|
-
.estimated_tokens;
|
|
486
|
-
throw new PmCliError(`pm tool discovery outputBudget is too small to return a tool; increase it to at least ${oneRowCost}.`, 64, { required: String(oneRowCost) });
|
|
487
|
-
}
|
|
488
|
-
if (request.budget !== "unbounded" &&
|
|
489
|
-
result.token_cost.estimated_tokens > request.budget) {
|
|
490
|
-
throw new PmCliError(`pm tool discovery outputBudget is too small; at least ${result.token_cost.estimated_tokens} estimated tokens are required for this page.`, 64, { required: String(result.token_cost.estimated_tokens) });
|
|
491
|
-
}
|
|
492
|
-
return result;
|
|
493
|
-
}
|
|
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]="31eda153-a06e-51ef-a62f-f6dce09064d3")}catch(e2){}})();import{createHash,createHmac,randomBytes,timingSafeEqual}from"node:crypto";import{PM_COMMAND_CAPABILITY_CONTRACTS,PM_MCP_TOOL_COMMAND_CONTRACTS,resolvePmCommandCapabilityFamily,resolvePmCommandVisibilityTier}from"../agent-capability-contracts.js";import{PmCliError}from"../runtime-primitives.js";const PM_MCP_PROGRESSIVE_DISCOVERY_EXTENSION="dev.unbrained.pm/progressive-tool-discovery";const PM_MCP_PROGRESSIVE_DISCOVERY_SERVER_CAPABILITY=Object.freeze({version:1,discoveryTool:"pm_discover",canonicalResult:"structuredContent.result",compatibilityText:"pointer"});const PM_MCP_ENTRY_TOOL_NAMES=Object.freeze(["pm_discover","pm_next","pm_context","pm_search","pm_get"]);const DISCOVERY_WEIGHTS=Object.freeze({lexical:.4,semantic:.2,graph:.1,permission:.15,freshness:.05,usage:.1});const DISCOVERY_CACHE_INVALIDATIONS=Object.freeze(["profile_changed","tool_contract_changed","workspace_extension_changed","authorization_changed","ranking_signal_changed","cursor_integrity_key_rotated"]);const TIER_RANK={core:0,standard:1,full:2,internal:3};const SELECTABLE_TIERS=Object.freeze(["core","standard","full"]);const MCP_TOOL_PROFILES=new Set(["core","standard","full","custom"]);const CAPABILITY_FAMILIES=new Set(PM_COMMAND_CAPABILITY_CONTRACTS.map(({family})=>family));const PROCESS_CURSOR_INTEGRITY_KEY=randomBytes(32);function boundedDiscoveryString(value,field){if(typeof value!=="string"){throw new PmCliError(`pm tool discovery ${field} must be a string of at most 4096 Unicode characters.`,64)}const iterator=value[Symbol.iterator]();let count=0;for(let next=iterator.next();!next.done;next=iterator.next()){count+=1;if(count>4096){throw new PmCliError(`pm tool discovery ${field} must be a string of at most 4096 Unicode characters.`,64)}}return value}function discoveryLimit(value){if(!Number.isInteger(value)||Number(value)<1||Number(value)>100){throw new PmCliError("pm tool discovery limit must be from 1 through 100.",64)}return Number(value)}function discoveryOutputBudget(value){if(value!=="unbounded"&&(!Number.isInteger(value)||Number(value)<128)){throw new PmCliError("pm tool discovery outputBudget must be unbounded or an integer of at least 128.",64)}return value==="unbounded"?value:Number(value)}function discoveryIncludeSchema(value){if(value!==void 0&&typeof value!=="boolean"){throw new PmCliError("pm tool discovery includeSchema must be a boolean.",64)}return value===true}function validateDiscoveryOptionsContainer(value){if(value===null||typeof value!=="object"||Array.isArray(value)){throw new PmCliError("pm tool discovery options must be an object.",64)}}function validateDiscoveryCandidates(candidates){if(!Array.isArray(candidates)){throw new PmCliError("pm tool discovery candidates must be an array.",64)}for(const[index,candidate]of candidates.entries()){if(candidate===null||typeof candidate!=="object"||Array.isArray(candidate)){throw new PmCliError(`pm tool discovery candidate ${index} must be an object.`,64)}if(typeof candidate.name!=="string"||candidate.name.trim().length===0){throw new PmCliError(`pm tool discovery candidate ${index} name must be a non-empty string.`,64)}if(typeof candidate.description!=="string"||candidate.description.trim().length===0){throw new PmCliError(`pm tool discovery candidate ${index} description must be a non-empty string.`,64)}if(candidate.inputSchema===null||typeof candidate.inputSchema!=="object"||Array.isArray(candidate.inputSchema)){throw new PmCliError(`pm tool discovery candidate ${index} inputSchema must be an object.`,64)}if(candidate.authorized!==void 0&&typeof candidate.authorized!=="boolean"){throw new PmCliError(`pm tool discovery candidate ${index} authorized must be a boolean.`,64)}}}function parsePmToolDiscoveryOptions(input){validateDiscoveryOptionsContainer(input);if(input.family!==void 0&&(typeof input.family!=="string"||!CAPABILITY_FAMILIES.has(input.family))){throw new PmCliError("pm tool discovery family must be a declared capability family.",64)}if(input.tier!==void 0&&(typeof input.tier!=="string"||!SELECTABLE_TIERS.includes(input.tier))){throw new PmCliError("pm tool discovery tier must be core, standard, or full.",64)}return{...input.query!==void 0?{query:boundedDiscoveryString(input.query,"query")}:{},...input.family!==void 0?{family:input.family}:{},...input.tier!==void 0?{tier:input.tier}:{},...input.limit!==void 0?{limit:discoveryLimit(input.limit)}:{},...input.cursor!==void 0?{cursor:boundedDiscoveryString(input.cursor,"cursor")}:{},...input.includeSchema!==void 0?{includeSchema:discoveryIncludeSchema(input.includeSchema)}:{},...input.outputBudget!==void 0?{outputBudget:discoveryOutputBudget(input.outputBudget)}:{}}}function normalizedUnitInterval(value){if(value===void 0||!Number.isFinite(value))return 0;return Math.min(1,Math.max(0,value))}function normalizedSearchTokens(value){return[...new Set(value.toLowerCase().match(/[a-z0-9]+/gu)??[])].sort()}function lexicalRelevance(query,text){const queryTokens=normalizedSearchTokens(query);if(queryTokens.length===0)return 0;const targetTokens=new Set(normalizedSearchTokens(text));const matched=queryTokens.filter(token=>targetTokens.has(token)).length;const exactBonus=text.toLowerCase().includes(query.toLowerCase())?.25:0;return Math.min(1,matched/queryTokens.length+exactBonus)}function semanticRelevance(query,text){const queryTokens=normalizedSearchTokens(query);if(queryTokens.length===0)return 0;const target=text.toLowerCase();const targetTokens=normalizedSearchTokens(text);const related=queryTokens.filter(queryToken=>targetTokens.some(targetToken=>targetToken.startsWith(queryToken)||queryToken.startsWith(targetToken))).length;const phraseBonus=target.includes(query.toLowerCase())?.2:0;return Math.min(1,related/queryTokens.length+phraseBonus)}function hashDiscoveryValue(value){return createHash("sha256").update(JSON.stringify(value)).digest("hex").slice(0,24)}function cursorSignature(fingerprint,offset,integrityKey){return createHmac("sha256",integrityKey).update(JSON.stringify({version:1,fingerprint,offset})).digest("base64url")}function encodeDiscoveryCursor(fingerprint,offset,integrityKey){const cursor={version:1,offset,signature:cursorSignature(fingerprint,offset,integrityKey)};return Buffer.from(JSON.stringify(cursor),"utf8").toString("base64url")}function decodeDiscoveryCursor(value,fingerprint,total,integrityKey){if(value===void 0)return 0;try{const decoded=JSON.parse(Buffer.from(value,"base64url").toString("utf8"));if(decoded.version!==1||!Number.isInteger(decoded.offset)||(decoded.offset??-1)<0||Number(decoded.offset)>total||typeof decoded.signature!=="string"){throw new Error("cursor fields do not match the request")}const expectedSignature=Buffer.from(cursorSignature(fingerprint,decoded.offset,integrityKey),"base64url");const suppliedSignature=Buffer.from(decoded.signature,"base64url");if(suppliedSignature.length!==expectedSignature.length||!timingSafeEqual(suppliedSignature,expectedSignature)){throw new Error("cursor signature does not match the request")}return decoded.offset}catch(error){throw new PmCliError("Invalid or stale pm tool discovery cursor; restart discovery without cursor.",64,{reason:String(error)})}}function appliedSignal(value,weight,source){return{value:normalizedUnitInterval(value),weight,available:source!=="unavailable",source}}function hostOrComputedSignal(hostValue,computedValue,weight){return appliedSignal(hostValue??computedValue,weight,hostValue===void 0?"computed":"host")}function buildRankedRow(candidate,query,includeSchema){const command=Object.hasOwn(PM_MCP_TOOL_COMMAND_CONTRACTS,candidate.name)?PM_MCP_TOOL_COMMAND_CONTRACTS[candidate.name]:"help";const family=resolvePmCommandCapabilityFamily(command);const searchableText=`${candidate.name} ${candidate.description} ${command} ${family}`;const lexical=lexicalRelevance(query,searchableText);const queryTokens=new Set(normalizedSearchTokens(query));const signals={lexical:appliedSignal(lexical,DISCOVERY_WEIGHTS.lexical,"computed"),semantic:hostOrComputedSignal(candidate.signals?.semantic,semanticRelevance(query,searchableText),DISCOVERY_WEIGHTS.semantic),graph:hostOrComputedSignal(candidate.signals?.graph,queryTokens.has(family)||queryTokens.has(command)?1:0,DISCOVERY_WEIGHTS.graph),permission:appliedSignal(1,DISCOVERY_WEIGHTS.permission,"authorization"),freshness:hostOrComputedSignal(candidate.signals?.freshness,1,DISCOVERY_WEIGHTS.freshness),usage:hostOrComputedSignal(candidate.signals?.usage,PM_MCP_ENTRY_TOOL_NAMES.includes(candidate.name)?1:0,DISCOVERY_WEIGHTS.usage)};const score=Object.values(signals).reduce((total,signal)=>total+signal.value*signal.weight,0);return{name:candidate.name,description:candidate.description,command,tier:resolvePmCommandVisibilityTier(command),family,score:Number(score.toFixed(6)),signals,...includeSchema?{input_schema:structuredClone(candidate.inputSchema)}:{}}}function validateDiscoveryFilters(options){if(options.cursorIntegrityKey!==void 0&&(!(options.cursorIntegrityKey instanceof Uint8Array)||options.cursorIntegrityKey.byteLength<32)){throw new PmCliError("pm tool discovery cursorIntegrityKey must contain at least 32 bytes.",64)}if(options.tier!==void 0&&(typeof options.tier!=="string"||!SELECTABLE_TIERS.includes(options.tier))){throw new PmCliError("pm tool discovery tier must be core, standard, or full.",64)}if(options.family!==void 0&&(typeof options.family!=="string"||!CAPABILITY_FAMILIES.has(options.family))){throw new PmCliError("pm tool discovery family must be a declared capability family.",64)}if(options.profile!==void 0&&(typeof options.profile!=="string"||!MCP_TOOL_PROFILES.has(options.profile))){throw new PmCliError("pm tool discovery profile must be core, standard, full, or custom.",64)}}function resolveDiscoveryRequest(options){const rawQuery=boundedDiscoveryString(options.query===void 0?"":options.query,"query");const query=rawQuery.trim().replace(/\s+/gu," ");boundedDiscoveryString(options.cursor===void 0?"":options.cursor,"cursor");const limit=discoveryLimit(options.limit===void 0?10:options.limit);const budget=discoveryOutputBudget(options.outputBudget===void 0?1200:options.outputBudget);validateDiscoveryFilters(options);return{query,includeSchema:discoveryIncludeSchema(options.includeSchema),limit,budget,maximumTier:TIER_RANK[options.tier??"full"],profile:options.profile===void 0?"core":options.profile}}function estimateDiscoveryResultTokens(resultWithoutCost,budget,serializedToolRowsBytes){const toolRowsBytes=serializedToolRowsBytes??resultWithoutCost.tools.reduce((total,row,index)=>total+(index===0?0:1)+Buffer.byteLength(JSON.stringify(row),"utf8"),0);const emptyToolsResult={...resultWithoutCost,tools:[]};let estimatedTokens=0;for(let iteration=0;iteration<4;iteration+=1){const envelopeBytes=Buffer.byteLength(JSON.stringify({...emptyToolsResult,token_cost:{estimated_tokens:estimatedTokens,budget,within_budget:true}}),"utf8");const nextEstimate=Math.ceil((envelopeBytes+toolRowsBytes)/4);if(nextEstimate===estimatedTokens)break;estimatedTokens=nextEstimate}return estimatedTokens}function rankedDiscoveryRows(candidates,options,request){return candidates.filter(candidate=>candidate.authorized!==false).map(candidate=>buildRankedRow(candidate,request.query,request.includeSchema)).filter(row=>row.tier!=="internal"&&TIER_RANK[row.tier]<=request.maximumTier&&(options.family===void 0||row.family===options.family)).sort((left,right)=>right.score-left.score||(left.name<right.name?-1:left.name>right.name?1:0))}function rowsWithinDiscoveryBudget(candidates,budget,buildResultWithoutCost){if(budget==="unbounded")return[...candidates];const selected=[];let serializedToolRowsBytes=0;for(const[index,row]of candidates.entries()){const candidateRowsBytes=serializedToolRowsBytes+(index===0?0:1)+Buffer.byteLength(JSON.stringify(row),"utf8");const estimatedTokens=estimateDiscoveryResultTokens(buildResultWithoutCost(index+1),budget,candidateRowsBytes);if(estimatedTokens>budget)break;selected.push(row);serializedToolRowsBytes=candidateRowsBytes}return selected}function discoverPmTools(candidates,options={}){validateDiscoveryCandidates(candidates);validateDiscoveryOptionsContainer(options);const request=resolveDiscoveryRequest(options);const cursorIntegrityKey=options.cursorIntegrityKey??PROCESS_CURSOR_INTEGRITY_KEY;const ranked=rankedDiscoveryRows(candidates,options,request);const fingerprint=hashDiscoveryValue({query:request.query,family:options.family??null,tier:options.tier??"full",includeSchema:request.includeSchema,profile:request.profile,ranked});const offset=decodeDiscoveryCursor(options.cursor,fingerprint,ranked.length,cursorIntegrityKey);const pageCandidates=ranked.slice(offset,offset+request.limit);const omitted=[];if(!request.includeSchema){omitted.push({name:"input_schema",reason:"compact_projection",restore_with:"Set includeSchema=true."})}if(offset+request.limit<ranked.length){omitted.push({name:"tools",reason:"limit",restore_with:"Continue with next_cursor or increase limit."})}const base={result_type:"pm_tool_discovery",contract_version:1,query:request.query,profile:request.profile,total:ranked.length,ranking_policy:{version:1,formula:"weighted_sum_then_name",weights:DISCOVERY_WEIGHTS},cache:{key:hashDiscoveryValue({fingerprint,cursorIntegrityKey:createHash("sha256").update(cursorIntegrityKey).digest("hex"),limit:request.limit,offset,budget:request.budget}),ttl_ms:3e4,scope:"private",invalidates_on:DISCOVERY_CACHE_INVALIDATIONS}};const buildResultWithoutCost=(selected2,selectedCount=selected2.length)=>{const endOffset=offset+selectedCount;const hasMore=endOffset<ranked.length;const resultOmissions=[...omitted];if(selectedCount<pageCandidates.length){resultOmissions.push({name:"tools",reason:"token_budget",restore_with:"Continue with next_cursor or increase outputBudget."})}const resultWithoutCost={...base,tools:[...selected2],returned:selectedCount,has_more:hasMore,...hasMore?{next_cursor:encodeDiscoveryCursor(fingerprint,endOffset,cursorIntegrityKey)}:{},omission_receipt:{has_omissions:resultOmissions.length>0,omitted:resultOmissions}};return resultWithoutCost};const buildResult=selected2=>{const resultWithoutCost=buildResultWithoutCost(selected2);const estimatedTokens=estimateDiscoveryResultTokens(resultWithoutCost,request.budget);return{...resultWithoutCost,token_cost:{estimated_tokens:estimatedTokens,budget:request.budget,within_budget:request.budget==="unbounded"||estimatedTokens<=request.budget}}};const selected=rowsWithinDiscoveryBudget(pageCandidates,request.budget,selectedCount=>buildResultWithoutCost([],selectedCount));const result=buildResult(selected);if(pageCandidates.length>0&&selected.length===0){const oneRowCost=buildResult([pageCandidates[0]]).token_cost.estimated_tokens;throw new PmCliError(`pm tool discovery outputBudget is too small to return a tool; increase it to at least ${oneRowCost}.`,64,{required:String(oneRowCost)})}if(request.budget!=="unbounded"&&result.token_cost.estimated_tokens>request.budget){throw new PmCliError(`pm tool discovery outputBudget is too small; at least ${result.token_cost.estimated_tokens} estimated tokens are required for this page.`,64,{required:String(result.token_cost.estimated_tokens)})}return result}export{PM_MCP_ENTRY_TOOL_NAMES,PM_MCP_PROGRESSIVE_DISCOVERY_EXTENSION,PM_MCP_PROGRESSIVE_DISCOVERY_SERVER_CAPABILITY,discoverPmTools,parsePmToolDiscoveryOptions};
|
|
494
2
|
//# sourceMappingURL=discovery.js.map
|
|
495
|
-
//# debugId=4853ebbf-f28a-55f1-b306-aa75cb9355ae
|