@unbrained/pm-cli 2026.5.18 → 2026.5.27
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +953 -472
- package/README.md +4 -11
- package/dist/cli/bootstrap-args.d.ts +18 -1
- package/dist/cli/bootstrap-args.js +143 -3
- package/dist/cli/bootstrap-args.js.map +1 -1
- package/dist/cli/commander-usage.js +147 -10
- package/dist/cli/commander-usage.js.map +1 -1
- package/dist/cli/commands/annotation-command.d.ts +49 -0
- package/dist/cli/commands/annotation-command.js +135 -0
- package/dist/cli/commands/annotation-command.js.map +1 -0
- package/dist/cli/commands/append.js +5 -8
- package/dist/cli/commands/append.js.map +1 -1
- package/dist/cli/commands/calendar.js +3 -6
- package/dist/cli/commands/calendar.js.map +1 -1
- package/dist/cli/commands/claim.js +15 -24
- package/dist/cli/commands/claim.js.map +1 -1
- package/dist/cli/commands/close.js +63 -10
- package/dist/cli/commands/close.js.map +1 -1
- package/dist/cli/commands/comments.d.ts +5 -0
- package/dist/cli/commands/comments.js +27 -117
- package/dist/cli/commands/comments.js.map +1 -1
- package/dist/cli/commands/completion.d.ts +2 -2
- package/dist/cli/commands/completion.js +203 -63
- package/dist/cli/commands/completion.js.map +1 -1
- package/dist/cli/commands/config.d.ts +1 -1
- package/dist/cli/commands/config.js +82 -4
- package/dist/cli/commands/config.js.map +1 -1
- package/dist/cli/commands/context.js +4 -10
- package/dist/cli/commands/context.js.map +1 -1
- package/dist/cli/commands/contracts.js +168 -36
- package/dist/cli/commands/contracts.js.map +1 -1
- package/dist/cli/commands/create.js +53 -313
- package/dist/cli/commands/create.js.map +1 -1
- package/dist/cli/commands/dedupe-audit.js +7 -4
- package/dist/cli/commands/dedupe-audit.js.map +1 -1
- package/dist/cli/commands/delete.d.ts +3 -0
- package/dist/cli/commands/delete.js +11 -9
- package/dist/cli/commands/delete.js.map +1 -1
- package/dist/cli/commands/docs.d.ts +2 -12
- package/dist/cli/commands/docs.js +8 -316
- package/dist/cli/commands/docs.js.map +1 -1
- package/dist/cli/commands/event-validation-messages.d.ts +3 -0
- package/dist/cli/commands/event-validation-messages.js +44 -0
- package/dist/cli/commands/event-validation-messages.js.map +1 -0
- package/dist/cli/commands/extension/bundled-catalog.d.ts +14 -0
- package/dist/cli/commands/extension/bundled-catalog.js +268 -0
- package/dist/cli/commands/extension/bundled-catalog.js.map +1 -0
- package/dist/cli/commands/extension/doctor.d.ts +31 -0
- package/dist/cli/commands/extension/doctor.js +345 -0
- package/dist/cli/commands/extension/doctor.js.map +1 -0
- package/dist/cli/commands/extension/install-sources.d.ts +37 -0
- package/dist/cli/commands/extension/install-sources.js +384 -0
- package/dist/cli/commands/extension/install-sources.js.map +1 -0
- package/dist/cli/commands/extension/managed-state.d.ts +48 -0
- package/dist/cli/commands/extension/managed-state.js +172 -0
- package/dist/cli/commands/extension/managed-state.js.map +1 -0
- package/dist/cli/commands/extension/scaffold.d.ts +14 -0
- package/dist/cli/commands/extension/scaffold.js +169 -0
- package/dist/cli/commands/extension/scaffold.js.map +1 -0
- package/dist/cli/commands/extension/shared.d.ts +14 -0
- package/dist/cli/commands/extension/shared.js +106 -0
- package/dist/cli/commands/extension/shared.js.map +1 -0
- package/dist/cli/commands/extension.d.ts +37 -68
- package/dist/cli/commands/extension.js +157 -1319
- package/dist/cli/commands/extension.js.map +1 -1
- package/dist/cli/commands/files.d.ts +1 -12
- package/dist/cli/commands/files.js +14 -318
- package/dist/cli/commands/files.js.map +1 -1
- package/dist/cli/commands/gc.js +17 -4
- package/dist/cli/commands/gc.js.map +1 -1
- package/dist/cli/commands/get.d.ts +3 -2
- package/dist/cli/commands/get.js +52 -9
- package/dist/cli/commands/get.js.map +1 -1
- package/dist/cli/commands/health.d.ts +10 -0
- package/dist/cli/commands/health.js +269 -76
- package/dist/cli/commands/health.js.map +1 -1
- package/dist/cli/commands/history-redact.d.ts +8 -0
- package/dist/cli/commands/history-redact.js +35 -113
- package/dist/cli/commands/history-redact.js.map +1 -1
- package/dist/cli/commands/history-repair.d.ts +33 -0
- package/dist/cli/commands/history-repair.js +172 -0
- package/dist/cli/commands/history-repair.js.map +1 -0
- package/dist/cli/commands/history.d.ts +4 -4
- package/dist/cli/commands/history.js +10 -88
- package/dist/cli/commands/history.js.map +1 -1
- package/dist/cli/commands/index.d.ts +3 -1
- package/dist/cli/commands/index.js +5 -3
- package/dist/cli/commands/index.js.map +1 -1
- package/dist/cli/commands/init.d.ts +28 -0
- package/dist/cli/commands/init.js +23 -2
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/learnings.js +20 -119
- package/dist/cli/commands/learnings.js.map +1 -1
- package/dist/cli/commands/legacy-none-tokens.d.ts +3 -0
- package/dist/cli/commands/legacy-none-tokens.js +39 -0
- package/dist/cli/commands/legacy-none-tokens.js.map +1 -0
- package/dist/cli/commands/linked-artifacts.d.ts +96 -0
- package/dist/cli/commands/linked-artifacts.js +335 -0
- package/dist/cli/commands/linked-artifacts.js.map +1 -0
- package/dist/cli/commands/linked-test-entry.d.ts +3 -0
- package/dist/cli/commands/linked-test-entry.js +62 -0
- package/dist/cli/commands/linked-test-entry.js.map +1 -0
- package/dist/cli/commands/linked-test-parsers.d.ts +28 -0
- package/dist/cli/commands/linked-test-parsers.js +192 -0
- package/dist/cli/commands/linked-test-parsers.js.map +1 -0
- package/dist/cli/commands/list.js +49 -24
- package/dist/cli/commands/list.js.map +1 -1
- package/dist/cli/commands/normalize.js +4 -3
- package/dist/cli/commands/normalize.js.map +1 -1
- package/dist/cli/commands/notes.js +20 -119
- package/dist/cli/commands/notes.js.map +1 -1
- package/dist/cli/commands/plan.d.ts +3 -0
- package/dist/cli/commands/plan.js +184 -22
- package/dist/cli/commands/plan.js.map +1 -1
- package/dist/cli/commands/recurrence-parsers.d.ts +26 -0
- package/dist/cli/commands/recurrence-parsers.js +98 -0
- package/dist/cli/commands/recurrence-parsers.js.map +1 -0
- package/dist/cli/commands/restore.js +24 -56
- package/dist/cli/commands/restore.js.map +1 -1
- package/dist/cli/commands/schema.d.ts +31 -0
- package/dist/cli/commands/schema.js +98 -0
- package/dist/cli/commands/schema.js.map +1 -0
- package/dist/cli/commands/search.js +154 -42
- package/dist/cli/commands/search.js.map +1 -1
- package/dist/cli/commands/templates.d.ts +4 -0
- package/dist/cli/commands/templates.js +89 -17
- package/dist/cli/commands/templates.js.map +1 -1
- package/dist/cli/commands/test/linked-command-detection.d.ts +37 -0
- package/dist/cli/commands/test/linked-command-detection.js +200 -0
- package/dist/cli/commands/test/linked-command-detection.js.map +1 -0
- package/dist/cli/commands/test-all.js +4 -8
- package/dist/cli/commands/test-all.js.map +1 -1
- package/dist/cli/commands/test.d.ts +2 -2
- package/dist/cli/commands/test.js +12 -357
- package/dist/cli/commands/test.js.map +1 -1
- package/dist/cli/commands/update-many.js +6 -9
- package/dist/cli/commands/update-many.js.map +1 -1
- package/dist/cli/commands/update.js +167 -401
- package/dist/cli/commands/update.js.map +1 -1
- package/dist/cli/commands/validate.d.ts +3 -1
- package/dist/cli/commands/validate.js +23 -71
- package/dist/cli/commands/validate.js.map +1 -1
- package/dist/cli/error-guidance.d.ts +1 -0
- package/dist/cli/error-guidance.js +100 -6
- package/dist/cli/error-guidance.js.map +1 -1
- package/dist/cli/extension-command-help.d.ts +0 -1
- package/dist/cli/extension-command-help.js +2 -13
- package/dist/cli/extension-command-help.js.map +1 -1
- package/dist/cli/extension-command-options.d.ts +1 -0
- package/dist/cli/extension-command-options.js +106 -7
- package/dist/cli/extension-command-options.js.map +1 -1
- package/dist/cli/help-content.d.ts +0 -1
- package/dist/cli/help-content.js +13 -9
- package/dist/cli/help-content.js.map +1 -1
- package/dist/cli/help-json-payload.d.ts +1 -0
- package/dist/cli/help-json-payload.js +33 -3
- package/dist/cli/help-json-payload.js.map +1 -1
- package/dist/cli/main.d.ts +11 -0
- package/dist/cli/main.js +109 -55
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/register-list-query.d.ts +5 -2
- package/dist/cli/register-list-query.js +254 -192
- package/dist/cli/register-list-query.js.map +1 -1
- package/dist/cli/register-mutation.d.ts +1 -1
- package/dist/cli/register-mutation.js +247 -64
- package/dist/cli/register-mutation.js.map +1 -1
- package/dist/cli/register-operations.js +17 -12
- package/dist/cli/register-operations.js.map +1 -1
- package/dist/cli/register-setup.js +33 -16
- package/dist/cli/register-setup.js.map +1 -1
- package/dist/cli/registration-helpers.d.ts +0 -2
- package/dist/cli/registration-helpers.js +14 -40
- package/dist/cli/registration-helpers.js.map +1 -1
- package/dist/cli.js +25 -4
- package/dist/cli.js.map +1 -1
- package/dist/core/config/positional-value.d.ts +44 -0
- package/dist/core/config/positional-value.js +109 -0
- package/dist/core/config/positional-value.js.map +1 -0
- package/dist/core/extensions/extension-capability-aliases.d.ts +14 -0
- package/dist/core/extensions/extension-capability-aliases.js +159 -0
- package/dist/core/extensions/extension-capability-aliases.js.map +1 -0
- package/dist/core/extensions/extension-hook-runtime.d.ts +13 -0
- package/dist/core/extensions/extension-hook-runtime.js +414 -0
- package/dist/core/extensions/extension-hook-runtime.js.map +1 -0
- package/dist/core/extensions/extension-policy.d.ts +69 -0
- package/dist/core/extensions/extension-policy.js +481 -0
- package/dist/core/extensions/extension-policy.js.map +1 -0
- package/dist/core/extensions/extension-registries.d.ts +8 -0
- package/dist/core/extensions/extension-registries.js +52 -0
- package/dist/core/extensions/extension-registries.js.map +1 -0
- package/dist/core/extensions/extension-runtime-helpers.d.ts +6 -0
- package/dist/core/extensions/extension-runtime-helpers.js +29 -0
- package/dist/core/extensions/extension-runtime-helpers.js.map +1 -0
- package/dist/core/extensions/extension-types.d.ts +13 -39
- package/dist/core/extensions/extension-types.js +34 -2
- package/dist/core/extensions/extension-types.js.map +1 -1
- package/dist/core/extensions/index.d.ts +7 -1
- package/dist/core/extensions/index.js +11 -14
- package/dist/core/extensions/index.js.map +1 -1
- package/dist/core/extensions/loader.d.ts +4 -22
- package/dist/core/extensions/loader.js +23 -1146
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/fs/path-utils.d.ts +1 -0
- package/dist/core/fs/path-utils.js +12 -0
- package/dist/core/fs/path-utils.js.map +1 -0
- package/dist/core/history/drift-scan.d.ts +22 -0
- package/dist/core/history/drift-scan.js +149 -0
- package/dist/core/history/drift-scan.js.map +1 -0
- package/dist/core/history/history-rewrite.d.ts +43 -0
- package/dist/core/history/history-rewrite.js +48 -0
- package/dist/core/history/history-rewrite.js.map +1 -0
- package/dist/core/history/history.js +5 -4
- package/dist/core/history/history.js.map +1 -1
- package/dist/core/history/replay.d.ts +82 -0
- package/dist/core/history/replay.js +250 -0
- package/dist/core/history/replay.js.map +1 -0
- package/dist/core/item/item-format.js +11 -8
- package/dist/core/item/item-format.js.map +1 -1
- package/dist/core/item/item-record.d.ts +19 -0
- package/dist/core/item/item-record.js +24 -0
- package/dist/core/item/item-record.js.map +1 -0
- package/dist/core/item/item-type-definition.d.ts +52 -0
- package/dist/core/item/item-type-definition.js +123 -0
- package/dist/core/item/item-type-definition.js.map +1 -0
- package/dist/core/item/parse.js +3 -2
- package/dist/core/item/parse.js.map +1 -1
- package/dist/core/item/priority.d.ts +23 -0
- package/dist/core/item/priority.js +55 -0
- package/dist/core/item/priority.js.map +1 -0
- package/dist/core/item/status.d.ts +14 -1
- package/dist/core/item/status.js +22 -2
- package/dist/core/item/status.js.map +1 -1
- package/dist/core/item/toon-decode.d.ts +19 -0
- package/dist/core/item/toon-decode.js +69 -0
- package/dist/core/item/toon-decode.js.map +1 -0
- package/dist/core/item/type-registry.js +13 -84
- package/dist/core/item/type-registry.js.map +1 -1
- package/dist/core/output/mutation-projection.d.ts +31 -0
- package/dist/core/output/mutation-projection.js +103 -0
- package/dist/core/output/mutation-projection.js.map +1 -0
- package/dist/core/output/output.d.ts +2 -0
- package/dist/core/output/output.js +5 -3
- package/dist/core/output/output.js.map +1 -1
- package/dist/core/packages/manifest.js +3 -9
- package/dist/core/packages/manifest.js.map +1 -1
- package/dist/core/schema/item-types-file.d.ts +85 -0
- package/dist/core/schema/item-types-file.js +243 -0
- package/dist/core/schema/item-types-file.js.map +1 -0
- package/dist/core/schema/runtime-schema.d.ts +2 -1
- package/dist/core/schema/runtime-schema.js +17 -45
- package/dist/core/schema/runtime-schema.js.map +1 -1
- package/dist/core/search/semantic-defaults.js +3 -3
- package/dist/core/search/semantic-defaults.js.map +1 -1
- package/dist/core/search/vector-stores.js +46 -9
- package/dist/core/search/vector-stores.js.map +1 -1
- package/dist/core/sentry/helpers.d.ts +1 -1
- package/dist/core/sentry/helpers.js +20 -3
- package/dist/core/sentry/helpers.js.map +1 -1
- package/dist/core/shared/author.d.ts +1 -0
- package/dist/core/shared/author.js +9 -0
- package/dist/core/shared/author.js.map +1 -0
- package/dist/core/shared/command-types.d.ts +1 -0
- package/dist/core/shared/command-types.js +2 -2
- package/dist/core/shared/command-types.js.map +1 -1
- package/dist/core/shared/constants.d.ts +10 -1
- package/dist/core/shared/constants.js +56 -58
- package/dist/core/shared/constants.js.map +1 -1
- package/dist/core/shared/lazy-module.d.ts +1 -0
- package/dist/core/shared/lazy-module.js +11 -0
- package/dist/core/shared/lazy-module.js.map +1 -0
- package/dist/core/shared/option-alias-visibility.d.ts +44 -0
- package/dist/core/shared/option-alias-visibility.js +76 -0
- package/dist/core/shared/option-alias-visibility.js.map +1 -0
- package/dist/core/shared/primitives.d.ts +23 -0
- package/dist/core/shared/primitives.js +39 -2
- package/dist/core/shared/primitives.js.map +1 -1
- package/dist/core/shared/text-normalization.d.ts +0 -1
- package/dist/core/shared/text-normalization.js +2 -5
- package/dist/core/shared/text-normalization.js.map +1 -1
- package/dist/core/store/front-matter-cache.d.ts +16 -2
- package/dist/core/store/front-matter-cache.js +99 -33
- package/dist/core/store/front-matter-cache.js.map +1 -1
- package/dist/core/store/item-store.d.ts +2 -0
- package/dist/core/store/item-store.js +76 -110
- package/dist/core/store/item-store.js.map +1 -1
- package/dist/core/store/settings-validator.d.ts +106 -0
- package/dist/core/store/settings-validator.js +279 -0
- package/dist/core/store/settings-validator.js.map +1 -0
- package/dist/core/store/settings.js +6 -343
- package/dist/core/store/settings.js.map +1 -1
- package/dist/core/telemetry/runtime.js +5 -3
- package/dist/core/telemetry/runtime.js.map +1 -1
- package/dist/mcp/server.js +138 -39
- package/dist/mcp/server.js.map +1 -1
- package/dist/sdk/cli-contracts/enum-contracts.d.ts +20 -0
- package/dist/sdk/cli-contracts/enum-contracts.js +156 -0
- package/dist/sdk/cli-contracts/enum-contracts.js.map +1 -0
- package/dist/sdk/cli-contracts/tool-option-contracts.d.ts +14 -0
- package/dist/sdk/cli-contracts/tool-option-contracts.js +243 -0
- package/dist/sdk/cli-contracts/tool-option-contracts.js.map +1 -0
- package/dist/sdk/cli-contracts/tool-parameter-tables.d.ts +11 -0
- package/dist/sdk/cli-contracts/tool-parameter-tables.js +901 -0
- package/dist/sdk/cli-contracts/tool-parameter-tables.js.map +1 -0
- package/dist/sdk/cli-contracts.d.ts +18 -33
- package/dist/sdk/cli-contracts.js +96 -1238
- package/dist/sdk/cli-contracts.js.map +1 -1
- package/dist/sdk/package-import-adapters.d.ts +74 -0
- package/dist/sdk/package-import-adapters.js +186 -0
- package/dist/sdk/package-import-adapters.js.map +1 -0
- package/dist/sdk/package-runtime-options.d.ts +26 -0
- package/dist/sdk/package-runtime-options.js +71 -0
- package/dist/sdk/package-runtime-options.js.map +1 -0
- package/dist/sdk/runtime.d.ts +27 -1
- package/dist/sdk/runtime.js +48 -3
- package/dist/sdk/runtime.js.map +1 -1
- package/dist/types.d.ts +6 -0
- package/dist/types.js +10 -2
- package/dist/types.js.map +1 -1
- package/docs/AGENT_GUIDE.md +13 -11
- package/docs/ARCHITECTURE.md +1 -1
- package/docs/CLAUDE_CODE_PLUGIN.md +5 -28
- package/docs/CODEX_PLUGIN.md +5 -5
- package/docs/COMMANDS.md +58 -9
- package/docs/CONFIGURATION.md +16 -1
- package/docs/EXTENSIONS.md +4 -63
- package/docs/RELEASING.md +12 -8
- package/docs/SDK.md +11 -2
- package/marketplace.json +7 -3
- package/package.json +18 -14
- package/packages/pm-beads/extensions/beads/index.js +2 -49
- package/packages/pm-beads/extensions/beads/index.ts +2 -54
- package/packages/pm-beads/extensions/beads/runtime-loader.js +86 -0
- package/packages/pm-beads/extensions/beads/runtime-loader.ts +88 -0
- package/packages/pm-beads/extensions/beads/runtime.js +26 -115
- package/packages/pm-beads/extensions/beads/runtime.ts +33 -132
- package/packages/pm-calendar/README.md +3 -1
- package/packages/pm-calendar/extensions/calendar/index.js +66 -2
- package/packages/pm-calendar/extensions/calendar/index.ts +71 -2
- package/packages/pm-calendar/extensions/calendar/runtime.js +1 -0
- package/packages/pm-calendar/extensions/calendar/runtime.ts +1 -0
- package/packages/pm-governance-audit/extensions/governance-audit/runtime.js +14 -41
- package/packages/pm-governance-audit/extensions/governance-audit/runtime.ts +25 -41
- package/packages/pm-guide-shell/extensions/guide-shell/runtime.js +10 -50
- package/packages/pm-guide-shell/extensions/guide-shell/runtime.ts +17 -50
- package/packages/pm-linked-test-adapters/extensions/linked-test-adapters/runtime.js +8 -40
- package/packages/pm-linked-test-adapters/extensions/linked-test-adapters/runtime.ts +10 -40
- package/packages/pm-search-advanced/README.md +8 -0
- package/packages/pm-search-advanced/extensions/search-advanced/index.js +75 -1
- package/packages/pm-search-advanced/extensions/search-advanced/index.ts +74 -0
- package/packages/pm-search-advanced/extensions/search-advanced/runtime.js +58 -33
- package/packages/pm-search-advanced/extensions/search-advanced/runtime.ts +60 -33
- package/packages/pm-templates/extensions/templates/runtime.js +11 -202
- package/packages/pm-templates/extensions/templates/runtime.ts +38 -230
- package/packages/pm-todos/extensions/todos/index.js +3 -50
- package/packages/pm-todos/extensions/todos/index.ts +3 -55
- package/packages/pm-todos/extensions/todos/runtime-loader.js +86 -0
- package/packages/pm-todos/extensions/todos/runtime-loader.ts +88 -0
- package/packages/pm-todos/extensions/todos/runtime.js +24 -117
- package/packages/pm-todos/extensions/todos/runtime.ts +32 -129
- package/plugins/pm-claude/README.md +2 -2
- package/plugins/pm-claude/commands/pm-planner.md +1 -15
- package/plugins/pm-claude/scripts/pm-mcp-server.mjs +5 -2
- package/plugins/pm-claude/skills/pm-planner/SKILL.md +3 -21
- package/plugins/pm-codex/scripts/pm-mcp-server.mjs +15 -6
- package/plugins/pm-codex/skills/pm-native/SKILL.md +1 -13
- package/PRD.md +0 -1734
- package/dist/core/output/command-aware.d.ts +0 -1
- package/dist/core/output/command-aware.js +0 -397
- package/dist/core/output/command-aware.js.map +0 -1
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
|
|
2
|
-
!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]="
|
|
2
|
+
!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]="f92d5c88-f7f6-522f-a15b-fb109875fdac")}catch(e){}}();
|
|
3
3
|
import fs from "node:fs/promises";
|
|
4
|
-
import jsonPatch from "fast-json-patch";
|
|
5
4
|
import { pathExists, readFileIfExists, writeFileAtomic } from "../../core/fs/fs-utils.js";
|
|
6
|
-
import { createHistoryEntry
|
|
5
|
+
import { createHistoryEntry } from "../../core/history/history.js";
|
|
6
|
+
import { checkHistoryRewriteOwnership, verifyHistoryRewriteNoDrift, } from "../../core/history/history-rewrite.js";
|
|
7
|
+
import { EMPTY_REPLAY_DOCUMENT, historyEntriesToRaw, replayHash, replayToItemDocument, tryApplyReplayPatch, verifyHistoryChain, } from "../../core/history/replay.js";
|
|
7
8
|
import { normalizeItemId, normalizeRawItemId } from "../../core/item/id.js";
|
|
8
9
|
import { canonicalDocument, serializeItemDocument } from "../../core/item/item-format.js";
|
|
9
10
|
import { resolveItemTypeRegistry } from "../../core/item/type-registry.js";
|
|
@@ -14,17 +15,9 @@ import { nowIso } from "../../core/shared/time.js";
|
|
|
14
15
|
import { getActiveExtensionRegistrations, runActiveOnWriteHooks } from "../../core/extensions/index.js";
|
|
15
16
|
import { locateItem, readLocatedItem } from "../../core/store/item-store.js";
|
|
16
17
|
import { getHistoryPath, getItemPath, getSettingsPath, resolvePmRoot } from "../../core/store/paths.js";
|
|
17
|
-
import { readSettings
|
|
18
|
+
import { readSettings } from "../../core/store/settings.js";
|
|
19
|
+
import { resolveAuthor } from "../../core/shared/author.js";
|
|
18
20
|
import { readHistoryEntries } from "./history.js";
|
|
19
|
-
const EMPTY_REPLAY_DOCUMENT = {
|
|
20
|
-
metadata: {},
|
|
21
|
-
body: "",
|
|
22
|
-
};
|
|
23
|
-
function toAuthor(candidate, defaultAuthor) {
|
|
24
|
-
const resolved = candidate ?? process.env.PM_AUTHOR ?? defaultAuthor;
|
|
25
|
-
const trimmed = resolved.trim();
|
|
26
|
-
return trimmed.length > 0 ? trimmed : "unknown";
|
|
27
|
-
}
|
|
28
21
|
function normalizeStringArrayInput(value) {
|
|
29
22
|
if (Array.isArray(value)) {
|
|
30
23
|
return value;
|
|
@@ -182,50 +175,12 @@ function redactUnknownValue(value, rules, replacement) {
|
|
|
182
175
|
replacements: 0,
|
|
183
176
|
};
|
|
184
177
|
}
|
|
185
|
-
function normalizeReplayPatchPath(path) {
|
|
186
|
-
if (path === "/front_matter") {
|
|
187
|
-
return "/metadata";
|
|
188
|
-
}
|
|
189
|
-
if (path.startsWith("/front_matter/")) {
|
|
190
|
-
return `/metadata/${path.slice("/front_matter/".length)}`;
|
|
191
|
-
}
|
|
192
|
-
return path;
|
|
193
|
-
}
|
|
194
|
-
function normalizeReplayPatchOps(patch) {
|
|
195
|
-
return patch.map((operation) => ({
|
|
196
|
-
...operation,
|
|
197
|
-
path: normalizeReplayPatchPath(operation.path),
|
|
198
|
-
from: operation.from ? normalizeReplayPatchPath(operation.from) : undefined,
|
|
199
|
-
}));
|
|
200
|
-
}
|
|
201
|
-
function replayHash(document) {
|
|
202
|
-
return hashDocument({
|
|
203
|
-
metadata: document.metadata,
|
|
204
|
-
body: document.body,
|
|
205
|
-
});
|
|
206
|
-
}
|
|
207
178
|
function applyHistoryPatch(current, patch, entryNumber, op) {
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
if (typeof applied !== "object" ||
|
|
212
|
-
applied === null ||
|
|
213
|
-
!("metadata" in applied) ||
|
|
214
|
-
!("body" in applied) ||
|
|
215
|
-
typeof applied.body !== "string" ||
|
|
216
|
-
typeof applied.metadata !== "object" ||
|
|
217
|
-
applied.metadata === null) {
|
|
218
|
-
throw new PmCliError(`history-redact replay produced an invalid document shape at entry ${entryNumber}.`, EXIT_CODE.GENERIC_FAILURE);
|
|
219
|
-
}
|
|
220
|
-
const replay = applied;
|
|
221
|
-
return {
|
|
222
|
-
metadata: replay.metadata,
|
|
223
|
-
body: replay.body,
|
|
224
|
-
};
|
|
225
|
-
}
|
|
226
|
-
catch (error) {
|
|
227
|
-
throw new PmCliError(`history-redact failed to apply patch at entry ${entryNumber} (op=${op}): ${error instanceof Error ? error.message : String(error)}`, EXIT_CODE.GENERIC_FAILURE);
|
|
179
|
+
const result = tryApplyReplayPatch(current, patch);
|
|
180
|
+
if (!result.ok) {
|
|
181
|
+
throw new PmCliError(`history-redact failed to apply patch at entry ${entryNumber} (op=${op}): ${result.error instanceof Error ? result.error.message : String(result.error)}`, EXIT_CODE.GENERIC_FAILURE);
|
|
228
182
|
}
|
|
183
|
+
return result.document;
|
|
229
184
|
}
|
|
230
185
|
function inspectHistoryIntegrity(entries) {
|
|
231
186
|
let replay = structuredClone(EMPTY_REPLAY_DOCUMENT);
|
|
@@ -311,41 +266,10 @@ function rewriteHistoryEntries(entries, rules, replacement) {
|
|
|
311
266
|
replacements,
|
|
312
267
|
};
|
|
313
268
|
}
|
|
314
|
-
function verifyHistoryEntries(entries) {
|
|
315
|
-
let replay = structuredClone(EMPTY_REPLAY_DOCUMENT);
|
|
316
|
-
for (let index = 0; index < entries.length; index += 1) {
|
|
317
|
-
const entry = entries[index];
|
|
318
|
-
const beforeHash = replayHash(replay);
|
|
319
|
-
if (beforeHash !== entry.before_hash) {
|
|
320
|
-
return {
|
|
321
|
-
ok: false,
|
|
322
|
-
errors: [`verify_failed:before_hash_mismatch:entry_${index + 1}`],
|
|
323
|
-
};
|
|
324
|
-
}
|
|
325
|
-
replay = applyHistoryPatch(replay, entry.patch, index + 1, entry.op);
|
|
326
|
-
const afterHash = replayHash(replay);
|
|
327
|
-
if (afterHash !== entry.after_hash) {
|
|
328
|
-
return {
|
|
329
|
-
ok: false,
|
|
330
|
-
errors: [`verify_failed:after_hash_mismatch:entry_${index + 1}`],
|
|
331
|
-
};
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
|
-
return {
|
|
335
|
-
ok: true,
|
|
336
|
-
errors: [],
|
|
337
|
-
};
|
|
338
|
-
}
|
|
339
|
-
function replayToItemDocument(replay) {
|
|
340
|
-
return {
|
|
341
|
-
metadata: replay.metadata,
|
|
342
|
-
body: replay.body,
|
|
343
|
-
};
|
|
344
|
-
}
|
|
345
269
|
function hasItemMetadata(replay) {
|
|
346
270
|
return Object.keys(replay.metadata).length > 0;
|
|
347
271
|
}
|
|
348
|
-
async function
|
|
272
|
+
export async function resolveHistorySubject(pmRoot, id, settings, typeToFolder) {
|
|
349
273
|
const located = await locateItem(pmRoot, id, settings.id_prefix, settings.item_format, typeToFolder);
|
|
350
274
|
if (located) {
|
|
351
275
|
return {
|
|
@@ -369,12 +293,6 @@ async function resolveSubject(pmRoot, id, settings, typeToFolder) {
|
|
|
369
293
|
}
|
|
370
294
|
throw new PmCliError(`Item ${id} not found`, EXIT_CODE.NOT_FOUND);
|
|
371
295
|
}
|
|
372
|
-
function toHistoryRaw(entries) {
|
|
373
|
-
if (entries.length === 0) {
|
|
374
|
-
return "";
|
|
375
|
-
}
|
|
376
|
-
return `${entries.map((entry) => JSON.stringify(entry)).join("\n")}\n`;
|
|
377
|
-
}
|
|
378
296
|
export async function runHistoryRedact(id, options, global) {
|
|
379
297
|
const pmRoot = resolvePmRoot(process.cwd(), global.path);
|
|
380
298
|
if (!(await pathExists(getSettingsPath(pmRoot)))) {
|
|
@@ -384,10 +302,11 @@ export async function runHistoryRedact(id, options, global) {
|
|
|
384
302
|
const typeRegistry = resolveItemTypeRegistry(settings, getActiveExtensionRegistrations());
|
|
385
303
|
const replacement = typeof options.replacement === "string" && options.replacement.length > 0 ? options.replacement : "[redacted]";
|
|
386
304
|
const rules = buildRedactionRules(options.literal, options.regex);
|
|
387
|
-
const subject = await
|
|
305
|
+
const subject = await resolveHistorySubject(pmRoot, id, settings, typeRegistry.type_to_folder);
|
|
388
306
|
if (!(await pathExists(subject.historyPath))) {
|
|
389
307
|
throw new PmCliError(`No history stream exists for ${subject.id}.`, EXIT_CODE.NOT_FOUND);
|
|
390
308
|
}
|
|
309
|
+
const historyRawBeforeLock = await readFileIfExists(subject.historyPath);
|
|
391
310
|
const historyEntries = await readHistoryEntries(subject.historyPath, subject.id);
|
|
392
311
|
if (historyEntries.length === 0) {
|
|
393
312
|
throw new PmCliError(`No history entries exist for ${subject.id}; nothing to redact.`, EXIT_CODE.USAGE);
|
|
@@ -429,7 +348,7 @@ export async function runHistoryRedact(id, options, global) {
|
|
|
429
348
|
}
|
|
430
349
|
const itemChanged = (currentItemPath ?? null) !== (nextItemPath ?? null) ||
|
|
431
350
|
(currentItemRaw ?? null) !== (nextItemRaw ?? null);
|
|
432
|
-
const author =
|
|
351
|
+
const author = resolveAuthor(options.author, settings.author_default);
|
|
433
352
|
const redactionMessage = typeof options.message === "string" && options.message.trim().length > 0
|
|
434
353
|
? options.message
|
|
435
354
|
: `history-redact replaced ${rewritten.replacements} match(es) across ${rewritten.entriesChanged} entr${rewritten.entriesChanged === 1 ? "y" : "ies"}.`;
|
|
@@ -447,26 +366,29 @@ export async function runHistoryRedact(id, options, global) {
|
|
|
447
366
|
}));
|
|
448
367
|
auditEntryAdded = true;
|
|
449
368
|
}
|
|
450
|
-
const historyVerify =
|
|
369
|
+
const historyVerify = verifyHistoryChain(rewrittenEntries);
|
|
451
370
|
if (!historyVerify.ok) {
|
|
452
371
|
throw new PmCliError(`history-redact produced an invalid rewritten chain (${historyVerify.errors.join(", ")}).`, EXIT_CODE.GENERIC_FAILURE);
|
|
453
372
|
}
|
|
454
373
|
if (!dryRun && changed) {
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
if (governance.ownership_enforcement === "warn") {
|
|
463
|
-
warnings.push(`ownership_warning:assignee_conflict:${subject.id}:${assigned}`);
|
|
464
|
-
}
|
|
465
|
-
}
|
|
466
|
-
}
|
|
374
|
+
warnings.push(...checkHistoryRewriteOwnership({
|
|
375
|
+
itemDocument: currentItemDocument,
|
|
376
|
+
subjectId: subject.id,
|
|
377
|
+
author,
|
|
378
|
+
force: options.force,
|
|
379
|
+
settings,
|
|
380
|
+
}));
|
|
467
381
|
const releaseLock = await acquireLock(pmRoot, subject.id, settings.locks.ttl_seconds, author, Boolean(options.force), settings.governance.force_required_for_stale_lock);
|
|
468
382
|
try {
|
|
469
|
-
const
|
|
383
|
+
const { historyRawUnderLock } = await verifyHistoryRewriteNoDrift({
|
|
384
|
+
pmRoot,
|
|
385
|
+
subject,
|
|
386
|
+
settings,
|
|
387
|
+
typeRegistry,
|
|
388
|
+
historyRawBeforeLock,
|
|
389
|
+
currentItemRawBeforeLock: currentItemRaw,
|
|
390
|
+
operation: "history-redact",
|
|
391
|
+
});
|
|
470
392
|
const affectedItemPaths = new Set();
|
|
471
393
|
if (currentItemPath) {
|
|
472
394
|
affectedItemPaths.add(currentItemPath);
|
|
@@ -485,14 +407,14 @@ export async function runHistoryRedact(id, options, global) {
|
|
|
485
407
|
if (currentItemPath && (!nextItemPath || nextItemPath !== currentItemPath)) {
|
|
486
408
|
await fs.rm(currentItemPath, { force: true });
|
|
487
409
|
}
|
|
488
|
-
await writeFileAtomic(subject.historyPath,
|
|
410
|
+
await writeFileAtomic(subject.historyPath, historyEntriesToRaw(rewrittenEntries));
|
|
489
411
|
}
|
|
490
412
|
catch (error) {
|
|
491
|
-
if (
|
|
413
|
+
if (historyRawUnderLock === null) {
|
|
492
414
|
await fs.rm(subject.historyPath, { force: true });
|
|
493
415
|
}
|
|
494
416
|
else {
|
|
495
|
-
await writeFileAtomic(subject.historyPath,
|
|
417
|
+
await writeFileAtomic(subject.historyPath, historyRawUnderLock);
|
|
496
418
|
}
|
|
497
419
|
for (const itemPath of affectedItemPaths) {
|
|
498
420
|
const snapshot = itemSnapshots.get(itemPath);
|
|
@@ -556,4 +478,4 @@ export async function runHistoryRedact(id, options, global) {
|
|
|
556
478
|
};
|
|
557
479
|
}
|
|
558
480
|
//# sourceMappingURL=history-redact.js.map
|
|
559
|
-
//# debugId=
|
|
481
|
+
//# debugId=f92d5c88-f7f6-522f-a15b-fb109875fdac
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"history-redact.js","sources":["cli/commands/history-redact.ts"],"sourceRoot":"/","sourcesContent":["import fs from \"node:fs/promises\";\nimport jsonPatch from \"fast-json-patch\";\nimport { pathExists, readFileIfExists, writeFileAtomic } from \"../../core/fs/fs-utils.js\";\nimport { createHistoryEntry, hashDocument } from \"../../core/history/history.js\";\nimport { normalizeItemId, normalizeRawItemId } from \"../../core/item/id.js\";\nimport { canonicalDocument, serializeItemDocument } from \"../../core/item/item-format.js\";\nimport { resolveItemTypeRegistry } from \"../../core/item/type-registry.js\";\nimport { acquireLock } from \"../../core/lock/lock.js\";\nimport { EXIT_CODE } from \"../../core/shared/constants.js\";\nimport type { GlobalOptions } from \"../../core/shared/command-types.js\";\nimport { PmCliError } from \"../../core/shared/errors.js\";\nimport { nowIso } from \"../../core/shared/time.js\";\nimport { getActiveExtensionRegistrations, runActiveOnWriteHooks } from \"../../core/extensions/index.js\";\nimport { locateItem, readLocatedItem } from \"../../core/store/item-store.js\";\nimport { getHistoryPath, getItemPath, getSettingsPath, resolvePmRoot } from \"../../core/store/paths.js\";\nimport { readSettings, resolveGovernanceKnobs } from \"../../core/store/settings.js\";\nimport type { HistoryEntry, HistoryPatchOp, ItemDocument, ItemMetadata } from \"../../types/index.js\";\nimport { readHistoryEntries } from \"./history.js\";\n\nexport interface HistoryRedactCommandOptions {\n literal?: string[] | string;\n regex?: string[] | string;\n replacement?: string;\n dryRun?: boolean;\n author?: string;\n message?: string;\n force?: boolean;\n}\n\ninterface ReplayDocument {\n metadata: Record<string, unknown>;\n body: string;\n}\n\ninterface RegexRule {\n kind: \"regex\";\n source: string;\n flags: string;\n label: string;\n}\n\ninterface LiteralRule {\n kind: \"literal\";\n value: string;\n label: string;\n}\n\ntype RedactionRule = RegexRule | LiteralRule;\n\ninterface RedactionRewriteResult {\n entries: HistoryEntry[];\n finalDocument: ReplayDocument;\n entriesChanged: number;\n replacements: number;\n}\n\ninterface HistoryVerifyResult {\n ok: boolean;\n errors: string[];\n}\n\ninterface HistoryIntegritySnapshot {\n hashMismatchesBefore: number;\n hashMismatchesAfter: number;\n finalDocument: ReplayDocument;\n}\n\ninterface HistoryRedactSubject {\n id: string;\n historyPath: string;\n located: Awaited<ReturnType<typeof locateItem>>;\n}\n\nexport interface HistoryRedactResult {\n id: string;\n dry_run: boolean;\n changed: boolean;\n patterns: {\n literals: string[];\n regex: string[];\n replacement: string;\n };\n history: {\n path: string;\n entries_scanned: number;\n entries_changed: number;\n replacements: number;\n hash_mismatches_before: number;\n hash_mismatches_after: number;\n preexisting_hash_mismatches: number;\n audit_entry_added: boolean;\n verify_ok: boolean;\n verify_errors: string[];\n };\n item: {\n existed_before: boolean;\n exists_after: boolean;\n path_before: string | null;\n path_after: string | null;\n changed: boolean;\n };\n warnings: string[];\n generated_at: string;\n}\n\nconst EMPTY_REPLAY_DOCUMENT: ReplayDocument = {\n metadata: {},\n body: \"\",\n};\n\nfunction toAuthor(candidate: string | undefined, defaultAuthor: string): string {\n const resolved = candidate ?? process.env.PM_AUTHOR ?? defaultAuthor;\n const trimmed = resolved.trim();\n return trimmed.length > 0 ? trimmed : \"unknown\";\n}\n\nfunction normalizeStringArrayInput(value: string[] | string | undefined): string[] {\n if (Array.isArray(value)) {\n return value;\n }\n if (typeof value === \"string\") {\n return [value];\n }\n return [];\n}\n\nfunction normalizeRegexFlags(flags: string): string {\n const unique: string[] = [];\n for (const token of flags) {\n if (!unique.includes(token)) {\n unique.push(token);\n }\n }\n if (!unique.includes(\"g\")) {\n unique.push(\"g\");\n }\n return unique.join(\"\");\n}\n\nfunction parseRegexRule(spec: string): RegexRule {\n const trimmed = spec.trim();\n if (trimmed.length === 0) {\n throw new PmCliError(\"history-redact --regex requires a non-empty pattern.\", EXIT_CODE.USAGE);\n }\n\n let source = trimmed;\n let flags = \"g\";\n if (trimmed.startsWith(\"/\") && trimmed.length > 1) {\n const slashIndex = trimmed.lastIndexOf(\"/\");\n if (slashIndex > 0) {\n source = trimmed.slice(1, slashIndex);\n flags = normalizeRegexFlags(trimmed.slice(slashIndex + 1));\n }\n }\n if (source.length === 0) {\n throw new PmCliError(\"history-redact --regex cannot use an empty pattern.\", EXIT_CODE.USAGE);\n }\n try {\n new RegExp(source, flags);\n } catch (error) {\n throw new PmCliError(\n `Invalid --regex value \"${spec}\": ${error instanceof Error ? error.message : String(error)}`,\n EXIT_CODE.USAGE,\n );\n }\n\n return {\n kind: \"regex\",\n source,\n flags,\n label: `/${source}/${flags}`,\n };\n}\n\nfunction buildRedactionRules(\n literalInput: string[] | string | undefined,\n regexInput: string[] | string | undefined,\n): RedactionRule[] {\n const literalRules = [...new Set(normalizeStringArrayInput(literalInput).map((entry) => entry.trim()))]\n .filter((entry) => entry.length > 0)\n .map<LiteralRule>((entry) => ({\n kind: \"literal\",\n value: entry,\n label: entry,\n }));\n const regexRules = [...new Set(normalizeStringArrayInput(regexInput).map((entry) => entry.trim()))]\n .filter((entry) => entry.length > 0)\n .map(parseRegexRule);\n\n const rules = [...literalRules, ...regexRules];\n if (rules.length === 0) {\n throw new PmCliError(\n \"history-redact requires at least one matcher via --literal or --regex.\",\n EXIT_CODE.USAGE,\n {\n code: \"missing_required_argument\",\n required: \"Provide --literal <value> and/or --regex <pattern>.\",\n examples: [\n 'pm history-redact pm-a1b2 --literal \"[redacted_path_prefix]/private\"',\n 'pm history-redact pm-a1b2 --regex \"/192\\\\\\\\.168\\\\\\\\.[0-9.]+/g\" --replacement \"[scrubbed_ip]\"',\n ],\n },\n );\n }\n return rules;\n}\n\nfunction applyLiteralRule(value: string, literal: string, replacement: string): { value: string; replacements: number } {\n if (literal.length === 0) {\n return { value, replacements: 0 };\n }\n let cursor = 0;\n let replacements = 0;\n while (cursor <= value.length) {\n const index = value.indexOf(literal, cursor);\n if (index === -1) {\n break;\n }\n replacements += 1;\n cursor = index + Math.max(1, literal.length);\n }\n if (replacements === 0) {\n return { value, replacements: 0 };\n }\n return {\n value: value.split(literal).join(replacement),\n replacements,\n };\n}\n\nfunction applyRegexRule(value: string, rule: RegexRule, replacement: string): { value: string; replacements: number } {\n const regex = new RegExp(rule.source, rule.flags);\n const matches = [...value.matchAll(regex)];\n if (matches.length === 0) {\n return { value, replacements: 0 };\n }\n return {\n value: value.replace(regex, replacement),\n replacements: matches.length,\n };\n}\n\nfunction redactStringValue(value: string, rules: RedactionRule[], replacement: string): { value: string; replacements: number } {\n let next = value;\n let replacements = 0;\n for (const rule of rules) {\n const result =\n rule.kind === \"literal\"\n ? applyLiteralRule(next, rule.value, replacement)\n : applyRegexRule(next, rule, replacement);\n next = result.value;\n replacements += result.replacements;\n }\n return {\n value: next,\n replacements,\n };\n}\n\nfunction redactUnknownValue(value: unknown, rules: RedactionRule[], replacement: string): { value: unknown; replacements: number } {\n if (typeof value === \"string\") {\n return redactStringValue(value, rules, replacement);\n }\n if (Array.isArray(value)) {\n let replacements = 0;\n const nextValues = value.map((entry) => {\n const redacted = redactUnknownValue(entry, rules, replacement);\n replacements += redacted.replacements;\n return redacted.value;\n });\n return {\n value: nextValues,\n replacements,\n };\n }\n if (typeof value === \"object\" && value !== null) {\n let replacements = 0;\n const nextRecord: Record<string, unknown> = {};\n for (const [key, entry] of Object.entries(value)) {\n const redacted = redactUnknownValue(entry, rules, replacement);\n replacements += redacted.replacements;\n nextRecord[key] = redacted.value;\n }\n return {\n value: nextRecord,\n replacements,\n };\n }\n return {\n value,\n replacements: 0,\n };\n}\n\nfunction normalizeReplayPatchPath(path: string): string {\n if (path === \"/front_matter\") {\n return \"/metadata\";\n }\n if (path.startsWith(\"/front_matter/\")) {\n return `/metadata/${path.slice(\"/front_matter/\".length)}`;\n }\n return path;\n}\n\nfunction normalizeReplayPatchOps(patch: HistoryPatchOp[]): HistoryPatchOp[] {\n return patch.map((operation) => ({\n ...operation,\n path: normalizeReplayPatchPath(operation.path),\n from: operation.from ? normalizeReplayPatchPath(operation.from) : undefined,\n }));\n}\n\nfunction replayHash(document: ReplayDocument): string {\n return hashDocument({\n metadata: document.metadata as unknown as ItemMetadata,\n body: document.body,\n });\n}\n\nfunction applyHistoryPatch(current: ReplayDocument, patch: HistoryPatchOp[], entryNumber: number, op: string): ReplayDocument {\n try {\n const normalizedPatch = normalizeReplayPatchOps(patch);\n const applied = jsonPatch.applyPatch(\n structuredClone(current),\n normalizedPatch as jsonPatch.Operation[],\n true,\n false,\n ).newDocument as unknown;\n if (\n typeof applied !== \"object\" ||\n applied === null ||\n !(\"metadata\" in applied) ||\n !(\"body\" in applied) ||\n typeof (applied as { body: unknown }).body !== \"string\" ||\n typeof (applied as { metadata: unknown }).metadata !== \"object\" ||\n (applied as { metadata: unknown }).metadata === null\n ) {\n throw new PmCliError(\n `history-redact replay produced an invalid document shape at entry ${entryNumber}.`,\n EXIT_CODE.GENERIC_FAILURE,\n );\n }\n const replay = applied as { metadata: Record<string, unknown>; body: string };\n return {\n metadata: replay.metadata,\n body: replay.body,\n };\n } catch (error) {\n throw new PmCliError(\n `history-redact failed to apply patch at entry ${entryNumber} (op=${op}): ${\n error instanceof Error ? error.message : String(error)\n }`,\n EXIT_CODE.GENERIC_FAILURE,\n );\n }\n}\n\nfunction inspectHistoryIntegrity(entries: HistoryEntry[]): HistoryIntegritySnapshot {\n let replay = structuredClone(EMPTY_REPLAY_DOCUMENT);\n let hashMismatchesBefore = 0;\n let hashMismatchesAfter = 0;\n for (let index = 0; index < entries.length; index += 1) {\n const entry = entries[index];\n if (replayHash(replay) !== entry.before_hash) {\n hashMismatchesBefore += 1;\n }\n replay = applyHistoryPatch(replay, entry.patch, index + 1, entry.op);\n if (replayHash(replay) !== entry.after_hash) {\n hashMismatchesAfter += 1;\n }\n }\n return {\n hashMismatchesBefore,\n hashMismatchesAfter,\n finalDocument: replay,\n };\n}\n\nfunction redactHistoryEntry(entry: HistoryEntry, rules: RedactionRule[], replacement: string): {\n entry: HistoryEntry;\n replacements: number;\n changed: boolean;\n} {\n let replacements = 0;\n let changed = false;\n let nextMessage = entry.message;\n\n if (typeof entry.message === \"string\") {\n const redactedMessage = redactStringValue(entry.message, rules, replacement);\n nextMessage = redactedMessage.value;\n replacements += redactedMessage.replacements;\n if (redactedMessage.replacements > 0) {\n changed = true;\n }\n }\n\n const nextPatch = entry.patch.map((operation) => {\n if (!Object.prototype.hasOwnProperty.call(operation, \"value\")) {\n return operation;\n }\n const redactedValue = redactUnknownValue(operation.value, rules, replacement);\n replacements += redactedValue.replacements;\n if (redactedValue.replacements > 0) {\n changed = true;\n return {\n ...operation,\n value: redactedValue.value,\n };\n }\n return operation;\n });\n\n return {\n entry: {\n ...entry,\n message: nextMessage,\n patch: nextPatch,\n },\n replacements,\n changed,\n };\n}\n\nfunction rewriteHistoryEntries(entries: HistoryEntry[], rules: RedactionRule[], replacement: string): RedactionRewriteResult {\n let replay = structuredClone(EMPTY_REPLAY_DOCUMENT);\n let entriesChanged = 0;\n let replacements = 0;\n const rewrittenEntries: HistoryEntry[] = [];\n\n for (let index = 0; index < entries.length; index += 1) {\n const redacted = redactHistoryEntry(entries[index], rules, replacement);\n replacements += redacted.replacements;\n if (redacted.changed) {\n entriesChanged += 1;\n }\n const beforeHash = replayHash(replay);\n replay = applyHistoryPatch(replay, redacted.entry.patch, index + 1, redacted.entry.op);\n const afterHash = replayHash(replay);\n rewrittenEntries.push({\n ...redacted.entry,\n before_hash: beforeHash,\n after_hash: afterHash,\n });\n }\n\n return {\n entries: rewrittenEntries,\n finalDocument: replay,\n entriesChanged,\n replacements,\n };\n}\n\nfunction verifyHistoryEntries(entries: HistoryEntry[]): HistoryVerifyResult {\n let replay = structuredClone(EMPTY_REPLAY_DOCUMENT);\n for (let index = 0; index < entries.length; index += 1) {\n const entry = entries[index];\n const beforeHash = replayHash(replay);\n if (beforeHash !== entry.before_hash) {\n return {\n ok: false,\n errors: [`verify_failed:before_hash_mismatch:entry_${index + 1}`],\n };\n }\n replay = applyHistoryPatch(replay, entry.patch, index + 1, entry.op);\n const afterHash = replayHash(replay);\n if (afterHash !== entry.after_hash) {\n return {\n ok: false,\n errors: [`verify_failed:after_hash_mismatch:entry_${index + 1}`],\n };\n }\n }\n return {\n ok: true,\n errors: [],\n };\n}\n\nfunction replayToItemDocument(replay: ReplayDocument): ItemDocument {\n return {\n metadata: replay.metadata as unknown as ItemMetadata,\n body: replay.body,\n };\n}\n\nfunction hasItemMetadata(replay: ReplayDocument): boolean {\n return Object.keys(replay.metadata).length > 0;\n}\n\nasync function resolveSubject(\n pmRoot: string,\n id: string,\n settings: Awaited<ReturnType<typeof readSettings>>,\n typeToFolder: Record<string, string>,\n): Promise<HistoryRedactSubject> {\n const located = await locateItem(pmRoot, id, settings.id_prefix, settings.item_format, typeToFolder);\n if (located) {\n return {\n id: located.id,\n historyPath: getHistoryPath(pmRoot, located.id),\n located,\n };\n }\n\n const normalizedId = normalizeItemId(id, settings.id_prefix);\n const rawNormalizedId = normalizeRawItemId(id);\n const candidateIds = normalizedId === rawNormalizedId ? [normalizedId] : [normalizedId, rawNormalizedId];\n for (const candidateId of candidateIds) {\n const historyPath = getHistoryPath(pmRoot, candidateId);\n if (await pathExists(historyPath)) {\n return {\n id: candidateId,\n historyPath,\n located: null,\n };\n }\n }\n throw new PmCliError(`Item ${id} not found`, EXIT_CODE.NOT_FOUND);\n}\n\nfunction toHistoryRaw(entries: HistoryEntry[]): string {\n if (entries.length === 0) {\n return \"\";\n }\n return `${entries.map((entry) => JSON.stringify(entry)).join(\"\\n\")}\\n`;\n}\n\nexport async function runHistoryRedact(\n id: string,\n options: HistoryRedactCommandOptions,\n global: GlobalOptions,\n): Promise<HistoryRedactResult> {\n const pmRoot = resolvePmRoot(process.cwd(), global.path);\n if (!(await pathExists(getSettingsPath(pmRoot)))) {\n throw new PmCliError(`Tracker is not initialized at ${pmRoot}. Run pm init first.`, EXIT_CODE.NOT_FOUND);\n }\n\n const settings = await readSettings(pmRoot);\n const typeRegistry = resolveItemTypeRegistry(settings, getActiveExtensionRegistrations());\n const replacement = typeof options.replacement === \"string\" && options.replacement.length > 0 ? options.replacement : \"[redacted]\";\n const rules = buildRedactionRules(options.literal, options.regex);\n const subject = await resolveSubject(pmRoot, id, settings, typeRegistry.type_to_folder);\n\n if (!(await pathExists(subject.historyPath))) {\n throw new PmCliError(`No history stream exists for ${subject.id}.`, EXIT_CODE.NOT_FOUND);\n }\n const historyEntries = await readHistoryEntries(subject.historyPath, subject.id);\n if (historyEntries.length === 0) {\n throw new PmCliError(`No history entries exist for ${subject.id}; nothing to redact.`, EXIT_CODE.USAGE);\n }\n\n const integritySnapshot = inspectHistoryIntegrity(historyEntries);\n const rewritten = rewriteHistoryEntries(historyEntries, rules, replacement);\n const preexistingHashMismatches = integritySnapshot.hashMismatchesBefore + integritySnapshot.hashMismatchesAfter;\n const dryRun = Boolean(options.dryRun);\n const changed = rewritten.replacements > 0;\n const warnings: string[] = [];\n if (preexistingHashMismatches > 0) {\n warnings.push(`history_redact_preexisting_hash_mismatches:${preexistingHashMismatches}`);\n }\n if (!changed) {\n warnings.push(\"history_redact_no_matches\");\n }\n\n let currentItemRaw: string | null = null;\n let currentItemPath: string | null = subject.located?.itemPath ?? null;\n let currentItemDocument: ItemDocument | null = null;\n if (subject.located) {\n const loaded = await readLocatedItem(subject.located, { schema: settings.schema });\n currentItemRaw = loaded.raw;\n currentItemDocument = loaded.document;\n }\n\n let nextItemPath: string | null = null;\n let nextItemRaw: string | null = null;\n let nextItemDocument: ItemDocument | null = null;\n if (hasItemMetadata(rewritten.finalDocument)) {\n const canonical = canonicalDocument(replayToItemDocument(rewritten.finalDocument), { schema: settings.schema });\n if (canonical.metadata.id !== subject.id) {\n throw new PmCliError(\n `history-redact would change item id from ${subject.id} to ${canonical.metadata.id}; narrow your patterns.`,\n EXIT_CODE.USAGE,\n );\n }\n nextItemDocument = canonical;\n nextItemPath = getItemPath(pmRoot, canonical.metadata.type, subject.id, \"toon\", typeRegistry.type_to_folder);\n nextItemRaw = serializeItemDocument(canonical, {\n format: \"toon\",\n schema: settings.schema,\n });\n }\n\n const itemChanged =\n (currentItemPath ?? null) !== (nextItemPath ?? null) ||\n (currentItemRaw ?? null) !== (nextItemRaw ?? null);\n\n const author = toAuthor(options.author, settings.author_default);\n const redactionMessage =\n typeof options.message === \"string\" && options.message.trim().length > 0\n ? options.message\n : `history-redact replaced ${rewritten.replacements} match(es) across ${rewritten.entriesChanged} entr${\n rewritten.entriesChanged === 1 ? \"y\" : \"ies\"\n }.`;\n\n const rewrittenEntries = [...rewritten.entries];\n let auditEntryAdded = false;\n if (!dryRun && changed) {\n const finalDocument = nextItemDocument ?? replayToItemDocument(rewritten.finalDocument);\n rewrittenEntries.push(\n createHistoryEntry({\n nowIso: nowIso(),\n author,\n op: \"history_redact\",\n before: finalDocument,\n after: finalDocument,\n message: redactionMessage,\n }),\n );\n auditEntryAdded = true;\n }\n const historyVerify = verifyHistoryEntries(rewrittenEntries);\n if (!historyVerify.ok) {\n throw new PmCliError(\n `history-redact produced an invalid rewritten chain (${historyVerify.errors.join(\", \")}).`,\n EXIT_CODE.GENERIC_FAILURE,\n );\n }\n\n if (!dryRun && changed) {\n if (currentItemDocument) {\n const governance = resolveGovernanceKnobs(settings);\n const assigned = currentItemDocument.metadata.assignee?.trim();\n if (assigned && assigned !== author && !options.force) {\n if (governance.ownership_enforcement === \"strict\") {\n throw new PmCliError(\n `Item ${subject.id} is assigned to ${assigned}. Use --force to override.`,\n EXIT_CODE.CONFLICT,\n );\n }\n if (governance.ownership_enforcement === \"warn\") {\n warnings.push(`ownership_warning:assignee_conflict:${subject.id}:${assigned}`);\n }\n }\n }\n\n const releaseLock = await acquireLock(\n pmRoot,\n subject.id,\n settings.locks.ttl_seconds,\n author,\n Boolean(options.force),\n settings.governance.force_required_for_stale_lock,\n );\n try {\n const previousHistoryRaw = await readFileIfExists(subject.historyPath);\n const affectedItemPaths = new Set<string>();\n if (currentItemPath) {\n affectedItemPaths.add(currentItemPath);\n }\n if (nextItemPath) {\n affectedItemPaths.add(nextItemPath);\n }\n const itemSnapshots = new Map<string, string>();\n if (currentItemPath && currentItemRaw !== null) {\n itemSnapshots.set(currentItemPath, currentItemRaw);\n }\n\n try {\n if (nextItemPath && nextItemRaw !== null && nextItemRaw !== currentItemRaw) {\n await writeFileAtomic(nextItemPath, nextItemRaw);\n }\n if (currentItemPath && (!nextItemPath || nextItemPath !== currentItemPath)) {\n await fs.rm(currentItemPath, { force: true });\n }\n await writeFileAtomic(subject.historyPath, toHistoryRaw(rewrittenEntries));\n } catch (error) {\n if (previousHistoryRaw === null) {\n await fs.rm(subject.historyPath, { force: true });\n } else {\n await writeFileAtomic(subject.historyPath, previousHistoryRaw);\n }\n for (const itemPath of affectedItemPaths) {\n const snapshot = itemSnapshots.get(itemPath);\n if (snapshot === undefined) {\n await fs.rm(itemPath, { force: true });\n } else {\n await writeFileAtomic(itemPath, snapshot);\n }\n }\n throw error;\n }\n\n const itemHookPath = nextItemPath ?? currentItemPath;\n if (itemHookPath) {\n warnings.push(\n ...(await runActiveOnWriteHooks({\n path: itemHookPath,\n scope: \"project\",\n op: \"history_redact\",\n })),\n );\n }\n warnings.push(\n ...(await runActiveOnWriteHooks({\n path: subject.historyPath,\n scope: \"project\",\n op: \"history_redact:history\",\n })),\n );\n } finally {\n await releaseLock();\n }\n }\n\n return {\n id: subject.id,\n dry_run: dryRun,\n changed,\n patterns: {\n literals: rules.filter((rule): rule is LiteralRule => rule.kind === \"literal\").map((rule) => rule.value),\n regex: rules.filter((rule): rule is RegexRule => rule.kind === \"regex\").map((rule) => `/${rule.source}/${rule.flags}`),\n replacement,\n },\n history: {\n path: subject.historyPath,\n entries_scanned: historyEntries.length,\n entries_changed: rewritten.entriesChanged,\n replacements: rewritten.replacements,\n hash_mismatches_before: integritySnapshot.hashMismatchesBefore,\n hash_mismatches_after: integritySnapshot.hashMismatchesAfter,\n preexisting_hash_mismatches: preexistingHashMismatches,\n audit_entry_added: auditEntryAdded,\n verify_ok: historyVerify.ok,\n verify_errors: historyVerify.errors,\n },\n item: {\n existed_before: currentItemPath !== null,\n exists_after: nextItemPath !== null,\n path_before: currentItemPath,\n path_after: nextItemPath,\n changed: itemChanged,\n },\n warnings: [...new Set(warnings)].sort((left, right) => left.localeCompare(right)),\n generated_at: nowIso(),\n };\n}\n"],"names":[],"mappings":"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","debugId":"90e97965-c3e5-5418-8f8b-5080d412cc95"}
|
|
1
|
+
{"version":3,"file":"history-redact.js","sources":["cli/commands/history-redact.ts"],"sourceRoot":"/","sourcesContent":["import fs from \"node:fs/promises\";\nimport { pathExists, readFileIfExists, writeFileAtomic } from \"../../core/fs/fs-utils.js\";\nimport { createHistoryEntry } from \"../../core/history/history.js\";\nimport {\n checkHistoryRewriteOwnership,\n verifyHistoryRewriteNoDrift,\n} from \"../../core/history/history-rewrite.js\";\nimport {\n EMPTY_REPLAY_DOCUMENT,\n historyEntriesToRaw,\n replayHash,\n replayToItemDocument,\n tryApplyReplayPatch,\n verifyHistoryChain,\n type ReplayDocument,\n} from \"../../core/history/replay.js\";\nimport { normalizeItemId, normalizeRawItemId } from \"../../core/item/id.js\";\nimport { canonicalDocument, serializeItemDocument } from \"../../core/item/item-format.js\";\nimport { resolveItemTypeRegistry } from \"../../core/item/type-registry.js\";\nimport { acquireLock } from \"../../core/lock/lock.js\";\nimport { EXIT_CODE } from \"../../core/shared/constants.js\";\nimport type { GlobalOptions } from \"../../core/shared/command-types.js\";\nimport { PmCliError } from \"../../core/shared/errors.js\";\nimport { nowIso } from \"../../core/shared/time.js\";\nimport { getActiveExtensionRegistrations, runActiveOnWriteHooks } from \"../../core/extensions/index.js\";\nimport { locateItem, readLocatedItem } from \"../../core/store/item-store.js\";\nimport { getHistoryPath, getItemPath, getSettingsPath, resolvePmRoot } from \"../../core/store/paths.js\";\nimport { readSettings } from \"../../core/store/settings.js\";\nimport { resolveAuthor } from \"../../core/shared/author.js\";\nimport type { HistoryEntry, HistoryPatchOp, ItemDocument } from \"../../types/index.js\";\nimport { readHistoryEntries } from \"./history.js\";\n\nexport interface HistoryRedactCommandOptions {\n literal?: string[] | string;\n regex?: string[] | string;\n replacement?: string;\n dryRun?: boolean;\n author?: string;\n message?: string;\n force?: boolean;\n}\n\ninterface RegexRule {\n kind: \"regex\";\n source: string;\n flags: string;\n label: string;\n}\n\ninterface LiteralRule {\n kind: \"literal\";\n value: string;\n label: string;\n}\n\ntype RedactionRule = RegexRule | LiteralRule;\n\ninterface RedactionRewriteResult {\n entries: HistoryEntry[];\n finalDocument: ReplayDocument;\n entriesChanged: number;\n replacements: number;\n}\n\ninterface HistoryIntegritySnapshot {\n hashMismatchesBefore: number;\n hashMismatchesAfter: number;\n finalDocument: ReplayDocument;\n}\n\nexport interface HistorySubject {\n id: string;\n historyPath: string;\n located: Awaited<ReturnType<typeof locateItem>>;\n}\n\nexport interface HistoryRedactResult {\n id: string;\n dry_run: boolean;\n changed: boolean;\n patterns: {\n literals: string[];\n regex: string[];\n replacement: string;\n };\n history: {\n path: string;\n entries_scanned: number;\n entries_changed: number;\n replacements: number;\n hash_mismatches_before: number;\n hash_mismatches_after: number;\n preexisting_hash_mismatches: number;\n audit_entry_added: boolean;\n verify_ok: boolean;\n verify_errors: string[];\n };\n item: {\n existed_before: boolean;\n exists_after: boolean;\n path_before: string | null;\n path_after: string | null;\n changed: boolean;\n };\n warnings: string[];\n generated_at: string;\n}\n\nfunction normalizeStringArrayInput(value: string[] | string | undefined): string[] {\n if (Array.isArray(value)) {\n return value;\n }\n if (typeof value === \"string\") {\n return [value];\n }\n return [];\n}\n\nfunction normalizeRegexFlags(flags: string): string {\n const unique: string[] = [];\n for (const token of flags) {\n if (!unique.includes(token)) {\n unique.push(token);\n }\n }\n if (!unique.includes(\"g\")) {\n unique.push(\"g\");\n }\n return unique.join(\"\");\n}\n\nfunction parseRegexRule(spec: string): RegexRule {\n const trimmed = spec.trim();\n if (trimmed.length === 0) {\n throw new PmCliError(\"history-redact --regex requires a non-empty pattern.\", EXIT_CODE.USAGE);\n }\n\n let source = trimmed;\n let flags = \"g\";\n if (trimmed.startsWith(\"/\") && trimmed.length > 1) {\n const slashIndex = trimmed.lastIndexOf(\"/\");\n if (slashIndex > 0) {\n source = trimmed.slice(1, slashIndex);\n flags = normalizeRegexFlags(trimmed.slice(slashIndex + 1));\n }\n }\n if (source.length === 0) {\n throw new PmCliError(\"history-redact --regex cannot use an empty pattern.\", EXIT_CODE.USAGE);\n }\n try {\n new RegExp(source, flags);\n } catch (error) {\n throw new PmCliError(\n `Invalid --regex value \"${spec}\": ${error instanceof Error ? error.message : String(error)}`,\n EXIT_CODE.USAGE,\n );\n }\n\n return {\n kind: \"regex\",\n source,\n flags,\n label: `/${source}/${flags}`,\n };\n}\n\nfunction buildRedactionRules(\n literalInput: string[] | string | undefined,\n regexInput: string[] | string | undefined,\n): RedactionRule[] {\n const literalRules = [...new Set(normalizeStringArrayInput(literalInput).map((entry) => entry.trim()))]\n .filter((entry) => entry.length > 0)\n .map<LiteralRule>((entry) => ({\n kind: \"literal\",\n value: entry,\n label: entry,\n }));\n const regexRules = [...new Set(normalizeStringArrayInput(regexInput).map((entry) => entry.trim()))]\n .filter((entry) => entry.length > 0)\n .map(parseRegexRule);\n\n const rules = [...literalRules, ...regexRules];\n if (rules.length === 0) {\n throw new PmCliError(\n \"history-redact requires at least one matcher via --literal or --regex.\",\n EXIT_CODE.USAGE,\n {\n code: \"missing_required_argument\",\n required: \"Provide --literal <value> and/or --regex <pattern>.\",\n examples: [\n 'pm history-redact pm-a1b2 --literal \"[redacted_path_prefix]/private\"',\n 'pm history-redact pm-a1b2 --regex \"/192\\\\\\\\.168\\\\\\\\.[0-9.]+/g\" --replacement \"[scrubbed_ip]\"',\n ],\n },\n );\n }\n return rules;\n}\n\nfunction applyLiteralRule(value: string, literal: string, replacement: string): { value: string; replacements: number } {\n if (literal.length === 0) {\n return { value, replacements: 0 };\n }\n let cursor = 0;\n let replacements = 0;\n while (cursor <= value.length) {\n const index = value.indexOf(literal, cursor);\n if (index === -1) {\n break;\n }\n replacements += 1;\n cursor = index + Math.max(1, literal.length);\n }\n if (replacements === 0) {\n return { value, replacements: 0 };\n }\n return {\n value: value.split(literal).join(replacement),\n replacements,\n };\n}\n\nfunction applyRegexRule(value: string, rule: RegexRule, replacement: string): { value: string; replacements: number } {\n const regex = new RegExp(rule.source, rule.flags);\n const matches = [...value.matchAll(regex)];\n if (matches.length === 0) {\n return { value, replacements: 0 };\n }\n return {\n value: value.replace(regex, replacement),\n replacements: matches.length,\n };\n}\n\nfunction redactStringValue(value: string, rules: RedactionRule[], replacement: string): { value: string; replacements: number } {\n let next = value;\n let replacements = 0;\n for (const rule of rules) {\n const result =\n rule.kind === \"literal\"\n ? applyLiteralRule(next, rule.value, replacement)\n : applyRegexRule(next, rule, replacement);\n next = result.value;\n replacements += result.replacements;\n }\n return {\n value: next,\n replacements,\n };\n}\n\nfunction redactUnknownValue(value: unknown, rules: RedactionRule[], replacement: string): { value: unknown; replacements: number } {\n if (typeof value === \"string\") {\n return redactStringValue(value, rules, replacement);\n }\n if (Array.isArray(value)) {\n let replacements = 0;\n const nextValues = value.map((entry) => {\n const redacted = redactUnknownValue(entry, rules, replacement);\n replacements += redacted.replacements;\n return redacted.value;\n });\n return {\n value: nextValues,\n replacements,\n };\n }\n if (typeof value === \"object\" && value !== null) {\n let replacements = 0;\n const nextRecord: Record<string, unknown> = {};\n for (const [key, entry] of Object.entries(value)) {\n const redacted = redactUnknownValue(entry, rules, replacement);\n replacements += redacted.replacements;\n nextRecord[key] = redacted.value;\n }\n return {\n value: nextRecord,\n replacements,\n };\n }\n return {\n value,\n replacements: 0,\n };\n}\n\nfunction applyHistoryPatch(current: ReplayDocument, patch: HistoryPatchOp[], entryNumber: number, op: string): ReplayDocument {\n const result = tryApplyReplayPatch(current, patch);\n if (!result.ok) {\n throw new PmCliError(\n `history-redact failed to apply patch at entry ${entryNumber} (op=${op}): ${\n result.error instanceof Error ? result.error.message : String(result.error)\n }`,\n EXIT_CODE.GENERIC_FAILURE,\n );\n }\n return result.document;\n}\n\nfunction inspectHistoryIntegrity(entries: HistoryEntry[]): HistoryIntegritySnapshot {\n let replay = structuredClone(EMPTY_REPLAY_DOCUMENT);\n let hashMismatchesBefore = 0;\n let hashMismatchesAfter = 0;\n for (let index = 0; index < entries.length; index += 1) {\n const entry = entries[index];\n if (replayHash(replay) !== entry.before_hash) {\n hashMismatchesBefore += 1;\n }\n replay = applyHistoryPatch(replay, entry.patch, index + 1, entry.op);\n if (replayHash(replay) !== entry.after_hash) {\n hashMismatchesAfter += 1;\n }\n }\n return {\n hashMismatchesBefore,\n hashMismatchesAfter,\n finalDocument: replay,\n };\n}\n\nfunction redactHistoryEntry(entry: HistoryEntry, rules: RedactionRule[], replacement: string): {\n entry: HistoryEntry;\n replacements: number;\n changed: boolean;\n} {\n let replacements = 0;\n let changed = false;\n let nextMessage = entry.message;\n\n if (typeof entry.message === \"string\") {\n const redactedMessage = redactStringValue(entry.message, rules, replacement);\n nextMessage = redactedMessage.value;\n replacements += redactedMessage.replacements;\n if (redactedMessage.replacements > 0) {\n changed = true;\n }\n }\n\n const nextPatch = entry.patch.map((operation) => {\n if (!Object.prototype.hasOwnProperty.call(operation, \"value\")) {\n return operation;\n }\n const redactedValue = redactUnknownValue(operation.value, rules, replacement);\n replacements += redactedValue.replacements;\n if (redactedValue.replacements > 0) {\n changed = true;\n return {\n ...operation,\n value: redactedValue.value,\n };\n }\n return operation;\n });\n\n return {\n entry: {\n ...entry,\n message: nextMessage,\n patch: nextPatch,\n },\n replacements,\n changed,\n };\n}\n\nfunction rewriteHistoryEntries(entries: HistoryEntry[], rules: RedactionRule[], replacement: string): RedactionRewriteResult {\n let replay = structuredClone(EMPTY_REPLAY_DOCUMENT);\n let entriesChanged = 0;\n let replacements = 0;\n const rewrittenEntries: HistoryEntry[] = [];\n\n for (let index = 0; index < entries.length; index += 1) {\n const redacted = redactHistoryEntry(entries[index], rules, replacement);\n replacements += redacted.replacements;\n if (redacted.changed) {\n entriesChanged += 1;\n }\n const beforeHash = replayHash(replay);\n replay = applyHistoryPatch(replay, redacted.entry.patch, index + 1, redacted.entry.op);\n const afterHash = replayHash(replay);\n rewrittenEntries.push({\n ...redacted.entry,\n before_hash: beforeHash,\n after_hash: afterHash,\n });\n }\n\n return {\n entries: rewrittenEntries,\n finalDocument: replay,\n entriesChanged,\n replacements,\n };\n}\n\nfunction hasItemMetadata(replay: ReplayDocument): boolean {\n return Object.keys(replay.metadata).length > 0;\n}\n\nexport async function resolveHistorySubject(\n pmRoot: string,\n id: string,\n settings: Awaited<ReturnType<typeof readSettings>>,\n typeToFolder: Record<string, string>,\n): Promise<HistorySubject> {\n const located = await locateItem(pmRoot, id, settings.id_prefix, settings.item_format, typeToFolder);\n if (located) {\n return {\n id: located.id,\n historyPath: getHistoryPath(pmRoot, located.id),\n located,\n };\n }\n\n const normalizedId = normalizeItemId(id, settings.id_prefix);\n const rawNormalizedId = normalizeRawItemId(id);\n const candidateIds = normalizedId === rawNormalizedId ? [normalizedId] : [normalizedId, rawNormalizedId];\n for (const candidateId of candidateIds) {\n const historyPath = getHistoryPath(pmRoot, candidateId);\n if (await pathExists(historyPath)) {\n return {\n id: candidateId,\n historyPath,\n located: null,\n };\n }\n }\n throw new PmCliError(`Item ${id} not found`, EXIT_CODE.NOT_FOUND);\n}\n\nexport async function runHistoryRedact(\n id: string,\n options: HistoryRedactCommandOptions,\n global: GlobalOptions,\n): Promise<HistoryRedactResult> {\n const pmRoot = resolvePmRoot(process.cwd(), global.path);\n if (!(await pathExists(getSettingsPath(pmRoot)))) {\n throw new PmCliError(`Tracker is not initialized at ${pmRoot}. Run pm init first.`, EXIT_CODE.NOT_FOUND);\n }\n\n const settings = await readSettings(pmRoot);\n const typeRegistry = resolveItemTypeRegistry(settings, getActiveExtensionRegistrations());\n const replacement = typeof options.replacement === \"string\" && options.replacement.length > 0 ? options.replacement : \"[redacted]\";\n const rules = buildRedactionRules(options.literal, options.regex);\n const subject = await resolveHistorySubject(pmRoot, id, settings, typeRegistry.type_to_folder);\n\n if (!(await pathExists(subject.historyPath))) {\n throw new PmCliError(`No history stream exists for ${subject.id}.`, EXIT_CODE.NOT_FOUND);\n }\n const historyRawBeforeLock = await readFileIfExists(subject.historyPath);\n const historyEntries = await readHistoryEntries(subject.historyPath, subject.id);\n if (historyEntries.length === 0) {\n throw new PmCliError(`No history entries exist for ${subject.id}; nothing to redact.`, EXIT_CODE.USAGE);\n }\n\n const integritySnapshot = inspectHistoryIntegrity(historyEntries);\n const rewritten = rewriteHistoryEntries(historyEntries, rules, replacement);\n const preexistingHashMismatches = integritySnapshot.hashMismatchesBefore + integritySnapshot.hashMismatchesAfter;\n const dryRun = Boolean(options.dryRun);\n const changed = rewritten.replacements > 0;\n const warnings: string[] = [];\n if (preexistingHashMismatches > 0) {\n warnings.push(`history_redact_preexisting_hash_mismatches:${preexistingHashMismatches}`);\n }\n if (!changed) {\n warnings.push(\"history_redact_no_matches\");\n }\n\n let currentItemRaw: string | null = null;\n let currentItemPath: string | null = subject.located?.itemPath ?? null;\n let currentItemDocument: ItemDocument | null = null;\n if (subject.located) {\n const loaded = await readLocatedItem(subject.located, { schema: settings.schema });\n currentItemRaw = loaded.raw;\n currentItemDocument = loaded.document;\n }\n\n let nextItemPath: string | null = null;\n let nextItemRaw: string | null = null;\n let nextItemDocument: ItemDocument | null = null;\n if (hasItemMetadata(rewritten.finalDocument)) {\n const canonical = canonicalDocument(replayToItemDocument(rewritten.finalDocument), { schema: settings.schema });\n if (canonical.metadata.id !== subject.id) {\n throw new PmCliError(\n `history-redact would change item id from ${subject.id} to ${canonical.metadata.id}; narrow your patterns.`,\n EXIT_CODE.USAGE,\n );\n }\n nextItemDocument = canonical;\n nextItemPath = getItemPath(pmRoot, canonical.metadata.type, subject.id, \"toon\", typeRegistry.type_to_folder);\n nextItemRaw = serializeItemDocument(canonical, {\n format: \"toon\",\n schema: settings.schema,\n });\n }\n\n const itemChanged =\n (currentItemPath ?? null) !== (nextItemPath ?? null) ||\n (currentItemRaw ?? null) !== (nextItemRaw ?? null);\n\n const author = resolveAuthor(options.author, settings.author_default);\n const redactionMessage =\n typeof options.message === \"string\" && options.message.trim().length > 0\n ? options.message\n : `history-redact replaced ${rewritten.replacements} match(es) across ${rewritten.entriesChanged} entr${\n rewritten.entriesChanged === 1 ? \"y\" : \"ies\"\n }.`;\n\n const rewrittenEntries = [...rewritten.entries];\n let auditEntryAdded = false;\n if (!dryRun && changed) {\n const finalDocument = nextItemDocument ?? replayToItemDocument(rewritten.finalDocument);\n rewrittenEntries.push(\n createHistoryEntry({\n nowIso: nowIso(),\n author,\n op: \"history_redact\",\n before: finalDocument,\n after: finalDocument,\n message: redactionMessage,\n }),\n );\n auditEntryAdded = true;\n }\n const historyVerify = verifyHistoryChain(rewrittenEntries);\n if (!historyVerify.ok) {\n throw new PmCliError(\n `history-redact produced an invalid rewritten chain (${historyVerify.errors.join(\", \")}).`,\n EXIT_CODE.GENERIC_FAILURE,\n );\n }\n\n if (!dryRun && changed) {\n warnings.push(\n ...checkHistoryRewriteOwnership({\n itemDocument: currentItemDocument,\n subjectId: subject.id,\n author,\n force: options.force,\n settings,\n }),\n );\n\n const releaseLock = await acquireLock(\n pmRoot,\n subject.id,\n settings.locks.ttl_seconds,\n author,\n Boolean(options.force),\n settings.governance.force_required_for_stale_lock,\n );\n try {\n const { historyRawUnderLock } = await verifyHistoryRewriteNoDrift({\n pmRoot,\n subject,\n settings,\n typeRegistry,\n historyRawBeforeLock,\n currentItemRawBeforeLock: currentItemRaw,\n operation: \"history-redact\",\n });\n const affectedItemPaths = new Set<string>();\n if (currentItemPath) {\n affectedItemPaths.add(currentItemPath);\n }\n if (nextItemPath) {\n affectedItemPaths.add(nextItemPath);\n }\n const itemSnapshots = new Map<string, string>();\n if (currentItemPath && currentItemRaw !== null) {\n itemSnapshots.set(currentItemPath, currentItemRaw);\n }\n\n try {\n if (nextItemPath && nextItemRaw !== null && nextItemRaw !== currentItemRaw) {\n await writeFileAtomic(nextItemPath, nextItemRaw);\n }\n if (currentItemPath && (!nextItemPath || nextItemPath !== currentItemPath)) {\n await fs.rm(currentItemPath, { force: true });\n }\n await writeFileAtomic(subject.historyPath, historyEntriesToRaw(rewrittenEntries));\n } catch (error) {\n if (historyRawUnderLock === null) {\n await fs.rm(subject.historyPath, { force: true });\n } else {\n await writeFileAtomic(subject.historyPath, historyRawUnderLock);\n }\n for (const itemPath of affectedItemPaths) {\n const snapshot = itemSnapshots.get(itemPath);\n if (snapshot === undefined) {\n await fs.rm(itemPath, { force: true });\n } else {\n await writeFileAtomic(itemPath, snapshot);\n }\n }\n throw error;\n }\n\n const itemHookPath = nextItemPath ?? currentItemPath;\n if (itemHookPath) {\n warnings.push(\n ...(await runActiveOnWriteHooks({\n path: itemHookPath,\n scope: \"project\",\n op: \"history_redact\",\n })),\n );\n }\n warnings.push(\n ...(await runActiveOnWriteHooks({\n path: subject.historyPath,\n scope: \"project\",\n op: \"history_redact:history\",\n })),\n );\n } finally {\n await releaseLock();\n }\n }\n\n return {\n id: subject.id,\n dry_run: dryRun,\n changed,\n patterns: {\n literals: rules.filter((rule): rule is LiteralRule => rule.kind === \"literal\").map((rule) => rule.value),\n regex: rules.filter((rule): rule is RegexRule => rule.kind === \"regex\").map((rule) => `/${rule.source}/${rule.flags}`),\n replacement,\n },\n history: {\n path: subject.historyPath,\n entries_scanned: historyEntries.length,\n entries_changed: rewritten.entriesChanged,\n replacements: rewritten.replacements,\n hash_mismatches_before: integritySnapshot.hashMismatchesBefore,\n hash_mismatches_after: integritySnapshot.hashMismatchesAfter,\n preexisting_hash_mismatches: preexistingHashMismatches,\n audit_entry_added: auditEntryAdded,\n verify_ok: historyVerify.ok,\n verify_errors: historyVerify.errors,\n },\n item: {\n existed_before: currentItemPath !== null,\n exists_after: nextItemPath !== null,\n path_before: currentItemPath,\n path_after: nextItemPath,\n changed: itemChanged,\n },\n warnings: [...new Set(warnings)].sort((left, right) => left.localeCompare(right)),\n generated_at: nowIso(),\n };\n}\n"],"names":[],"mappings":"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","debugId":"f92d5c88-f7f6-522f-a15b-fb109875fdac"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { GlobalOptions } from "../../core/shared/command-types.js";
|
|
2
|
+
export interface HistoryRepairCommandOptions {
|
|
3
|
+
dryRun?: boolean;
|
|
4
|
+
author?: string;
|
|
5
|
+
message?: string;
|
|
6
|
+
force?: boolean;
|
|
7
|
+
}
|
|
8
|
+
export interface HistoryRepairResult {
|
|
9
|
+
id: string;
|
|
10
|
+
dry_run: boolean;
|
|
11
|
+
changed: boolean;
|
|
12
|
+
history: {
|
|
13
|
+
path: string;
|
|
14
|
+
entries_scanned: number;
|
|
15
|
+
chain_drift_before: boolean;
|
|
16
|
+
entries_rehashed: number;
|
|
17
|
+
entries_patch_repaired: number;
|
|
18
|
+
converted_replace_to_add: number;
|
|
19
|
+
skipped_ops: number;
|
|
20
|
+
reconciled_with_item: boolean;
|
|
21
|
+
audit_entry_added: boolean;
|
|
22
|
+
verify_ok: boolean;
|
|
23
|
+
verify_errors: string[];
|
|
24
|
+
};
|
|
25
|
+
item: {
|
|
26
|
+
exists: boolean;
|
|
27
|
+
path: string | null;
|
|
28
|
+
matched_chain_before: boolean | null;
|
|
29
|
+
};
|
|
30
|
+
warnings: string[];
|
|
31
|
+
generated_at: string;
|
|
32
|
+
}
|
|
33
|
+
export declare function runHistoryRepair(id: string, options: HistoryRepairCommandOptions, global: GlobalOptions): Promise<HistoryRepairResult>;
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
|
|
2
|
+
!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]="01f463d2-97ef-5ddb-8346-156e456e097b")}catch(e){}}();
|
|
3
|
+
import fs from "node:fs/promises";
|
|
4
|
+
import jsonPatch from "fast-json-patch";
|
|
5
|
+
import { pathExists, readFileIfExists, writeFileAtomic } from "../../core/fs/fs-utils.js";
|
|
6
|
+
import { checkHistoryRewriteOwnership, verifyHistoryRewriteNoDrift, } from "../../core/history/history-rewrite.js";
|
|
7
|
+
import { historyEntriesToRaw, reanchorHistoryEntries, replayHash, toReplayDocument, verifyHistoryChain, } from "../../core/history/replay.js";
|
|
8
|
+
import { resolveItemTypeRegistry } from "../../core/item/type-registry.js";
|
|
9
|
+
import { acquireLock } from "../../core/lock/lock.js";
|
|
10
|
+
import { EXIT_CODE } from "../../core/shared/constants.js";
|
|
11
|
+
import { PmCliError } from "../../core/shared/errors.js";
|
|
12
|
+
import { nowIso } from "../../core/shared/time.js";
|
|
13
|
+
import { getActiveExtensionRegistrations, runActiveOnWriteHooks } from "../../core/extensions/index.js";
|
|
14
|
+
import { readLocatedItem } from "../../core/store/item-store.js";
|
|
15
|
+
import { getSettingsPath, resolvePmRoot } from "../../core/store/paths.js";
|
|
16
|
+
import { readSettings } from "../../core/store/settings.js";
|
|
17
|
+
import { readHistoryEntries } from "./history.js";
|
|
18
|
+
import { resolveHistorySubject } from "./history-redact.js";
|
|
19
|
+
function toAuthor(candidate, defaultAuthor) {
|
|
20
|
+
const resolved = candidate ?? process.env.PM_AUTHOR ?? defaultAuthor;
|
|
21
|
+
const trimmed = resolved.trim();
|
|
22
|
+
return trimmed.length > 0 ? trimmed : "unknown";
|
|
23
|
+
}
|
|
24
|
+
export async function runHistoryRepair(id, options, global) {
|
|
25
|
+
const pmRoot = resolvePmRoot(process.cwd(), global.path);
|
|
26
|
+
if (!(await pathExists(getSettingsPath(pmRoot)))) {
|
|
27
|
+
throw new PmCliError(`Tracker is not initialized at ${pmRoot}. Run pm init first.`, EXIT_CODE.NOT_FOUND);
|
|
28
|
+
}
|
|
29
|
+
const settings = await readSettings(pmRoot);
|
|
30
|
+
const typeRegistry = resolveItemTypeRegistry(settings, getActiveExtensionRegistrations());
|
|
31
|
+
const subject = await resolveHistorySubject(pmRoot, id, settings, typeRegistry.type_to_folder);
|
|
32
|
+
if (!(await pathExists(subject.historyPath))) {
|
|
33
|
+
throw new PmCliError(`No history stream exists for ${subject.id}.`, EXIT_CODE.NOT_FOUND);
|
|
34
|
+
}
|
|
35
|
+
const historyRawBeforeLock = await readFileIfExists(subject.historyPath);
|
|
36
|
+
const historyEntries = await readHistoryEntries(subject.historyPath, subject.id);
|
|
37
|
+
if (historyEntries.length === 0) {
|
|
38
|
+
throw new PmCliError(`No history entries exist for ${subject.id}; nothing to repair.`, EXIT_CODE.USAGE);
|
|
39
|
+
}
|
|
40
|
+
const chainBefore = verifyHistoryChain(historyEntries);
|
|
41
|
+
const reanchor = reanchorHistoryEntries(historyEntries);
|
|
42
|
+
// Reconcile the replayed chain with the current on-disk item document so the
|
|
43
|
+
// latest after_hash matches what pm validate/health compute for the item.
|
|
44
|
+
let currentItemReplay = null;
|
|
45
|
+
const currentItemPath = subject.located?.itemPath ?? null;
|
|
46
|
+
let matchedChainBefore = null;
|
|
47
|
+
const loadedItem = subject.located
|
|
48
|
+
? await readLocatedItem(subject.located, { schema: settings.schema })
|
|
49
|
+
: null;
|
|
50
|
+
const currentItemRawBeforeLock = loadedItem?.raw ?? null;
|
|
51
|
+
if (loadedItem) {
|
|
52
|
+
// Use the shared canonical replay form so reconciliation hashing matches the
|
|
53
|
+
// semantics pm validate/health use for the on-disk item (avoids hash divergence).
|
|
54
|
+
currentItemReplay = toReplayDocument(loadedItem.document);
|
|
55
|
+
const lastOriginalAfterHash = historyEntries[historyEntries.length - 1]?.after_hash;
|
|
56
|
+
matchedChainBefore = replayHash(currentItemReplay) === lastOriginalAfterHash;
|
|
57
|
+
}
|
|
58
|
+
const finalReplay = reanchor.finalDocument;
|
|
59
|
+
const reconcileNeeded = currentItemReplay !== null && replayHash(finalReplay) !== replayHash(currentItemReplay);
|
|
60
|
+
const changed = reanchor.entriesRehashed > 0 || reanchor.entriesPatchRepaired > 0 || reconcileNeeded;
|
|
61
|
+
const author = toAuthor(options.author, settings.author_default);
|
|
62
|
+
const dryRun = Boolean(options.dryRun);
|
|
63
|
+
const repairMessage = typeof options.message === "string" && options.message.trim().length > 0
|
|
64
|
+
? options.message
|
|
65
|
+
: `history-repair re-anchored ${reanchor.entriesRehashed} entr${reanchor.entriesRehashed === 1 ? "y" : "ies"}${reanchor.entriesPatchRepaired > 0 ? `, repaired ${reanchor.entriesPatchRepaired} patch(es)` : ""}${reconcileNeeded ? ", reconciled chain with on-disk item" : ""}.`;
|
|
66
|
+
const rewrittenEntries = [...reanchor.entries];
|
|
67
|
+
let auditEntryAdded = false;
|
|
68
|
+
if (changed) {
|
|
69
|
+
if (reconcileNeeded && currentItemReplay) {
|
|
70
|
+
rewrittenEntries.push({
|
|
71
|
+
ts: nowIso(),
|
|
72
|
+
author,
|
|
73
|
+
op: "history_repair",
|
|
74
|
+
patch: jsonPatch.compare(finalReplay, currentItemReplay),
|
|
75
|
+
before_hash: replayHash(finalReplay),
|
|
76
|
+
after_hash: replayHash(currentItemReplay),
|
|
77
|
+
message: repairMessage,
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
rewrittenEntries.push({
|
|
82
|
+
ts: nowIso(),
|
|
83
|
+
author,
|
|
84
|
+
op: "history_repair",
|
|
85
|
+
patch: [],
|
|
86
|
+
before_hash: replayHash(finalReplay),
|
|
87
|
+
after_hash: replayHash(finalReplay),
|
|
88
|
+
message: repairMessage,
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
auditEntryAdded = true;
|
|
92
|
+
}
|
|
93
|
+
const historyVerify = verifyHistoryChain(rewrittenEntries);
|
|
94
|
+
if (!historyVerify.ok) {
|
|
95
|
+
throw new PmCliError(`history-repair produced an invalid rewritten chain (${historyVerify.errors.join(", ")}).`, EXIT_CODE.GENERIC_FAILURE);
|
|
96
|
+
}
|
|
97
|
+
const warnings = [];
|
|
98
|
+
if (!changed) {
|
|
99
|
+
warnings.push("history_repair_no_changes");
|
|
100
|
+
}
|
|
101
|
+
if (reanchor.skippedOps > 0) {
|
|
102
|
+
warnings.push(`history_repair_skipped_unresolvable_ops:${reanchor.skippedOps}`);
|
|
103
|
+
}
|
|
104
|
+
if (changed && !dryRun) {
|
|
105
|
+
warnings.push(...checkHistoryRewriteOwnership({
|
|
106
|
+
itemDocument: loadedItem?.document ?? null,
|
|
107
|
+
subjectId: subject.id,
|
|
108
|
+
author,
|
|
109
|
+
force: options.force,
|
|
110
|
+
settings,
|
|
111
|
+
}));
|
|
112
|
+
const releaseLock = await acquireLock(pmRoot, subject.id, settings.locks.ttl_seconds, author, Boolean(options.force), settings.governance.force_required_for_stale_lock);
|
|
113
|
+
try {
|
|
114
|
+
const { historyRawUnderLock } = await verifyHistoryRewriteNoDrift({
|
|
115
|
+
pmRoot,
|
|
116
|
+
subject,
|
|
117
|
+
settings,
|
|
118
|
+
typeRegistry,
|
|
119
|
+
historyRawBeforeLock,
|
|
120
|
+
currentItemRawBeforeLock,
|
|
121
|
+
operation: "history-repair",
|
|
122
|
+
});
|
|
123
|
+
try {
|
|
124
|
+
await writeFileAtomic(subject.historyPath, historyEntriesToRaw(rewrittenEntries));
|
|
125
|
+
}
|
|
126
|
+
catch (error) {
|
|
127
|
+
if (historyRawUnderLock === null) {
|
|
128
|
+
await fs.rm(subject.historyPath, { force: true });
|
|
129
|
+
}
|
|
130
|
+
else {
|
|
131
|
+
await writeFileAtomic(subject.historyPath, historyRawUnderLock);
|
|
132
|
+
}
|
|
133
|
+
throw error;
|
|
134
|
+
}
|
|
135
|
+
warnings.push(...(await runActiveOnWriteHooks({
|
|
136
|
+
path: subject.historyPath,
|
|
137
|
+
scope: "project",
|
|
138
|
+
op: "history_repair:history",
|
|
139
|
+
})));
|
|
140
|
+
}
|
|
141
|
+
finally {
|
|
142
|
+
await releaseLock();
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
return {
|
|
146
|
+
id: subject.id,
|
|
147
|
+
dry_run: dryRun,
|
|
148
|
+
changed,
|
|
149
|
+
history: {
|
|
150
|
+
path: subject.historyPath,
|
|
151
|
+
entries_scanned: historyEntries.length,
|
|
152
|
+
chain_drift_before: !chainBefore.ok,
|
|
153
|
+
entries_rehashed: reanchor.entriesRehashed,
|
|
154
|
+
entries_patch_repaired: reanchor.entriesPatchRepaired,
|
|
155
|
+
converted_replace_to_add: reanchor.convertedReplaceToAdd,
|
|
156
|
+
skipped_ops: reanchor.skippedOps,
|
|
157
|
+
reconciled_with_item: reconcileNeeded,
|
|
158
|
+
audit_entry_added: auditEntryAdded,
|
|
159
|
+
verify_ok: historyVerify.ok,
|
|
160
|
+
verify_errors: historyVerify.errors,
|
|
161
|
+
},
|
|
162
|
+
item: {
|
|
163
|
+
exists: currentItemPath !== null,
|
|
164
|
+
path: currentItemPath,
|
|
165
|
+
matched_chain_before: matchedChainBefore,
|
|
166
|
+
},
|
|
167
|
+
warnings: [...new Set(warnings)].sort((left, right) => left.localeCompare(right)),
|
|
168
|
+
generated_at: nowIso(),
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
//# sourceMappingURL=history-repair.js.map
|
|
172
|
+
//# debugId=01f463d2-97ef-5ddb-8346-156e456e097b
|