@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,531 +1,2 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @module sdk/linked-artifacts
|
|
3
|
-
*
|
|
4
|
-
* Implements the pm linked artifacts command surface and its agent-facing runtime behavior.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
!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]="accd0229-6974-5950-8cea-74f517706878")}catch(e){}}();
|
|
8
|
-
import { assertInitializedTracker } from "./environment/tracker-preflight.js";
|
|
9
|
-
import fs from "node:fs/promises";
|
|
10
|
-
import path from "node:path";
|
|
11
|
-
import fg from "fast-glob";
|
|
12
|
-
import { isFileAbsentError } from "../core/fs/fs-utils.js";
|
|
13
|
-
import { getActiveExtensionRegistrations } from "../core/extensions/index.js";
|
|
14
|
-
import { assertNoAmbiguousBareCommaEntry, assertNoUnknownCsvKeys, createStdinTokenResolver, looksLikeGenericKeyValueEntry, parseCsvKv, } from "../core/item/parse.js";
|
|
15
|
-
import { resolveItemTypeRegistry } from "../core/item/type-registry.js";
|
|
16
|
-
import { isRemoteLinkedArtifactReference } from "../core/validate/linked-artifact-reference.js";
|
|
17
|
-
import { EXIT_CODE } from "../core/shared/constants.js";
|
|
18
|
-
import { PmCliError } from "../core/shared/errors.js";
|
|
19
|
-
import { stableValueEquals } from "../core/shared/serialization.js";
|
|
20
|
-
import { locateItem, mutateItem, readLocatedItem, } from "../core/store/item-store.js";
|
|
21
|
-
import { resolvePmRoot, resolveWorkspaceRoot } from "../core/store/paths.js";
|
|
22
|
-
import { readSettings } from "../core/store/settings.js";
|
|
23
|
-
import { SCOPE_VALUES } from "../types/index.js";
|
|
24
|
-
import { resolveAuthor } from "../core/shared/author.js";
|
|
25
|
-
/** Allowed CSV/markdown keys for each structured linked-artifact option (GH-258). */
|
|
26
|
-
export const LINKED_ARTIFACT_ADD_KEYS = ["path", "scope", "note"];
|
|
27
|
-
/** Public contract for linked artifact add glob keys, shared by SDK and presentation-layer consumers. */
|
|
28
|
-
export const LINKED_ARTIFACT_ADD_GLOB_KEYS = [
|
|
29
|
-
"pattern",
|
|
30
|
-
"glob",
|
|
31
|
-
"path",
|
|
32
|
-
"scope",
|
|
33
|
-
"note",
|
|
34
|
-
];
|
|
35
|
-
/** Public contract for linked artifact remove keys, shared by SDK and presentation-layer consumers. */
|
|
36
|
-
export const LINKED_ARTIFACT_REMOVE_KEYS = ["path"];
|
|
37
|
-
/** Public contract for linked artifact migrate keys, shared by SDK and presentation-layer consumers. */
|
|
38
|
-
export const LINKED_ARTIFACT_MIGRATE_KEYS = ["from", "to"];
|
|
39
|
-
/** Keys that are valid on --add but meaningless on --remove (GH-277). Rejected with audit-trail guidance (--message) rather than the generic unknown-key error so agents are not left believing a removal note was recorded. */
|
|
40
|
-
const LINKED_ARTIFACT_REMOVE_UNSUPPORTED_KEYS = new Set([
|
|
41
|
-
"note",
|
|
42
|
-
"scope",
|
|
43
|
-
]);
|
|
44
|
-
/** Implements ensure scope for the public runtime surface of this module. */
|
|
45
|
-
export function ensureScope(raw) {
|
|
46
|
-
const value = (raw ?? "project");
|
|
47
|
-
if (!SCOPE_VALUES.includes(value)) {
|
|
48
|
-
throw new PmCliError(`Invalid scope "${raw}". Valid scopes: ${SCOPE_VALUES.join(", ")} (default: project).`, EXIT_CODE.USAGE);
|
|
49
|
-
}
|
|
50
|
-
return value;
|
|
51
|
-
}
|
|
52
|
-
/** Implements looks like structured path entry for the public runtime surface of this module. */
|
|
53
|
-
export function looksLikeStructuredPathEntry(raw) {
|
|
54
|
-
if (raw.startsWith("```") || raw.includes("\n")) {
|
|
55
|
-
return true;
|
|
56
|
-
}
|
|
57
|
-
if (/^(?:[-*+]\s+)?(?:path|scope|note)\s*[:=]/i.test(raw)) {
|
|
58
|
-
return true;
|
|
59
|
-
}
|
|
60
|
-
// An equals sign is valid inside filesystem paths and URL query strings.
|
|
61
|
-
// Preserve unmistakable whitespace-free path/URL shapes while routing
|
|
62
|
-
// leading assignment syntax through the structured-key allowlist so typos
|
|
63
|
-
// and malformed URL-plus-note input remain atomic failures (GH-258,
|
|
64
|
-
// GH-1000).
|
|
65
|
-
const firstCommaIndex = raw.indexOf(",");
|
|
66
|
-
const leadingSegment = raw.slice(0, firstCommaIndex >= 0 ? firstCommaIndex : raw.length);
|
|
67
|
-
const equalsIndex = leadingSegment.indexOf("=");
|
|
68
|
-
if (equalsIndex >= 0 &&
|
|
69
|
-
!/\s/u.test(raw) &&
|
|
70
|
-
(/^[A-Za-z][A-Za-z0-9+.-]*:\/\//u.test(raw) ||
|
|
71
|
-
/^(?:[A-Za-z]:[\\/]|[\\/]{1,2}|\.\.?(?:[\\/]))/u.test(raw) ||
|
|
72
|
-
[raw.indexOf("/"), raw.indexOf("\\")].some((separatorIndex) => separatorIndex >= 0 && separatorIndex < equalsIndex))) {
|
|
73
|
-
return false;
|
|
74
|
-
}
|
|
75
|
-
return leadingSegment.includes("=") || looksLikeGenericKeyValueEntry(raw);
|
|
76
|
-
}
|
|
77
|
-
/** Whether a Markdown destination contains only balanced parentheses. */
|
|
78
|
-
function hasBalancedParentheses(value) {
|
|
79
|
-
let depth = 0;
|
|
80
|
-
for (const character of value) {
|
|
81
|
-
if (character === "(")
|
|
82
|
-
depth += 1;
|
|
83
|
-
if (character === ")")
|
|
84
|
-
depth -= 1;
|
|
85
|
-
if (depth < 0)
|
|
86
|
-
return false;
|
|
87
|
-
}
|
|
88
|
-
return depth === 0;
|
|
89
|
-
}
|
|
90
|
-
/** Parse one lossless bare, Markdown, or CSV-label remote documentation reference. */
|
|
91
|
-
function parseDocumentationReference(trimmed) {
|
|
92
|
-
if (/^[A-Za-z][A-Za-z0-9+.-]*:\/\//u.test(trimmed) &&
|
|
93
|
-
!looksLikeStructuredPathEntry(trimmed)) {
|
|
94
|
-
return { path: trimmed, scope: "project", note: undefined };
|
|
95
|
-
}
|
|
96
|
-
const labelEnd = trimmed.indexOf("](");
|
|
97
|
-
if (trimmed.startsWith("[") && labelEnd > 0 && trimmed.endsWith(")")) {
|
|
98
|
-
const destination = trimmed.slice(labelEnd + 2, -1).trim();
|
|
99
|
-
if (destination.length > 0 && hasBalancedParentheses(destination)) {
|
|
100
|
-
return {
|
|
101
|
-
path: destination,
|
|
102
|
-
scope: "project",
|
|
103
|
-
note: trimmed.slice(1, labelEnd).trim() || undefined,
|
|
104
|
-
};
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
const delimiterIndex = trimmed.indexOf(",");
|
|
108
|
-
if (delimiterIndex < 0)
|
|
109
|
-
return undefined;
|
|
110
|
-
const label = trimmed.slice(0, delimiterIndex).trim();
|
|
111
|
-
const destination = trimmed.slice(delimiterIndex + 1).trim();
|
|
112
|
-
if (label.length === 0 ||
|
|
113
|
-
!/^[A-Za-z][A-Za-z0-9+.-]*:\/\//u.test(destination)) {
|
|
114
|
-
return undefined;
|
|
115
|
-
}
|
|
116
|
-
return { path: destination, scope: "project", note: label };
|
|
117
|
-
}
|
|
118
|
-
/** Implements parse add entries for the public runtime surface of this module. */
|
|
119
|
-
export function parseAddEntries(raw, bareNoun) {
|
|
120
|
-
if (!raw)
|
|
121
|
-
return [];
|
|
122
|
-
return raw.flatMap((entry) => {
|
|
123
|
-
const trimmed = entry.trim();
|
|
124
|
-
if (bareNoun === "doc") {
|
|
125
|
-
const reference = parseDocumentationReference(trimmed);
|
|
126
|
-
if (reference !== undefined)
|
|
127
|
-
return [reference];
|
|
128
|
-
}
|
|
129
|
-
assertNoAmbiguousBareCommaEntry(trimmed, "--add", `${bareNoun} path`, looksLikeStructuredPathEntry(trimmed));
|
|
130
|
-
const kv = looksLikeStructuredPathEntry(trimmed)
|
|
131
|
-
? parseCsvKv(entry, "--add")
|
|
132
|
-
: { path: trimmed };
|
|
133
|
-
assertNoUnknownCsvKeys(kv, "--add", LINKED_ARTIFACT_ADD_KEYS);
|
|
134
|
-
if (!kv.path) {
|
|
135
|
-
throw new PmCliError(`--add requires path=<value> or a bare ${bareNoun} path`, EXIT_CODE.USAGE);
|
|
136
|
-
}
|
|
137
|
-
return [
|
|
138
|
-
{
|
|
139
|
-
path: kv.path,
|
|
140
|
-
scope: ensureScope(kv.scope),
|
|
141
|
-
note: kv.note?.trim() || undefined,
|
|
142
|
-
},
|
|
143
|
-
];
|
|
144
|
-
});
|
|
145
|
-
}
|
|
146
|
-
/** Implements parse add glob entries for the public runtime surface of this module. */
|
|
147
|
-
export function parseAddGlobEntries(raw) {
|
|
148
|
-
if (!raw)
|
|
149
|
-
return [];
|
|
150
|
-
return raw.map((entry) => {
|
|
151
|
-
const trimmed = entry.trim();
|
|
152
|
-
if (!trimmed) {
|
|
153
|
-
throw new PmCliError("--add-glob requires a glob pattern value", EXIT_CODE.USAGE);
|
|
154
|
-
}
|
|
155
|
-
if (trimmed.includes("=") ||
|
|
156
|
-
/^(?:[-*+]\s+)?(?:pattern|glob|path)\s*[:=]/i.test(trimmed) ||
|
|
157
|
-
trimmed.startsWith("```")) {
|
|
158
|
-
const kv = parseCsvKv(trimmed, "--add-glob");
|
|
159
|
-
assertNoUnknownCsvKeys(kv, "--add-glob", LINKED_ARTIFACT_ADD_GLOB_KEYS);
|
|
160
|
-
const pattern = kv.pattern?.trim() || kv.glob?.trim() || kv.path?.trim();
|
|
161
|
-
if (!pattern) {
|
|
162
|
-
throw new PmCliError("--add-glob key/value form requires pattern=<glob>", EXIT_CODE.USAGE);
|
|
163
|
-
}
|
|
164
|
-
return {
|
|
165
|
-
pattern,
|
|
166
|
-
scope: ensureScope(kv.scope),
|
|
167
|
-
note: kv.note?.trim() || undefined,
|
|
168
|
-
};
|
|
169
|
-
}
|
|
170
|
-
return {
|
|
171
|
-
pattern: trimmed,
|
|
172
|
-
scope: "project",
|
|
173
|
-
};
|
|
174
|
-
});
|
|
175
|
-
}
|
|
176
|
-
/** Implements parse remove entries for the public runtime surface of this module. */
|
|
177
|
-
export function parseRemoveEntries(raw) {
|
|
178
|
-
if (!raw)
|
|
179
|
-
return [];
|
|
180
|
-
return raw.map((entry) => {
|
|
181
|
-
const trimmed = entry.trim();
|
|
182
|
-
if (!trimmed) {
|
|
183
|
-
throw new PmCliError("--remove requires a path value", EXIT_CODE.USAGE);
|
|
184
|
-
}
|
|
185
|
-
if (trimmed.includes("=") ||
|
|
186
|
-
/^(?:[-*+]\s+)?path\s*[:=]/i.test(trimmed) ||
|
|
187
|
-
trimmed.startsWith("```")) {
|
|
188
|
-
const kv = parseCsvKv(trimmed, "--remove");
|
|
189
|
-
// GH-277: --remove identifies an existing link by path only; it does not
|
|
190
|
-
// attach per-link metadata. Reject the --add-only keys with guidance toward
|
|
191
|
-
// the audit-trail path (--message) rather than the generic "unrecognized
|
|
192
|
-
// key" error, which left agents believing they had recorded a removal note.
|
|
193
|
-
const unsupportedRemoveKeys = Object.keys(kv).filter((key) => LINKED_ARTIFACT_REMOVE_UNSUPPORTED_KEYS.has(key.toLowerCase()));
|
|
194
|
-
if (unsupportedRemoveKeys.length > 0) {
|
|
195
|
-
throw new PmCliError(`--remove identifies a linked artifact by path only and does not accept ${unsupportedRemoveKeys
|
|
196
|
-
.map((key) => `"${key}"`)
|
|
197
|
-
.join(", ")}. Pass just the path (path=<value>, path:<value>, or a bare path); record removal context with --message "<why removed>".`, EXIT_CODE.USAGE);
|
|
198
|
-
}
|
|
199
|
-
assertNoUnknownCsvKeys(kv, "--remove", LINKED_ARTIFACT_REMOVE_KEYS);
|
|
200
|
-
if (!kv.path) {
|
|
201
|
-
throw new PmCliError("--remove key/value form requires path=<value>", EXIT_CODE.USAGE);
|
|
202
|
-
}
|
|
203
|
-
return kv.path;
|
|
204
|
-
}
|
|
205
|
-
return trimmed;
|
|
206
|
-
});
|
|
207
|
-
}
|
|
208
|
-
/** Implements parse migrate entries for the public runtime surface of this module. */
|
|
209
|
-
export function parseMigrateEntries(raw) {
|
|
210
|
-
if (!raw)
|
|
211
|
-
return [];
|
|
212
|
-
return raw.map((entry) => {
|
|
213
|
-
const kv = parseCsvKv(entry, "--migrate");
|
|
214
|
-
assertNoUnknownCsvKeys(kv, "--migrate", LINKED_ARTIFACT_MIGRATE_KEYS);
|
|
215
|
-
const from = kv.from?.trim();
|
|
216
|
-
const to = kv.to?.trim();
|
|
217
|
-
if (!from || !to) {
|
|
218
|
-
throw new PmCliError("--migrate requires from=<value> and to=<value>", EXIT_CODE.USAGE);
|
|
219
|
-
}
|
|
220
|
-
return { from, to };
|
|
221
|
-
});
|
|
222
|
-
}
|
|
223
|
-
/** Implements apply path migrations for the public runtime surface of this module. */
|
|
224
|
-
export function applyPathMigrations(artifactPath, migrations) {
|
|
225
|
-
let next = artifactPath;
|
|
226
|
-
for (const migration of migrations) {
|
|
227
|
-
if (next.startsWith(migration.from)) {
|
|
228
|
-
next = `${migration.to}${next.slice(migration.from.length)}`;
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
return next;
|
|
232
|
-
}
|
|
233
|
-
/** Reject a transaction that resolves the same linked path into both add and remove sets. */
|
|
234
|
-
export function assertLinkedArtifactMutationIsUnambiguous(adds, removes, migrations = []) {
|
|
235
|
-
if (adds.length === 0 || removes.length === 0) {
|
|
236
|
-
return;
|
|
237
|
-
}
|
|
238
|
-
const addedPaths = new Set(adds.map((entry) => applyPathMigrations(entry.path, migrations)));
|
|
239
|
-
const conflicts = [
|
|
240
|
-
...new Set(removes
|
|
241
|
-
.map((entry) => applyPathMigrations(entry, migrations))
|
|
242
|
-
.filter((entry) => addedPaths.has(entry))),
|
|
243
|
-
].sort((left, right) => left.localeCompare(right));
|
|
244
|
-
if (conflicts.length === 0) {
|
|
245
|
-
return;
|
|
246
|
-
}
|
|
247
|
-
throw new PmCliError(`Linked artifact mutation cannot add and remove the same normalized path in one transaction: ${conflicts.join(", ")}. Split the replacement into separate commands so each history event has one unambiguous intent.`, EXIT_CODE.USAGE, {
|
|
248
|
-
code: "linked_artifact_mutation_conflict",
|
|
249
|
-
reason: "same_path_added_and_removed",
|
|
250
|
-
required: "Use distinct normalized paths for --add and --remove in one invocation.",
|
|
251
|
-
why: "Conflicting batch intent cannot be applied deterministically without silently discarding metadata or a removal.",
|
|
252
|
-
nextSteps: [
|
|
253
|
-
"Run the removal and addition as separate commands with a --message describing each intent.",
|
|
254
|
-
],
|
|
255
|
-
});
|
|
256
|
-
}
|
|
257
|
-
/** Implements normalize linked path for the public runtime surface of this module. */
|
|
258
|
-
export function normalizeLinkedPath(value) {
|
|
259
|
-
return value.split(path.sep).join("/");
|
|
260
|
-
}
|
|
261
|
-
/** Anchor a local linked path to the project workspace while preserving remote references and absolute paths. */
|
|
262
|
-
export function anchorLinkedPath(value, workspaceRoot, invocationRoot = process.cwd()) {
|
|
263
|
-
const trimmed = value.trim();
|
|
264
|
-
if (isRemoteLinkedArtifactReference(trimmed)) {
|
|
265
|
-
return trimmed;
|
|
266
|
-
}
|
|
267
|
-
if (path.isAbsolute(trimmed) || /^[A-Za-z]:[\\/]/.test(trimmed)) {
|
|
268
|
-
return normalizeLinkedPath(trimmed.replaceAll("\\", path.sep));
|
|
269
|
-
}
|
|
270
|
-
const invocationRelativeToWorkspace = path.relative(workspaceRoot, invocationRoot);
|
|
271
|
-
if (invocationRelativeToWorkspace.startsWith(`..${path.sep}`) ||
|
|
272
|
-
invocationRelativeToWorkspace === ".." ||
|
|
273
|
-
path.isAbsolute(invocationRelativeToWorkspace)) {
|
|
274
|
-
return normalizeLinkedPath(path.normalize(trimmed));
|
|
275
|
-
}
|
|
276
|
-
return normalizeLinkedPath(path.relative(workspaceRoot, path.resolve(invocationRoot, trimmed)));
|
|
277
|
-
}
|
|
278
|
-
/** Implements expand add glob entries for the public runtime surface of this module. */
|
|
279
|
-
export async function expandAddGlobEntries(entries, workspaceRoot = process.cwd(), invocationRoot = process.cwd()) {
|
|
280
|
-
const expanded = [];
|
|
281
|
-
for (const entry of entries) {
|
|
282
|
-
const absolutePattern = path.isAbsolute(entry.pattern);
|
|
283
|
-
const matches = await fg(entry.pattern, {
|
|
284
|
-
cwd: invocationRoot,
|
|
285
|
-
absolute: absolutePattern,
|
|
286
|
-
onlyFiles: true,
|
|
287
|
-
dot: true,
|
|
288
|
-
unique: true,
|
|
289
|
-
followSymbolicLinks: true,
|
|
290
|
-
});
|
|
291
|
-
const sortedMatches = [
|
|
292
|
-
...new Set(matches.map((match) => anchorLinkedPath(match, workspaceRoot, invocationRoot))),
|
|
293
|
-
].sort((left, right) => left.localeCompare(right));
|
|
294
|
-
for (const matchedPath of sortedMatches) {
|
|
295
|
-
expanded.push({
|
|
296
|
-
path: matchedPath,
|
|
297
|
-
scope: entry.scope,
|
|
298
|
-
note: entry.note,
|
|
299
|
-
});
|
|
300
|
-
}
|
|
301
|
-
}
|
|
302
|
-
return expanded;
|
|
303
|
-
}
|
|
304
|
-
/** GH-170 (pm-pfnx): apply a standalone --note to the links added in this invocation. Semantics (documented on pm-pfnx): the note is attached to EVERY entry added via --add/--add-glob so a single flag annotates the whole batch predictably; a per-entry embedded `note=` wins over the standalone flag; and --note without any --add/--add-glob flag is a usage error because there is nothing to annotate (it never retro-edits existing links). `hasAddFlags` reflects flag presence, not match count, so a glob that legitimately matches zero files is not an error. */
|
|
305
|
-
export function applyStandaloneNote(adds, note, hasAddFlags) {
|
|
306
|
-
if (note === undefined) {
|
|
307
|
-
return adds;
|
|
308
|
-
}
|
|
309
|
-
if (!hasAddFlags) {
|
|
310
|
-
throw new PmCliError("--note requires --add or --add-glob in the same invocation (the note annotates the links being added)", EXIT_CODE.USAGE);
|
|
311
|
-
}
|
|
312
|
-
const trimmed = note.trim();
|
|
313
|
-
if (trimmed.length === 0) {
|
|
314
|
-
return adds;
|
|
315
|
-
}
|
|
316
|
-
return adds.map((entry) => entry.note === undefined ? { ...entry, note: trimmed } : entry);
|
|
317
|
-
}
|
|
318
|
-
/** Implements artifact key for the public runtime surface of this module. */
|
|
319
|
-
export function artifactKey(value) {
|
|
320
|
-
return `${value.path}::${value.scope}`;
|
|
321
|
-
}
|
|
322
|
-
/** Implements sort linked artifacts for the public runtime surface of this module. */
|
|
323
|
-
export function sortLinkedArtifacts(artifacts) {
|
|
324
|
-
return [...artifacts].sort((left, right) => {
|
|
325
|
-
const byPath = left.path.localeCompare(right.path);
|
|
326
|
-
if (byPath !== 0)
|
|
327
|
-
return byPath;
|
|
328
|
-
return left.scope.localeCompare(right.scope);
|
|
329
|
-
});
|
|
330
|
-
}
|
|
331
|
-
/** Implements dedupe linked artifacts for the public runtime surface of this module. */
|
|
332
|
-
export function dedupeLinkedArtifacts(artifacts) {
|
|
333
|
-
return [
|
|
334
|
-
...new Map(artifacts.map((entry) => [artifactKey(entry), entry])).values(),
|
|
335
|
-
].map((entry) => ({
|
|
336
|
-
...entry,
|
|
337
|
-
note: entry.note?.trim() || undefined,
|
|
338
|
-
}));
|
|
339
|
-
}
|
|
340
|
-
/** Implements validate linked paths for the public runtime surface of this module. */
|
|
341
|
-
export async function validateLinkedPaths(paths, workspaceRoot = process.cwd()) {
|
|
342
|
-
const uniquePaths = [...new Set(paths)].sort((left, right) => left.localeCompare(right));
|
|
343
|
-
const existingFiles = [];
|
|
344
|
-
const missingPaths = [];
|
|
345
|
-
const nonFilePaths = [];
|
|
346
|
-
const remoteReferences = [];
|
|
347
|
-
for (const relativePath of uniquePaths) {
|
|
348
|
-
// Remote references (https:// PR/issue/design-doc URLs) are not local
|
|
349
|
-
// files; report them separately (trimmed, to match buildFilesCheck's
|
|
350
|
-
// output shape) instead of probing a meaningless path.
|
|
351
|
-
if (isRemoteLinkedArtifactReference(relativePath)) {
|
|
352
|
-
remoteReferences.push(relativePath.trim());
|
|
353
|
-
continue;
|
|
354
|
-
}
|
|
355
|
-
const resolvedPath = path.isAbsolute(relativePath)
|
|
356
|
-
? relativePath
|
|
357
|
-
: path.resolve(workspaceRoot, relativePath);
|
|
358
|
-
try {
|
|
359
|
-
const stats = await fs.stat(resolvedPath);
|
|
360
|
-
if (stats.isFile()) {
|
|
361
|
-
existingFiles.push(relativePath);
|
|
362
|
-
}
|
|
363
|
-
else {
|
|
364
|
-
nonFilePaths.push(relativePath);
|
|
365
|
-
}
|
|
366
|
-
}
|
|
367
|
-
catch (error) {
|
|
368
|
-
if (typeof error === "object" &&
|
|
369
|
-
error !== null &&
|
|
370
|
-
"code" in error &&
|
|
371
|
-
isFileAbsentError(error)) {
|
|
372
|
-
missingPaths.push(relativePath);
|
|
373
|
-
continue;
|
|
374
|
-
}
|
|
375
|
-
nonFilePaths.push(relativePath);
|
|
376
|
-
}
|
|
377
|
-
}
|
|
378
|
-
return {
|
|
379
|
-
checked: uniquePaths.length,
|
|
380
|
-
existing_files: existingFiles,
|
|
381
|
-
missing_paths: missingPaths,
|
|
382
|
-
non_file_paths: nonFilePaths,
|
|
383
|
-
remote_references: remoteReferences,
|
|
384
|
-
};
|
|
385
|
-
}
|
|
386
|
-
function applyLinkedArtifactMigrations(current, adds, removes, migrations) {
|
|
387
|
-
let count = 0;
|
|
388
|
-
for (let index = 0; index < current.length; index += 1) {
|
|
389
|
-
const migratedPath = applyPathMigrations(current[index].path, migrations);
|
|
390
|
-
if (migratedPath !== current[index].path) {
|
|
391
|
-
current[index] = { ...current[index], path: migratedPath };
|
|
392
|
-
count += 1;
|
|
393
|
-
}
|
|
394
|
-
}
|
|
395
|
-
const migratedAdds = adds.map((entry) => {
|
|
396
|
-
const migratedPath = applyPathMigrations(entry.path, migrations);
|
|
397
|
-
if (migratedPath !== entry.path)
|
|
398
|
-
count += 1;
|
|
399
|
-
return { ...entry, path: migratedPath };
|
|
400
|
-
});
|
|
401
|
-
return {
|
|
402
|
-
adds: migratedAdds,
|
|
403
|
-
removes: removes.map((entry) => applyPathMigrations(entry, migrations)),
|
|
404
|
-
count,
|
|
405
|
-
};
|
|
406
|
-
}
|
|
407
|
-
function mergeLinkedArtifactChanges(current, adds, removes, appendStable) {
|
|
408
|
-
for (const add of adds) {
|
|
409
|
-
if (!current.some((entry) => entry.path === add.path && entry.scope === add.scope)) {
|
|
410
|
-
current.push(add);
|
|
411
|
-
}
|
|
412
|
-
}
|
|
413
|
-
if (removes.length > 0) {
|
|
414
|
-
for (let index = current.length - 1; index >= 0; index -= 1) {
|
|
415
|
-
if (removes.includes(current[index].path))
|
|
416
|
-
current.splice(index, 1);
|
|
417
|
-
}
|
|
418
|
-
}
|
|
419
|
-
const deduped = dedupeLinkedArtifacts(current);
|
|
420
|
-
return appendStable ? deduped : sortLinkedArtifacts(deduped);
|
|
421
|
-
}
|
|
422
|
-
async function buildLinkedArtifactResult(params) {
|
|
423
|
-
const paths = params.artifacts.map((entry) => entry.path);
|
|
424
|
-
return {
|
|
425
|
-
id: params.id,
|
|
426
|
-
artifacts: params.artifacts,
|
|
427
|
-
changed: params.changed,
|
|
428
|
-
count: params.artifacts.length,
|
|
429
|
-
migrations_applied: params.migrationsApplied && params.migrationsApplied > 0
|
|
430
|
-
? params.migrationsApplied
|
|
431
|
-
: undefined,
|
|
432
|
-
validation: params.options.validatePaths || params.changed
|
|
433
|
-
? await validateLinkedPaths(paths, params.workspaceRoot)
|
|
434
|
-
: undefined,
|
|
435
|
-
};
|
|
436
|
-
}
|
|
437
|
-
/** Shared linked-artifact list/mutate command core used by runFiles and runDocs. The kind config selects metadata key, op, bare-path noun, and whether append-stable ordering is honored, preserving each twin's exact semantics. */
|
|
438
|
-
export async function runLinkedArtifacts(id, options, global, config) {
|
|
439
|
-
const { metadataKey } = config;
|
|
440
|
-
const stdinResolver = createStdinTokenResolver();
|
|
441
|
-
const pmRoot = resolvePmRoot(process.cwd(), global.path);
|
|
442
|
-
const workspaceRoot = resolveWorkspaceRoot(pmRoot);
|
|
443
|
-
const invocationRoot = process.cwd();
|
|
444
|
-
await assertInitializedTracker(pmRoot);
|
|
445
|
-
const settings = await readSettings(pmRoot);
|
|
446
|
-
const typeRegistry = resolveItemTypeRegistry(settings, getActiveExtensionRegistrations());
|
|
447
|
-
const resolvedAdds = await stdinResolver.resolveList(options.add, "--add");
|
|
448
|
-
const resolvedAddGlobs = await stdinResolver.resolveList(options.addGlob, "--add-glob");
|
|
449
|
-
const resolvedRemoves = await stdinResolver.resolveList(options.remove, "--remove");
|
|
450
|
-
const resolvedMigrations = await stdinResolver.resolveList(options.migrate, "--migrate");
|
|
451
|
-
const parsedAdds = parseAddEntries(resolvedAdds, config.bareNoun).map((entry) => ({
|
|
452
|
-
...entry,
|
|
453
|
-
path: anchorLinkedPath(entry.path, workspaceRoot, invocationRoot),
|
|
454
|
-
}));
|
|
455
|
-
const addGlobs = parseAddGlobEntries(resolvedAddGlobs);
|
|
456
|
-
const expandedGlobAdds = await expandAddGlobEntries(addGlobs, workspaceRoot, invocationRoot);
|
|
457
|
-
const adds = applyStandaloneNote([...parsedAdds, ...expandedGlobAdds], options.note, parsedAdds.length > 0 || addGlobs.length > 0);
|
|
458
|
-
const removes = parseRemoveEntries(resolvedRemoves).map((entry) => anchorLinkedPath(entry, workspaceRoot, invocationRoot));
|
|
459
|
-
const migrations = parseMigrateEntries(resolvedMigrations);
|
|
460
|
-
assertLinkedArtifactMutationIsUnambiguous(adds, removes, migrations);
|
|
461
|
-
const shouldMutate = adds.length > 0 || removes.length > 0 || migrations.length > 0;
|
|
462
|
-
if (!shouldMutate) {
|
|
463
|
-
const located = await locateItem(pmRoot, id, settings.id_prefix, settings.item_format, typeRegistry.type_to_folder);
|
|
464
|
-
if (!located) {
|
|
465
|
-
throw new PmCliError(`Item ${id} not found`, EXIT_CODE.NOT_FOUND);
|
|
466
|
-
}
|
|
467
|
-
const loaded = await readLocatedItem(located, { schema: settings.schema });
|
|
468
|
-
const artifacts = loaded.document.metadata[metadataKey] ?? [];
|
|
469
|
-
return buildLinkedArtifactResult({
|
|
470
|
-
id: located.id,
|
|
471
|
-
artifacts,
|
|
472
|
-
changed: false,
|
|
473
|
-
options,
|
|
474
|
-
workspaceRoot,
|
|
475
|
-
});
|
|
476
|
-
}
|
|
477
|
-
const author = resolveAuthor(options.author, settings.author_default);
|
|
478
|
-
const result = await mutateItem({
|
|
479
|
-
pmRoot,
|
|
480
|
-
settings,
|
|
481
|
-
id,
|
|
482
|
-
op: config.op,
|
|
483
|
-
author,
|
|
484
|
-
message: options.message,
|
|
485
|
-
force: options.force,
|
|
486
|
-
skipNoop: true,
|
|
487
|
-
mutate(document) {
|
|
488
|
-
const metadata = document.metadata;
|
|
489
|
-
const current = metadata[metadataKey] ?? [];
|
|
490
|
-
const next = [...current];
|
|
491
|
-
const migrated = applyLinkedArtifactMigrations(next, adds, removes, migrations);
|
|
492
|
-
const normalized = mergeLinkedArtifactChanges(next, migrated.adds, migrated.removes, config.supportsAppendStable && options.appendStable === true);
|
|
493
|
-
if (normalized.length > 0) {
|
|
494
|
-
metadata[metadataKey] = normalized;
|
|
495
|
-
}
|
|
496
|
-
else {
|
|
497
|
-
delete metadata[metadataKey];
|
|
498
|
-
}
|
|
499
|
-
const changed = !stableValueEquals(current, normalized);
|
|
500
|
-
return {
|
|
501
|
-
changedFields: changed ? [metadataKey] : [],
|
|
502
|
-
warnings: changed && migrated.count > 0
|
|
503
|
-
? [`path_migrations_applied:${migrated.count}`]
|
|
504
|
-
: [],
|
|
505
|
-
};
|
|
506
|
-
},
|
|
507
|
-
});
|
|
508
|
-
const artifacts = result.item[metadataKey] ?? [];
|
|
509
|
-
const migrationWarning = result.warnings.find((warning) => warning.startsWith("path_migrations_applied:"));
|
|
510
|
-
const migrationCount = migrationWarning
|
|
511
|
-
? Number(migrationWarning.slice("path_migrations_applied:".length))
|
|
512
|
-
: 0;
|
|
513
|
-
return buildLinkedArtifactResult({
|
|
514
|
-
id: result.item.id,
|
|
515
|
-
artifacts,
|
|
516
|
-
changed: result.changedFields.includes(metadataKey),
|
|
517
|
-
migrationsApplied: migrationCount,
|
|
518
|
-
options,
|
|
519
|
-
workspaceRoot,
|
|
520
|
-
});
|
|
521
|
-
}
|
|
522
|
-
/** Re-key the generic `artifacts` field to the resource-specific name (files/docs) while preserving the original key order and presence so kind-specific result shapes (and their deterministic JSON key ordering) stay byte-identical. */
|
|
523
|
-
export function renameArtifactsResultKey(result, key) {
|
|
524
|
-
const out = {};
|
|
525
|
-
for (const [field, value] of Object.entries(result)) {
|
|
526
|
-
out[field === "artifacts" ? key : field] = value;
|
|
527
|
-
}
|
|
528
|
-
return out;
|
|
529
|
-
}
|
|
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]="02743545-3a44-565d-932c-7fe736d17eb8")}catch(e2){}})();import{assertInitializedTracker}from"./environment/tracker-preflight.js";import fs from"node:fs/promises";import path from"node:path";import fg from"fast-glob";import{isFileAbsentError}from"../core/fs/fs-utils.js";import{getActiveExtensionRegistrations}from"../core/extensions/index.js";import{assertNoAmbiguousBareCommaEntry,assertNoUnknownCsvKeys,createStdinTokenResolver,looksLikeGenericKeyValueEntry,parseCsvKv}from"../core/item/parse.js";import{resolveItemTypeRegistry}from"../core/item/type-registry.js";import{isRemoteLinkedArtifactReference}from"../core/validate/linked-artifact-reference.js";import{EXIT_CODE}from"../core/shared/constants.js";import{PmCliError}from"../core/shared/errors.js";import{stableValueEquals}from"../core/shared/serialization.js";import{locateItem,mutateItem,readLocatedItem}from"../core/store/item-store.js";import{resolvePmRoot,resolveWorkspaceRoot}from"../core/store/paths.js";import{readSettings}from"../core/store/settings.js";import{SCOPE_VALUES}from"../types/index.js";import{resolveAuthor}from"../core/shared/author.js";const LINKED_ARTIFACT_ADD_KEYS=["path","scope","note"];const LINKED_ARTIFACT_ADD_GLOB_KEYS=["pattern","glob","path","scope","note"];const LINKED_ARTIFACT_REMOVE_KEYS=["path"];const LINKED_ARTIFACT_MIGRATE_KEYS=["from","to"];const LINKED_ARTIFACT_REMOVE_UNSUPPORTED_KEYS=new Set(["note","scope"]);function ensureScope(raw){const value=raw??"project";if(!SCOPE_VALUES.includes(value)){throw new PmCliError(`Invalid scope "${raw}". Valid scopes: ${SCOPE_VALUES.join(", ")} (default: project).`,EXIT_CODE.USAGE)}return value}function looksLikeStructuredPathEntry(raw){if(raw.startsWith("```")||raw.includes("\n")){return true}if(/^(?:[-*+]\s+)?(?:path|scope|note)\s*[:=]/i.test(raw)){return true}const firstCommaIndex=raw.indexOf(",");const leadingSegment=raw.slice(0,firstCommaIndex>=0?firstCommaIndex:raw.length);const equalsIndex=leadingSegment.indexOf("=");if(equalsIndex>=0&&!/\s/u.test(raw)&&(/^[A-Za-z][A-Za-z0-9+.-]*:\/\//u.test(raw)||/^(?:[A-Za-z]:[\\/]|[\\/]{1,2}|\.\.?(?:[\\/]))/u.test(raw)||[raw.indexOf("/"),raw.indexOf("\\")].some(separatorIndex=>separatorIndex>=0&&separatorIndex<equalsIndex))){return false}return leadingSegment.includes("=")||looksLikeGenericKeyValueEntry(raw)}function hasBalancedParentheses(value){let depth=0;for(const character of value){if(character==="(")depth+=1;if(character===")")depth-=1;if(depth<0)return false}return depth===0}function parseDocumentationReference(trimmed){if(/^[A-Za-z][A-Za-z0-9+.-]*:\/\//u.test(trimmed)&&!looksLikeStructuredPathEntry(trimmed)){return{path:trimmed,scope:"project",note:void 0}}const labelEnd=trimmed.indexOf("](");if(trimmed.startsWith("[")&&labelEnd>0&&trimmed.endsWith(")")){const destination2=trimmed.slice(labelEnd+2,-1).trim();if(destination2.length>0&&hasBalancedParentheses(destination2)){return{path:destination2,scope:"project",note:trimmed.slice(1,labelEnd).trim()||void 0}}}const delimiterIndex=trimmed.indexOf(",");if(delimiterIndex<0)return void 0;const label=trimmed.slice(0,delimiterIndex).trim();const destination=trimmed.slice(delimiterIndex+1).trim();if(label.length===0||!/^[A-Za-z][A-Za-z0-9+.-]*:\/\//u.test(destination)){return void 0}return{path:destination,scope:"project",note:label}}function parseAddEntries(raw,bareNoun){if(!raw)return[];return raw.flatMap(entry=>{const trimmed=entry.trim();if(bareNoun==="doc"){const reference=parseDocumentationReference(trimmed);if(reference!==void 0)return[reference]}assertNoAmbiguousBareCommaEntry(trimmed,"--add",`${bareNoun} path`,looksLikeStructuredPathEntry(trimmed));const kv=looksLikeStructuredPathEntry(trimmed)?parseCsvKv(entry,"--add"):{path:trimmed};assertNoUnknownCsvKeys(kv,"--add",LINKED_ARTIFACT_ADD_KEYS);if(!kv.path){throw new PmCliError(`--add requires path=<value> or a bare ${bareNoun} path`,EXIT_CODE.USAGE)}return[{path:kv.path,scope:ensureScope(kv.scope),note:kv.note?.trim()||void 0}]})}function parseAddGlobEntries(raw){if(!raw)return[];return raw.map(entry=>{const trimmed=entry.trim();if(!trimmed){throw new PmCliError("--add-glob requires a glob pattern value",EXIT_CODE.USAGE)}if(trimmed.includes("=")||/^(?:[-*+]\s+)?(?:pattern|glob|path)\s*[:=]/i.test(trimmed)||trimmed.startsWith("```")){const kv=parseCsvKv(trimmed,"--add-glob");assertNoUnknownCsvKeys(kv,"--add-glob",LINKED_ARTIFACT_ADD_GLOB_KEYS);const pattern=kv.pattern?.trim()||kv.glob?.trim()||kv.path?.trim();if(!pattern){throw new PmCliError("--add-glob key/value form requires pattern=<glob>",EXIT_CODE.USAGE)}return{pattern,scope:ensureScope(kv.scope),note:kv.note?.trim()||void 0}}return{pattern:trimmed,scope:"project"}})}function parseRemoveEntries(raw){if(!raw)return[];return raw.map(entry=>{const trimmed=entry.trim();if(!trimmed){throw new PmCliError("--remove requires a path value",EXIT_CODE.USAGE)}if(trimmed.includes("=")||/^(?:[-*+]\s+)?path\s*[:=]/i.test(trimmed)||trimmed.startsWith("```")){const kv=parseCsvKv(trimmed,"--remove");const unsupportedRemoveKeys=Object.keys(kv).filter(key=>LINKED_ARTIFACT_REMOVE_UNSUPPORTED_KEYS.has(key.toLowerCase()));if(unsupportedRemoveKeys.length>0){throw new PmCliError(`--remove identifies a linked artifact by path only and does not accept ${unsupportedRemoveKeys.map(key=>`"${key}"`).join(", ")}. Pass just the path (path=<value>, path:<value>, or a bare path); record removal context with --message "<why removed>".`,EXIT_CODE.USAGE)}assertNoUnknownCsvKeys(kv,"--remove",LINKED_ARTIFACT_REMOVE_KEYS);if(!kv.path){throw new PmCliError("--remove key/value form requires path=<value>",EXIT_CODE.USAGE)}return kv.path}return trimmed})}function parseMigrateEntries(raw){if(!raw)return[];return raw.map(entry=>{const kv=parseCsvKv(entry,"--migrate");assertNoUnknownCsvKeys(kv,"--migrate",LINKED_ARTIFACT_MIGRATE_KEYS);const from=kv.from?.trim();const to=kv.to?.trim();if(!from||!to){throw new PmCliError("--migrate requires from=<value> and to=<value>",EXIT_CODE.USAGE)}return{from,to}})}function applyPathMigrations(artifactPath,migrations){let next=artifactPath;for(const migration of migrations){if(next.startsWith(migration.from)){next=`${migration.to}${next.slice(migration.from.length)}`}}return next}function assertLinkedArtifactMutationIsUnambiguous(adds,removes,migrations=[]){if(adds.length===0||removes.length===0){return}const addedPaths=new Set(adds.map(entry=>applyPathMigrations(entry.path,migrations)));const conflicts=[...new Set(removes.map(entry=>applyPathMigrations(entry,migrations)).filter(entry=>addedPaths.has(entry)))].sort((left,right)=>left.localeCompare(right));if(conflicts.length===0){return}throw new PmCliError(`Linked artifact mutation cannot add and remove the same normalized path in one transaction: ${conflicts.join(", ")}. Split the replacement into separate commands so each history event has one unambiguous intent.`,EXIT_CODE.USAGE,{code:"linked_artifact_mutation_conflict",reason:"same_path_added_and_removed",required:"Use distinct normalized paths for --add and --remove in one invocation.",why:"Conflicting batch intent cannot be applied deterministically without silently discarding metadata or a removal.",nextSteps:["Run the removal and addition as separate commands with a --message describing each intent."]})}function normalizeLinkedPath(value){return value.split(path.sep).join("/")}function anchorLinkedPath(value,workspaceRoot,invocationRoot=process.cwd()){const trimmed=value.trim();if(isRemoteLinkedArtifactReference(trimmed)){return trimmed}if(path.isAbsolute(trimmed)||/^[A-Za-z]:[\\/]/.test(trimmed)){return normalizeLinkedPath(trimmed.replaceAll("\\",path.sep))}const invocationRelativeToWorkspace=path.relative(workspaceRoot,invocationRoot);if(invocationRelativeToWorkspace.startsWith(`..${path.sep}`)||invocationRelativeToWorkspace===".."||path.isAbsolute(invocationRelativeToWorkspace)){return normalizeLinkedPath(path.normalize(trimmed))}return normalizeLinkedPath(path.relative(workspaceRoot,path.resolve(invocationRoot,trimmed)))}async function expandAddGlobEntries(entries,workspaceRoot=process.cwd(),invocationRoot=process.cwd()){const expanded=[];for(const entry of entries){const absolutePattern=path.isAbsolute(entry.pattern);const matches=await fg(entry.pattern,{cwd:invocationRoot,absolute:absolutePattern,onlyFiles:true,dot:true,unique:true,followSymbolicLinks:true});const sortedMatches=[...new Set(matches.map(match=>anchorLinkedPath(match,workspaceRoot,invocationRoot)))].sort((left,right)=>left.localeCompare(right));for(const matchedPath of sortedMatches){expanded.push({path:matchedPath,scope:entry.scope,note:entry.note})}}return expanded}function applyStandaloneNote(adds,note,hasAddFlags){if(note===void 0){return adds}if(!hasAddFlags){throw new PmCliError("--note requires --add or --add-glob in the same invocation (the note annotates the links being added)",EXIT_CODE.USAGE)}const trimmed=note.trim();if(trimmed.length===0){return adds}return adds.map(entry=>entry.note===void 0?{...entry,note:trimmed}:entry)}function artifactKey(value){return`${value.path}::${value.scope}`}function sortLinkedArtifacts(artifacts){return[...artifacts].sort((left,right)=>{const byPath=left.path.localeCompare(right.path);if(byPath!==0)return byPath;return left.scope.localeCompare(right.scope)})}function dedupeLinkedArtifacts(artifacts){return[...new Map(artifacts.map(entry=>[artifactKey(entry),entry])).values()].map(entry=>({...entry,note:entry.note?.trim()||void 0}))}async function validateLinkedPaths(paths,workspaceRoot=process.cwd()){const uniquePaths=[...new Set(paths)].sort((left,right)=>left.localeCompare(right));const existingFiles=[];const missingPaths=[];const nonFilePaths=[];const remoteReferences=[];for(const relativePath of uniquePaths){if(isRemoteLinkedArtifactReference(relativePath)){remoteReferences.push(relativePath.trim());continue}const resolvedPath=path.isAbsolute(relativePath)?relativePath:path.resolve(workspaceRoot,relativePath);try{const stats=await fs.stat(resolvedPath);if(stats.isFile()){existingFiles.push(relativePath)}else{nonFilePaths.push(relativePath)}}catch(error){if(typeof error==="object"&&error!==null&&"code"in error&&isFileAbsentError(error)){missingPaths.push(relativePath);continue}nonFilePaths.push(relativePath)}}return{checked:uniquePaths.length,existing_files:existingFiles,missing_paths:missingPaths,non_file_paths:nonFilePaths,remote_references:remoteReferences}}function applyLinkedArtifactMigrations(current,adds,removes,migrations){let count=0;for(let index=0;index<current.length;index+=1){const migratedPath=applyPathMigrations(current[index].path,migrations);if(migratedPath!==current[index].path){current[index]={...current[index],path:migratedPath};count+=1}}const migratedAdds=adds.map(entry=>{const migratedPath=applyPathMigrations(entry.path,migrations);if(migratedPath!==entry.path)count+=1;return{...entry,path:migratedPath}});return{adds:migratedAdds,removes:removes.map(entry=>applyPathMigrations(entry,migrations)),count}}function mergeLinkedArtifactChanges(current,adds,removes,appendStable){for(const add of adds){if(!current.some(entry=>entry.path===add.path&&entry.scope===add.scope)){current.push(add)}}if(removes.length>0){for(let index=current.length-1;index>=0;index-=1){if(removes.includes(current[index].path))current.splice(index,1)}}const deduped=dedupeLinkedArtifacts(current);return appendStable?deduped:sortLinkedArtifacts(deduped)}async function buildLinkedArtifactResult(params){const paths=params.artifacts.map(entry=>entry.path);return{id:params.id,artifacts:params.artifacts,changed:params.changed,count:params.artifacts.length,migrations_applied:params.migrationsApplied&¶ms.migrationsApplied>0?params.migrationsApplied:void 0,validation:params.options.validatePaths||params.changed?await validateLinkedPaths(paths,params.workspaceRoot):void 0}}async function runLinkedArtifacts(id,options,global2,config){const{metadataKey}=config;const stdinResolver=createStdinTokenResolver();const pmRoot=resolvePmRoot(process.cwd(),global2.path);const workspaceRoot=resolveWorkspaceRoot(pmRoot);const invocationRoot=process.cwd();await assertInitializedTracker(pmRoot);const settings=await readSettings(pmRoot);const typeRegistry=resolveItemTypeRegistry(settings,getActiveExtensionRegistrations());const resolvedAdds=await stdinResolver.resolveList(options.add,"--add");const resolvedAddGlobs=await stdinResolver.resolveList(options.addGlob,"--add-glob");const resolvedRemoves=await stdinResolver.resolveList(options.remove,"--remove");const resolvedMigrations=await stdinResolver.resolveList(options.migrate,"--migrate");const parsedAdds=parseAddEntries(resolvedAdds,config.bareNoun).map(entry=>({...entry,path:anchorLinkedPath(entry.path,workspaceRoot,invocationRoot)}));const addGlobs=parseAddGlobEntries(resolvedAddGlobs);const expandedGlobAdds=await expandAddGlobEntries(addGlobs,workspaceRoot,invocationRoot);const adds=applyStandaloneNote([...parsedAdds,...expandedGlobAdds],options.note,parsedAdds.length>0||addGlobs.length>0);const removes=parseRemoveEntries(resolvedRemoves).map(entry=>anchorLinkedPath(entry,workspaceRoot,invocationRoot));const migrations=parseMigrateEntries(resolvedMigrations);assertLinkedArtifactMutationIsUnambiguous(adds,removes,migrations);const shouldMutate=adds.length>0||removes.length>0||migrations.length>0;if(!shouldMutate){const located=await locateItem(pmRoot,id,settings.id_prefix,settings.item_format,typeRegistry.type_to_folder);if(!located){throw new PmCliError(`Item ${id} not found`,EXIT_CODE.NOT_FOUND)}const loaded=await readLocatedItem(located,{schema:settings.schema});const artifacts2=loaded.document.metadata[metadataKey]??[];return buildLinkedArtifactResult({id:located.id,artifacts:artifacts2,changed:false,options,workspaceRoot})}const author=resolveAuthor(options.author,settings.author_default);const result=await mutateItem({pmRoot,settings,id,op:config.op,author,message:options.message,force:options.force,skipNoop:true,mutate(document){const metadata=document.metadata;const current=metadata[metadataKey]??[];const next=[...current];const migrated=applyLinkedArtifactMigrations(next,adds,removes,migrations);const normalized=mergeLinkedArtifactChanges(next,migrated.adds,migrated.removes,config.supportsAppendStable&&options.appendStable===true);if(normalized.length>0){metadata[metadataKey]=normalized}else{delete metadata[metadataKey]}const changed=!stableValueEquals(current,normalized);return{changedFields:changed?[metadataKey]:[],warnings:changed&&migrated.count>0?[`path_migrations_applied:${migrated.count}`]:[]}}});const artifacts=result.item[metadataKey]??[];const migrationWarning=result.warnings.find(warning=>warning.startsWith("path_migrations_applied:"));const migrationCount=migrationWarning?Number(migrationWarning.slice("path_migrations_applied:".length)):0;return buildLinkedArtifactResult({id:result.item.id,artifacts,changed:result.changedFields.includes(metadataKey),migrationsApplied:migrationCount,options,workspaceRoot})}function renameArtifactsResultKey(result,key){const out={};for(const[field,value]of Object.entries(result)){out[field==="artifacts"?key:field]=value}return out}export{LINKED_ARTIFACT_ADD_GLOB_KEYS,LINKED_ARTIFACT_ADD_KEYS,LINKED_ARTIFACT_MIGRATE_KEYS,LINKED_ARTIFACT_REMOVE_KEYS,anchorLinkedPath,applyPathMigrations,applyStandaloneNote,artifactKey,assertLinkedArtifactMutationIsUnambiguous,dedupeLinkedArtifacts,ensureScope,expandAddGlobEntries,looksLikeStructuredPathEntry,normalizeLinkedPath,parseAddEntries,parseAddGlobEntries,parseMigrateEntries,parseRemoveEntries,renameArtifactsResultKey,runLinkedArtifacts,sortLinkedArtifacts,validateLinkedPaths};
|
|
530
2
|
//# sourceMappingURL=linked-artifacts.js.map
|
|
531
|
-
//# debugId=accd0229-6974-5950-8cea-74f517706878
|