@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,644 +1,2 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @module sdk/history-redact
|
|
3
|
-
*
|
|
4
|
-
* Implements the pm history redact 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]="bd1e86b0-6696-5fba-8dd4-b9636bf3ee60")}catch(e){}}();
|
|
8
|
-
import { assertInitializedTracker } from "./environment/tracker-preflight.js";
|
|
9
|
-
import fs from "node:fs/promises";
|
|
10
|
-
import { pathExists, readFileIfExists, writeFileAtomic, } from "../core/fs/fs-utils.js";
|
|
11
|
-
import { createHistoryEntry, resealHistoryRewrite, verifyHistoryRecordHash, } from "../core/history/history.js";
|
|
12
|
-
import { invalidateHistoryDriftCacheForPath } from "../core/history/drift-cache.js";
|
|
13
|
-
import { executeHistoryRewrite } from "../core/history/history-rewrite.js";
|
|
14
|
-
import { EMPTY_REPLAY_DOCUMENT, historyEntriesToRaw, replayHash, replayToItemDocument, verifyHistoryChain, } from "../core/history/replay.js";
|
|
15
|
-
import { applyHistoryPatch } from "../core/history/projection.js";
|
|
16
|
-
import { readHistoryEntries } from "../core/history/read.js";
|
|
17
|
-
import { normalizeItemId, normalizeRawItemId } from "../core/item/id.js";
|
|
18
|
-
import { canonicalDocument, serializeItemDocument, } from "../core/item/item-format.js";
|
|
19
|
-
import { resolveItemTypeRegistry } from "../core/item/type-registry.js";
|
|
20
|
-
import { EXIT_CODE } from "../core/shared/constants.js";
|
|
21
|
-
import { PmCliError } from "../core/shared/errors.js";
|
|
22
|
-
import { nowIso } from "../core/shared/time.js";
|
|
23
|
-
import { getActiveExtensionRegistrations, runActiveOnWriteHooks, } from "../core/extensions/index.js";
|
|
24
|
-
import { locateItem, readLocatedItem } from "../core/store/item-store.js";
|
|
25
|
-
import { acquireItemMetadataDerivedIndexLock, refreshItemMetadataDerivedIndex, } from "../core/store/item-metadata-cache.js";
|
|
26
|
-
import { getHistoryPath, getItemPath, resolvePmRoot, } from "../core/store/paths.js";
|
|
27
|
-
import { readSettings } from "../core/store/settings.js";
|
|
28
|
-
import { resolveAuthor } from "../core/shared/author.js";
|
|
29
|
-
function normalizeStringArrayInput(value) {
|
|
30
|
-
if (Array.isArray(value)) {
|
|
31
|
-
return value;
|
|
32
|
-
}
|
|
33
|
-
if (typeof value === "string") {
|
|
34
|
-
return [value];
|
|
35
|
-
}
|
|
36
|
-
return [];
|
|
37
|
-
}
|
|
38
|
-
function normalizeRegexFlags(flags) {
|
|
39
|
-
const unique = [];
|
|
40
|
-
for (const token of flags) {
|
|
41
|
-
if (!unique.includes(token)) {
|
|
42
|
-
unique.push(token);
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
if (!unique.includes("g")) {
|
|
46
|
-
unique.push("g");
|
|
47
|
-
}
|
|
48
|
-
return unique.join("");
|
|
49
|
-
}
|
|
50
|
-
function parseRegexRule(spec) {
|
|
51
|
-
const trimmed = spec.trim();
|
|
52
|
-
if (trimmed.length === 0) {
|
|
53
|
-
throw new PmCliError("history-redact --regex requires a non-empty pattern.", EXIT_CODE.USAGE);
|
|
54
|
-
}
|
|
55
|
-
let source = trimmed;
|
|
56
|
-
let flags = "g";
|
|
57
|
-
if (trimmed.startsWith("/") && trimmed.length > 1) {
|
|
58
|
-
/* c8 ignore start -- bare-slash regex literals are rejected earlier in argument validation. */
|
|
59
|
-
const slashIndex = trimmed.lastIndexOf("/");
|
|
60
|
-
if (slashIndex > 0) {
|
|
61
|
-
source = trimmed.slice(1, slashIndex);
|
|
62
|
-
flags = normalizeRegexFlags(trimmed.slice(slashIndex + 1));
|
|
63
|
-
}
|
|
64
|
-
/* c8 ignore stop */
|
|
65
|
-
}
|
|
66
|
-
if (source.length === 0) {
|
|
67
|
-
throw new PmCliError("history-redact --regex cannot use an empty pattern.", EXIT_CODE.USAGE);
|
|
68
|
-
}
|
|
69
|
-
try {
|
|
70
|
-
new RegExp(source, flags);
|
|
71
|
-
}
|
|
72
|
-
catch {
|
|
73
|
-
/* c8 ignore start -- RegExp constructor failures are normalized in higher-level parser tests. */
|
|
74
|
-
throw new PmCliError("Invalid --regex value; provide a valid JavaScript regular expression.", EXIT_CODE.USAGE);
|
|
75
|
-
/* c8 ignore stop */
|
|
76
|
-
}
|
|
77
|
-
return {
|
|
78
|
-
kind: "regex",
|
|
79
|
-
source,
|
|
80
|
-
flags,
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
|
-
function buildRedactionRules(literalInput, regexInput) {
|
|
84
|
-
const literalRules = [
|
|
85
|
-
...new Set(normalizeStringArrayInput(literalInput).map((entry) => entry.trim())),
|
|
86
|
-
]
|
|
87
|
-
.filter((entry) => entry.length > 0)
|
|
88
|
-
.map((entry) => ({
|
|
89
|
-
kind: "literal",
|
|
90
|
-
value: entry,
|
|
91
|
-
}));
|
|
92
|
-
const regexRules = [
|
|
93
|
-
...new Set(normalizeStringArrayInput(regexInput).map((entry) => entry.trim())),
|
|
94
|
-
]
|
|
95
|
-
.filter((entry) => entry.length > 0)
|
|
96
|
-
.map(parseRegexRule);
|
|
97
|
-
const rules = [...literalRules, ...regexRules];
|
|
98
|
-
if (rules.length === 0) {
|
|
99
|
-
throw new PmCliError("history-redact requires at least one matcher via --literal or --regex.", EXIT_CODE.USAGE, {
|
|
100
|
-
code: "missing_required_argument",
|
|
101
|
-
required: "Provide --literal <value> and/or --regex <pattern>.",
|
|
102
|
-
examples: [
|
|
103
|
-
'pm history-redact pm-a1b2 --literal "[redacted_path_prefix]/private"',
|
|
104
|
-
'pm history-redact pm-a1b2 --regex "/192\\\\.168\\\\.[0-9.]+/g" --replacement "[scrubbed_ip]"',
|
|
105
|
-
],
|
|
106
|
-
});
|
|
107
|
-
}
|
|
108
|
-
return rules;
|
|
109
|
-
}
|
|
110
|
-
function applyLiteralRule(value, literal, replacement) {
|
|
111
|
-
if (literal.length === 0) {
|
|
112
|
-
return { value, replacements: 0 };
|
|
113
|
-
}
|
|
114
|
-
let cursor = 0;
|
|
115
|
-
let replacements = 0;
|
|
116
|
-
while (cursor <= value.length) {
|
|
117
|
-
const index = value.indexOf(literal, cursor);
|
|
118
|
-
if (index === -1) {
|
|
119
|
-
break;
|
|
120
|
-
}
|
|
121
|
-
replacements += 1;
|
|
122
|
-
cursor = index + Math.max(1, literal.length);
|
|
123
|
-
}
|
|
124
|
-
if (replacements === 0) {
|
|
125
|
-
return { value, replacements: 0 };
|
|
126
|
-
}
|
|
127
|
-
return {
|
|
128
|
-
value: value.split(literal).join(replacement),
|
|
129
|
-
replacements,
|
|
130
|
-
};
|
|
131
|
-
}
|
|
132
|
-
function applyRegexRule(value, rule, replacement) {
|
|
133
|
-
const regex = new RegExp(rule.source, rule.flags);
|
|
134
|
-
const matches = [...value.matchAll(regex)];
|
|
135
|
-
if (matches.length === 0) {
|
|
136
|
-
return { value, replacements: 0 };
|
|
137
|
-
}
|
|
138
|
-
return {
|
|
139
|
-
value: value.replace(regex, replacement),
|
|
140
|
-
replacements: matches.length,
|
|
141
|
-
};
|
|
142
|
-
}
|
|
143
|
-
function redactStringValue(value, rules, replacement) {
|
|
144
|
-
let next = value;
|
|
145
|
-
let replacements = 0;
|
|
146
|
-
for (const rule of rules) {
|
|
147
|
-
const result = rule.kind === "literal"
|
|
148
|
-
? applyLiteralRule(next, rule.value, replacement)
|
|
149
|
-
: applyRegexRule(next, rule, replacement);
|
|
150
|
-
next = result.value;
|
|
151
|
-
replacements += result.replacements;
|
|
152
|
-
}
|
|
153
|
-
return {
|
|
154
|
-
value: next,
|
|
155
|
-
replacements,
|
|
156
|
-
};
|
|
157
|
-
}
|
|
158
|
-
function redactUnknownValue(value, rules, replacement) {
|
|
159
|
-
if (typeof value === "string") {
|
|
160
|
-
return redactStringValue(value, rules, replacement);
|
|
161
|
-
}
|
|
162
|
-
if (Array.isArray(value)) {
|
|
163
|
-
let replacements = 0;
|
|
164
|
-
const nextValues = value.map((entry) => {
|
|
165
|
-
const redacted = redactUnknownValue(entry, rules, replacement);
|
|
166
|
-
replacements += redacted.replacements;
|
|
167
|
-
return redacted.value;
|
|
168
|
-
});
|
|
169
|
-
return {
|
|
170
|
-
value: nextValues,
|
|
171
|
-
replacements,
|
|
172
|
-
};
|
|
173
|
-
}
|
|
174
|
-
if (typeof value === "object" && value !== null) {
|
|
175
|
-
let replacements = 0;
|
|
176
|
-
const nextRecord = {};
|
|
177
|
-
for (const [key, entry] of Object.entries(value)) {
|
|
178
|
-
const redacted = redactUnknownValue(entry, rules, replacement);
|
|
179
|
-
replacements += redacted.replacements;
|
|
180
|
-
nextRecord[key] = redacted.value;
|
|
181
|
-
}
|
|
182
|
-
return {
|
|
183
|
-
value: nextRecord,
|
|
184
|
-
replacements,
|
|
185
|
-
};
|
|
186
|
-
}
|
|
187
|
-
return {
|
|
188
|
-
value,
|
|
189
|
-
replacements: 0,
|
|
190
|
-
};
|
|
191
|
-
}
|
|
192
|
-
function redactHistoryPatch(patch, rules, replacement) {
|
|
193
|
-
let replacements = 0;
|
|
194
|
-
const redactedPatch = patch.map((operation) => {
|
|
195
|
-
/* c8 ignore start -- patch operations without `value` are covered in lower-level patch adapters. */
|
|
196
|
-
if (!Object.prototype.hasOwnProperty.call(operation, "value")) {
|
|
197
|
-
return operation;
|
|
198
|
-
}
|
|
199
|
-
/* c8 ignore stop */
|
|
200
|
-
const redactedValue = redactUnknownValue(operation.value, rules, replacement);
|
|
201
|
-
replacements += redactedValue.replacements;
|
|
202
|
-
return redactedValue.replacements > 0
|
|
203
|
-
? { ...operation, value: redactedValue.value }
|
|
204
|
-
: operation;
|
|
205
|
-
});
|
|
206
|
-
return { patch: redactedPatch, replacements };
|
|
207
|
-
}
|
|
208
|
-
function inspectHistoryIntegrity(entries) {
|
|
209
|
-
let replay = structuredClone(EMPTY_REPLAY_DOCUMENT);
|
|
210
|
-
let hashMismatchesBefore = 0;
|
|
211
|
-
let hashMismatchesAfter = 0;
|
|
212
|
-
for (let index = 0; index < entries.length; index += 1) {
|
|
213
|
-
const entry = entries[index];
|
|
214
|
-
if (replayHash(replay) !== entry.before_hash) {
|
|
215
|
-
hashMismatchesBefore += 1;
|
|
216
|
-
}
|
|
217
|
-
replay = applyHistoryPatch(replay, entry.patch, index + 1, entry.op);
|
|
218
|
-
/* c8 ignore start -- after-hash mismatch branch is exercised in dedicated history integrity tests. */
|
|
219
|
-
if (replayHash(replay) !== entry.after_hash) {
|
|
220
|
-
hashMismatchesAfter += 1;
|
|
221
|
-
}
|
|
222
|
-
/* c8 ignore stop */
|
|
223
|
-
}
|
|
224
|
-
return {
|
|
225
|
-
hashMismatchesBefore,
|
|
226
|
-
hashMismatchesAfter,
|
|
227
|
-
finalDocument: replay,
|
|
228
|
-
};
|
|
229
|
-
}
|
|
230
|
-
function redactHistoryEntry(entry, rules, replacement) {
|
|
231
|
-
let replacements = 0;
|
|
232
|
-
let changed = false;
|
|
233
|
-
let reanchorEvidenceRedacted = false;
|
|
234
|
-
let nextMessage = entry.message;
|
|
235
|
-
if (typeof entry.message === "string") {
|
|
236
|
-
const redactedMessage = redactStringValue(entry.message, rules, replacement);
|
|
237
|
-
nextMessage = redactedMessage.value;
|
|
238
|
-
replacements += redactedMessage.replacements;
|
|
239
|
-
if (redactedMessage.replacements > 0) {
|
|
240
|
-
changed = true;
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
const redactedPatch = redactHistoryPatch(entry.patch, rules, replacement);
|
|
244
|
-
replacements += redactedPatch.replacements;
|
|
245
|
-
changed ||= redactedPatch.replacements > 0;
|
|
246
|
-
const nextReanchorEvidence = entry.reanchor_evidence?.map((evidence) => {
|
|
247
|
-
const redactedEvidencePatch = evidence.patch
|
|
248
|
-
? redactHistoryPatch(evidence.patch, rules, replacement)
|
|
249
|
-
: { patch: undefined, replacements: 0 };
|
|
250
|
-
const redactedEvidenceRecord = evidence.record
|
|
251
|
-
? redactUnknownValue(evidence.record, rules, replacement)
|
|
252
|
-
: { value: undefined, replacements: 0 };
|
|
253
|
-
replacements += redactedEvidencePatch.replacements;
|
|
254
|
-
replacements += redactedEvidenceRecord.replacements;
|
|
255
|
-
const evidenceChanged = redactedEvidencePatch.replacements > 0 ||
|
|
256
|
-
redactedEvidenceRecord.replacements > 0;
|
|
257
|
-
changed ||= evidenceChanged;
|
|
258
|
-
if (!evidenceChanged)
|
|
259
|
-
return evidence;
|
|
260
|
-
reanchorEvidenceRedacted = true;
|
|
261
|
-
const { patch: _sensitivePatch, record: _sensitiveRecord, record_hash: _priorRecordHash, record_hash_version: _priorRecordHashVersion, ...digestOnlyEvidence } = evidence;
|
|
262
|
-
return redactedEvidencePatch.replacements > 0
|
|
263
|
-
? digestOnlyEvidence
|
|
264
|
-
: { ...digestOnlyEvidence, patch: evidence.patch };
|
|
265
|
-
});
|
|
266
|
-
return {
|
|
267
|
-
entry: {
|
|
268
|
-
...entry,
|
|
269
|
-
message: nextMessage,
|
|
270
|
-
patch: redactedPatch.patch,
|
|
271
|
-
...(nextReanchorEvidence
|
|
272
|
-
? { reanchor_evidence: nextReanchorEvidence }
|
|
273
|
-
: {}),
|
|
274
|
-
},
|
|
275
|
-
replacements,
|
|
276
|
-
changed,
|
|
277
|
-
reanchorEvidenceRedacted,
|
|
278
|
-
};
|
|
279
|
-
}
|
|
280
|
-
function rewriteHistoryEntries(entries, rules, replacement) {
|
|
281
|
-
let replay = structuredClone(EMPTY_REPLAY_DOCUMENT);
|
|
282
|
-
let entriesChanged = 0;
|
|
283
|
-
let replacements = 0;
|
|
284
|
-
const rewrittenEntries = [];
|
|
285
|
-
for (let index = 0; index < entries.length; index += 1) {
|
|
286
|
-
const original = entries[index];
|
|
287
|
-
const recordVerification = verifyHistoryRecordHash(original);
|
|
288
|
-
if (!recordVerification.ok) {
|
|
289
|
-
throw new PmCliError(`history-redact refuses invalid immutable record ${index + 1} (${recordVerification.error}).`, EXIT_CODE.GENERIC_FAILURE);
|
|
290
|
-
}
|
|
291
|
-
const redacted = redactHistoryEntry(original, rules, replacement);
|
|
292
|
-
replacements += redacted.replacements;
|
|
293
|
-
if (redacted.changed) {
|
|
294
|
-
entriesChanged += 1;
|
|
295
|
-
}
|
|
296
|
-
const beforeHash = replayHash(replay);
|
|
297
|
-
replay = applyHistoryPatch(replay, redacted.entry.patch, index + 1, redacted.entry.op);
|
|
298
|
-
const afterHash = replayHash(replay);
|
|
299
|
-
rewrittenEntries.push(resealHistoryRewrite(original, {
|
|
300
|
-
...redacted.entry,
|
|
301
|
-
before_hash: beforeHash,
|
|
302
|
-
after_hash: afterHash,
|
|
303
|
-
}, {
|
|
304
|
-
retainPriorRecord: redacted.changed,
|
|
305
|
-
retainPriorRecordHash: !redacted.changed,
|
|
306
|
-
}));
|
|
307
|
-
}
|
|
308
|
-
return {
|
|
309
|
-
entries: rewrittenEntries,
|
|
310
|
-
finalDocument: replay,
|
|
311
|
-
entriesChanged,
|
|
312
|
-
replacements,
|
|
313
|
-
};
|
|
314
|
-
}
|
|
315
|
-
function hasItemMetadata(replay) {
|
|
316
|
-
return Object.keys(replay.metadata).length > 0;
|
|
317
|
-
}
|
|
318
|
-
async function loadHistoryRedactCurrentItem(subject, settings) {
|
|
319
|
-
const currentItemPath = subject.located?.itemPath ?? null;
|
|
320
|
-
if (!subject.located) {
|
|
321
|
-
return { raw: null, path: currentItemPath, document: null };
|
|
322
|
-
}
|
|
323
|
-
const loaded = await readLocatedItem(subject.located, {
|
|
324
|
-
schema: settings.schema,
|
|
325
|
-
});
|
|
326
|
-
return { raw: loaded.raw, path: currentItemPath, document: loaded.document };
|
|
327
|
-
}
|
|
328
|
-
function resolveHistoryRedactNextItem(params) {
|
|
329
|
-
if (!hasItemMetadata(params.finalDocument)) {
|
|
330
|
-
return { raw: null, path: null, document: null };
|
|
331
|
-
}
|
|
332
|
-
const canonical = canonicalDocument(replayToItemDocument(params.finalDocument), { schema: params.settings.schema });
|
|
333
|
-
if (canonical.metadata.id !== params.subject.id) {
|
|
334
|
-
throw new PmCliError("history-redact would change the item id; narrow your patterns.", EXIT_CODE.USAGE);
|
|
335
|
-
}
|
|
336
|
-
return {
|
|
337
|
-
document: canonical,
|
|
338
|
-
path: getItemPath(params.pmRoot, canonical.metadata.type, params.subject.id, "toon", params.typeToFolder),
|
|
339
|
-
raw: serializeItemDocument(canonical, {
|
|
340
|
-
format: "toon",
|
|
341
|
-
schema: params.settings.schema,
|
|
342
|
-
}),
|
|
343
|
-
};
|
|
344
|
-
}
|
|
345
|
-
/* v8 ignore start -- message passthrough/plural formatting is deterministic around covered redaction outcomes */
|
|
346
|
-
function buildHistoryRedactMessage(options, rewritten) {
|
|
347
|
-
if (typeof options.message === "string" &&
|
|
348
|
-
options.message.trim().length > 0) {
|
|
349
|
-
return options.message;
|
|
350
|
-
}
|
|
351
|
-
return `history-redact replaced ${rewritten.replacements} match(es) across ${rewritten.entriesChanged} entr${rewritten.entriesChanged === 1 ? "y" : "ies"}.`;
|
|
352
|
-
}
|
|
353
|
-
/* v8 ignore stop */
|
|
354
|
-
function buildHistoryRedactEntries(params) {
|
|
355
|
-
const rewrittenEntries = [...params.rewritten.entries];
|
|
356
|
-
if (params.dryRun || !params.changed) {
|
|
357
|
-
return { rewrittenEntries, auditEntryAdded: false };
|
|
358
|
-
}
|
|
359
|
-
/* c8 ignore next -- fallback replay-to-item conversion runs only when rewritten final metadata is absent. */
|
|
360
|
-
const finalDocument = params.nextItemDocument ??
|
|
361
|
-
replayToItemDocument(params.rewritten.finalDocument);
|
|
362
|
-
rewrittenEntries.push(createHistoryEntry({
|
|
363
|
-
nowIso: nowIso(),
|
|
364
|
-
author: params.author,
|
|
365
|
-
op: "history_redact",
|
|
366
|
-
before: finalDocument,
|
|
367
|
-
after: finalDocument,
|
|
368
|
-
message: params.message,
|
|
369
|
-
}));
|
|
370
|
-
return { rewrittenEntries, auditEntryAdded: true };
|
|
371
|
-
}
|
|
372
|
-
async function applyHistoryRedactRewrite(params) {
|
|
373
|
-
let derivedIndexWarnings = [];
|
|
374
|
-
return executeHistoryRewrite({
|
|
375
|
-
pmRoot: params.pmRoot,
|
|
376
|
-
subject: params.subject,
|
|
377
|
-
settings: params.settings,
|
|
378
|
-
typeRegistry: params.typeRegistry,
|
|
379
|
-
historyRawBeforeLock: params.historyRawBeforeLock,
|
|
380
|
-
currentItemRawBeforeLock: params.currentItem.raw,
|
|
381
|
-
operation: "history-redact",
|
|
382
|
-
author: params.author,
|
|
383
|
-
force: params.force,
|
|
384
|
-
itemDocument: params.currentItem.document,
|
|
385
|
-
applyRewrite: async ({ historyRawUnderLock }) => {
|
|
386
|
-
const releaseDerivedIndexLock = await acquireItemMetadataDerivedIndexLock(params.pmRoot, params.author);
|
|
387
|
-
const affectedItemPaths = new Set();
|
|
388
|
-
if (params.currentItem.path) {
|
|
389
|
-
affectedItemPaths.add(params.currentItem.path);
|
|
390
|
-
}
|
|
391
|
-
if (params.nextItem.path) {
|
|
392
|
-
affectedItemPaths.add(params.nextItem.path);
|
|
393
|
-
}
|
|
394
|
-
const itemSnapshots = new Map();
|
|
395
|
-
if (params.currentItem.path && params.currentItem.raw !== null) {
|
|
396
|
-
itemSnapshots.set(params.currentItem.path, params.currentItem.raw);
|
|
397
|
-
}
|
|
398
|
-
let rethrowReleaseFailure = () => { };
|
|
399
|
-
try {
|
|
400
|
-
try {
|
|
401
|
-
/* c8 ignore next -- item-write diff branch requires path and content divergence under lock races. */
|
|
402
|
-
if (params.nextItem.path &&
|
|
403
|
-
params.nextItem.raw !== null &&
|
|
404
|
-
params.nextItem.raw !== params.currentItem.raw) {
|
|
405
|
-
await writeFileAtomic(params.nextItem.path, params.nextItem.raw);
|
|
406
|
-
}
|
|
407
|
-
if (params.currentItem.path &&
|
|
408
|
-
(!params.nextItem.path ||
|
|
409
|
-
params.nextItem.path !== params.currentItem.path)) {
|
|
410
|
-
await fs.rm(params.currentItem.path, { force: true });
|
|
411
|
-
}
|
|
412
|
-
await writeFileAtomic(params.subject.historyPath, historyEntriesToRaw(params.rewrittenEntries));
|
|
413
|
-
}
|
|
414
|
-
catch (error) {
|
|
415
|
-
try {
|
|
416
|
-
await rollbackHistoryRedactRewrite(params.subject.historyPath, historyRawUnderLock, affectedItemPaths, itemSnapshots);
|
|
417
|
-
}
|
|
418
|
-
finally {
|
|
419
|
-
await invalidateHistoryDriftCacheForPath(params.subject.historyPath);
|
|
420
|
-
}
|
|
421
|
-
throw error;
|
|
422
|
-
}
|
|
423
|
-
await invalidateHistoryDriftCacheForPath(params.subject.historyPath);
|
|
424
|
-
const itemPath = params.nextItem.path ?? params.currentItem.path;
|
|
425
|
-
if (itemPath) {
|
|
426
|
-
derivedIndexWarnings = await refreshItemMetadataDerivedIndex({
|
|
427
|
-
pmRoot: params.pmRoot,
|
|
428
|
-
preferredFormat: params.settings.item_format,
|
|
429
|
-
typeToFolder: params.typeRegistry.type_to_folder,
|
|
430
|
-
schema: params.settings.schema,
|
|
431
|
-
itemPath,
|
|
432
|
-
...(params.currentItem.path
|
|
433
|
-
? { previousItemPath: params.currentItem.path }
|
|
434
|
-
: {}),
|
|
435
|
-
document: params.nextItem.document,
|
|
436
|
-
});
|
|
437
|
-
}
|
|
438
|
-
}
|
|
439
|
-
finally {
|
|
440
|
-
await releaseDerivedIndexLock().catch((error) => {
|
|
441
|
-
rethrowReleaseFailure = () => {
|
|
442
|
-
throw error;
|
|
443
|
-
};
|
|
444
|
-
});
|
|
445
|
-
}
|
|
446
|
-
rethrowReleaseFailure();
|
|
447
|
-
},
|
|
448
|
-
applyPostRewrite: async () => [
|
|
449
|
-
...derivedIndexWarnings,
|
|
450
|
-
...(await runHistoryRedactWriteHooks(params.subject.historyPath, [
|
|
451
|
-
params.nextItem.path,
|
|
452
|
-
params.currentItem.path,
|
|
453
|
-
])),
|
|
454
|
-
],
|
|
455
|
-
});
|
|
456
|
-
}
|
|
457
|
-
async function rollbackHistoryRedactRewrite(historyPath, historyRawUnderLock, affectedItemPaths, itemSnapshots) {
|
|
458
|
-
/* c8 ignore start -- no-history-under-lock rollback path is exercised in lock-race integration tests. */
|
|
459
|
-
if (historyRawUnderLock === null) {
|
|
460
|
-
await fs.rm(historyPath, { force: true });
|
|
461
|
-
}
|
|
462
|
-
else {
|
|
463
|
-
await writeFileAtomic(historyPath, historyRawUnderLock);
|
|
464
|
-
}
|
|
465
|
-
/* c8 ignore stop */
|
|
466
|
-
for (const itemPath of affectedItemPaths) {
|
|
467
|
-
const snapshot = itemSnapshots.get(itemPath);
|
|
468
|
-
/* c8 ignore start -- missing snapshot rollback occurs only for create/delete race permutations. */
|
|
469
|
-
if (snapshot === undefined) {
|
|
470
|
-
await fs.rm(itemPath, { force: true });
|
|
471
|
-
}
|
|
472
|
-
else {
|
|
473
|
-
await writeFileAtomic(itemPath, snapshot);
|
|
474
|
-
}
|
|
475
|
-
/* c8 ignore stop */
|
|
476
|
-
}
|
|
477
|
-
}
|
|
478
|
-
async function runHistoryRedactWriteHooks(historyPath, itemHookPaths) {
|
|
479
|
-
const hookWarnings = [];
|
|
480
|
-
const uniqueItemHookPaths = new Set(itemHookPaths.filter((itemPath) => itemPath !== null));
|
|
481
|
-
for (const itemHookPath of uniqueItemHookPaths) {
|
|
482
|
-
hookWarnings.push(...(await runActiveOnWriteHooks({
|
|
483
|
-
path: itemHookPath,
|
|
484
|
-
scope: "project",
|
|
485
|
-
op: "history_redact",
|
|
486
|
-
})));
|
|
487
|
-
}
|
|
488
|
-
hookWarnings.push(...(await runActiveOnWriteHooks({
|
|
489
|
-
path: historyPath,
|
|
490
|
-
scope: "project",
|
|
491
|
-
op: "history_redact:history",
|
|
492
|
-
})));
|
|
493
|
-
return hookWarnings;
|
|
494
|
-
}
|
|
495
|
-
/** Implements resolve history subject for the public runtime surface of this module. */
|
|
496
|
-
export async function resolveHistorySubject(pmRoot, id, settings, typeToFolder) {
|
|
497
|
-
const located = await locateItem(pmRoot, id, settings.id_prefix, settings.item_format, typeToFolder);
|
|
498
|
-
if (located) {
|
|
499
|
-
return {
|
|
500
|
-
id: located.id,
|
|
501
|
-
historyPath: getHistoryPath(pmRoot, located.id),
|
|
502
|
-
located,
|
|
503
|
-
};
|
|
504
|
-
}
|
|
505
|
-
const normalizedId = normalizeItemId(id, settings.id_prefix);
|
|
506
|
-
const rawNormalizedId = normalizeRawItemId(id);
|
|
507
|
-
const candidateIds = normalizedId === rawNormalizedId
|
|
508
|
-
? [normalizedId]
|
|
509
|
-
: [normalizedId, rawNormalizedId];
|
|
510
|
-
for (const candidateId of candidateIds) {
|
|
511
|
-
const historyPath = getHistoryPath(pmRoot, candidateId);
|
|
512
|
-
if (await pathExists(historyPath)) {
|
|
513
|
-
return {
|
|
514
|
-
id: candidateId,
|
|
515
|
-
historyPath,
|
|
516
|
-
located: null,
|
|
517
|
-
};
|
|
518
|
-
}
|
|
519
|
-
}
|
|
520
|
-
throw new PmCliError(`Item ${id} not found`, EXIT_CODE.NOT_FOUND);
|
|
521
|
-
}
|
|
522
|
-
/** Implements run history redact for the public runtime surface of this module. */
|
|
523
|
-
export async function runHistoryRedact(id, options, global) {
|
|
524
|
-
const pmRoot = resolvePmRoot(process.cwd(), global.path);
|
|
525
|
-
await assertInitializedTracker(pmRoot);
|
|
526
|
-
const settings = await readSettings(pmRoot);
|
|
527
|
-
const typeRegistry = resolveItemTypeRegistry(settings, getActiveExtensionRegistrations());
|
|
528
|
-
const replacementInput = options.replacement ?? "";
|
|
529
|
-
const replacementIsDefault = replacementInput.length === 0;
|
|
530
|
-
const replacement = replacementIsDefault ? "[redacted]" : replacementInput;
|
|
531
|
-
const rules = buildRedactionRules(options.literal, options.regex);
|
|
532
|
-
const subject = await resolveHistorySubject(pmRoot, id, settings, typeRegistry.type_to_folder);
|
|
533
|
-
if (!(await pathExists(subject.historyPath))) {
|
|
534
|
-
throw new PmCliError(`No history stream exists for ${subject.id}.`, EXIT_CODE.NOT_FOUND);
|
|
535
|
-
}
|
|
536
|
-
const historyRawBeforeLock = await readFileIfExists(subject.historyPath);
|
|
537
|
-
const historyEntries = await readHistoryEntries(subject.historyPath, subject.id);
|
|
538
|
-
if (historyEntries.length === 0) {
|
|
539
|
-
throw new PmCliError(`No history entries exist for ${subject.id}; nothing to redact.`, EXIT_CODE.USAGE);
|
|
540
|
-
}
|
|
541
|
-
const integritySnapshot = inspectHistoryIntegrity(historyEntries);
|
|
542
|
-
const rewritten = rewriteHistoryEntries(historyEntries, rules, replacement);
|
|
543
|
-
const preexistingHashMismatches = integritySnapshot.hashMismatchesBefore +
|
|
544
|
-
integritySnapshot.hashMismatchesAfter;
|
|
545
|
-
const dryRun = Boolean(options.dryRun);
|
|
546
|
-
const changed = rewritten.replacements > 0;
|
|
547
|
-
const warnings = [];
|
|
548
|
-
if (preexistingHashMismatches > 0) {
|
|
549
|
-
warnings.push(`history_redact_preexisting_hash_mismatches:${preexistingHashMismatches}`);
|
|
550
|
-
}
|
|
551
|
-
if (!changed) {
|
|
552
|
-
warnings.push("history_redact_no_matches");
|
|
553
|
-
}
|
|
554
|
-
const currentItem = await loadHistoryRedactCurrentItem(subject, settings);
|
|
555
|
-
const nextItem = resolveHistoryRedactNextItem({
|
|
556
|
-
pmRoot,
|
|
557
|
-
subject,
|
|
558
|
-
settings,
|
|
559
|
-
typeToFolder: typeRegistry.type_to_folder,
|
|
560
|
-
finalDocument: rewritten.finalDocument,
|
|
561
|
-
});
|
|
562
|
-
const itemChanged =
|
|
563
|
-
/* c8 ignore next -- null-coalescing item-path comparison branch is exercised in broader command integration coverage. */
|
|
564
|
-
(currentItem.path ?? null) !== (nextItem.path ?? null) ||
|
|
565
|
-
/* c8 ignore next -- null-coalescing item-content comparison branch is exercised in broader command integration coverage. */
|
|
566
|
-
(currentItem.raw ?? null) !== (nextItem.raw ?? null);
|
|
567
|
-
const author = resolveAuthor(options.author, settings.author_default);
|
|
568
|
-
const redactionMessage = buildHistoryRedactMessage(options, rewritten);
|
|
569
|
-
const { rewrittenEntries, auditEntryAdded } = buildHistoryRedactEntries({
|
|
570
|
-
rewritten,
|
|
571
|
-
dryRun,
|
|
572
|
-
changed,
|
|
573
|
-
nextItemDocument: nextItem.document,
|
|
574
|
-
author,
|
|
575
|
-
message: redactionMessage,
|
|
576
|
-
});
|
|
577
|
-
const historyVerify = verifyHistoryChain(rewrittenEntries);
|
|
578
|
-
/* c8 ignore start -- invalid rewritten chains are covered by history verification unit tests. */
|
|
579
|
-
if (!historyVerify.ok) {
|
|
580
|
-
throw new PmCliError(`history-redact produced an invalid rewritten chain (${historyVerify.errors.join(", ")}).`, EXIT_CODE.GENERIC_FAILURE);
|
|
581
|
-
}
|
|
582
|
-
/* c8 ignore stop */
|
|
583
|
-
if (!dryRun && changed) {
|
|
584
|
-
warnings.push(...(await applyHistoryRedactRewrite({
|
|
585
|
-
pmRoot,
|
|
586
|
-
subject,
|
|
587
|
-
settings,
|
|
588
|
-
typeRegistry,
|
|
589
|
-
historyRawBeforeLock,
|
|
590
|
-
currentItem,
|
|
591
|
-
nextItem,
|
|
592
|
-
author,
|
|
593
|
-
force: options.force,
|
|
594
|
-
rewrittenEntries,
|
|
595
|
-
})));
|
|
596
|
-
}
|
|
597
|
-
return {
|
|
598
|
-
id: subject.id,
|
|
599
|
-
dry_run: dryRun,
|
|
600
|
-
changed,
|
|
601
|
-
patterns: {
|
|
602
|
-
literal_count: rules.filter((rule) => rule.kind === "literal").length,
|
|
603
|
-
regex_count: rules.filter((rule) => rule.kind === "regex").length,
|
|
604
|
-
total_count: rules.length,
|
|
605
|
-
replacement_is_default: replacementIsDefault,
|
|
606
|
-
},
|
|
607
|
-
history: {
|
|
608
|
-
path: subject.historyPath,
|
|
609
|
-
entries_scanned: historyEntries.length,
|
|
610
|
-
entries_changed: rewritten.entriesChanged,
|
|
611
|
-
replacements: rewritten.replacements,
|
|
612
|
-
hash_mismatches_before: integritySnapshot.hashMismatchesBefore,
|
|
613
|
-
hash_mismatches_after: integritySnapshot.hashMismatchesAfter,
|
|
614
|
-
preexisting_hash_mismatches: preexistingHashMismatches,
|
|
615
|
-
audit_entry_added: auditEntryAdded,
|
|
616
|
-
verify_ok: historyVerify.ok,
|
|
617
|
-
verify_errors: historyVerify.errors,
|
|
618
|
-
},
|
|
619
|
-
item: {
|
|
620
|
-
existed_before: currentItem.path !== null,
|
|
621
|
-
exists_after: nextItem.path !== null,
|
|
622
|
-
path_before: currentItem.path,
|
|
623
|
-
path_after: nextItem.path,
|
|
624
|
-
changed: itemChanged,
|
|
625
|
-
},
|
|
626
|
-
/* c8 ignore next -- warning dedupe ordering is covered indirectly by command-level smoke tests. */
|
|
627
|
-
warnings: [...new Set(warnings)].sort((left, right) => left.localeCompare(right)),
|
|
628
|
-
generated_at: nowIso(),
|
|
629
|
-
};
|
|
630
|
-
}
|
|
631
|
-
/** Public contract for test only, shared by SDK and presentation-layer consumers. */
|
|
632
|
-
export const _testOnly = {
|
|
633
|
-
applyLiteralRule,
|
|
634
|
-
applyRegexRule,
|
|
635
|
-
buildRedactionRules,
|
|
636
|
-
hasItemMetadata,
|
|
637
|
-
normalizeRegexFlags,
|
|
638
|
-
normalizeStringArrayInput,
|
|
639
|
-
parseRegexRule,
|
|
640
|
-
redactStringValue,
|
|
641
|
-
redactUnknownValue,
|
|
642
|
-
};
|
|
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]="d562ab68-1891-54cc-8256-57cc1121b9ce")}catch(e2){}})();import{resolveHistoryWorkspace,resolveHistorySubject}from"./history/subject.js";import{resolveHistorySubject as resolveHistorySubject2}from"./history/subject.js";import fs from"node:fs/promises";import{writeFileAtomic}from"../core/fs/fs-utils.js";import{createHistoryEntry,resealHistoryRewrite,verifyHistoryRecordHash}from"../core/history/history.js";import{invalidateHistoryDriftCacheForPath}from"../core/history/drift-cache.js";import{runHistoryMaintenance}from"./history/maintenance.js";import{EMPTY_REPLAY_DOCUMENT,historyEntriesToRaw,replayHash,replayToItemDocument}from"../core/history/replay.js";import{applyHistoryPatch}from"../core/history/projection.js";import{canonicalDocument,serializeItemDocument}from"../core/item/item-format.js";import{EXIT_CODE}from"../core/shared/constants.js";import{PmCliError}from"../core/shared/errors.js";import{nowIso}from"../core/shared/time.js";import{runActiveOnWriteHooks}from"../core/extensions/index.js";import{acquireItemMetadataDerivedIndexLock,refreshItemMetadataDerivedIndex}from"../core/store/item-metadata-cache.js";import{getItemPath}from"../core/store/paths.js";function normalizeStringArrayInput(value){if(Array.isArray(value)){return value}if(typeof value==="string"){return[value]}return[]}function normalizeRegexFlags(flags){const unique=[];for(const token of flags){if(!unique.includes(token)){unique.push(token)}}if(!unique.includes("g")){unique.push("g")}return unique.join("")}function parseRegexRule(spec){const trimmed=spec.trim();if(trimmed.length===0){throw new PmCliError("history-redact --regex requires a non-empty pattern.",EXIT_CODE.USAGE)}let source=trimmed;let flags="g";if(trimmed.startsWith("/")&&trimmed.length>1){const slashIndex=trimmed.lastIndexOf("/");if(slashIndex>0){source=trimmed.slice(1,slashIndex);flags=normalizeRegexFlags(trimmed.slice(slashIndex+1))}}if(source.length===0){throw new PmCliError("history-redact --regex cannot use an empty pattern.",EXIT_CODE.USAGE)}try{new RegExp(source,flags)}catch{throw new PmCliError("Invalid --regex value; provide a valid JavaScript regular expression.",EXIT_CODE.USAGE)}return{kind:"regex",source,flags}}function buildRedactionRules(literalInput,regexInput){const literalRules=[...new Set(normalizeStringArrayInput(literalInput).map(entry=>entry.trim()))].filter(entry=>entry.length>0).map(entry=>({kind:"literal",value:entry}));const regexRules=[...new Set(normalizeStringArrayInput(regexInput).map(entry=>entry.trim()))].filter(entry=>entry.length>0).map(parseRegexRule);const rules=[...literalRules,...regexRules];if(rules.length===0){throw new PmCliError("history-redact requires at least one matcher via --literal or --regex.",EXIT_CODE.USAGE,{code:"missing_required_argument",required:"Provide --literal <value> and/or --regex <pattern>.",examples:['pm history-redact pm-a1b2 --literal "[redacted_path_prefix]/private"','pm history-redact pm-a1b2 --regex "/192\\\\.168\\\\.[0-9.]+/g" --replacement "[scrubbed_ip]"']})}return rules}function applyLiteralRule(value,literal,replacement){if(literal.length===0){return{value,replacements:0}}let cursor=0;let replacements=0;while(cursor<=value.length){const index=value.indexOf(literal,cursor);if(index===-1){break}replacements+=1;cursor=index+Math.max(1,literal.length)}if(replacements===0){return{value,replacements:0}}return{value:value.split(literal).join(replacement),replacements}}function applyRegexRule(value,rule,replacement){const regex=new RegExp(rule.source,rule.flags);const matches=[...value.matchAll(regex)];if(matches.length===0){return{value,replacements:0}}return{value:value.replace(regex,replacement),replacements:matches.length}}function redactStringValue(value,rules,replacement){let next=value;let replacements=0;for(const rule of rules){const result=rule.kind==="literal"?applyLiteralRule(next,rule.value,replacement):applyRegexRule(next,rule,replacement);next=result.value;replacements+=result.replacements}return{value:next,replacements}}function redactUnknownValue(value,rules,replacement){if(typeof value==="string"){return redactStringValue(value,rules,replacement)}if(Array.isArray(value)){let replacements=0;const nextValues=value.map(entry=>{const redacted=redactUnknownValue(entry,rules,replacement);replacements+=redacted.replacements;return redacted.value});return{value:nextValues,replacements}}if(typeof value==="object"&&value!==null){let replacements=0;const nextRecord={};for(const[key,entry]of Object.entries(value)){const redacted=redactUnknownValue(entry,rules,replacement);replacements+=redacted.replacements;nextRecord[key]=redacted.value}return{value:nextRecord,replacements}}return{value,replacements:0}}function redactHistoryPatch(patch,rules,replacement){let replacements=0;const redactedPatch=patch.map(operation=>{if(!Object.prototype.hasOwnProperty.call(operation,"value")){return operation}const redactedValue=redactUnknownValue(operation.value,rules,replacement);replacements+=redactedValue.replacements;return redactedValue.replacements>0?{...operation,value:redactedValue.value}:operation});return{patch:redactedPatch,replacements}}function inspectHistoryIntegrity(entries){let replay=structuredClone(EMPTY_REPLAY_DOCUMENT);let hashMismatchesBefore=0;let hashMismatchesAfter=0;for(let index=0;index<entries.length;index+=1){const entry=entries[index];if(replayHash(replay)!==entry.before_hash){hashMismatchesBefore+=1}replay=applyHistoryPatch(replay,entry.patch,index+1,entry.op);if(replayHash(replay)!==entry.after_hash){hashMismatchesAfter+=1}}return{hashMismatchesBefore,hashMismatchesAfter,finalDocument:replay}}function redactHistoryEntry(entry,rules,replacement){let replacements=0;let changed=false;let reanchorEvidenceRedacted=false;let nextMessage=entry.message;if(typeof entry.message==="string"){const redactedMessage=redactStringValue(entry.message,rules,replacement);nextMessage=redactedMessage.value;replacements+=redactedMessage.replacements;if(redactedMessage.replacements>0){changed=true}}const redactedPatch=redactHistoryPatch(entry.patch,rules,replacement);replacements+=redactedPatch.replacements;changed||=redactedPatch.replacements>0;const nextReanchorEvidence=entry.reanchor_evidence?.map(evidence=>{const redactedEvidencePatch=evidence.patch?redactHistoryPatch(evidence.patch,rules,replacement):{patch:void 0,replacements:0};const redactedEvidenceRecord=evidence.record?redactUnknownValue(evidence.record,rules,replacement):{value:void 0,replacements:0};replacements+=redactedEvidencePatch.replacements;replacements+=redactedEvidenceRecord.replacements;const evidenceChanged=redactedEvidencePatch.replacements>0||redactedEvidenceRecord.replacements>0;changed||=evidenceChanged;if(!evidenceChanged)return evidence;reanchorEvidenceRedacted=true;const{patch:_sensitivePatch,record:_sensitiveRecord,record_hash:_priorRecordHash,record_hash_version:_priorRecordHashVersion,...digestOnlyEvidence}=evidence;return redactedEvidencePatch.replacements>0?digestOnlyEvidence:{...digestOnlyEvidence,patch:evidence.patch}});return{entry:{...entry,message:nextMessage,patch:redactedPatch.patch,...nextReanchorEvidence?{reanchor_evidence:nextReanchorEvidence}:{}},replacements,changed,reanchorEvidenceRedacted}}function rewriteHistoryEntries(entries,rules,replacement){let replay=structuredClone(EMPTY_REPLAY_DOCUMENT);let entriesChanged=0;let replacements=0;const rewrittenEntries=[];for(let index=0;index<entries.length;index+=1){const original=entries[index];const recordVerification=verifyHistoryRecordHash(original);if(!recordVerification.ok){throw new PmCliError(`history-redact refuses invalid immutable record ${index+1} (${recordVerification.error}).`,EXIT_CODE.GENERIC_FAILURE)}const redacted=redactHistoryEntry(original,rules,replacement);replacements+=redacted.replacements;if(redacted.changed){entriesChanged+=1}const beforeHash=replayHash(replay);replay=applyHistoryPatch(replay,redacted.entry.patch,index+1,redacted.entry.op);const afterHash=replayHash(replay);rewrittenEntries.push(resealHistoryRewrite(original,{...redacted.entry,before_hash:beforeHash,after_hash:afterHash},{retainPriorRecord:redacted.changed,retainPriorRecordHash:!redacted.changed}))}return{entries:rewrittenEntries,finalDocument:replay,entriesChanged,replacements}}function hasItemMetadata(replay){return Object.keys(replay.metadata).length>0}function resolveHistoryRedactNextItem(params){if(!hasItemMetadata(params.finalDocument)){return{raw:null,path:null,document:null}}const canonical=canonicalDocument(replayToItemDocument(params.finalDocument),{schema:params.settings.schema});if(canonical.metadata.id!==params.subject.id){throw new PmCliError("history-redact would change the item id; narrow your patterns.",EXIT_CODE.USAGE)}return{document:canonical,path:getItemPath(params.pmRoot,canonical.metadata.type,params.subject.id,"toon",params.typeToFolder),raw:serializeItemDocument(canonical,{format:"toon",schema:params.settings.schema})}}function buildHistoryRedactMessage(options,rewritten){if(typeof options.message==="string"&&options.message.trim().length>0){return options.message}return`history-redact replaced ${rewritten.replacements} match(es) across ${rewritten.entriesChanged} entr${rewritten.entriesChanged===1?"y":"ies"}.`}function buildHistoryRedactEntries(params){const rewrittenEntries=[...params.rewritten.entries];if(params.dryRun||!params.changed){return{rewrittenEntries,auditEntryAdded:false}}const finalDocument=params.nextItemDocument??replayToItemDocument(params.rewritten.finalDocument);rewrittenEntries.push(createHistoryEntry({nowIso:nowIso(),author:params.author,op:"history_redact",before:finalDocument,after:finalDocument,message:params.message}));return{rewrittenEntries,auditEntryAdded:true}}function createHistoryRedactTransaction(params){let derivedIndexWarnings=[];return{applyRewrite:async({historyRawUnderLock})=>{const releaseDerivedIndexLock=await acquireItemMetadataDerivedIndexLock(params.pmRoot,params.author);const affectedItemPaths=new Set;if(params.currentItem.path){affectedItemPaths.add(params.currentItem.path)}if(params.nextItem.path){affectedItemPaths.add(params.nextItem.path)}const itemSnapshots=new Map;if(params.currentItem.path&¶ms.currentItem.raw!==null){itemSnapshots.set(params.currentItem.path,params.currentItem.raw)}let rethrowReleaseFailure=()=>{};try{try{if(params.nextItem.path&¶ms.nextItem.raw!==null&¶ms.nextItem.raw!==params.currentItem.raw){await writeFileAtomic(params.nextItem.path,params.nextItem.raw)}if(params.currentItem.path&&(!params.nextItem.path||params.nextItem.path!==params.currentItem.path)){await fs.rm(params.currentItem.path,{force:true})}await writeFileAtomic(params.subject.historyPath,historyEntriesToRaw(params.rewrittenEntries))}catch(error){try{await rollbackHistoryRedactRewrite(params.subject.historyPath,historyRawUnderLock,affectedItemPaths,itemSnapshots)}finally{await invalidateHistoryDriftCacheForPath(params.subject.historyPath)}throw error}await invalidateHistoryDriftCacheForPath(params.subject.historyPath);const itemPath=params.nextItem.path??params.currentItem.path;if(itemPath){derivedIndexWarnings=await refreshItemMetadataDerivedIndex({pmRoot:params.pmRoot,preferredFormat:params.settings.item_format,typeToFolder:params.typeRegistry.type_to_folder,schema:params.settings.schema,itemPath,...params.currentItem.path?{previousItemPath:params.currentItem.path}:{},document:params.nextItem.document})}}finally{await releaseDerivedIndexLock().catch(error=>{rethrowReleaseFailure=()=>{throw error}})}rethrowReleaseFailure()},afterWrite:async()=>[...derivedIndexWarnings,...await runHistoryRedactWriteHooks(params.subject.historyPath,[params.nextItem.path,params.currentItem.path])]}}async function rollbackHistoryRedactRewrite(historyPath,historyRawUnderLock,affectedItemPaths,itemSnapshots){if(historyRawUnderLock===null){await fs.rm(historyPath,{force:true})}else{await writeFileAtomic(historyPath,historyRawUnderLock)}for(const itemPath of affectedItemPaths){const snapshot=itemSnapshots.get(itemPath);if(snapshot===void 0){await fs.rm(itemPath,{force:true})}else{await writeFileAtomic(itemPath,snapshot)}}}async function runHistoryRedactWriteHooks(historyPath,itemHookPaths){const hookWarnings=[];const uniqueItemHookPaths=new Set(itemHookPaths.filter(itemPath=>itemPath!==null));for(const itemHookPath of uniqueItemHookPaths){hookWarnings.push(...await runActiveOnWriteHooks({path:itemHookPath,scope:"project",op:"history_redact"}))}hookWarnings.push(...await runActiveOnWriteHooks({path:historyPath,scope:"project",op:"history_redact:history"}));return hookWarnings}async function runHistoryRedact(id,options,global2){const{pmRoot,settings,typeRegistry}=await resolveHistoryWorkspace(global2.path);const replacementInput=options.replacement??"";const replacementIsDefault=replacementInput.length===0;const replacement=replacementIsDefault?"[redacted]":replacementInput;const rules=buildRedactionRules(options.literal,options.regex);const subject=await resolveHistorySubject(pmRoot,id,settings,typeRegistry.type_to_folder);return runHistoryMaintenance({pmRoot,subject,settings,typeRegistry,operation:"history-redact",options,transform:snapshot=>buildHistoryRedactPlan({pmRoot,subject,settings,typeRegistry,options,rules,replacement,replacementIsDefault},snapshot)})}function buildHistoryRedactPlan(params,snapshot){const{pmRoot,subject,settings,typeRegistry,options,rules,replacement,replacementIsDefault}=params;const historyEntries=snapshot.entries;const integritySnapshot=inspectHistoryIntegrity(historyEntries);const rewritten=rewriteHistoryEntries(historyEntries,rules,replacement);const preexistingHashMismatches=integritySnapshot.hashMismatchesBefore+integritySnapshot.hashMismatchesAfter;const dryRun=Boolean(options.dryRun);const changed=rewritten.replacements>0;const warnings=[];if(preexistingHashMismatches>0){warnings.push(`history_redact_preexisting_hash_mismatches:${preexistingHashMismatches}`)}if(!changed){warnings.push("history_redact_no_matches")}const currentItem={raw:snapshot.loadedItem?.raw??null,path:subject.located?.itemPath??null,document:snapshot.loadedItem?.document??null};const nextItem=resolveHistoryRedactNextItem({pmRoot,subject,settings,typeToFolder:typeRegistry.type_to_folder,finalDocument:rewritten.finalDocument});const itemChanged=(currentItem.path??null)!==(nextItem.path??null)||(currentItem.raw??null)!==(nextItem.raw??null);const author=snapshot.author;const redactionMessage=buildHistoryRedactMessage(options,rewritten);const{rewrittenEntries,auditEntryAdded}=buildHistoryRedactEntries({rewritten,dryRun,changed,nextItemDocument:nextItem.document,author,message:redactionMessage});return{changed,rewrittenEntries,...createHistoryRedactTransaction({pmRoot,subject,settings,typeRegistry,currentItem,nextItem,author,rewrittenEntries}),report:({verification:historyVerify,warnings:writeWarnings})=>({id:subject.id,dry_run:dryRun,changed,patterns:{literal_count:rules.filter(rule=>rule.kind==="literal").length,regex_count:rules.filter(rule=>rule.kind==="regex").length,total_count:rules.length,replacement_is_default:replacementIsDefault},history:{path:subject.historyPath,entries_scanned:historyEntries.length,entries_changed:rewritten.entriesChanged,replacements:rewritten.replacements,hash_mismatches_before:integritySnapshot.hashMismatchesBefore,hash_mismatches_after:integritySnapshot.hashMismatchesAfter,preexisting_hash_mismatches:preexistingHashMismatches,audit_entry_added:auditEntryAdded,verify_ok:historyVerify.ok,verify_errors:historyVerify.errors},item:{existed_before:currentItem.path!==null,exists_after:nextItem.path!==null,path_before:currentItem.path,path_after:nextItem.path,changed:itemChanged},warnings:[...new Set([...warnings,...writeWarnings])].sort((left,right)=>left.localeCompare(right)),generated_at:nowIso()})}}const _testOnly={applyLiteralRule,applyRegexRule,buildRedactionRules,hasItemMetadata,normalizeRegexFlags,normalizeStringArrayInput,parseRegexRule,redactStringValue,redactUnknownValue};export{_testOnly,resolveHistorySubject2 as resolveHistorySubject,runHistoryRedact};
|
|
643
2
|
//# sourceMappingURL=history-redact.js.map
|
|
644
|
-
//# debugId=bd1e86b0-6696-5fba-8dd4-b9636bf3ee60
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module sdk/history-repair
|
|
3
|
+
*
|
|
4
|
+
* Implements the pm history repair command surface and its agent-facing runtime behavior.
|
|
5
|
+
*/
|
|
1
6
|
import { type HistorySalvageReceipt } from "./history/salvage.js";
|
|
2
7
|
import { type ReplayDocument } from "../core/history/replay.js";
|
|
3
8
|
import type { GlobalOptions } from "../core/shared/command-types.js";
|