@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,6 +1,6 @@
|
|
|
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]="
|
|
3
|
-
import { normalizeStatusInput } from "../../core/item/status.js";
|
|
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]="4abe8ce0-f927-56d3-8afa-c64f8bed13d0")}catch(e){}}();
|
|
3
|
+
import { isTerminalStatus, normalizeStatusInput } from "../../core/item/status.js";
|
|
4
4
|
import { resolveRuntimeStatusRegistry } from "../../core/schema/runtime-schema.js";
|
|
5
5
|
import { EXIT_CODE } from "../../core/shared/constants.js";
|
|
6
6
|
import { PmCliError } from "../../core/shared/errors.js";
|
|
@@ -42,7 +42,10 @@ function parseThreshold(raw) {
|
|
|
42
42
|
return parsed;
|
|
43
43
|
}
|
|
44
44
|
function isTerminal(status) {
|
|
45
|
-
|
|
45
|
+
if (dedupeStatusRegistry) {
|
|
46
|
+
return isTerminalStatus(status, dedupeStatusRegistry);
|
|
47
|
+
}
|
|
48
|
+
const normalized = normalizeStatusInput(status) ?? status;
|
|
46
49
|
return dedupeTerminalStatuses.has(normalized);
|
|
47
50
|
}
|
|
48
51
|
function compareCandidates(left, right) {
|
|
@@ -321,4 +324,4 @@ export async function runDedupeAudit(options, global) {
|
|
|
321
324
|
};
|
|
322
325
|
}
|
|
323
326
|
//# sourceMappingURL=dedupe-audit.js.map
|
|
324
|
-
//# debugId=
|
|
327
|
+
//# debugId=4abe8ce0-f927-56d3-8afa-c64f8bed13d0
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dedupe-audit.js","sources":["cli/commands/dedupe-audit.ts"],"sourceRoot":"/","sourcesContent":["import { normalizeStatusInput } from \"../../core/item/status.js\";\nimport { resolveRuntimeStatusRegistry, type RuntimeStatusRegistry } from \"../../core/schema/runtime-schema.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 { compareTimestampStrings, nowIso } from \"../../core/shared/time.js\";\nimport { jaccardSimilarity, normalizeLowercaseWhitespace, tokenizeAlphaNumeric } from \"../../core/shared/text-normalization.js\";\nimport { resolvePmRoot } from \"../../core/store/paths.js\";\nimport { readSettings } from \"../../core/store/settings.js\";\nimport { type ItemStatus } from \"../../types/index.js\";\nimport { parseIntegerLimit } from \"../shared-parsers.js\";\nimport { runList } from \"./list.js\";\n\nexport const DEDUPE_AUDIT_MODES = [\"title_exact\", \"title_fuzzy\", \"parent_scope\"] as const;\n\nexport type DedupeAuditMode = (typeof DEDUPE_AUDIT_MODES)[number];\n\ninterface DedupeAuditPreparedCandidate {\n id: string;\n title: string;\n type: string;\n status: ItemStatus;\n parent: string | null;\n priority: number;\n created_at: string;\n updated_at: string;\n normalized_title: string;\n title_tokens: string[];\n}\n\nexport interface DedupeAuditCandidate {\n id: string;\n title: string;\n type: string;\n status: ItemStatus;\n parent: string | null;\n priority: number;\n created_at: string;\n updated_at: string;\n}\n\nexport interface DedupeMergeSuggestion {\n duplicate_id: string;\n canonical_id: string;\n suggested_close_reason: string;\n suggested_message: string;\n suggested_command: string;\n}\n\nexport interface DedupeAuditCluster {\n mode: DedupeAuditMode;\n key: string;\n match_reason: string;\n cluster_size: number;\n canonical: DedupeAuditCandidate;\n duplicates: DedupeAuditCandidate[];\n merge_suggestions: DedupeMergeSuggestion[];\n similarity?: {\n metric: \"token_jaccard\";\n threshold: number;\n min: number;\n max: number;\n };\n}\n\nexport interface DedupeAuditOptions {\n mode?: string;\n status?: string;\n type?: string;\n tag?: string;\n priority?: string;\n deadlineBefore?: string;\n deadlineAfter?: string;\n assignee?: string;\n assigneeFilter?: string;\n parent?: string;\n sprint?: string;\n release?: string;\n limit?: string;\n threshold?: string;\n}\n\nexport interface DedupeAuditResult {\n mode: DedupeAuditMode;\n clusters: DedupeAuditCluster[];\n count: number;\n totals: {\n items_considered: number;\n duplicate_candidates: number;\n merge_suggestions: number;\n };\n filters: {\n mode: DedupeAuditMode;\n status: ItemStatus | null;\n type: string | null;\n tag: string | null;\n priority: string | null;\n deadline_before: string | null;\n deadline_after: string | null;\n assignee: string | null;\n assignee_filter: string | null;\n parent: string | null;\n sprint: string | null;\n release: string | null;\n limit: number | null;\n threshold: number | null;\n };\n now: string;\n warnings?: string[];\n}\n\nfunction parseMode(raw: string | undefined): DedupeAuditMode {\n const normalized = (raw ?? \"title_exact\").trim().toLowerCase();\n if (!DEDUPE_AUDIT_MODES.includes(normalized as DedupeAuditMode)) {\n throw new PmCliError(`Dedupe audit mode must be one of ${DEDUPE_AUDIT_MODES.join(\"|\")}`, EXIT_CODE.USAGE);\n }\n return normalized as DedupeAuditMode;\n}\n\nlet dedupeAllowedStatuses = new Set<string>([\"draft\", \"open\", \"in_progress\", \"blocked\", \"closed\", \"canceled\"]);\nlet dedupeTerminalStatuses = new Set<string>([\"closed\", \"canceled\"]);\nlet dedupeStatusRegistry: RuntimeStatusRegistry | null = null;\n\nfunction parseStatus(raw: string | undefined): ItemStatus | undefined {\n if (raw === undefined) {\n return undefined;\n }\n const normalized = raw.trim().toLowerCase().replaceAll(\"-\", \"_\");\n if (!dedupeAllowedStatuses.has(normalized)) {\n throw new PmCliError(`Status filter must be one of ${[...dedupeAllowedStatuses].join(\"|\")}`, EXIT_CODE.USAGE);\n }\n return normalized as ItemStatus;\n}\n\nfunction parseThreshold(raw: string | undefined): number | undefined {\n if (raw === undefined) {\n return undefined;\n }\n const parsed = Number(raw);\n if (!Number.isFinite(parsed) || parsed < 0 || parsed > 1) {\n throw new PmCliError(\"--threshold must be a number between 0 and 1\", EXIT_CODE.USAGE);\n }\n return parsed;\n}\n\nfunction isTerminal(status: ItemStatus): boolean {\n const normalized = normalizeStatusInput(status, dedupeStatusRegistry ?? undefined) ?? status;\n return dedupeTerminalStatuses.has(normalized);\n}\n\nfunction compareCandidates(left: DedupeAuditPreparedCandidate, right: DedupeAuditPreparedCandidate): number {\n const leftTerminal = isTerminal(left.status);\n const rightTerminal = isTerminal(right.status);\n if (leftTerminal !== rightTerminal) {\n return leftTerminal ? 1 : -1;\n }\n const byPriority = left.priority - right.priority;\n if (byPriority !== 0) {\n return byPriority;\n }\n const byUpdated = compareTimestampStrings(right.updated_at, left.updated_at);\n if (byUpdated !== 0) {\n return byUpdated;\n }\n return left.id.localeCompare(right.id);\n}\n\nfunction toCandidate(candidate: DedupeAuditPreparedCandidate): DedupeAuditCandidate {\n return {\n id: candidate.id,\n title: candidate.title,\n type: candidate.type,\n status: candidate.status,\n parent: candidate.parent,\n priority: candidate.priority,\n created_at: candidate.created_at,\n updated_at: candidate.updated_at,\n };\n}\n\nfunction toMergeSuggestion(duplicate: DedupeAuditPreparedCandidate, canonical: DedupeAuditPreparedCandidate, mode: DedupeAuditMode): DedupeMergeSuggestion {\n const closeReason = `Duplicate of ${canonical.id}`;\n const message = `Close ${duplicate.id} as duplicate of ${canonical.id} from pm dedupe-audit (${mode}).`;\n const escapedReason = closeReason.replaceAll('\"', '\\\\\"');\n const escapedMessage = message.replaceAll('\"', '\\\\\"');\n return {\n duplicate_id: duplicate.id,\n canonical_id: canonical.id,\n suggested_close_reason: closeReason,\n suggested_message: message,\n suggested_command: `pm close ${duplicate.id} \"${escapedReason}\" --message \"${escapedMessage}\"`,\n };\n}\n\nfunction clusterFromMembers(\n mode: DedupeAuditMode,\n key: string,\n members: DedupeAuditPreparedCandidate[],\n matchReason: string,\n threshold: number | undefined,\n): DedupeAuditCluster {\n const sortedMembers = [...members].sort(compareCandidates);\n const canonical = sortedMembers[0];\n const duplicates = sortedMembers.slice(1);\n const mergeSuggestions = duplicates.map((candidate) => toMergeSuggestion(candidate, canonical, mode));\n const cluster: DedupeAuditCluster = {\n mode,\n key,\n match_reason: matchReason,\n cluster_size: sortedMembers.length,\n canonical: toCandidate(canonical),\n duplicates: duplicates.map((candidate) => toCandidate(candidate)),\n merge_suggestions: mergeSuggestions,\n };\n if (mode === \"title_fuzzy\") {\n let min = Number.POSITIVE_INFINITY;\n let max = Number.NEGATIVE_INFINITY;\n for (let leftIndex = 0; leftIndex < sortedMembers.length; leftIndex += 1) {\n for (let rightIndex = leftIndex + 1; rightIndex < sortedMembers.length; rightIndex += 1) {\n const score = similarityScore(sortedMembers[leftIndex], sortedMembers[rightIndex]);\n min = Math.min(min, score);\n max = Math.max(max, score);\n }\n }\n if (!Number.isFinite(min)) {\n min = 1;\n }\n if (!Number.isFinite(max)) {\n max = 1;\n }\n cluster.similarity = {\n metric: \"token_jaccard\",\n threshold: threshold ?? 0.8,\n min,\n max,\n };\n }\n return cluster;\n}\n\nfunction similarityScore(left: DedupeAuditPreparedCandidate, right: DedupeAuditPreparedCandidate): number {\n if (left.normalized_title === right.normalized_title) {\n return 1;\n }\n return jaccardSimilarity(left.title_tokens, right.title_tokens);\n}\n\nfunction collectExactTitleClusters(items: DedupeAuditPreparedCandidate[]): DedupeAuditCluster[] {\n const byTitle = new Map<string, DedupeAuditPreparedCandidate[]>();\n for (const item of items) {\n if (item.normalized_title.length === 0) {\n continue;\n }\n const existing = byTitle.get(item.normalized_title);\n if (existing) {\n existing.push(item);\n } else {\n byTitle.set(item.normalized_title, [item]);\n }\n }\n const clusters: DedupeAuditCluster[] = [];\n for (const [title, members] of byTitle.entries()) {\n if (members.length <= 1) {\n continue;\n }\n clusters.push(clusterFromMembers(\"title_exact\", title, members, \"exact_normalized_title_match\", undefined));\n }\n return clusters;\n}\n\nfunction collectParentScopedClusters(items: DedupeAuditPreparedCandidate[]): DedupeAuditCluster[] {\n const byParentAndTitle = new Map<string, DedupeAuditPreparedCandidate[]>();\n for (const item of items) {\n if (!item.parent || item.normalized_title.length === 0) {\n continue;\n }\n const key = `${item.parent}|${item.normalized_title}`;\n const existing = byParentAndTitle.get(key);\n if (existing) {\n existing.push(item);\n } else {\n byParentAndTitle.set(key, [item]);\n }\n }\n const clusters: DedupeAuditCluster[] = [];\n for (const [key, members] of byParentAndTitle.entries()) {\n if (members.length <= 1) {\n continue;\n }\n clusters.push(clusterFromMembers(\"parent_scope\", key, members, \"same_parent_and_exact_normalized_title\", undefined));\n }\n return clusters;\n}\n\nfunction findRoot(parents: number[], index: number): number {\n let current = index;\n while (parents[current] !== current) {\n parents[current] = parents[parents[current]];\n current = parents[current];\n }\n return current;\n}\n\nfunction unionRoots(parents: number[], left: number, right: number): void {\n const leftRoot = findRoot(parents, left);\n const rightRoot = findRoot(parents, right);\n if (leftRoot === rightRoot) {\n return;\n }\n if (leftRoot < rightRoot) {\n parents[rightRoot] = leftRoot;\n } else {\n parents[leftRoot] = rightRoot;\n }\n}\n\nfunction collectFuzzyTitleClusters(items: DedupeAuditPreparedCandidate[], threshold: number): DedupeAuditCluster[] {\n if (items.length <= 1) {\n return [];\n }\n const parents = items.map((_item, index) => index);\n for (let leftIndex = 0; leftIndex < items.length; leftIndex += 1) {\n for (let rightIndex = leftIndex + 1; rightIndex < items.length; rightIndex += 1) {\n const score = similarityScore(items[leftIndex], items[rightIndex]);\n if (score >= threshold) {\n unionRoots(parents, leftIndex, rightIndex);\n }\n }\n }\n const groupedIndices = new Map<number, number[]>();\n for (let index = 0; index < items.length; index += 1) {\n const root = findRoot(parents, index);\n const existing = groupedIndices.get(root);\n if (existing) {\n existing.push(index);\n } else {\n groupedIndices.set(root, [index]);\n }\n }\n const clusters: DedupeAuditCluster[] = [];\n for (const indices of groupedIndices.values()) {\n if (indices.length <= 1) {\n continue;\n }\n const members = indices.map((index) => items[index]);\n const canonicalKey = [...members].sort(compareCandidates)[0]?.id ?? `cluster-${clusters.length + 1}`;\n clusters.push(\n clusterFromMembers(\"title_fuzzy\", canonicalKey, members, \"title_token_jaccard_above_threshold\", threshold),\n );\n }\n return clusters;\n}\n\nfunction compareClusters(left: DedupeAuditCluster, right: DedupeAuditCluster): number {\n const bySize = right.cluster_size - left.cluster_size;\n if (bySize !== 0) {\n return bySize;\n }\n return left.canonical.id.localeCompare(right.canonical.id);\n}\n\nexport async function runDedupeAudit(options: DedupeAuditOptions, global: GlobalOptions): Promise<DedupeAuditResult> {\n const pmRoot = resolvePmRoot(process.cwd(), global.path);\n const settings = await readSettings(pmRoot);\n const statusRegistry = resolveRuntimeStatusRegistry(settings.schema);\n dedupeStatusRegistry = statusRegistry;\n dedupeAllowedStatuses = new Set(statusRegistry.definitions.map((definition) => definition.id));\n dedupeTerminalStatuses = new Set(statusRegistry.terminal_statuses);\n const mode = parseMode(options.mode);\n const status = parseStatus(options.status);\n const limit = parseIntegerLimit(options.limit);\n const threshold = parseThreshold(options.threshold);\n const fuzzyThreshold = threshold ?? 0.8;\n\n const listed = await runList(\n status,\n {\n type: options.type,\n tag: options.tag,\n priority: options.priority,\n deadlineBefore: options.deadlineBefore,\n deadlineAfter: options.deadlineAfter,\n assignee: options.assignee,\n assigneeFilter: options.assigneeFilter,\n parent: options.parent,\n sprint: options.sprint,\n release: options.release,\n },\n global,\n );\n\n const prepared: DedupeAuditPreparedCandidate[] = listed.items.map((item) => ({\n id: item.id,\n title: item.title,\n type: item.type,\n status: item.status,\n parent: item.parent ?? null,\n priority: item.priority,\n created_at: item.created_at,\n updated_at: item.updated_at,\n normalized_title: normalizeLowercaseWhitespace(item.title),\n title_tokens: tokenizeAlphaNumeric(item.title),\n }));\n\n const clusters = (() => {\n if (mode === \"title_exact\") {\n return collectExactTitleClusters(prepared);\n }\n if (mode === \"parent_scope\") {\n return collectParentScopedClusters(prepared);\n }\n return collectFuzzyTitleClusters(prepared, fuzzyThreshold);\n })();\n\n const sortedClusters = clusters.sort(compareClusters);\n const limitedClusters = limit === undefined ? sortedClusters : sortedClusters.slice(0, limit);\n const duplicateCandidates = limitedClusters.reduce((total, cluster) => total + cluster.cluster_size, 0);\n const mergeSuggestions = limitedClusters.reduce((total, cluster) => total + cluster.merge_suggestions.length, 0);\n const warnings = listed.warnings && listed.warnings.length > 0 ? listed.warnings : undefined;\n\n return {\n mode,\n clusters: limitedClusters,\n count: limitedClusters.length,\n totals: {\n items_considered: prepared.length,\n duplicate_candidates: duplicateCandidates,\n merge_suggestions: mergeSuggestions,\n },\n filters: {\n mode,\n status: status ?? null,\n type: options.type ?? null,\n tag: options.tag ?? null,\n priority: options.priority ?? null,\n deadline_before: options.deadlineBefore ?? null,\n deadline_after: options.deadlineAfter ?? null,\n assignee: options.assignee ?? null,\n assignee_filter: options.assigneeFilter ?? null,\n parent: options.parent ?? null,\n sprint: options.sprint ?? null,\n release: options.release ?? null,\n limit: limit ?? null,\n threshold: mode === \"title_fuzzy\" ? fuzzyThreshold : null,\n },\n now: nowIso(),\n ...(warnings ? { warnings } : {}),\n };\n}\n"],"names":[],"mappings":"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","debugId":"cc1be667-d250-57a7-9e55-29786633a146"}
|
|
1
|
+
{"version":3,"file":"dedupe-audit.js","sources":["cli/commands/dedupe-audit.ts"],"sourceRoot":"/","sourcesContent":["import { isTerminalStatus, normalizeStatusInput } from \"../../core/item/status.js\";\nimport { resolveRuntimeStatusRegistry, type RuntimeStatusRegistry } from \"../../core/schema/runtime-schema.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 { compareTimestampStrings, nowIso } from \"../../core/shared/time.js\";\nimport { jaccardSimilarity, normalizeLowercaseWhitespace, tokenizeAlphaNumeric } from \"../../core/shared/text-normalization.js\";\nimport { resolvePmRoot } from \"../../core/store/paths.js\";\nimport { readSettings } from \"../../core/store/settings.js\";\nimport { type ItemStatus } from \"../../types/index.js\";\nimport { parseIntegerLimit } from \"../shared-parsers.js\";\nimport { runList } from \"./list.js\";\n\nexport const DEDUPE_AUDIT_MODES = [\"title_exact\", \"title_fuzzy\", \"parent_scope\"] as const;\n\nexport type DedupeAuditMode = (typeof DEDUPE_AUDIT_MODES)[number];\n\ninterface DedupeAuditPreparedCandidate {\n id: string;\n title: string;\n type: string;\n status: ItemStatus;\n parent: string | null;\n priority: number;\n created_at: string;\n updated_at: string;\n normalized_title: string;\n title_tokens: string[];\n}\n\nexport interface DedupeAuditCandidate {\n id: string;\n title: string;\n type: string;\n status: ItemStatus;\n parent: string | null;\n priority: number;\n created_at: string;\n updated_at: string;\n}\n\nexport interface DedupeMergeSuggestion {\n duplicate_id: string;\n canonical_id: string;\n suggested_close_reason: string;\n suggested_message: string;\n suggested_command: string;\n}\n\nexport interface DedupeAuditCluster {\n mode: DedupeAuditMode;\n key: string;\n match_reason: string;\n cluster_size: number;\n canonical: DedupeAuditCandidate;\n duplicates: DedupeAuditCandidate[];\n merge_suggestions: DedupeMergeSuggestion[];\n similarity?: {\n metric: \"token_jaccard\";\n threshold: number;\n min: number;\n max: number;\n };\n}\n\nexport interface DedupeAuditOptions {\n mode?: string;\n status?: string;\n type?: string;\n tag?: string;\n priority?: string;\n deadlineBefore?: string;\n deadlineAfter?: string;\n assignee?: string;\n assigneeFilter?: string;\n parent?: string;\n sprint?: string;\n release?: string;\n limit?: string;\n threshold?: string;\n}\n\nexport interface DedupeAuditResult {\n mode: DedupeAuditMode;\n clusters: DedupeAuditCluster[];\n count: number;\n totals: {\n items_considered: number;\n duplicate_candidates: number;\n merge_suggestions: number;\n };\n filters: {\n mode: DedupeAuditMode;\n status: ItemStatus | null;\n type: string | null;\n tag: string | null;\n priority: string | null;\n deadline_before: string | null;\n deadline_after: string | null;\n assignee: string | null;\n assignee_filter: string | null;\n parent: string | null;\n sprint: string | null;\n release: string | null;\n limit: number | null;\n threshold: number | null;\n };\n now: string;\n warnings?: string[];\n}\n\nfunction parseMode(raw: string | undefined): DedupeAuditMode {\n const normalized = (raw ?? \"title_exact\").trim().toLowerCase();\n if (!DEDUPE_AUDIT_MODES.includes(normalized as DedupeAuditMode)) {\n throw new PmCliError(`Dedupe audit mode must be one of ${DEDUPE_AUDIT_MODES.join(\"|\")}`, EXIT_CODE.USAGE);\n }\n return normalized as DedupeAuditMode;\n}\n\nlet dedupeAllowedStatuses = new Set<string>([\"draft\", \"open\", \"in_progress\", \"blocked\", \"closed\", \"canceled\"]);\nlet dedupeTerminalStatuses = new Set<string>([\"closed\", \"canceled\"]);\nlet dedupeStatusRegistry: RuntimeStatusRegistry | null = null;\n\nfunction parseStatus(raw: string | undefined): ItemStatus | undefined {\n if (raw === undefined) {\n return undefined;\n }\n const normalized = raw.trim().toLowerCase().replaceAll(\"-\", \"_\");\n if (!dedupeAllowedStatuses.has(normalized)) {\n throw new PmCliError(`Status filter must be one of ${[...dedupeAllowedStatuses].join(\"|\")}`, EXIT_CODE.USAGE);\n }\n return normalized as ItemStatus;\n}\n\nfunction parseThreshold(raw: string | undefined): number | undefined {\n if (raw === undefined) {\n return undefined;\n }\n const parsed = Number(raw);\n if (!Number.isFinite(parsed) || parsed < 0 || parsed > 1) {\n throw new PmCliError(\"--threshold must be a number between 0 and 1\", EXIT_CODE.USAGE);\n }\n return parsed;\n}\n\nfunction isTerminal(status: ItemStatus): boolean {\n if (dedupeStatusRegistry) {\n return isTerminalStatus(status, dedupeStatusRegistry);\n }\n const normalized = normalizeStatusInput(status) ?? status;\n return dedupeTerminalStatuses.has(normalized);\n}\n\nfunction compareCandidates(left: DedupeAuditPreparedCandidate, right: DedupeAuditPreparedCandidate): number {\n const leftTerminal = isTerminal(left.status);\n const rightTerminal = isTerminal(right.status);\n if (leftTerminal !== rightTerminal) {\n return leftTerminal ? 1 : -1;\n }\n const byPriority = left.priority - right.priority;\n if (byPriority !== 0) {\n return byPriority;\n }\n const byUpdated = compareTimestampStrings(right.updated_at, left.updated_at);\n if (byUpdated !== 0) {\n return byUpdated;\n }\n return left.id.localeCompare(right.id);\n}\n\nfunction toCandidate(candidate: DedupeAuditPreparedCandidate): DedupeAuditCandidate {\n return {\n id: candidate.id,\n title: candidate.title,\n type: candidate.type,\n status: candidate.status,\n parent: candidate.parent,\n priority: candidate.priority,\n created_at: candidate.created_at,\n updated_at: candidate.updated_at,\n };\n}\n\nfunction toMergeSuggestion(duplicate: DedupeAuditPreparedCandidate, canonical: DedupeAuditPreparedCandidate, mode: DedupeAuditMode): DedupeMergeSuggestion {\n const closeReason = `Duplicate of ${canonical.id}`;\n const message = `Close ${duplicate.id} as duplicate of ${canonical.id} from pm dedupe-audit (${mode}).`;\n const escapedReason = closeReason.replaceAll('\"', '\\\\\"');\n const escapedMessage = message.replaceAll('\"', '\\\\\"');\n return {\n duplicate_id: duplicate.id,\n canonical_id: canonical.id,\n suggested_close_reason: closeReason,\n suggested_message: message,\n suggested_command: `pm close ${duplicate.id} \"${escapedReason}\" --message \"${escapedMessage}\"`,\n };\n}\n\nfunction clusterFromMembers(\n mode: DedupeAuditMode,\n key: string,\n members: DedupeAuditPreparedCandidate[],\n matchReason: string,\n threshold: number | undefined,\n): DedupeAuditCluster {\n const sortedMembers = [...members].sort(compareCandidates);\n const canonical = sortedMembers[0];\n const duplicates = sortedMembers.slice(1);\n const mergeSuggestions = duplicates.map((candidate) => toMergeSuggestion(candidate, canonical, mode));\n const cluster: DedupeAuditCluster = {\n mode,\n key,\n match_reason: matchReason,\n cluster_size: sortedMembers.length,\n canonical: toCandidate(canonical),\n duplicates: duplicates.map((candidate) => toCandidate(candidate)),\n merge_suggestions: mergeSuggestions,\n };\n if (mode === \"title_fuzzy\") {\n let min = Number.POSITIVE_INFINITY;\n let max = Number.NEGATIVE_INFINITY;\n for (let leftIndex = 0; leftIndex < sortedMembers.length; leftIndex += 1) {\n for (let rightIndex = leftIndex + 1; rightIndex < sortedMembers.length; rightIndex += 1) {\n const score = similarityScore(sortedMembers[leftIndex], sortedMembers[rightIndex]);\n min = Math.min(min, score);\n max = Math.max(max, score);\n }\n }\n if (!Number.isFinite(min)) {\n min = 1;\n }\n if (!Number.isFinite(max)) {\n max = 1;\n }\n cluster.similarity = {\n metric: \"token_jaccard\",\n threshold: threshold ?? 0.8,\n min,\n max,\n };\n }\n return cluster;\n}\n\nfunction similarityScore(left: DedupeAuditPreparedCandidate, right: DedupeAuditPreparedCandidate): number {\n if (left.normalized_title === right.normalized_title) {\n return 1;\n }\n return jaccardSimilarity(left.title_tokens, right.title_tokens);\n}\n\nfunction collectExactTitleClusters(items: DedupeAuditPreparedCandidate[]): DedupeAuditCluster[] {\n const byTitle = new Map<string, DedupeAuditPreparedCandidate[]>();\n for (const item of items) {\n if (item.normalized_title.length === 0) {\n continue;\n }\n const existing = byTitle.get(item.normalized_title);\n if (existing) {\n existing.push(item);\n } else {\n byTitle.set(item.normalized_title, [item]);\n }\n }\n const clusters: DedupeAuditCluster[] = [];\n for (const [title, members] of byTitle.entries()) {\n if (members.length <= 1) {\n continue;\n }\n clusters.push(clusterFromMembers(\"title_exact\", title, members, \"exact_normalized_title_match\", undefined));\n }\n return clusters;\n}\n\nfunction collectParentScopedClusters(items: DedupeAuditPreparedCandidate[]): DedupeAuditCluster[] {\n const byParentAndTitle = new Map<string, DedupeAuditPreparedCandidate[]>();\n for (const item of items) {\n if (!item.parent || item.normalized_title.length === 0) {\n continue;\n }\n const key = `${item.parent}|${item.normalized_title}`;\n const existing = byParentAndTitle.get(key);\n if (existing) {\n existing.push(item);\n } else {\n byParentAndTitle.set(key, [item]);\n }\n }\n const clusters: DedupeAuditCluster[] = [];\n for (const [key, members] of byParentAndTitle.entries()) {\n if (members.length <= 1) {\n continue;\n }\n clusters.push(clusterFromMembers(\"parent_scope\", key, members, \"same_parent_and_exact_normalized_title\", undefined));\n }\n return clusters;\n}\n\nfunction findRoot(parents: number[], index: number): number {\n let current = index;\n while (parents[current] !== current) {\n parents[current] = parents[parents[current]];\n current = parents[current];\n }\n return current;\n}\n\nfunction unionRoots(parents: number[], left: number, right: number): void {\n const leftRoot = findRoot(parents, left);\n const rightRoot = findRoot(parents, right);\n if (leftRoot === rightRoot) {\n return;\n }\n if (leftRoot < rightRoot) {\n parents[rightRoot] = leftRoot;\n } else {\n parents[leftRoot] = rightRoot;\n }\n}\n\nfunction collectFuzzyTitleClusters(items: DedupeAuditPreparedCandidate[], threshold: number): DedupeAuditCluster[] {\n if (items.length <= 1) {\n return [];\n }\n const parents = items.map((_item, index) => index);\n for (let leftIndex = 0; leftIndex < items.length; leftIndex += 1) {\n for (let rightIndex = leftIndex + 1; rightIndex < items.length; rightIndex += 1) {\n const score = similarityScore(items[leftIndex], items[rightIndex]);\n if (score >= threshold) {\n unionRoots(parents, leftIndex, rightIndex);\n }\n }\n }\n const groupedIndices = new Map<number, number[]>();\n for (let index = 0; index < items.length; index += 1) {\n const root = findRoot(parents, index);\n const existing = groupedIndices.get(root);\n if (existing) {\n existing.push(index);\n } else {\n groupedIndices.set(root, [index]);\n }\n }\n const clusters: DedupeAuditCluster[] = [];\n for (const indices of groupedIndices.values()) {\n if (indices.length <= 1) {\n continue;\n }\n const members = indices.map((index) => items[index]);\n const canonicalKey = [...members].sort(compareCandidates)[0]?.id ?? `cluster-${clusters.length + 1}`;\n clusters.push(\n clusterFromMembers(\"title_fuzzy\", canonicalKey, members, \"title_token_jaccard_above_threshold\", threshold),\n );\n }\n return clusters;\n}\n\nfunction compareClusters(left: DedupeAuditCluster, right: DedupeAuditCluster): number {\n const bySize = right.cluster_size - left.cluster_size;\n if (bySize !== 0) {\n return bySize;\n }\n return left.canonical.id.localeCompare(right.canonical.id);\n}\n\nexport async function runDedupeAudit(options: DedupeAuditOptions, global: GlobalOptions): Promise<DedupeAuditResult> {\n const pmRoot = resolvePmRoot(process.cwd(), global.path);\n const settings = await readSettings(pmRoot);\n const statusRegistry = resolveRuntimeStatusRegistry(settings.schema);\n dedupeStatusRegistry = statusRegistry;\n dedupeAllowedStatuses = new Set(statusRegistry.definitions.map((definition) => definition.id));\n dedupeTerminalStatuses = new Set(statusRegistry.terminal_statuses);\n const mode = parseMode(options.mode);\n const status = parseStatus(options.status);\n const limit = parseIntegerLimit(options.limit);\n const threshold = parseThreshold(options.threshold);\n const fuzzyThreshold = threshold ?? 0.8;\n\n const listed = await runList(\n status,\n {\n type: options.type,\n tag: options.tag,\n priority: options.priority,\n deadlineBefore: options.deadlineBefore,\n deadlineAfter: options.deadlineAfter,\n assignee: options.assignee,\n assigneeFilter: options.assigneeFilter,\n parent: options.parent,\n sprint: options.sprint,\n release: options.release,\n },\n global,\n );\n\n const prepared: DedupeAuditPreparedCandidate[] = listed.items.map((item) => ({\n id: item.id,\n title: item.title,\n type: item.type,\n status: item.status,\n parent: item.parent ?? null,\n priority: item.priority,\n created_at: item.created_at,\n updated_at: item.updated_at,\n normalized_title: normalizeLowercaseWhitespace(item.title),\n title_tokens: tokenizeAlphaNumeric(item.title),\n }));\n\n const clusters = (() => {\n if (mode === \"title_exact\") {\n return collectExactTitleClusters(prepared);\n }\n if (mode === \"parent_scope\") {\n return collectParentScopedClusters(prepared);\n }\n return collectFuzzyTitleClusters(prepared, fuzzyThreshold);\n })();\n\n const sortedClusters = clusters.sort(compareClusters);\n const limitedClusters = limit === undefined ? sortedClusters : sortedClusters.slice(0, limit);\n const duplicateCandidates = limitedClusters.reduce((total, cluster) => total + cluster.cluster_size, 0);\n const mergeSuggestions = limitedClusters.reduce((total, cluster) => total + cluster.merge_suggestions.length, 0);\n const warnings = listed.warnings && listed.warnings.length > 0 ? listed.warnings : undefined;\n\n return {\n mode,\n clusters: limitedClusters,\n count: limitedClusters.length,\n totals: {\n items_considered: prepared.length,\n duplicate_candidates: duplicateCandidates,\n merge_suggestions: mergeSuggestions,\n },\n filters: {\n mode,\n status: status ?? null,\n type: options.type ?? null,\n tag: options.tag ?? null,\n priority: options.priority ?? null,\n deadline_before: options.deadlineBefore ?? null,\n deadline_after: options.deadlineAfter ?? null,\n assignee: options.assignee ?? null,\n assignee_filter: options.assigneeFilter ?? null,\n parent: options.parent ?? null,\n sprint: options.sprint ?? null,\n release: options.release ?? null,\n limit: limit ?? null,\n threshold: mode === \"title_fuzzy\" ? fuzzyThreshold : null,\n },\n now: nowIso(),\n ...(warnings ? { warnings } : {}),\n };\n}\n"],"names":[],"mappings":"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","debugId":"4abe8ce0-f927-56d3-8afa-c64f8bed13d0"}
|
|
@@ -3,10 +3,13 @@ export interface DeleteCommandOptions {
|
|
|
3
3
|
author?: string;
|
|
4
4
|
message?: string;
|
|
5
5
|
force?: boolean;
|
|
6
|
+
dryRun?: boolean;
|
|
6
7
|
}
|
|
7
8
|
export interface DeleteResult {
|
|
8
9
|
item: Record<string, unknown>;
|
|
9
10
|
changed_fields: string[];
|
|
11
|
+
dry_run: boolean;
|
|
12
|
+
target_path?: string;
|
|
10
13
|
warnings: string[];
|
|
11
14
|
}
|
|
12
15
|
export declare function runDelete(id: string, options: DeleteCommandOptions, global: GlobalOptions): Promise<DeleteResult>;
|
|
@@ -1,23 +1,21 @@
|
|
|
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]="dde4c802-3d48-5847-b800-0994d53218fd")}catch(e){}}();
|
|
3
|
+
import path from "node:path";
|
|
3
4
|
import { pathExists } from "../../core/fs/fs-utils.js";
|
|
4
5
|
import { EXIT_CODE } from "../../core/shared/constants.js";
|
|
5
6
|
import { PmCliError } from "../../core/shared/errors.js";
|
|
7
|
+
import { toItemRecord } from "../../core/item/item-record.js";
|
|
6
8
|
import { deleteItem } from "../../core/store/item-store.js";
|
|
7
9
|
import { getSettingsPath, resolvePmRoot } from "../../core/store/paths.js";
|
|
8
10
|
import { readSettings } from "../../core/store/settings.js";
|
|
9
|
-
|
|
10
|
-
const resolved = candidate ?? process.env.PM_AUTHOR ?? defaultAuthor;
|
|
11
|
-
const trimmed = resolved.trim();
|
|
12
|
-
return trimmed || "unknown";
|
|
13
|
-
}
|
|
11
|
+
import { resolveAuthor } from "../../core/shared/author.js";
|
|
14
12
|
export async function runDelete(id, options, global) {
|
|
15
13
|
const pmRoot = resolvePmRoot(process.cwd(), global.path);
|
|
16
14
|
if (!(await pathExists(getSettingsPath(pmRoot)))) {
|
|
17
15
|
throw new PmCliError(`Tracker is not initialized at ${pmRoot}. Run pm init first.`, EXIT_CODE.NOT_FOUND);
|
|
18
16
|
}
|
|
19
17
|
const settings = await readSettings(pmRoot);
|
|
20
|
-
const author =
|
|
18
|
+
const author = resolveAuthor(options.author, settings.author_default);
|
|
21
19
|
const result = await deleteItem({
|
|
22
20
|
pmRoot,
|
|
23
21
|
settings,
|
|
@@ -25,12 +23,16 @@ export async function runDelete(id, options, global) {
|
|
|
25
23
|
author,
|
|
26
24
|
message: options.message,
|
|
27
25
|
force: options.force,
|
|
26
|
+
dryRun: options.dryRun,
|
|
28
27
|
});
|
|
28
|
+
const targetPath = result.targetPath ? path.relative(pmRoot, result.targetPath).split(path.sep).join("/") : undefined;
|
|
29
29
|
return {
|
|
30
|
-
item: result.item,
|
|
30
|
+
item: toItemRecord(result.item),
|
|
31
31
|
changed_fields: result.changedFields,
|
|
32
|
+
dry_run: options.dryRun === true,
|
|
33
|
+
...(targetPath ? { target_path: targetPath } : {}),
|
|
32
34
|
warnings: result.warnings,
|
|
33
35
|
};
|
|
34
36
|
}
|
|
35
37
|
//# sourceMappingURL=delete.js.map
|
|
36
|
-
//# debugId=
|
|
38
|
+
//# debugId=dde4c802-3d48-5847-b800-0994d53218fd
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"delete.js","sources":["cli/commands/delete.ts"],"sourceRoot":"/","sourcesContent":["import { pathExists } from \"../../core/fs/fs-utils.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 { deleteItem } from \"../../core/store/item-store.js\";\nimport { getSettingsPath, resolvePmRoot } from \"../../core/store/paths.js\";\nimport { readSettings } from \"../../core/store/settings.js\";\n\nexport interface DeleteCommandOptions {\n author?: string;\n message?: string;\n force?: boolean;\n}\n\nexport interface DeleteResult {\n item: Record<string, unknown>;\n changed_fields: string[];\n
|
|
1
|
+
{"version":3,"file":"delete.js","sources":["cli/commands/delete.ts"],"sourceRoot":"/","sourcesContent":["import path from \"node:path\";\nimport { pathExists } from \"../../core/fs/fs-utils.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 { toItemRecord } from \"../../core/item/item-record.js\";\nimport { deleteItem } from \"../../core/store/item-store.js\";\nimport { getSettingsPath, resolvePmRoot } from \"../../core/store/paths.js\";\nimport { readSettings } from \"../../core/store/settings.js\";\nimport { resolveAuthor } from \"../../core/shared/author.js\";\n\nexport interface DeleteCommandOptions {\n author?: string;\n message?: string;\n force?: boolean;\n dryRun?: boolean;\n}\n\nexport interface DeleteResult {\n item: Record<string, unknown>;\n changed_fields: string[];\n dry_run: boolean;\n target_path?: string;\n warnings: string[];\n}\n\nexport async function runDelete(id: string, options: DeleteCommandOptions, global: GlobalOptions): Promise<DeleteResult> {\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 author = resolveAuthor(options.author, settings.author_default);\n\n const result = await deleteItem({\n pmRoot,\n settings,\n id,\n author,\n message: options.message,\n force: options.force,\n dryRun: options.dryRun,\n });\n const targetPath = result.targetPath ? path.relative(pmRoot, result.targetPath).split(path.sep).join(\"/\") : undefined;\n\n return {\n item: toItemRecord(result.item),\n changed_fields: result.changedFields,\n dry_run: options.dryRun === true,\n ...(targetPath ? { target_path: targetPath } : {}),\n warnings: result.warnings,\n };\n}\n"],"names":[],"mappings":";;AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,gCAAgC,CAAC;AAE3D,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC3E,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAiB5D,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,EAAU,EAAE,OAA6B,EAAE,MAAqB;IAC9F,MAAM,MAAM,GAAG,aAAa,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;IACzD,IAAI,CAAC,CAAC,MAAM,UAAU,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;QACjD,MAAM,IAAI,UAAU,CAAC,iCAAiC,MAAM,sBAAsB,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC3G,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,MAAM,CAAC,CAAC;IAC5C,MAAM,MAAM,GAAG,aAAa,CAAC,OAAO,CAAC,MAAM,EAAE,QAAQ,CAAC,cAAc,CAAC,CAAC;IAEtE,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC;QAC9B,MAAM;QACN,QAAQ;QACR,EAAE;QACF,MAAM;QACN,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,MAAM,EAAE,OAAO,CAAC,MAAM;KACvB,CAAC,CAAC;IACH,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAEtH,OAAO;QACL,IAAI,EAAE,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC;QAC/B,cAAc,EAAE,MAAM,CAAC,aAAa;QACpC,OAAO,EAAE,OAAO,CAAC,MAAM,KAAK,IAAI;QAChC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAClD,QAAQ,EAAE,MAAM,CAAC,QAAQ;KAC1B,CAAC;AACJ,CAAC","debugId":"dde4c802-3d48-5847-b800-0994d53218fd"}
|
|
@@ -1,27 +1,18 @@
|
|
|
1
1
|
import type { GlobalOptions } from "../../core/shared/command-types.js";
|
|
2
2
|
import type { LinkedDoc } from "../../types/index.js";
|
|
3
|
+
import { type LinkedPathAuditEntry, type LinkedPathValidation } from "./linked-artifacts.js";
|
|
3
4
|
export interface DocsCommandOptions {
|
|
4
5
|
add?: string[];
|
|
5
6
|
addGlob?: string[];
|
|
6
7
|
remove?: string[];
|
|
7
8
|
migrate?: string[];
|
|
9
|
+
list?: boolean;
|
|
8
10
|
validatePaths?: boolean;
|
|
9
11
|
audit?: boolean;
|
|
10
12
|
author?: string;
|
|
11
13
|
message?: string;
|
|
12
14
|
force?: boolean;
|
|
13
15
|
}
|
|
14
|
-
interface LinkedPathValidation {
|
|
15
|
-
checked: number;
|
|
16
|
-
existing_files: string[];
|
|
17
|
-
missing_paths: string[];
|
|
18
|
-
non_file_paths: string[];
|
|
19
|
-
}
|
|
20
|
-
interface LinkedPathAuditEntry {
|
|
21
|
-
path: string;
|
|
22
|
-
linked_by_count: number;
|
|
23
|
-
linked_item_ids: string[];
|
|
24
|
-
}
|
|
25
16
|
export interface DocsResult {
|
|
26
17
|
id: string;
|
|
27
18
|
docs: LinkedDoc[];
|
|
@@ -32,4 +23,3 @@ export interface DocsResult {
|
|
|
32
23
|
audit?: LinkedPathAuditEntry[];
|
|
33
24
|
}
|
|
34
25
|
export declare function runDocs(id: string, options: DocsCommandOptions, global: GlobalOptions): Promise<DocsResult>;
|
|
35
|
-
export {};
|
|
@@ -1,322 +1,14 @@
|
|
|
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]="
|
|
3
|
-
import
|
|
4
|
-
import path from "node:path";
|
|
5
|
-
import fg from "fast-glob";
|
|
6
|
-
import { pathExists } from "../../core/fs/fs-utils.js";
|
|
7
|
-
import { getActiveExtensionRegistrations } from "../../core/extensions/index.js";
|
|
8
|
-
import { createStdinTokenResolver, parseCsvKv } from "../../core/item/parse.js";
|
|
9
|
-
import { resolveItemTypeRegistry } from "../../core/item/type-registry.js";
|
|
10
|
-
import { EXIT_CODE } from "../../core/shared/constants.js";
|
|
11
|
-
import { PmCliError } from "../../core/shared/errors.js";
|
|
12
|
-
import { listAllFrontMatter, locateItem, mutateItem, readLocatedItem } from "../../core/store/item-store.js";
|
|
13
|
-
import { getSettingsPath, resolvePmRoot } from "../../core/store/paths.js";
|
|
14
|
-
import { readSettings } from "../../core/store/settings.js";
|
|
15
|
-
import { SCOPE_VALUES } from "../../types/index.js";
|
|
16
|
-
function resolveAuthor(candidate, fallback) {
|
|
17
|
-
const resolved = candidate ?? process.env.PM_AUTHOR ?? fallback;
|
|
18
|
-
const trimmed = resolved.trim();
|
|
19
|
-
return trimmed || "unknown";
|
|
20
|
-
}
|
|
21
|
-
function ensureScope(raw) {
|
|
22
|
-
const value = (raw ?? "project");
|
|
23
|
-
if (!SCOPE_VALUES.includes(value)) {
|
|
24
|
-
throw new PmCliError(`Invalid scope "${raw}"`, EXIT_CODE.USAGE);
|
|
25
|
-
}
|
|
26
|
-
return value;
|
|
27
|
-
}
|
|
28
|
-
function looksLikeStructuredPathEntry(raw) {
|
|
29
|
-
if (raw.startsWith("```") || raw.includes("\n")) {
|
|
30
|
-
return true;
|
|
31
|
-
}
|
|
32
|
-
return /^(?:[-*+]\s+)?(?:path|scope|note)\s*[:=]/i.test(raw);
|
|
33
|
-
}
|
|
34
|
-
function parseAddEntries(raw) {
|
|
35
|
-
if (!raw)
|
|
36
|
-
return [];
|
|
37
|
-
return raw.map((entry) => {
|
|
38
|
-
const trimmed = entry.trim();
|
|
39
|
-
const kv = looksLikeStructuredPathEntry(trimmed) ? parseCsvKv(entry, "--add") : { path: trimmed };
|
|
40
|
-
if (!kv.path) {
|
|
41
|
-
throw new PmCliError("--add requires path=<value> or a bare doc path", EXIT_CODE.USAGE);
|
|
42
|
-
}
|
|
43
|
-
return {
|
|
44
|
-
path: kv.path,
|
|
45
|
-
scope: ensureScope(kv.scope),
|
|
46
|
-
note: kv.note?.trim() || undefined,
|
|
47
|
-
};
|
|
48
|
-
});
|
|
49
|
-
}
|
|
50
|
-
function parseAddGlobEntries(raw) {
|
|
51
|
-
if (!raw)
|
|
52
|
-
return [];
|
|
53
|
-
return raw.map((entry) => {
|
|
54
|
-
const trimmed = entry.trim();
|
|
55
|
-
if (!trimmed) {
|
|
56
|
-
throw new PmCliError("--add-glob requires a glob pattern value", EXIT_CODE.USAGE);
|
|
57
|
-
}
|
|
58
|
-
if (trimmed.includes("=") || /^(?:[-*+]\s+)?(?:pattern|glob|path)\s*[:=]/i.test(trimmed) || trimmed.startsWith("```")) {
|
|
59
|
-
const kv = parseCsvKv(trimmed, "--add-glob");
|
|
60
|
-
const pattern = kv.pattern?.trim() || kv.glob?.trim() || kv.path?.trim();
|
|
61
|
-
if (!pattern) {
|
|
62
|
-
throw new PmCliError("--add-glob key/value form requires pattern=<glob>", EXIT_CODE.USAGE);
|
|
63
|
-
}
|
|
64
|
-
return {
|
|
65
|
-
pattern,
|
|
66
|
-
scope: ensureScope(kv.scope),
|
|
67
|
-
note: kv.note?.trim() || undefined,
|
|
68
|
-
};
|
|
69
|
-
}
|
|
70
|
-
return {
|
|
71
|
-
pattern: trimmed,
|
|
72
|
-
scope: "project",
|
|
73
|
-
};
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
function parseRemoveEntries(raw) {
|
|
77
|
-
if (!raw)
|
|
78
|
-
return [];
|
|
79
|
-
return raw.map((entry) => {
|
|
80
|
-
const trimmed = entry.trim();
|
|
81
|
-
if (!trimmed) {
|
|
82
|
-
throw new PmCliError("--remove requires a path value", EXIT_CODE.USAGE);
|
|
83
|
-
}
|
|
84
|
-
if (trimmed.includes("=") || /^(?:[-*+]\s+)?path\s*[:=]/i.test(trimmed) || trimmed.startsWith("```")) {
|
|
85
|
-
const kv = parseCsvKv(trimmed, "--remove");
|
|
86
|
-
if (!kv.path) {
|
|
87
|
-
throw new PmCliError("--remove key/value form requires path=<value>", EXIT_CODE.USAGE);
|
|
88
|
-
}
|
|
89
|
-
return kv.path;
|
|
90
|
-
}
|
|
91
|
-
return trimmed;
|
|
92
|
-
});
|
|
93
|
-
}
|
|
94
|
-
function parseMigrateEntries(raw) {
|
|
95
|
-
if (!raw)
|
|
96
|
-
return [];
|
|
97
|
-
return raw.map((entry) => {
|
|
98
|
-
const kv = parseCsvKv(entry, "--migrate");
|
|
99
|
-
const from = kv.from?.trim();
|
|
100
|
-
const to = kv.to?.trim();
|
|
101
|
-
if (!from || !to) {
|
|
102
|
-
throw new PmCliError("--migrate requires from=<value> and to=<value>", EXIT_CODE.USAGE);
|
|
103
|
-
}
|
|
104
|
-
return { from, to };
|
|
105
|
-
});
|
|
106
|
-
}
|
|
107
|
-
function applyPathMigrations(docPath, migrations) {
|
|
108
|
-
let next = docPath;
|
|
109
|
-
for (const migration of migrations) {
|
|
110
|
-
if (next.startsWith(migration.from)) {
|
|
111
|
-
next = `${migration.to}${next.slice(migration.from.length)}`;
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
return next;
|
|
115
|
-
}
|
|
116
|
-
function normalizeLinkedPath(value) {
|
|
117
|
-
return value.split(path.sep).join("/");
|
|
118
|
-
}
|
|
119
|
-
async function expandAddGlobEntries(entries) {
|
|
120
|
-
const expanded = [];
|
|
121
|
-
for (const entry of entries) {
|
|
122
|
-
const absolutePattern = path.isAbsolute(entry.pattern);
|
|
123
|
-
const matches = await fg(entry.pattern, {
|
|
124
|
-
cwd: process.cwd(),
|
|
125
|
-
absolute: absolutePattern,
|
|
126
|
-
onlyFiles: true,
|
|
127
|
-
dot: true,
|
|
128
|
-
unique: true,
|
|
129
|
-
followSymbolicLinks: true,
|
|
130
|
-
});
|
|
131
|
-
const sortedMatches = [...new Set(matches.map((match) => normalizeLinkedPath(path.normalize(match))))].sort((left, right) => left.localeCompare(right));
|
|
132
|
-
for (const matchedPath of sortedMatches) {
|
|
133
|
-
expanded.push({
|
|
134
|
-
path: matchedPath,
|
|
135
|
-
scope: entry.scope,
|
|
136
|
-
note: entry.note,
|
|
137
|
-
});
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
return expanded;
|
|
141
|
-
}
|
|
142
|
-
function docKey(value) {
|
|
143
|
-
return `${value.path}::${value.scope}`;
|
|
144
|
-
}
|
|
145
|
-
function sortLinkedDocs(docs) {
|
|
146
|
-
return [...docs].sort((left, right) => {
|
|
147
|
-
const byPath = left.path.localeCompare(right.path);
|
|
148
|
-
if (byPath !== 0)
|
|
149
|
-
return byPath;
|
|
150
|
-
return left.scope.localeCompare(right.scope);
|
|
151
|
-
});
|
|
152
|
-
}
|
|
153
|
-
async function validateLinkedDocPaths(paths) {
|
|
154
|
-
const uniquePaths = [...new Set(paths)].sort((left, right) => left.localeCompare(right));
|
|
155
|
-
const existingFiles = [];
|
|
156
|
-
const missingPaths = [];
|
|
157
|
-
const nonFilePaths = [];
|
|
158
|
-
for (const relativePath of uniquePaths) {
|
|
159
|
-
const resolvedPath = path.isAbsolute(relativePath) ? relativePath : path.resolve(process.cwd(), relativePath);
|
|
160
|
-
try {
|
|
161
|
-
const stats = await fs.stat(resolvedPath);
|
|
162
|
-
if (stats.isFile()) {
|
|
163
|
-
existingFiles.push(relativePath);
|
|
164
|
-
}
|
|
165
|
-
else {
|
|
166
|
-
nonFilePaths.push(relativePath);
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
catch (error) {
|
|
170
|
-
if (typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT") {
|
|
171
|
-
missingPaths.push(relativePath);
|
|
172
|
-
continue;
|
|
173
|
-
}
|
|
174
|
-
nonFilePaths.push(relativePath);
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
return {
|
|
178
|
-
checked: uniquePaths.length,
|
|
179
|
-
existing_files: existingFiles,
|
|
180
|
-
missing_paths: missingPaths,
|
|
181
|
-
non_file_paths: nonFilePaths,
|
|
182
|
-
};
|
|
183
|
-
}
|
|
184
|
-
function buildLinkedDocAudit(paths, allItems) {
|
|
185
|
-
const index = new Map();
|
|
186
|
-
for (const item of allItems) {
|
|
187
|
-
for (const linkedDoc of item.docs ?? []) {
|
|
188
|
-
const seen = index.get(linkedDoc.path) ?? new Set();
|
|
189
|
-
seen.add(item.id);
|
|
190
|
-
index.set(linkedDoc.path, seen);
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
return [...new Set(paths)]
|
|
194
|
-
.sort((left, right) => left.localeCompare(right))
|
|
195
|
-
.map((linkedPath) => {
|
|
196
|
-
const linkedIds = [...(index.get(linkedPath) ?? new Set())].sort((left, right) => left.localeCompare(right));
|
|
197
|
-
return {
|
|
198
|
-
path: linkedPath,
|
|
199
|
-
linked_by_count: linkedIds.length,
|
|
200
|
-
linked_item_ids: linkedIds,
|
|
201
|
-
};
|
|
202
|
-
});
|
|
203
|
-
}
|
|
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]="c472c425-e416-5ea3-b562-6a5aa7642b1d")}catch(e){}}();
|
|
3
|
+
import { renameArtifactsResultKey, runLinkedArtifacts, } from "./linked-artifacts.js";
|
|
204
4
|
export async function runDocs(id, options, global) {
|
|
205
|
-
const
|
|
206
|
-
|
|
207
|
-
if (!(await pathExists(getSettingsPath(pmRoot)))) {
|
|
208
|
-
throw new PmCliError(`Tracker is not initialized at ${pmRoot}. Run pm init first.`, EXIT_CODE.NOT_FOUND);
|
|
209
|
-
}
|
|
210
|
-
const settings = await readSettings(pmRoot);
|
|
211
|
-
const typeRegistry = resolveItemTypeRegistry(settings, getActiveExtensionRegistrations());
|
|
212
|
-
const resolvedAdds = await stdinResolver.resolveList(options.add, "--add");
|
|
213
|
-
const resolvedAddGlobs = await stdinResolver.resolveList(options.addGlob, "--add-glob");
|
|
214
|
-
const resolvedRemoves = await stdinResolver.resolveList(options.remove, "--remove");
|
|
215
|
-
const resolvedMigrations = await stdinResolver.resolveList(options.migrate, "--migrate");
|
|
216
|
-
const parsedAdds = parseAddEntries(resolvedAdds);
|
|
217
|
-
const addGlobs = parseAddGlobEntries(resolvedAddGlobs);
|
|
218
|
-
const expandedGlobAdds = await expandAddGlobEntries(addGlobs);
|
|
219
|
-
const adds = [...parsedAdds, ...expandedGlobAdds];
|
|
220
|
-
const removes = parseRemoveEntries(resolvedRemoves);
|
|
221
|
-
const migrations = parseMigrateEntries(resolvedMigrations);
|
|
222
|
-
const shouldMutate = adds.length > 0 || removes.length > 0 || migrations.length > 0;
|
|
223
|
-
if (!shouldMutate) {
|
|
224
|
-
const located = await locateItem(pmRoot, id, settings.id_prefix, settings.item_format, typeRegistry.type_to_folder);
|
|
225
|
-
if (!located) {
|
|
226
|
-
throw new PmCliError(`Item ${id} not found`, EXIT_CODE.NOT_FOUND);
|
|
227
|
-
}
|
|
228
|
-
const loaded = await readLocatedItem(located, { schema: settings.schema });
|
|
229
|
-
const docs = loaded.document.metadata.docs ?? [];
|
|
230
|
-
return {
|
|
231
|
-
id: located.id,
|
|
232
|
-
docs,
|
|
233
|
-
changed: false,
|
|
234
|
-
count: docs.length,
|
|
235
|
-
validation: options.validatePaths ? await validateLinkedDocPaths(docs.map((entry) => entry.path)) : undefined,
|
|
236
|
-
audit: options.audit
|
|
237
|
-
? buildLinkedDocAudit(docs.map((entry) => entry.path), (await listAllFrontMatter(pmRoot, settings.item_format, typeRegistry.type_to_folder, undefined, settings.schema)).map((entry) => ({
|
|
238
|
-
id: entry.id,
|
|
239
|
-
docs: entry.docs,
|
|
240
|
-
})))
|
|
241
|
-
: undefined,
|
|
242
|
-
};
|
|
243
|
-
}
|
|
244
|
-
const author = resolveAuthor(options.author, settings.author_default);
|
|
245
|
-
const result = await mutateItem({
|
|
246
|
-
pmRoot,
|
|
247
|
-
settings,
|
|
248
|
-
id,
|
|
5
|
+
const result = await runLinkedArtifacts(id, options, global, {
|
|
6
|
+
metadataKey: "docs",
|
|
249
7
|
op: "docs_add",
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
force: options.force,
|
|
253
|
-
mutate(document) {
|
|
254
|
-
const next = [...(document.metadata.docs ?? [])];
|
|
255
|
-
let migrationCount = 0;
|
|
256
|
-
if (migrations.length > 0) {
|
|
257
|
-
for (let index = 0; index < next.length; index += 1) {
|
|
258
|
-
const migratedPath = applyPathMigrations(next[index].path, migrations);
|
|
259
|
-
if (migratedPath !== next[index].path) {
|
|
260
|
-
next[index] = { ...next[index], path: migratedPath };
|
|
261
|
-
migrationCount += 1;
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
const migratedAdds = adds.map((entry) => {
|
|
266
|
-
const migratedPath = applyPathMigrations(entry.path, migrations);
|
|
267
|
-
if (migratedPath !== entry.path) {
|
|
268
|
-
migrationCount += 1;
|
|
269
|
-
}
|
|
270
|
-
return {
|
|
271
|
-
...entry,
|
|
272
|
-
path: migratedPath,
|
|
273
|
-
};
|
|
274
|
-
});
|
|
275
|
-
const migratedRemoves = removes.map((entry) => applyPathMigrations(entry, migrations));
|
|
276
|
-
for (const add of migratedAdds) {
|
|
277
|
-
const exists = next.some((entry) => entry.path === add.path && entry.scope === add.scope);
|
|
278
|
-
if (!exists) {
|
|
279
|
-
next.push(add);
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
if (migratedRemoves.length > 0) {
|
|
283
|
-
for (let i = next.length - 1; i >= 0; i -= 1) {
|
|
284
|
-
if (migratedRemoves.includes(next[i].path)) {
|
|
285
|
-
next.splice(i, 1);
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
const deduped = sortLinkedDocs([...new Map(next.map((entry) => [docKey(entry), entry])).values()].map((entry) => ({
|
|
290
|
-
...entry,
|
|
291
|
-
note: entry.note?.trim() || undefined,
|
|
292
|
-
})));
|
|
293
|
-
if (deduped.length > 0) {
|
|
294
|
-
document.metadata.docs = deduped;
|
|
295
|
-
}
|
|
296
|
-
else {
|
|
297
|
-
delete document.metadata.docs;
|
|
298
|
-
}
|
|
299
|
-
return { changedFields: ["docs"], warnings: migrationCount > 0 ? [`path_migrations_applied:${migrationCount}`] : [] };
|
|
300
|
-
},
|
|
8
|
+
bareNoun: "doc",
|
|
9
|
+
supportsAppendStable: false,
|
|
301
10
|
});
|
|
302
|
-
|
|
303
|
-
const migrationWarning = result.warnings.find((warning) => warning.startsWith("path_migrations_applied:"));
|
|
304
|
-
const migrationCount = migrationWarning ? Number(migrationWarning.split(":")[1] ?? "0") : 0;
|
|
305
|
-
const allItems = options.audit
|
|
306
|
-
? (await listAllFrontMatter(pmRoot, settings.item_format, typeRegistry.type_to_folder, undefined, settings.schema)).map((entry) => ({
|
|
307
|
-
id: entry.id,
|
|
308
|
-
docs: entry.docs,
|
|
309
|
-
}))
|
|
310
|
-
: [];
|
|
311
|
-
return {
|
|
312
|
-
id: result.item.id,
|
|
313
|
-
docs,
|
|
314
|
-
changed: true,
|
|
315
|
-
count: docs.length,
|
|
316
|
-
migrations_applied: migrationCount > 0 ? migrationCount : undefined,
|
|
317
|
-
validation: options.validatePaths ? await validateLinkedDocPaths(docs.map((entry) => entry.path)) : undefined,
|
|
318
|
-
audit: options.audit ? buildLinkedDocAudit(docs.map((entry) => entry.path), allItems) : undefined,
|
|
319
|
-
};
|
|
11
|
+
return renameArtifactsResultKey(result, "docs");
|
|
320
12
|
}
|
|
321
13
|
//# sourceMappingURL=docs.js.map
|
|
322
|
-
//# debugId=
|
|
14
|
+
//# debugId=c472c425-e416-5ea3-b562-6a5aa7642b1d
|