@unbrained/pm-cli 2026.9.6 → 2026.9.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/skills/pm-developer/SKILL.md +12 -4
- package/.agents/skills/pm-developer/references/MULTI_AGENT_MERGE.md +19 -10
- package/.agents/skills/pm-extensions/SKILL.md +6 -0
- package/.agents/skills/pm-sdk/SKILL.md +11 -2
- package/.agents/skills/pm-user/SKILL.md +5 -0
- package/.agents/skills/pm-user/references/ECOSYSTEM_PLANNING.md +95 -0
- package/.claude-plugin/marketplace.json +2 -2
- package/CHANGELOG.md +218 -182
- package/dist/cli/after-command-context-usage.js +1 -48
- package/dist/cli/argv-utils.js +1 -40
- package/dist/cli/bootstrap-args.js +1 -9
- package/dist/cli/bundle-integrity.js +2 -110
- package/dist/cli/commander-usage.js +11 -771
- package/dist/cli/commands/activity.js +1 -9
- package/dist/cli/commands/aggregate.js +1 -5
- package/dist/cli/commands/append.js +1 -5
- package/dist/cli/commands/claim.js +1 -5
- package/dist/cli/commands/close-many.js +1 -5
- package/dist/cli/commands/close.js +1 -9
- package/dist/cli/commands/comments.js +1 -5
- package/dist/cli/commands/config.js +1 -9
- package/dist/cli/commands/context.js +1 -9
- package/dist/cli/commands/contracts.js +1 -5
- package/dist/cli/commands/copy.js +1 -9
- package/dist/cli/commands/create.js +1 -9
- package/dist/cli/commands/delete.js +1 -9
- package/dist/cli/commands/deps.js +1 -9
- package/dist/cli/commands/docs.js +1 -9
- package/dist/cli/commands/duplicates.js +1 -9
- package/dist/cli/commands/eval.js +1 -9
- package/dist/cli/commands/extension/describe.js +1 -5
- package/dist/cli/commands/extension/scaffold.js +1 -5
- package/dist/cli/commands/extension/shared.js +1 -5
- package/dist/cli/commands/extension.js +1 -9
- package/dist/cli/commands/files.js +1 -9
- package/dist/cli/commands/focus.js +1 -9
- package/dist/cli/commands/gc.js +1 -9
- package/dist/cli/commands/get.js +1 -9
- package/dist/cli/commands/graph.js +1 -10
- package/dist/cli/commands/health.js +1 -9
- package/dist/cli/commands/history-compact.js +1 -10
- package/dist/cli/commands/history-redact.js +1 -11
- package/dist/cli/commands/history-repair.js +1 -10
- package/dist/cli/commands/history.js +1 -5
- package/dist/cli/commands/index.js +1 -58
- package/dist/cli/commands/init-agent-guidance.js +1 -9
- package/dist/cli/commands/init.js +1 -9
- package/dist/cli/commands/learnings.js +1 -5
- package/dist/cli/commands/lifecycle-transitions.js +1 -5
- package/dist/cli/commands/list.js +1 -9
- package/dist/cli/commands/merge.js +1 -11
- package/dist/cli/commands/next.js +1 -9
- package/dist/cli/commands/notes.js +1 -5
- package/dist/cli/commands/plan.js +1 -9
- package/dist/cli/commands/profile.js +1 -9
- package/dist/cli/commands/restore.js +1 -9
- package/dist/cli/commands/scheduling-shortcuts.js +1 -9
- package/dist/cli/commands/schema.js +1 -10
- package/dist/cli/commands/search.js +1 -9
- package/dist/cli/commands/stats.js +1 -9
- package/dist/cli/commands/telemetry.js +1 -9
- package/dist/cli/commands/test-all.js +1 -9
- package/dist/cli/commands/test-runs.js +1 -9
- package/dist/cli/commands/test.js +1 -9
- package/dist/cli/commands/update-many.js +1 -5
- package/dist/cli/commands/update.js +1 -9
- package/dist/cli/commands/upgrade.js +1 -5
- package/dist/cli/commands/validate.js +1 -15
- package/dist/cli/context-intent-invocation.js +1 -20
- package/dist/cli/description-stdin.js +1 -17
- package/dist/cli/error-guidance.js +1 -1353
- package/dist/cli/extension-command-help.js +5 -636
- package/dist/cli/extension-command-options.js +1 -427
- package/dist/cli/extension-recovery.js +1 -126
- package/dist/cli/help-content.js +2 -1001
- package/dist/cli/help-json-payload.js +4 -570
- package/dist/cli/main.d.ts +4 -0
- package/dist/cli/main.js +5 -2573
- package/dist/cli/migration-gates.js +1 -289
- package/dist/cli/public.js +1 -20
- package/dist/cli/register-annotations.js +1 -270
- package/dist/cli/register-assurance.js +1 -62
- package/dist/cli/register-files-lookup.js +1 -56
- package/dist/cli/register-history-activity.d.ts +8 -0
- package/dist/cli/register-history-activity.js +2 -0
- package/dist/cli/register-history-author.js +1 -38
- package/dist/cli/register-history-maintenance.d.ts +9 -0
- package/dist/cli/register-history-maintenance.js +2 -0
- package/dist/cli/register-list-query.js +10 -943
- package/dist/cli/register-mutation-options.js +1 -9
- package/dist/cli/register-mutation.js +19 -1893
- package/dist/cli/register-operations.js +1 -920
- package/dist/cli/register-setup.js +1 -716
- package/dist/cli/register-structured-mutation.js +1 -196
- package/dist/cli/registration-helpers.js +1 -5
- package/dist/cli/runtime-compatibility-boundary.js +4 -42
- package/dist/cli/schema-registration-helpers.js +1 -73
- package/dist/cli/search-refresh.js +1 -13
- package/dist/cli/stats-analytics-json.js +1 -68
- package/dist/cli/telemetry-flush.js +1 -10
- package/dist/cli-bundle/bundle-manifest.json +164 -156
- package/dist/cli-bundle/chunks/chunk-3BZZA6A3.js +5 -0
- package/dist/cli-bundle/chunks/chunk-AMRDVX36.js +235 -0
- package/dist/cli-bundle/chunks/chunk-DAM4CBBR.js +2202 -0
- package/dist/cli-bundle/chunks/{chunk-WYRZZ5ZE.js → chunk-DEZPZOQ7.js} +2 -2
- package/dist/cli-bundle/chunks/chunk-FLDWYEND.js +77 -0
- package/dist/cli-bundle/chunks/{chunk-NPN5I67J.js → chunk-G5ADGQ2D.js} +3 -3
- package/dist/cli-bundle/chunks/chunk-JAAEYHUA.js +2 -0
- package/dist/cli-bundle/chunks/{chunk-JX4DH4WC.js → chunk-KR3RP4FH.js} +3 -3
- package/dist/cli-bundle/chunks/chunk-LEZOUXG6.js +2 -0
- package/dist/cli-bundle/chunks/chunk-NSAPNEYH.js +2 -0
- package/dist/cli-bundle/chunks/chunk-QOEKOECV.js +29 -0
- package/dist/cli-bundle/chunks/chunk-RHSFOMHU.js +2 -0
- package/dist/cli-bundle/chunks/chunk-XOD2PCB6.js +20 -0
- package/dist/cli-bundle/chunks/{chunk-JT6XF6GE.js → chunk-YVEQ2AMO.js} +4 -4
- package/dist/cli-bundle/chunks/register-list-query-KSK3R63M.js +11 -0
- package/dist/cli-bundle/chunks/register-mutation-IQ5C7U6O.js +20 -0
- package/dist/cli-bundle/chunks/{register-operations-I5W3KMGB.js → register-operations-DWVHR2NC.js} +2 -2
- package/dist/cli-bundle/chunks/register-setup-BQ5SVD4B.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-3WRPWLA7.js +3 -0
- package/dist/cli-bundle/focused-chunks/chunk-7MBUII7U.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-COPBO5HW.js +8 -0
- package/dist/cli-bundle/focused-chunks/chunk-DUN4IXYN.js +20 -0
- package/dist/cli-bundle/focused-chunks/{chunk-LIJIA4TY.js → chunk-EE5QSM4Z.js} +3 -3
- package/dist/cli-bundle/focused-chunks/chunk-HJVARYM3.js +6 -0
- package/dist/cli-bundle/focused-chunks/chunk-IAUOUGVR.js +177 -0
- package/dist/cli-bundle/focused-chunks/chunk-KOOMJ54F.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-MZDXX7JY.js +56 -0
- package/dist/cli-bundle/focused-chunks/{chunk-M6PBRFSH.js → chunk-OPFHFGDD.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-QHNETP77.js +9 -0
- package/dist/cli-bundle/focused-chunks/{chunk-3BZEOXLT.js → chunk-RMWES4M6.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-RXT4P5QH.js +10 -0
- package/dist/cli-bundle/focused-chunks/chunk-SDOL6FM2.js +12 -0
- package/dist/cli-bundle/focused-chunks/chunk-SQV4AAUC.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-PEFABF7E.js → chunk-WE3IUNIW.js} +3 -3
- package/dist/cli-bundle/focused-chunks/chunk-YALOUBWJ.js +2 -0
- package/dist/cli-bundle/main.js +20 -20
- package/dist/cli-bundle/sdk-authoring.js +1 -1
- package/dist/cli-bundle/sdk-contracts.js +2 -2
- package/dist/cli-bundle/sdk-core.js +29 -29
- package/dist/cli-bundle/sdk-governance.js +1 -1
- package/dist/cli-bundle/sdk-graph.js +1 -1
- package/dist/cli-bundle/sdk-merge.js +42 -42
- package/dist/cli-bundle/sdk-query.js +1 -1
- package/dist/cli-bundle/sdk-runtime.js +1 -1
- package/dist/cli-bundle/sdk-testing.js +1 -1
- package/dist/cli-bundle/sdk.js +11 -11
- package/dist/cli.js +1 -104
- package/dist/core/checkpoint/checkpoint-gc.js +1 -169
- package/dist/core/checkpoint/mutation-checkpoint.js +2 -133
- package/dist/core/config/nested-settings.js +1 -534
- package/dist/core/config/positional-value.js +1 -109
- package/dist/core/diagnostics/remediation.js +1 -506
- package/dist/core/extensions/activation-summary-markdown.js +2 -145
- package/dist/core/extensions/activation-summary.js +1 -92
- package/dist/core/extensions/activation-transaction.js +1 -46
- package/dist/core/extensions/capability-usage.js +1 -173
- package/dist/core/extensions/command-hook-context.js +1 -13
- package/dist/core/extensions/command-metadata-contract.js +1 -22
- package/dist/core/extensions/command-visibility-tier.js +1 -29
- package/dist/core/extensions/contribution-inventory.js +1 -173
- package/dist/core/extensions/exporter-output-contract.js +1 -66
- package/dist/core/extensions/extension-candidate.js +1 -18
- package/dist/core/extensions/extension-capability-aliases.js +1 -158
- package/dist/core/extensions/extension-hook-runtime.js +1 -699
- package/dist/core/extensions/extension-policy.js +1 -599
- package/dist/core/extensions/extension-registries.js +1 -62
- package/dist/core/extensions/extension-runtime-helpers.js +1 -33
- package/dist/core/extensions/extension-types.js +1 -102
- package/dist/core/extensions/flag-definition-validation.js +1 -52
- package/dist/core/extensions/flag-value-types.js +1 -64
- package/dist/core/extensions/index.js +1 -526
- package/dist/core/extensions/item-field-types.js +1 -39
- package/dist/core/extensions/item-fields.js +1 -261
- package/dist/core/extensions/loader.js +1 -2223
- package/dist/core/extensions/manifest-schema.js +1 -69
- package/dist/core/extensions/module-graph-snapshot.js +1 -33
- package/dist/core/extensions/preflight-ownership.js +1 -41
- package/dist/core/extensions/registration-validation.js +1 -82
- package/dist/core/extensions/registration-values.js +1 -209
- package/dist/core/extensions/reserved-host-flags.js +1 -36
- package/dist/core/extensions/runtime-registrations.js +1 -67
- package/dist/core/extensions/service-ownership.js +1 -19
- package/dist/core/extensions/version-compat.js +1 -216
- package/dist/core/fs/fs-utils.js +2 -158
- package/dist/core/fs/host-environment-errors.js +1 -141
- package/dist/core/fs/index.js +1 -9
- package/dist/core/fs/path-utils.js +1 -17
- package/dist/core/governance/content-fields.js +1 -160
- package/dist/core/governance/issue-codes.js +1 -151
- package/dist/core/governance/metadata-coverage.js +1 -358
- package/dist/core/history/drift-cache.js +3 -72
- package/dist/core/history/drift-scan.js +1 -342
- package/dist/core/history/event-classification.js +1 -109
- package/dist/core/history/event-index.js +8 -784
- package/dist/core/history/history-compact-bulk.js +1 -104
- package/dist/core/history/history-diff.js +1 -158
- package/dist/core/history/history-rewrite.d.ts +6 -1
- package/dist/core/history/history-rewrite.js +1 -107
- package/dist/core/history/history-storage-stats.js +1 -102
- package/dist/core/history/history-stream-policy.js +1 -62
- package/dist/core/history/history.js +2 -617
- package/dist/core/history/identity.js +1 -30
- package/dist/core/history/index.js +1 -9
- package/dist/core/history/projection.js +1 -196
- package/dist/core/history/read.d.ts +9 -0
- package/dist/core/history/read.js +1 -57
- package/dist/core/history/replay.js +2 -439
- package/dist/core/history/version-address.js +1 -32
- package/dist/core/history/workspace-history.js +2 -433
- package/dist/core/io/body-file.js +1 -62
- package/dist/core/io/bulk-ids-input.js +1 -112
- package/dist/core/item/actionability.js +1 -327
- package/dist/core/item/dependency-reference.js +1 -20
- package/dist/core/item/id.js +1 -112
- package/dist/core/item/index.js +1 -12
- package/dist/core/item/item-format-version.js +1 -78
- package/dist/core/item/item-format.js +5 -1473
- package/dist/core/item/item-record.js +1 -23
- package/dist/core/item/item-type-definition.js +1 -133
- package/dist/core/item/parent-reference-policy.js +1 -57
- package/dist/core/item/parse.js +2 -603
- package/dist/core/item/plan-lifecycle.js +1 -19
- package/dist/core/item/priority.js +1 -61
- package/dist/core/item/sprint-release-format.js +1 -38
- package/dist/core/item/status-filter.js +1 -115
- package/dist/core/item/status.js +1 -43
- package/dist/core/item/toon-decode.js +1 -29
- package/dist/core/item/type-registry.js +1 -715
- package/dist/core/item/type-synonyms.js +1 -38
- package/dist/core/lock/index.js +1 -9
- package/dist/core/lock/lock-gc.js +1 -240
- package/dist/core/lock/lock.js +3 -590
- package/dist/core/output/mutation-projection.js +1 -217
- package/dist/core/output/output-control.js +1 -25
- package/dist/core/output/output.js +11 -494
- package/dist/core/output/query-summary.js +1 -58
- package/dist/core/output/tabular.js +1 -77
- package/dist/core/packages/manifest.js +1 -244
- package/dist/core/packages/root.js +1 -84
- package/dist/core/profile/profile-describe.js +1 -83
- package/dist/core/profile/profile-lint.js +1 -415
- package/dist/core/profile/profile-plan.js +0 -0
- package/dist/core/profile/profile-presets.js +1 -370
- package/dist/core/reproducibility/context.js +1 -82
- package/dist/core/schema/fields-file.js +2 -288
- package/dist/core/schema/item-types-file.js +2 -296
- package/dist/core/schema/runtime-field-filters.js +1 -49
- package/dist/core/schema/runtime-field-values.js +1 -313
- package/dist/core/schema/runtime-schema.js +2 -826
- package/dist/core/schema/status-defs-file.js +2 -227
- package/dist/core/schema/status-token.js +1 -31
- package/dist/core/schema/type-inference.js +1 -95
- package/dist/core/schema/type-presets.js +1 -87
- package/dist/core/schema/type-workflows.js +1 -104
- package/dist/core/search/background-refresh.js +2 -286
- package/dist/core/search/bm25.js +1 -146
- package/dist/core/search/cache.js +2 -534
- package/dist/core/search/corpus.js +1 -311
- package/dist/core/search/embedding-batches.js +1 -163
- package/dist/core/search/eval.js +1 -225
- package/dist/core/search/http-client.js +1 -75
- package/dist/core/search/providers.js +1 -242
- package/dist/core/search/relevance.js +1 -244
- package/dist/core/search/semantic-defaults.js +1 -199
- package/dist/core/search/staleness.js +1 -30
- package/dist/core/search/vector-stores.js +2 -664
- package/dist/core/search/vectorization-metadata.js +1 -81
- package/dist/core/sentry/helpers.js +1 -272
- package/dist/core/sentry/instrument.js +1 -387
- package/dist/core/session/session-state.js +1 -260
- package/dist/core/shared/agent-session-context.js +1 -133
- package/dist/core/shared/author.js +1 -1172
- package/dist/core/shared/command-types.js +1 -4
- package/dist/core/shared/conflict-markers.js +1 -31
- package/dist/core/shared/constants.js +1 -405
- package/dist/core/shared/errors.js +1 -20
- package/dist/core/shared/html-entity-decode.js +1 -131
- package/dist/core/shared/index.js +1 -12
- package/dist/core/shared/item-metadata-contract.js +1 -89
- package/dist/core/shared/lazy-module.js +1 -16
- package/dist/core/shared/levenshtein.js +1 -61
- package/dist/core/shared/memo.js +1 -19
- package/dist/core/shared/numeric-parsers.js +1 -20
- package/dist/core/shared/option-alias-visibility.js +1 -67
- package/dist/core/shared/primitives.js +1 -127
- package/dist/core/shared/serial-queue.js +1 -79
- package/dist/core/shared/serialization.js +1 -210
- package/dist/core/shared/split-comma-list.js +1 -30
- package/dist/core/shared/text-normalization.js +1 -38
- package/dist/core/shared/time.js +1 -306
- package/dist/core/store/index.js +1 -12
- package/dist/core/store/item-format-migration.js +1 -125
- package/dist/core/store/item-metadata-cache.js +1 -1116
- package/dist/core/store/item-metadata-query-index.js +9 -394
- package/dist/core/store/item-metadata-read-work.js +1 -43
- package/dist/core/store/item-store.js +1 -693
- package/dist/core/store/paths.d.ts +1 -1
- package/dist/core/store/paths.js +1 -214
- package/dist/core/store/settings-read-cache.js +1 -85
- package/dist/core/store/settings-validator.js +1 -421
- package/dist/core/store/settings.js +3 -1309
- package/dist/core/store/tracker-preflight.js +1 -141
- package/dist/core/telemetry/consent.js +5 -108
- package/dist/core/telemetry/observability.js +1 -246
- package/dist/core/telemetry/runtime.js +4 -1988
- package/dist/core/test/background-runs.js +4 -945
- package/dist/core/test/item-test-run-tracking.js +1 -63
- package/dist/core/test/run-selectors.js +1 -120
- package/dist/core/validate/estimate-defaults.js +1 -89
- package/dist/core/validate/fix-planning.js +1 -189
- package/dist/core/validate/linked-artifact-reference.js +1 -36
- package/dist/core/validate/missing-by-type.js +1 -34
- package/dist/core/validate/missing-link-owners.js +1 -95
- package/dist/core/validate/stale-file-classification.js +1 -82
- package/dist/mcp/http-server.js +5 -448
- package/dist/mcp/legacy-adapter.js +1 -77
- package/dist/mcp/runtime-capabilities.js +1 -200
- package/dist/mcp/server.js +4 -1233
- package/dist/mcp/tool-definitions.js +1 -804
- package/dist/sdk/actionability.js +1 -13
- package/dist/sdk/agent/closed-domain-contracts.js +1 -161
- package/dist/sdk/agent/command-recovery.js +1 -59
- package/dist/sdk/agent/command-suggestions.js +1 -66
- package/dist/sdk/agent/create-option-policy.js +1 -31
- package/dist/sdk/agent/identity-config.js +1 -106
- package/dist/sdk/agent/item-addressing.js +1 -207
- package/dist/sdk/agent/refusal-closure-census.js +1 -151
- package/dist/sdk/agent/refusal-closure.js +1 -133
- package/dist/sdk/agent/refusal-corpus-contracts.js +1 -193
- package/dist/sdk/agent/refusal-reachability.js +1 -593
- package/dist/sdk/agent/subcommand-recovery.js +1 -83
- package/dist/sdk/agent/task-transcript-contracts.js +1 -197
- package/dist/sdk/agent/tracker-preflight-contracts.js +1 -126
- package/dist/sdk/agent-capability-contracts.js +1 -428
- package/dist/sdk/agent-session-context.js +1 -9
- package/dist/sdk/annotations.js +1 -448
- package/dist/sdk/author-attribution.js +1 -468
- package/dist/sdk/authoring.js +1 -20
- package/dist/sdk/cli-bootstrap.js +1 -838
- package/dist/sdk/cli-contracts/agent-output-contracts.d.ts +1 -1
- package/dist/sdk/cli-contracts/agent-output-contracts.js +4 -476
- package/dist/sdk/cli-contracts/bootstrap-command-scanner.js +1 -79
- package/dist/sdk/cli-contracts/command-aliases.d.ts +4 -0
- package/dist/sdk/cli-contracts/command-aliases.js +1 -107
- package/dist/sdk/cli-contracts/command-exit-contracts.js +1 -151
- package/dist/sdk/cli-contracts/commander-mutation-options.js +1 -1081
- package/dist/sdk/cli-contracts/commander-types.js +1 -159
- package/dist/sdk/cli-contracts/completeness.js +1 -393
- package/dist/sdk/cli-contracts/enum-contracts.js +1 -222
- package/dist/sdk/cli-contracts/flag-contracts.js +1 -1947
- package/dist/sdk/cli-contracts/flag-lexicon-contracts.js +1 -347
- package/dist/sdk/cli-contracts/grammar-contracts.js +1 -986
- package/dist/sdk/cli-contracts/registration-helpers.js +7 -990
- package/dist/sdk/cli-contracts/runtime-contracts.d.ts +5 -0
- package/dist/sdk/cli-contracts/runtime-contracts.js +1 -2090
- package/dist/sdk/cli-contracts/schemas/assurance-definition.js +1 -324
- package/dist/sdk/cli-contracts/string-lists.js +1 -16
- package/dist/sdk/cli-contracts/tool-option-contracts.js +1 -461
- package/dist/sdk/cli-contracts/tool-parameter-tables.js +1 -2167
- package/dist/sdk/cli-contracts/tool-schema.d.ts +3 -1
- package/dist/sdk/cli-contracts/tool-schema.js +1 -1664
- package/dist/sdk/cli-contracts/typed-action-inputs.js +1 -4
- package/dist/sdk/cli-contracts.d.ts +1 -1
- package/dist/sdk/cli-contracts.js +1 -17
- package/dist/sdk/cli-program.js +1 -49
- package/dist/sdk/command-line.d.ts +2 -5
- package/dist/sdk/command-line.js +1 -78
- package/dist/sdk/comments.js +1 -133
- package/dist/sdk/compile-cache.js +1 -73
- package/dist/sdk/completion.js +157 -837
- package/dist/sdk/compose.js +1 -1090
- package/dist/sdk/config.js +1 -1204
- package/dist/sdk/context/recency.js +1 -33
- package/dist/sdk/context/semantic-session-attribution.js +1 -82
- package/dist/sdk/context/usage-egress.js +1 -29
- package/dist/sdk/context/usage-ledger.js +3 -185
- package/dist/sdk/context-intent-contracts.js +1 -709
- package/dist/sdk/context-intent-runtime.js +1 -115
- package/dist/sdk/context-packing.js +1 -218
- package/dist/sdk/context-relevance.js +1 -503
- package/dist/sdk/context-signal-store.js +2 -426
- package/dist/sdk/context-usage.js +1 -367
- package/dist/sdk/contracts.js +1 -23
- package/dist/sdk/core-governance.js +1 -14
- package/dist/sdk/core.js +1 -14
- package/dist/sdk/corpus-shape.js +1 -401
- package/dist/sdk/define.js +1 -220
- package/dist/sdk/dependencies.js +1 -718
- package/dist/sdk/dependency-flag-validation.js +1 -156
- package/dist/sdk/dependency-provenance.js +1 -135
- package/dist/sdk/docs.js +1 -14
- package/dist/sdk/duplicates.js +1 -40
- package/dist/sdk/environment/agent-environment.js +1 -466
- package/dist/sdk/environment/host-environment-errors.js +1 -8
- package/dist/sdk/environment/project-runtime-compatibility.js +1 -481
- package/dist/sdk/environment/source-context.js +1 -28
- package/dist/sdk/environment/tracker-preflight.js +1 -9
- package/dist/sdk/error-code-catalog.js +1 -153
- package/dist/sdk/error-runtime.js +1 -58
- package/dist/sdk/errors.js +1 -58
- package/dist/sdk/eval.js +1 -190
- package/dist/sdk/extension/author-manifest.js +1 -92
- package/dist/sdk/extension/bundled-catalog.js +1 -332
- package/dist/sdk/extension/concurrency.js +1 -25
- package/dist/sdk/extension/copy-scope.d.ts +2 -0
- package/dist/sdk/extension/copy-scope.js +2 -0
- package/dist/sdk/extension/custom-field-collisions.js +1 -30
- package/dist/sdk/extension/describe.js +3 -189
- package/dist/sdk/extension/doctor.js +1 -606
- package/dist/sdk/extension/install-plan.d.ts +69 -0
- package/dist/sdk/extension/install-plan.js +2 -0
- package/dist/sdk/extension/install-receipts.d.ts +7 -0
- package/dist/sdk/extension/install-receipts.js +2 -0
- package/dist/sdk/extension/install-runtime.js +3 -313
- package/dist/sdk/extension/install-snapshot.js +1 -66
- package/dist/sdk/extension/install-sources.js +5 -1057
- package/dist/sdk/extension/managed-state.js +2 -252
- package/dist/sdk/extension/migrations.js +2 -174
- package/dist/sdk/extension/output-ownership.js +1 -25
- package/dist/sdk/extension/runtime-summary.js +1 -18
- package/dist/sdk/extension/scaffold.js +4 -2308
- package/dist/sdk/extension/shared.js +1 -147
- package/dist/sdk/extension/source-resolution.js +1 -65
- package/dist/sdk/extension/update-check.js +1 -67
- package/dist/sdk/extension-command-context.js +1 -44
- package/dist/sdk/extension-contracts.js +1 -73
- package/dist/sdk/extension.d.ts +7 -2
- package/dist/sdk/extension.js +1 -2196
- package/dist/sdk/files.js +1 -535
- package/dist/sdk/flag-invocation-contracts.d.ts +0 -5
- package/dist/sdk/flag-invocation-contracts.js +1 -344
- package/dist/sdk/generated/generated-error-code-catalog-part-1.js +1 -2224
- package/dist/sdk/generated/generated-error-code-catalog-part-2.js +1 -2236
- package/dist/sdk/generated-error-code-catalog.js +1 -16
- package/dist/sdk/governance/assurance-action-contracts.js +1 -4
- package/dist/sdk/governance/assurance-action.js +1 -411
- package/dist/sdk/governance/assurance-limits.js +1 -10
- package/dist/sdk/governance/assurance-mutation-error.js +1 -81
- package/dist/sdk/governance/assurance-presets.js +1 -135
- package/dist/sdk/governance/assurance-runtime.js +1 -238
- package/dist/sdk/governance/assurance.js +4 -1182
- package/dist/sdk/governance/boundary-fixtures.js +1 -200
- package/dist/sdk/governance/coverage-assurance.js +1 -60
- package/dist/sdk/governance/defect-recurrence-coverage.js +1 -188
- package/dist/sdk/governance/defect-recurrence-graph.js +1 -120
- package/dist/sdk/governance/defect-recurrence-signals.js +1 -24
- package/dist/sdk/governance/defect-recurrence.js +1 -623
- package/dist/sdk/governance/extension-host-version.js +1 -115
- package/dist/sdk/governance/gc.js +1 -368
- package/dist/sdk/governance/health.js +1 -2367
- package/dist/sdk/governance/hierarchy-validation.js +1 -108
- package/dist/sdk/governance/linked-file-report.js +1 -71
- package/dist/sdk/governance/merge-receipt-history.js +1 -206
- package/dist/sdk/governance/provenance-health.js +1 -282
- package/dist/sdk/governance/reindex.js +4 -761
- package/dist/sdk/governance/stale-work.js +1 -82
- package/dist/sdk/governance/status-role-diagnostics.js +1 -35
- package/dist/sdk/governance/storage-integrity.js +1 -280
- package/dist/sdk/governance/tracked-runtime-cache.js +1 -106
- package/dist/sdk/governance/upgrade.js +2 -327
- package/dist/sdk/governance/validate-history-drift.js +1 -81
- package/dist/sdk/governance/validate-item-reader.js +1 -17
- package/dist/sdk/governance/validate-normalization.js +1 -36
- package/dist/sdk/governance/validate.js +1 -2261
- package/dist/sdk/governance/workspace-position.js +1 -163
- package/dist/sdk/governance.d.ts +1 -0
- package/dist/sdk/governance.js +1 -31
- package/dist/sdk/graph/adapter.js +1 -181
- package/dist/sdk/graph/analytics.js +1 -474
- package/dist/sdk/graph/assembly.js +1 -377
- package/dist/sdk/graph/cache.js +1 -160
- package/dist/sdk/graph/centrality.js +1 -258
- package/dist/sdk/graph/conformance.js +1 -130
- package/dist/sdk/graph/deadline-scheduling.d.ts +90 -0
- package/dist/sdk/graph/deadline-scheduling.js +2 -0
- package/dist/sdk/graph/durable-cache.d.ts +1 -1
- package/dist/sdk/graph/durable-cache.js +1 -361
- package/dist/sdk/graph/governance-contracts.js +1 -34
- package/dist/sdk/graph/governance.d.ts +13 -1
- package/dist/sdk/graph/governance.js +1 -735
- package/dist/sdk/graph/hierarchy-integrity.js +1 -310
- package/dist/sdk/graph/index.d.ts +3 -2
- package/dist/sdk/graph/index.js +1 -26
- package/dist/sdk/graph/lifecycle-coverage.d.ts +32 -0
- package/dist/sdk/graph/lifecycle-coverage.js +2 -0
- package/dist/sdk/graph/mutation-advisory.js +1 -176
- package/dist/sdk/graph/remediation.js +1 -197
- package/dist/sdk/graph/run.d.ts +15 -1
- package/dist/sdk/graph/run.js +1 -768
- package/dist/sdk/graph/scheduling.js +1 -124
- package/dist/sdk/graph/traversal.js +1 -284
- package/dist/sdk/graph/workspace-relationship-kind-registry.js +1 -27
- package/dist/sdk/graph.js +1 -15
- package/dist/sdk/guide-topics.js +1 -707
- package/dist/sdk/guide.js +1 -279
- package/dist/sdk/history/maintenance.d.ts +71 -0
- package/dist/sdk/history/maintenance.js +2 -0
- package/dist/sdk/history/salvage.js +2 -247
- package/dist/sdk/history/subject.d.ts +19 -0
- package/dist/sdk/history/subject.js +2 -0
- package/dist/sdk/history-analytics.js +1 -282
- package/dist/sdk/history-compact.js +1 -527
- package/dist/sdk/history-mcp.js +1 -68
- package/dist/sdk/history-provenance.js +1 -182
- package/dist/sdk/history-read.js +1 -96
- package/dist/sdk/history-redact.d.ts +1 -14
- package/dist/sdk/history-redact.js +1 -643
- package/dist/sdk/history-repair.d.ts +5 -0
- package/dist/sdk/history-repair.js +1 -657
- package/dist/sdk/improvement-ledger-validation.js +1 -62
- package/dist/sdk/improvement-ledger.js +2 -257
- package/dist/sdk/index.d.ts +4 -0
- package/dist/sdk/index.js +1 -183
- package/dist/sdk/init-agent-guidance.js +2 -496
- package/dist/sdk/init.js +2 -820
- package/dist/sdk/invocation-author.js +1 -39
- package/dist/sdk/item-children.js +1 -90
- package/dist/sdk/item-metadata-index.js +1 -15
- package/dist/sdk/item-schedule.js +1 -27
- package/dist/sdk/item-transaction.js +1 -396
- package/dist/sdk/learnings.js +1 -29
- package/dist/sdk/lifecycle/append.js +2 -53
- package/dist/sdk/lifecycle/claim.d.ts +2 -0
- package/dist/sdk/lifecycle/claim.js +1 -242
- package/dist/sdk/lifecycle/close-many.js +1 -438
- package/dist/sdk/lifecycle/close.js +1 -468
- package/dist/sdk/lifecycle/copy.js +1 -212
- package/dist/sdk/lifecycle/create.js +1 -1949
- package/dist/sdk/lifecycle/delete.js +1 -45
- package/dist/sdk/lifecycle/event-validation-messages.js +1 -91
- package/dist/sdk/lifecycle/focus.js +1 -91
- package/dist/sdk/lifecycle/hierarchy-mutation-lock.js +1 -24
- package/dist/sdk/lifecycle/legacy-none-tokens.js +1 -149
- package/dist/sdk/lifecycle/lifecycle-transitions.js +1 -40
- package/dist/sdk/lifecycle/mcp-actions.d.ts +2 -0
- package/dist/sdk/lifecycle/mcp-actions.js +1 -51
- package/dist/sdk/lifecycle/metadata-normalizers.js +1 -46
- package/dist/sdk/lifecycle/mutation-command-options.js +1 -9
- package/dist/sdk/lifecycle/plan.js +1 -1606
- package/dist/sdk/lifecycle/recurrence-parsers.js +1 -147
- package/dist/sdk/lifecycle/reopen.js +1 -68
- package/dist/sdk/lifecycle/repeatable-metadata-parsers.js +1 -143
- package/dist/sdk/lifecycle/restore.d.ts +1 -0
- package/dist/sdk/lifecycle/restore.js +1 -330
- package/dist/sdk/lifecycle/shared-unset-fields.js +1 -295
- package/dist/sdk/lifecycle/update-many.js +1 -861
- package/dist/sdk/lifecycle/update.js +1 -2136
- package/dist/sdk/lifecycle-completion.js +1 -92
- package/dist/sdk/lifecycle-policy.js +1 -120
- package/dist/sdk/linked-artifacts.js +1 -530
- package/dist/sdk/mcp/apps.js +4 -133
- package/dist/sdk/mcp/authorization.js +1 -404
- package/dist/sdk/mcp/discovery.js +1 -494
- package/dist/sdk/mcp/interactions.js +1 -336
- package/dist/sdk/mcp/protocol.d.ts +7 -0
- package/dist/sdk/mcp/protocol.js +1 -184
- package/dist/sdk/mcp/skills.js +1 -389
- package/dist/sdk/mcp/subscriptions.js +1 -211
- package/dist/sdk/mcp/tasks.js +2 -430
- package/dist/sdk/mcp/transport.js +1 -260
- package/dist/sdk/merge/abandoned-receipts.js +1 -46
- package/dist/sdk/merge/driver.js +1 -212
- package/dist/sdk/merge/index.js +1 -16
- package/dist/sdk/merge/install.js +3 -561
- package/dist/sdk/merge/receipt-file-boundary.js +1 -46
- package/dist/sdk/merge/receipt-operation.js +1 -96
- package/dist/sdk/merge/receipt-schema.js +1 -397
- package/dist/sdk/merge/receipts.js +4 -525
- package/dist/sdk/merge/reconcile.js +1 -352
- package/dist/sdk/merge/three-way.js +3 -775
- package/dist/sdk/merge.js +1 -10
- package/dist/sdk/mutation-events.js +1 -292
- package/dist/sdk/mutation-guard.js +1 -216
- package/dist/sdk/notes.js +1 -139
- package/dist/sdk/output-contracts.js +1 -172
- package/dist/sdk/output-projection.js +1 -430
- package/dist/sdk/output-token-accounting.js +1 -140
- package/dist/sdk/output.js +1 -64
- package/dist/sdk/ownership-source.js +1 -21
- package/dist/sdk/package-import-adapters.js +1 -442
- package/dist/sdk/package-migrations.js +1 -20
- package/dist/sdk/package-runtime-options.js +1 -80
- package/dist/sdk/pagination.js +1 -162
- package/dist/sdk/profile.js +1 -454
- package/dist/sdk/provenance.js +1 -258
- package/dist/sdk/public-surface.json +1 -1
- package/dist/sdk/query/activity.js +1 -401
- package/dist/sdk/query/aggregate.d.ts +16 -0
- package/dist/sdk/query/aggregate.js +1 -390
- package/dist/sdk/query/calendar.js +1 -964
- package/dist/sdk/query/complete-list.js +1 -215
- package/dist/sdk/query/context.js +1 -1702
- package/dist/sdk/query/duplicate-candidates.js +1 -70
- package/dist/sdk/query/get.js +1 -450
- package/dist/sdk/query/history.js +1 -186
- package/dist/sdk/query/item-filter-options.js +1 -9
- package/dist/sdk/query/light-metadata.js +1 -18
- package/dist/sdk/query/list-filter-shared.js +1 -81
- package/dist/sdk/query/list.js +1 -1304
- package/dist/sdk/query/multi-value-filters.js +1 -78
- package/dist/sdk/query/next.js +1 -513
- package/dist/sdk/query/parsers.js +1 -44
- package/dist/sdk/query/projection-contracts.js +1 -184
- package/dist/sdk/query/search-contracts.js +1 -230
- package/dist/sdk/query/search-pagination.js +1 -35
- package/dist/sdk/query/search-rendering.js +1 -105
- package/dist/sdk/query/search.js +2 -1987
- package/dist/sdk/query.js +1 -35
- package/dist/sdk/read-output/continuation.js +1 -194
- package/dist/sdk/read-output-budget.js +1 -135
- package/dist/sdk/read-output-contracts.js +1 -1225
- package/dist/sdk/read-output-rows.js +1 -186
- package/dist/sdk/read-output-session.js +1 -208
- package/dist/sdk/relationship-analytics.js +1 -410
- package/dist/sdk/relationship-context.js +1 -284
- package/dist/sdk/relationship-history.js +4 -519
- package/dist/sdk/relationship-kinds/contract.js +1 -22
- package/dist/sdk/relationship-migration.js +1 -77
- package/dist/sdk/relationships.js +1 -579
- package/dist/sdk/reproducibility/process.js +1 -87
- package/dist/sdk/runtime-action-aliases.js +1 -59
- package/dist/sdk/runtime-extended-actions.js +1 -177
- package/dist/sdk/runtime-input.js +1 -614
- package/dist/sdk/runtime-primitives.js +1 -84
- package/dist/sdk/runtime-public-contracts.js +1 -4
- package/dist/sdk/runtime-stats-options.js +1 -38
- package/dist/sdk/runtime.js +1 -1928
- package/dist/sdk/scheduling-shortcuts.js +1 -63
- package/dist/sdk/schema-migration.js +3 -856
- package/dist/sdk/schema.js +1 -1376
- package/dist/sdk/search-refresh-worker.js +1 -18
- package/dist/sdk/similarity-scoring.js +1 -53
- package/dist/sdk/similarity.js +1 -326
- package/dist/sdk/start-task-status.js +1 -14
- package/dist/sdk/stats.js +1 -270
- package/dist/sdk/structured-mutations.js +1 -580
- package/dist/sdk/telemetry-flush.js +1 -13
- package/dist/sdk/telemetry.js +1 -405
- package/dist/sdk/templates.js +2 -292
- package/dist/sdk/test/batch.js +2 -509
- package/dist/sdk/test/entry.js +1 -70
- package/dist/sdk/test/execution.js +6 -2211
- package/dist/sdk/test/linked-command-detection.js +1 -546
- package/dist/sdk/test/measurements.js +1 -91
- package/dist/sdk/test/parsers.js +1 -545
- package/dist/sdk/test/runs.js +1 -193
- package/dist/sdk/test/trust.js +2 -206
- package/dist/sdk/testing.js +4 -1391
- package/dist/sdk/traceability/runtime-files-lookup.js +1 -32
- package/dist/sdk/traceability/source-traceability.js +1 -292
- package/dist/sdk/tracker-root-discovery.js +1 -9
- package/dist/sdk/workspace-contracts-cache.js +1 -28
- package/dist/sdk/workspace-contracts.js +1 -33
- package/dist/sdk/workspace-memory.js +2 -318
- package/dist/sdk/workspace-recipe.js +1 -71
- package/dist/sdk/workspace-snapshot.js +4 -613
- package/dist/sdk/workspace-transaction-gc.js +1 -149
- package/dist/sdk/workspace-transaction.js +2 -363
- package/dist/sdk/workspace.js +3 -127
- package/dist/types/index.js +1 -9
- package/dist/types.js +1 -245
- package/docs/AGENT_GUIDE.md +1 -1
- package/docs/CONTEXT_ALGORITHM_PORTFOLIO.md +167 -0
- package/docs/DIAGNOSTIC_OUTPUT_CONTRACTS.md +9 -3
- package/docs/EXTENSIONS.md +1 -0
- package/docs/HISTORY_MAINTENANCE.md +125 -0
- package/docs/MCP_2026_07_28_CONFORMANCE.md +20 -10
- package/docs/PACKAGE_EVIDENCE.md +92 -0
- package/docs/PLANNING_MEASUREMENTS.md +183 -0
- package/docs/README.md +3 -0
- package/docs/RELEASING.md +1 -0
- package/docs/SCRIPTING.md +21 -0
- package/docs/TESTING.md +23 -0
- package/docs/generated/FLAG_LEXICON_BUDGETS.md +5 -5
- package/docs/generated/REFUSAL_CLOSURE_CENSUS.md +2 -2
- package/marketplace.json +2 -2
- package/package.json +1 -1
- package/packages/pm-beads/package.json +1 -1
- package/packages/pm-calendar/package.json +1 -1
- package/packages/pm-command-kit/package.json +1 -1
- package/packages/pm-digital-twin/package.json +1 -1
- package/packages/pm-governance-audit/package.json +1 -1
- package/packages/pm-guide-shell/package.json +1 -1
- package/packages/pm-kanban/package.json +1 -1
- package/packages/pm-lifecycle-hooks/package.json +1 -1
- package/packages/pm-linked-test-adapters/package.json +1 -1
- package/packages/pm-search-advanced/package.json +1 -1
- package/packages/pm-templates/package.json +1 -1
- package/packages/pm-todos/package.json +1 -1
- package/packages/pm-vcs/package.json +1 -1
- package/plugins/pm-claude/.claude-plugin/plugin.json +1 -1
- package/plugins/pm-codex/.codex-plugin/plugin.json +1 -1
- package/scripts/finalize-build.mjs +45 -3
- package/dist/cli-bundle/chunks/chunk-AZDFJGH6.js +0 -9
- package/dist/cli-bundle/chunks/chunk-BAX2BYUW.js +0 -2111
- package/dist/cli-bundle/chunks/chunk-CKOL5U7J.js +0 -77
- package/dist/cli-bundle/chunks/chunk-OF76PSDQ.js +0 -5
- package/dist/cli-bundle/chunks/chunk-QUWFABDM.js +0 -232
- package/dist/cli-bundle/chunks/chunk-QWRRFYK3.js +0 -2
- package/dist/cli-bundle/chunks/chunk-RWWBOWJ5.js +0 -2
- package/dist/cli-bundle/chunks/chunk-WGAOYSYH.js +0 -40
- package/dist/cli-bundle/chunks/chunk-WI2AYPA7.js +0 -2
- package/dist/cli-bundle/chunks/register-list-query-5JL52D33.js +0 -11
- package/dist/cli-bundle/chunks/register-mutation-ZPG7KMVP.js +0 -20
- package/dist/cli-bundle/chunks/register-setup-H4SVAVX7.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-AL5ON6K6.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-CHC2IDXA.js +0 -6
- package/dist/cli-bundle/focused-chunks/chunk-CK6QFAPZ.js +0 -20
- package/dist/cli-bundle/focused-chunks/chunk-EZR3GHFE.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-H2WJWK7L.js +0 -56
- package/dist/cli-bundle/focused-chunks/chunk-NTPY5GSO.js +0 -3
- package/dist/cli-bundle/focused-chunks/chunk-P5O7MP5Y.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-PDMW2E36.js +0 -177
- package/dist/cli-bundle/focused-chunks/chunk-QTVCLMSZ.js +0 -6
- package/dist/cli-bundle/focused-chunks/chunk-QTZRBUYA.js +0 -8
- package/dist/cli-bundle/focused-chunks/chunk-SGQST3PQ.js +0 -12
- package/dist/cli-bundle/focused-chunks/chunk-UKHASMMP.js +0 -10
- package/dist/cli-bundle/focused-chunks/chunk-ZPEKQHOC.js +0 -2
|
@@ -1,83 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
* @module sdk/governance/stale-work
|
|
3
|
-
*
|
|
4
|
-
* Detects abandoned in-progress work from tracker metadata and append-only
|
|
5
|
-
* history without changing item ownership or lifecycle state.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="376bb9d2-e202-57e7-86c8-d70a7d3fa7ab")}catch(e){}}();
|
|
9
|
-
import path from "node:path";
|
|
10
|
-
import { readHistoryEntries } from "../../core/history/read.js";
|
|
11
|
-
function normalizedStatus(value) {
|
|
12
|
-
return (value ?? "in_progress").trim().toLowerCase().replaceAll("-", "_");
|
|
13
|
-
}
|
|
14
|
-
function latestValidTimestamp(item, historyTimestamp) {
|
|
15
|
-
const candidates = [item.updated_at, historyTimestamp]
|
|
16
|
-
.map((value) => ({ value, time: Date.parse(value ?? "") }))
|
|
17
|
-
.filter((candidate) => typeof candidate.value === "string" && Number.isFinite(candidate.time))
|
|
18
|
-
.sort((left, right) => right.time - left.time);
|
|
19
|
-
return candidates[0]?.value ?? item.updated_at;
|
|
20
|
-
}
|
|
21
|
-
/** Classify stale unclaimed in-progress items without filesystem access. */
|
|
22
|
-
export function inspectStaleInProgressItems(items, options) {
|
|
23
|
-
const thresholdHours = Math.max(1, Math.trunc(options.threshold_hours));
|
|
24
|
-
const nowMs = (options.now ?? new Date()).getTime();
|
|
25
|
-
const inProgressStatus = normalizedStatus(options.in_progress_status);
|
|
26
|
-
const staleItems = [];
|
|
27
|
-
for (const item of items) {
|
|
28
|
-
if (normalizedStatus(String(item.status)) !== inProgressStatus ||
|
|
29
|
-
(item.assignee?.trim().length ?? 0) > 0) {
|
|
30
|
-
continue;
|
|
31
|
-
}
|
|
32
|
-
const lastActivityAt = latestValidTimestamp(item, options.last_history_activity?.(item));
|
|
33
|
-
const lastActivityMs = Date.parse(lastActivityAt);
|
|
34
|
-
if (!Number.isFinite(lastActivityMs)) {
|
|
35
|
-
continue;
|
|
36
|
-
}
|
|
37
|
-
const ageHours = Math.max(0, Math.floor((nowMs - lastActivityMs) / 3_600_000));
|
|
38
|
-
if (ageHours >= thresholdHours) {
|
|
39
|
-
staleItems.push({
|
|
40
|
-
id: item.id,
|
|
41
|
-
last_activity_at: lastActivityAt,
|
|
42
|
-
age_hours: ageHours,
|
|
43
|
-
});
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
staleItems.sort((left, right) => right.age_hours - left.age_hours || left.id.localeCompare(right.id));
|
|
47
|
-
return {
|
|
48
|
-
threshold_hours: thresholdHours,
|
|
49
|
-
count: staleItems.length,
|
|
50
|
-
items: staleItems,
|
|
51
|
-
remediation: "Claim active work with `pm claim <id>` or return abandoned work to open with `pm update <id> --status open`.",
|
|
52
|
-
};
|
|
53
|
-
}
|
|
54
|
-
/** Scan tracker history and metadata for stale unclaimed in-progress work. */
|
|
55
|
-
export async function scanStaleInProgressItems(pmRoot, items, options) {
|
|
56
|
-
const historyTimestamps = new Map();
|
|
57
|
-
await Promise.all(items
|
|
58
|
-
.filter((item) => normalizedStatus(String(item.status)) ===
|
|
59
|
-
normalizedStatus(options.in_progress_status) &&
|
|
60
|
-
(item.assignee?.trim().length ?? 0) === 0)
|
|
61
|
-
.map(async (item) => {
|
|
62
|
-
let history;
|
|
63
|
-
try {
|
|
64
|
-
history = await readHistoryEntries(path.join(pmRoot, "history", `${item.id}.jsonl`), item.id);
|
|
65
|
-
}
|
|
66
|
-
catch {
|
|
67
|
-
return;
|
|
68
|
-
}
|
|
69
|
-
const latest = history
|
|
70
|
-
.map((entry) => entry.ts)
|
|
71
|
-
.filter((timestamp) => Number.isFinite(Date.parse(timestamp)))
|
|
72
|
-
.sort((left, right) => Date.parse(right) - Date.parse(left))[0];
|
|
73
|
-
if (latest) {
|
|
74
|
-
historyTimestamps.set(item.id, latest);
|
|
75
|
-
}
|
|
76
|
-
}));
|
|
77
|
-
return inspectStaleInProgressItems(items, {
|
|
78
|
-
...options,
|
|
79
|
-
last_history_activity: (item) => historyTimestamps.get(item.id),
|
|
80
|
-
});
|
|
81
|
-
}
|
|
1
|
+
!(function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="cdae67c6-8316-5e97-84ca-0be4460ffd57")}catch(e2){}})();import path from"node:path";import{readHistoryEntries}from"../../core/history/read.js";function normalizedStatus(value){return(value??"in_progress").trim().toLowerCase().replaceAll("-","_")}function latestValidTimestamp(item,historyTimestamp){const candidates=[item.updated_at,historyTimestamp].map(value=>({value,time:Date.parse(value??"")})).filter(candidate=>typeof candidate.value==="string"&&Number.isFinite(candidate.time)).sort((left,right)=>right.time-left.time);return candidates[0]?.value??item.updated_at}function inspectStaleInProgressItems(items,options){const thresholdHours=Math.max(1,Math.trunc(options.threshold_hours));const nowMs=(options.now??new Date).getTime();const inProgressStatus=normalizedStatus(options.in_progress_status);const staleItems=[];for(const item of items){if(normalizedStatus(String(item.status))!==inProgressStatus||(item.assignee?.trim().length??0)>0){continue}const lastActivityAt=latestValidTimestamp(item,options.last_history_activity?.(item));const lastActivityMs=Date.parse(lastActivityAt);if(!Number.isFinite(lastActivityMs)){continue}const ageHours=Math.max(0,Math.floor((nowMs-lastActivityMs)/36e5));if(ageHours>=thresholdHours){staleItems.push({id:item.id,last_activity_at:lastActivityAt,age_hours:ageHours})}}staleItems.sort((left,right)=>right.age_hours-left.age_hours||left.id.localeCompare(right.id));return{threshold_hours:thresholdHours,count:staleItems.length,items:staleItems,remediation:"Claim active work with `pm claim <id>` or return abandoned work to open with `pm update <id> --status open`."}}async function scanStaleInProgressItems(pmRoot,items,options){const historyTimestamps=new Map;await Promise.all(items.filter(item=>normalizedStatus(String(item.status))===normalizedStatus(options.in_progress_status)&&(item.assignee?.trim().length??0)===0).map(async item=>{let history;try{history=await readHistoryEntries(path.join(pmRoot,"history",`${item.id}.jsonl`),item.id)}catch{return}const latest=history.map(entry=>entry.ts).filter(timestamp=>Number.isFinite(Date.parse(timestamp))).sort((left,right)=>Date.parse(right)-Date.parse(left))[0];if(latest){historyTimestamps.set(item.id,latest)}}));return inspectStaleInProgressItems(items,{...options,last_history_activity:item=>historyTimestamps.get(item.id)})}export{inspectStaleInProgressItems,scanStaleInProgressItems};
|
|
82
2
|
//# sourceMappingURL=stale-work.js.map
|
|
83
|
-
//# debugId=376bb9d2-e202-57e7-86c8-d70a7d3fa7ab
|
|
@@ -1,36 +1,2 @@
|
|
|
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]="cd7acf28-cb93-516e-9058-54c32625ec26")}catch(e){}}();
|
|
3
|
-
import { normalizeStatusInputWithRegistry, } from "../../core/schema/runtime-schema.js";
|
|
4
|
-
/** Inspect role registration and affected items without mutating the tracker. */
|
|
5
|
-
export function inspectStatusRoleAssignments(statusRegistry, items, itemLimit = 25) {
|
|
6
|
-
const rolelessStatuses = statusRegistry.definitions
|
|
7
|
-
.filter((definition) => definition.roles.length === 0)
|
|
8
|
-
.map((definition) => definition.id)
|
|
9
|
-
.sort((left, right) => left.localeCompare(right));
|
|
10
|
-
const rolelessSet = new Set(rolelessStatuses);
|
|
11
|
-
const affectedItemIds = items
|
|
12
|
-
.filter((item) => {
|
|
13
|
-
const resolved = normalizeStatusInputWithRegistry(item.status, statusRegistry);
|
|
14
|
-
return resolved !== undefined && rolelessSet.has(resolved);
|
|
15
|
-
})
|
|
16
|
-
.map((item) => item.id)
|
|
17
|
-
.sort((left, right) => left.localeCompare(right));
|
|
18
|
-
return {
|
|
19
|
-
roleless_status_count: rolelessStatuses.length,
|
|
20
|
-
roleless_statuses: rolelessStatuses.slice(0, itemLimit),
|
|
21
|
-
roleless_statuses_truncated: rolelessStatuses.length > itemLimit,
|
|
22
|
-
affected_item_count: affectedItemIds.length,
|
|
23
|
-
affected_item_ids: affectedItemIds.slice(0, itemLimit),
|
|
24
|
-
affected_item_ids_truncated: affectedItemIds.length > itemLimit,
|
|
25
|
-
};
|
|
26
|
-
}
|
|
27
|
-
/** Convert role diagnostics into the stable health/validate warning token. */
|
|
28
|
-
export function buildStatusRoleWarnings(diagnostics) {
|
|
29
|
-
return diagnostics.roleless_status_count === 0
|
|
30
|
-
? []
|
|
31
|
-
: [
|
|
32
|
-
`schema_status_missing_lifecycle_role:${diagnostics.roleless_status_count}`,
|
|
33
|
-
];
|
|
34
|
-
}
|
|
1
|
+
!(function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="77ccea6e-a118-53df-94b7-a740bb3d7681")}catch(e2){}})();import{normalizeStatusInputWithRegistry}from"../../core/schema/runtime-schema.js";function inspectStatusRoleAssignments(statusRegistry,items,itemLimit=25){const rolelessStatuses=statusRegistry.definitions.filter(definition=>definition.roles.length===0).map(definition=>definition.id).sort((left,right)=>left.localeCompare(right));const rolelessSet=new Set(rolelessStatuses);const affectedItemIds=items.filter(item=>{const resolved=normalizeStatusInputWithRegistry(item.status,statusRegistry);return resolved!==void 0&&rolelessSet.has(resolved)}).map(item=>item.id).sort((left,right)=>left.localeCompare(right));return{roleless_status_count:rolelessStatuses.length,roleless_statuses:rolelessStatuses.slice(0,itemLimit),roleless_statuses_truncated:rolelessStatuses.length>itemLimit,affected_item_count:affectedItemIds.length,affected_item_ids:affectedItemIds.slice(0,itemLimit),affected_item_ids_truncated:affectedItemIds.length>itemLimit}}function buildStatusRoleWarnings(diagnostics){return diagnostics.roleless_status_count===0?[]:[`schema_status_missing_lifecycle_role:${diagnostics.roleless_status_count}`]}export{buildStatusRoleWarnings,inspectStatusRoleAssignments};
|
|
35
2
|
//# sourceMappingURL=status-role-diagnostics.js.map
|
|
36
|
-
//# debugId=cd7acf28-cb93-516e-9058-54c32625ec26
|
|
@@ -1,281 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
* @module sdk/governance/storage-integrity
|
|
3
|
-
*
|
|
4
|
-
* Post-merge storage-integrity check for `pm validate`: fails the workspace
|
|
5
|
-
* when tracker storage is provably corrupted in ways the ordinary read path
|
|
6
|
-
* silently tolerates — unparseable item documents (skipped by the list scan),
|
|
7
|
-
* history streams containing unresolved merge-conflict markers, deleted items
|
|
8
|
-
* silently resurrected by a delete/modify merge, and configuration or schema
|
|
9
|
-
* files whose parse failure would otherwise fall back to defaults behind a
|
|
10
|
-
* green gate. This is the detection half of the tracker merge-semantics
|
|
11
|
-
* contract; the merge drivers in `sdk/merge` are the prevention half.
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
!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]="59b566d5-1d4f-500b-98e3-004e6f57d2b4")}catch(e){}}();
|
|
15
|
-
import fs from "node:fs/promises";
|
|
16
|
-
import path from "node:path";
|
|
17
|
-
import { readFileIfExists } from "../../core/fs/fs-utils.js";
|
|
18
|
-
import { parseItemDocument, } from "../../core/item/item-format.js";
|
|
19
|
-
import { findFirstMergeConflictMarker } from "../../core/shared/conflict-markers.js";
|
|
20
|
-
import { getSettingsPath, ITEM_FILE_EXTENSIONS, } from "../../core/store/paths.js";
|
|
21
|
-
async function listItemFilesOnDisk(pmRoot, typeToFolder) {
|
|
22
|
-
const folders = [...new Set(Object.values(typeToFolder))];
|
|
23
|
-
const found = [];
|
|
24
|
-
await Promise.all(folders.map(async (folder) => {
|
|
25
|
-
let entries;
|
|
26
|
-
try {
|
|
27
|
-
entries = await fs.readdir(path.join(pmRoot, folder));
|
|
28
|
-
}
|
|
29
|
-
catch {
|
|
30
|
-
return;
|
|
31
|
-
}
|
|
32
|
-
for (const entry of entries) {
|
|
33
|
-
for (const extension of ITEM_FILE_EXTENSIONS) {
|
|
34
|
-
if (entry.toLowerCase().endsWith(extension)) {
|
|
35
|
-
found.push({
|
|
36
|
-
relativePath: `${folder}/${entry}`,
|
|
37
|
-
id: entry.slice(0, -extension.length),
|
|
38
|
-
});
|
|
39
|
-
break;
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
}));
|
|
44
|
-
return found.sort((left, right) => left.relativePath.localeCompare(right.relativePath));
|
|
45
|
-
}
|
|
46
|
-
function scanHistoryStreamContent(accumulator, raw) {
|
|
47
|
-
const { id, relativePath, liveItemIds, out } = accumulator;
|
|
48
|
-
const conflictMarker = findFirstMergeConflictMarker(raw);
|
|
49
|
-
if (conflictMarker) {
|
|
50
|
-
out.conflictMarkers.push({
|
|
51
|
-
id,
|
|
52
|
-
path: relativePath,
|
|
53
|
-
line: conflictMarker.line,
|
|
54
|
-
detail: `unresolved merge conflict marker ${conflictMarker.marker}`,
|
|
55
|
-
});
|
|
56
|
-
return;
|
|
57
|
-
}
|
|
58
|
-
let latestEntry = null;
|
|
59
|
-
const lines = raw
|
|
60
|
-
.split(/\r?\n/)
|
|
61
|
-
.map((line, index) => ({ content: line.trim(), number: index + 1 }))
|
|
62
|
-
.filter((line) => line.content.length > 0);
|
|
63
|
-
for (const line of lines) {
|
|
64
|
-
try {
|
|
65
|
-
const parsed = JSON.parse(line.content);
|
|
66
|
-
if (typeof parsed !== "object" ||
|
|
67
|
-
parsed === null ||
|
|
68
|
-
Array.isArray(parsed)) {
|
|
69
|
-
throw new TypeError("history entry must be an object");
|
|
70
|
-
}
|
|
71
|
-
latestEntry = parsed;
|
|
72
|
-
}
|
|
73
|
-
catch {
|
|
74
|
-
out.unparseable.push({
|
|
75
|
-
id,
|
|
76
|
-
path: relativePath,
|
|
77
|
-
line: line.number,
|
|
78
|
-
detail: "history line is not a valid JSON object",
|
|
79
|
-
});
|
|
80
|
-
return;
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
if (latestEntry === null) {
|
|
84
|
-
return;
|
|
85
|
-
}
|
|
86
|
-
if (latestEntry.op === "delete" && liveItemIds.has(id)) {
|
|
87
|
-
out.resurrected.push({
|
|
88
|
-
id,
|
|
89
|
-
deleted_at: typeof latestEntry.ts === "string" ? latestEntry.ts : "",
|
|
90
|
-
deleted_by: typeof latestEntry.author === "string" ? latestEntry.author : "",
|
|
91
|
-
});
|
|
92
|
-
}
|
|
93
|
-
if (latestEntry.op === "history_repair" &&
|
|
94
|
-
Array.isArray(latestEntry.patch) &&
|
|
95
|
-
latestEntry.patch.length > 0) {
|
|
96
|
-
out.repairReconciliations += 1;
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
/** Describe a filesystem read failure without exposing the absolute workspace path. */
|
|
100
|
-
function describeFileReadFailure(subject, error) {
|
|
101
|
-
const code = typeof error === "object" &&
|
|
102
|
-
error !== null &&
|
|
103
|
-
"code" in error &&
|
|
104
|
-
typeof error.code === "string"
|
|
105
|
-
? error.code
|
|
106
|
-
: "UNKNOWN";
|
|
107
|
-
return `${subject} could not be read (error code: ${code})`;
|
|
108
|
-
}
|
|
109
|
-
async function scanHistoryStreams(pmRoot, liveItemIds) {
|
|
110
|
-
const out = {
|
|
111
|
-
conflictMarkers: [],
|
|
112
|
-
unparseable: [],
|
|
113
|
-
resurrected: [],
|
|
114
|
-
repairReconciliations: 0,
|
|
115
|
-
scanned: 0,
|
|
116
|
-
};
|
|
117
|
-
let entries;
|
|
118
|
-
try {
|
|
119
|
-
entries = await fs.readdir(path.join(pmRoot, "history"));
|
|
120
|
-
}
|
|
121
|
-
catch {
|
|
122
|
-
return out;
|
|
123
|
-
}
|
|
124
|
-
for (const entry of entries.sort((left, right) => left.localeCompare(right))) {
|
|
125
|
-
if (!entry.endsWith(".jsonl")) {
|
|
126
|
-
continue;
|
|
127
|
-
}
|
|
128
|
-
out.scanned += 1;
|
|
129
|
-
let raw;
|
|
130
|
-
try {
|
|
131
|
-
raw = await fs.readFile(path.join(pmRoot, "history", entry), "utf8");
|
|
132
|
-
}
|
|
133
|
-
catch (error) {
|
|
134
|
-
out.unparseable.push({
|
|
135
|
-
id: entry.slice(0, -".jsonl".length),
|
|
136
|
-
path: `history/${entry}`,
|
|
137
|
-
detail: describeFileReadFailure("history stream", error),
|
|
138
|
-
});
|
|
139
|
-
continue;
|
|
140
|
-
}
|
|
141
|
-
scanHistoryStreamContent({
|
|
142
|
-
id: entry.slice(0, -".jsonl".length),
|
|
143
|
-
relativePath: `history/${entry}`,
|
|
144
|
-
liveItemIds,
|
|
145
|
-
out,
|
|
146
|
-
}, raw);
|
|
147
|
-
}
|
|
148
|
-
return out;
|
|
149
|
-
}
|
|
150
|
-
function describeUnparseableJson(raw) {
|
|
151
|
-
const conflictMarker = findFirstMergeConflictMarker(raw);
|
|
152
|
-
if (conflictMarker) {
|
|
153
|
-
return `unresolved merge conflict marker ${conflictMarker.marker} at line ${conflictMarker.line}`;
|
|
154
|
-
}
|
|
155
|
-
try {
|
|
156
|
-
JSON.parse(raw);
|
|
157
|
-
return null;
|
|
158
|
-
}
|
|
159
|
-
catch (error) {
|
|
160
|
-
return `invalid JSON (${String(error)})`;
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
async function scanConfigFiles(pmRoot) {
|
|
164
|
-
const unparseable = [];
|
|
165
|
-
let scanned = 0;
|
|
166
|
-
let settingsRaw = null;
|
|
167
|
-
try {
|
|
168
|
-
settingsRaw = await readFileIfExists(getSettingsPath(pmRoot));
|
|
169
|
-
}
|
|
170
|
-
catch (error) {
|
|
171
|
-
scanned += 1;
|
|
172
|
-
unparseable.push({
|
|
173
|
-
path: "settings.json",
|
|
174
|
-
detail: describeFileReadFailure("configuration file", error),
|
|
175
|
-
});
|
|
176
|
-
}
|
|
177
|
-
if (settingsRaw !== null) {
|
|
178
|
-
scanned += 1;
|
|
179
|
-
const detail = describeUnparseableJson(settingsRaw);
|
|
180
|
-
if (detail !== null) {
|
|
181
|
-
unparseable.push({ path: "settings.json", detail });
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
let schemaEntries;
|
|
185
|
-
try {
|
|
186
|
-
schemaEntries = await fs.readdir(path.join(pmRoot, "schema"));
|
|
187
|
-
}
|
|
188
|
-
catch {
|
|
189
|
-
return { scanned, unparseable };
|
|
190
|
-
}
|
|
191
|
-
for (const entry of schemaEntries.sort((left, right) => left.localeCompare(right))) {
|
|
192
|
-
if (!entry.endsWith(".json")) {
|
|
193
|
-
continue;
|
|
194
|
-
}
|
|
195
|
-
scanned += 1;
|
|
196
|
-
let raw;
|
|
197
|
-
try {
|
|
198
|
-
raw = await fs.readFile(path.join(pmRoot, "schema", entry), "utf8");
|
|
199
|
-
}
|
|
200
|
-
catch (error) {
|
|
201
|
-
unparseable.push({
|
|
202
|
-
path: `schema/${entry}`,
|
|
203
|
-
detail: describeFileReadFailure("configuration file", error),
|
|
204
|
-
});
|
|
205
|
-
continue;
|
|
206
|
-
}
|
|
207
|
-
const detail = describeUnparseableJson(raw);
|
|
208
|
-
if (detail !== null) {
|
|
209
|
-
unparseable.push({ path: `schema/${entry}`, detail });
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
return { scanned, unparseable };
|
|
213
|
-
}
|
|
214
|
-
/**
|
|
215
|
-
* Scan tracker storage for integrity failures the ordinary read path masks.
|
|
216
|
-
* `parsedItemIds` are the ids the standard cached list scan successfully
|
|
217
|
-
* parsed; any on-disk item file whose id is missing from that set is an
|
|
218
|
-
* unreadable document that `pm get` would hard-error on while list-based
|
|
219
|
-
* commands silently skip it.
|
|
220
|
-
*/
|
|
221
|
-
export async function scanStorageIntegrity(pmRoot, parsedItemIds, typeToFolder, itemParseOptions = {}) {
|
|
222
|
-
const itemFiles = await listItemFilesOnDisk(pmRoot, typeToFolder);
|
|
223
|
-
const idsOnDisk = new Set(itemFiles.map((file) => file.id));
|
|
224
|
-
const pathsById = new Map();
|
|
225
|
-
for (const file of itemFiles) {
|
|
226
|
-
const paths = pathsById.get(file.id);
|
|
227
|
-
if (paths === undefined) {
|
|
228
|
-
pathsById.set(file.id, [file.relativePath]);
|
|
229
|
-
}
|
|
230
|
-
else {
|
|
231
|
-
paths.push(file.relativePath);
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
const duplicateItemIds = [...pathsById.entries()]
|
|
235
|
-
.filter(([, paths]) => paths.length > 1)
|
|
236
|
-
.map(([id, paths]) => ({
|
|
237
|
-
id,
|
|
238
|
-
paths: [...paths].sort((left, right) => left.localeCompare(right)),
|
|
239
|
-
}))
|
|
240
|
-
.sort((left, right) => left.id.localeCompare(right.id));
|
|
241
|
-
const unreadableItemFiles = (await Promise.all(itemFiles.map(async (file) => {
|
|
242
|
-
if (!parsedItemIds.has(file.id)) {
|
|
243
|
-
return { path: file.relativePath, id: file.id };
|
|
244
|
-
}
|
|
245
|
-
try {
|
|
246
|
-
const absolutePath = path.join(pmRoot, file.relativePath);
|
|
247
|
-
parseItemDocument(await fs.readFile(absolutePath, "utf8"), {
|
|
248
|
-
format: absolutePath.toLowerCase().endsWith(".md")
|
|
249
|
-
? "json_markdown"
|
|
250
|
-
: "toon",
|
|
251
|
-
schema: itemParseOptions.schema,
|
|
252
|
-
extensionFieldNames: itemParseOptions.extensionFieldNames,
|
|
253
|
-
});
|
|
254
|
-
return null;
|
|
255
|
-
}
|
|
256
|
-
catch {
|
|
257
|
-
return { path: file.relativePath, id: file.id };
|
|
258
|
-
}
|
|
259
|
-
}))).filter((row) => row !== null);
|
|
260
|
-
// "Live" for resurrection detection means an item file exists on disk —
|
|
261
|
-
// deleted items keep their history stream but lose the document, so a
|
|
262
|
-
// delete-terminated stream is only suspicious when the document is back.
|
|
263
|
-
const historyScan = await scanHistoryStreams(pmRoot, idsOnDisk);
|
|
264
|
-
const configScan = await scanConfigFiles(pmRoot);
|
|
265
|
-
return {
|
|
266
|
-
item_files_on_disk: itemFiles.length,
|
|
267
|
-
item_ids_on_disk: idsOnDisk.size,
|
|
268
|
-
parsed_items: parsedItemIds.size,
|
|
269
|
-
unreadable_item_files: unreadableItemFiles,
|
|
270
|
-
duplicate_item_ids: duplicateItemIds,
|
|
271
|
-
history_streams_scanned: historyScan.scanned,
|
|
272
|
-
history_conflict_marker_streams: historyScan.conflictMarkers,
|
|
273
|
-
history_unparseable_streams: historyScan.unparseable,
|
|
274
|
-
resurrected_items: historyScan.resurrected,
|
|
275
|
-
history_repair_reconciliations: historyScan.repairReconciliations,
|
|
276
|
-
config_files_scanned: configScan.scanned,
|
|
277
|
-
unparseable_config_files: configScan.unparseable,
|
|
278
|
-
};
|
|
279
|
-
}
|
|
1
|
+
!(function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="7a24fc6d-8be3-5128-977f-f28842040050")}catch(e2){}})();import fs from"node:fs/promises";import path from"node:path";import{readFileIfExists}from"../../core/fs/fs-utils.js";import{parseItemDocument}from"../../core/item/item-format.js";import{findFirstMergeConflictMarker}from"../../core/shared/conflict-markers.js";import{getSettingsPath,ITEM_FILE_EXTENSIONS}from"../../core/store/paths.js";async function listItemFilesOnDisk(pmRoot,typeToFolder){const folders=[...new Set(Object.values(typeToFolder))];const found=[];await Promise.all(folders.map(async folder=>{let entries;try{entries=await fs.readdir(path.join(pmRoot,folder))}catch{return}for(const entry of entries){for(const extension of ITEM_FILE_EXTENSIONS){if(entry.toLowerCase().endsWith(extension)){found.push({relativePath:`${folder}/${entry}`,id:entry.slice(0,-extension.length)});break}}}}));return found.sort((left,right)=>left.relativePath.localeCompare(right.relativePath))}function scanHistoryStreamContent(accumulator,raw){const{id,relativePath,liveItemIds,out}=accumulator;const conflictMarker=findFirstMergeConflictMarker(raw);if(conflictMarker){out.conflictMarkers.push({id,path:relativePath,line:conflictMarker.line,detail:`unresolved merge conflict marker ${conflictMarker.marker}`});return}let latestEntry=null;const lines=raw.split(/\r?\n/).map((line,index)=>({content:line.trim(),number:index+1})).filter(line=>line.content.length>0);for(const line of lines){try{const parsed=JSON.parse(line.content);if(typeof parsed!=="object"||parsed===null||Array.isArray(parsed)){throw new TypeError("history entry must be an object")}latestEntry=parsed}catch{out.unparseable.push({id,path:relativePath,line:line.number,detail:"history line is not a valid JSON object"});return}}if(latestEntry===null){return}if(latestEntry.op==="delete"&&liveItemIds.has(id)){out.resurrected.push({id,deleted_at:typeof latestEntry.ts==="string"?latestEntry.ts:"",deleted_by:typeof latestEntry.author==="string"?latestEntry.author:""})}if(latestEntry.op==="history_repair"&&Array.isArray(latestEntry.patch)&&latestEntry.patch.length>0){out.repairReconciliations+=1}}function describeFileReadFailure(subject,error){const code=typeof error==="object"&&error!==null&&"code"in error&&typeof error.code==="string"?error.code:"UNKNOWN";return`${subject} could not be read (error code: ${code})`}async function scanHistoryStreams(pmRoot,liveItemIds){const out={conflictMarkers:[],unparseable:[],resurrected:[],repairReconciliations:0,scanned:0};let entries;try{entries=await fs.readdir(path.join(pmRoot,"history"))}catch{return out}for(const entry of entries.sort((left,right)=>left.localeCompare(right))){if(!entry.endsWith(".jsonl")){continue}out.scanned+=1;let raw;try{raw=await fs.readFile(path.join(pmRoot,"history",entry),"utf8")}catch(error){out.unparseable.push({id:entry.slice(0,-".jsonl".length),path:`history/${entry}`,detail:describeFileReadFailure("history stream",error)});continue}scanHistoryStreamContent({id:entry.slice(0,-".jsonl".length),relativePath:`history/${entry}`,liveItemIds,out},raw)}return out}function describeUnparseableJson(raw){const conflictMarker=findFirstMergeConflictMarker(raw);if(conflictMarker){return`unresolved merge conflict marker ${conflictMarker.marker} at line ${conflictMarker.line}`}try{JSON.parse(raw);return null}catch(error){return`invalid JSON (${String(error)})`}}async function scanConfigFiles(pmRoot){const unparseable=[];let scanned=0;let settingsRaw=null;try{settingsRaw=await readFileIfExists(getSettingsPath(pmRoot))}catch(error){scanned+=1;unparseable.push({path:"settings.json",detail:describeFileReadFailure("configuration file",error)})}if(settingsRaw!==null){scanned+=1;const detail=describeUnparseableJson(settingsRaw);if(detail!==null){unparseable.push({path:"settings.json",detail})}}let schemaEntries;try{schemaEntries=await fs.readdir(path.join(pmRoot,"schema"))}catch{return{scanned,unparseable}}for(const entry of schemaEntries.sort((left,right)=>left.localeCompare(right))){if(!entry.endsWith(".json")){continue}scanned+=1;let raw;try{raw=await fs.readFile(path.join(pmRoot,"schema",entry),"utf8")}catch(error){unparseable.push({path:`schema/${entry}`,detail:describeFileReadFailure("configuration file",error)});continue}const detail=describeUnparseableJson(raw);if(detail!==null){unparseable.push({path:`schema/${entry}`,detail})}}return{scanned,unparseable}}async function scanStorageIntegrity(pmRoot,parsedItemIds,typeToFolder,itemParseOptions={}){const itemFiles=await listItemFilesOnDisk(pmRoot,typeToFolder);const idsOnDisk=new Set(itemFiles.map(file=>file.id));const pathsById=new Map;for(const file of itemFiles){const paths=pathsById.get(file.id);if(paths===void 0){pathsById.set(file.id,[file.relativePath])}else{paths.push(file.relativePath)}}const duplicateItemIds=[...pathsById.entries()].filter(([,paths])=>paths.length>1).map(([id,paths])=>({id,paths:[...paths].sort((left,right)=>left.localeCompare(right))})).sort((left,right)=>left.id.localeCompare(right.id));const unreadableItemFiles=(await Promise.all(itemFiles.map(async file=>{if(!parsedItemIds.has(file.id)){return{path:file.relativePath,id:file.id}}try{const absolutePath=path.join(pmRoot,file.relativePath);parseItemDocument(await fs.readFile(absolutePath,"utf8"),{format:absolutePath.toLowerCase().endsWith(".md")?"json_markdown":"toon",schema:itemParseOptions.schema,extensionFieldNames:itemParseOptions.extensionFieldNames});return null}catch{return{path:file.relativePath,id:file.id}}}))).filter(row=>row!==null);const historyScan=await scanHistoryStreams(pmRoot,idsOnDisk);const configScan=await scanConfigFiles(pmRoot);return{item_files_on_disk:itemFiles.length,item_ids_on_disk:idsOnDisk.size,parsed_items:parsedItemIds.size,unreadable_item_files:unreadableItemFiles,duplicate_item_ids:duplicateItemIds,history_streams_scanned:historyScan.scanned,history_conflict_marker_streams:historyScan.conflictMarkers,history_unparseable_streams:historyScan.unparseable,resurrected_items:historyScan.resurrected,history_repair_reconciliations:historyScan.repairReconciliations,config_files_scanned:configScan.scanned,unparseable_config_files:configScan.unparseable}}export{scanStorageIntegrity};
|
|
280
2
|
//# sourceMappingURL=storage-integrity.js.map
|
|
281
|
-
//# debugId=59b566d5-1d4f-500b-98e3-004e6f57d2b4
|
|
@@ -1,107 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
* @module sdk/governance/tracked-runtime-cache
|
|
3
|
-
*
|
|
4
|
-
* Detects clone-local tracker runtime artifacts that were committed before the
|
|
5
|
-
* managed `.gitignore` fence existed. The scan is read-only and returns only
|
|
6
|
-
* repository-relative paths so health and validation output stays portable.
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
!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]="d18b51d7-294a-52da-b1cf-a10f24aefbc9")}catch(e){}}();
|
|
10
|
-
import { execFile } from "node:child_process";
|
|
11
|
-
import { realpath } from "node:fs/promises";
|
|
12
|
-
import path from "node:path";
|
|
13
|
-
import { promisify } from "node:util";
|
|
14
|
-
import { PM_GITIGNORE_RUNTIME_DIRECTORIES } from "../workspace.js";
|
|
15
|
-
import { findGitWorkspaceRoot } from "../merge/install.js";
|
|
16
|
-
const execFileAsync = promisify(execFile);
|
|
17
|
-
const GIT_LS_FILES_MAX_BUFFER = 32 * 1024 * 1024;
|
|
18
|
-
const GIT_LS_FILES_TIMEOUT_MS = 10_000;
|
|
19
|
-
const TRACKED_RUNTIME_AUTHORITATIVE_PATHS = [
|
|
20
|
-
"search/eval-queries.json",
|
|
21
|
-
];
|
|
22
|
-
function toPosixPath(value) {
|
|
23
|
-
return value.replaceAll("\\", "/").replace(/\/+$/, "");
|
|
24
|
-
}
|
|
25
|
-
function quoteShellArgument(value) {
|
|
26
|
-
return `'${value.replaceAll("'", "'\\''")}'`;
|
|
27
|
-
}
|
|
28
|
-
/** Resolves a tracker root while retaining a deterministic fallback for missing paths. */
|
|
29
|
-
export async function resolveCanonicalTrackerRoot(pmRoot, resolver = realpath) {
|
|
30
|
-
return resolver(pmRoot).catch(() => path.resolve(pmRoot));
|
|
31
|
-
}
|
|
32
|
-
/**
|
|
33
|
-
* Find tracked files below every clone-local tracker directory.
|
|
34
|
-
*
|
|
35
|
-
* A non-Git tracker, a tracker outside the enclosing repository, or an
|
|
36
|
-
* unavailable Git executable yields an empty scan rather than turning project
|
|
37
|
-
* health into an infrastructure failure.
|
|
38
|
-
*/
|
|
39
|
-
export async function scanTrackedRuntimeCache(pmRoot) {
|
|
40
|
-
const gitWorkspaceRoot = await findGitWorkspaceRoot(pmRoot);
|
|
41
|
-
if (gitWorkspaceRoot === null) {
|
|
42
|
-
return {
|
|
43
|
-
git_workspace_root: null,
|
|
44
|
-
tracker_relative_root: null,
|
|
45
|
-
tracked_paths: [],
|
|
46
|
-
tracked_path_count: 0,
|
|
47
|
-
remediation_command: null,
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
const canonicalPmRoot = await resolveCanonicalTrackerRoot(pmRoot);
|
|
51
|
-
const trackerRelativeRoot = toPosixPath(path.relative(gitWorkspaceRoot, canonicalPmRoot));
|
|
52
|
-
if (trackerRelativeRoot.length === 0) {
|
|
53
|
-
return {
|
|
54
|
-
git_workspace_root: gitWorkspaceRoot,
|
|
55
|
-
tracker_relative_root: null,
|
|
56
|
-
tracked_paths: [],
|
|
57
|
-
tracked_path_count: 0,
|
|
58
|
-
remediation_command: null,
|
|
59
|
-
};
|
|
60
|
-
}
|
|
61
|
-
const runtimeDirectories = PM_GITIGNORE_RUNTIME_DIRECTORIES.map((directory) => `${trackerRelativeRoot}/${toPosixPath(directory)}`);
|
|
62
|
-
try {
|
|
63
|
-
const { stdout } = await execFileAsync("git", [
|
|
64
|
-
"ls-files",
|
|
65
|
-
"-z",
|
|
66
|
-
"--",
|
|
67
|
-
...runtimeDirectories.map((directory) => `:(literal)${directory}`),
|
|
68
|
-
], {
|
|
69
|
-
cwd: gitWorkspaceRoot,
|
|
70
|
-
encoding: "utf8",
|
|
71
|
-
maxBuffer: GIT_LS_FILES_MAX_BUFFER,
|
|
72
|
-
windowsHide: true,
|
|
73
|
-
timeout: GIT_LS_FILES_TIMEOUT_MS,
|
|
74
|
-
});
|
|
75
|
-
const authoritativePaths = new Set(TRACKED_RUNTIME_AUTHORITATIVE_PATHS.map((relativePath) => `${trackerRelativeRoot}/${relativePath}`));
|
|
76
|
-
const trackedPaths = [
|
|
77
|
-
...new Set(stdout
|
|
78
|
-
.split("\0")
|
|
79
|
-
.filter((entry) => entry.length > 0 && !authoritativePaths.has(toPosixPath(entry)))),
|
|
80
|
-
].sort((left, right) => left.localeCompare(right));
|
|
81
|
-
const trackedRuntimeDirectories = runtimeDirectories.filter((directory) => trackedPaths.some((trackedPath) => trackedPath === directory || trackedPath.startsWith(`${directory}/`)));
|
|
82
|
-
return {
|
|
83
|
-
git_workspace_root: gitWorkspaceRoot,
|
|
84
|
-
tracker_relative_root: trackerRelativeRoot,
|
|
85
|
-
tracked_paths: trackedPaths,
|
|
86
|
-
tracked_path_count: trackedPaths.length,
|
|
87
|
-
remediation_command: trackedPaths.length === 0
|
|
88
|
-
? null
|
|
89
|
-
: `git rm --cached -r -- ${trackedRuntimeDirectories
|
|
90
|
-
.map((directory) => quoteShellArgument(`:(literal)${directory}`))
|
|
91
|
-
.join(" ")}`,
|
|
92
|
-
};
|
|
93
|
-
}
|
|
94
|
-
catch {
|
|
95
|
-
/* c8 ignore start -- Git executable failures are environment-specific; the contract is an empty non-blocking scan. */
|
|
96
|
-
return {
|
|
97
|
-
git_workspace_root: gitWorkspaceRoot,
|
|
98
|
-
tracker_relative_root: trackerRelativeRoot,
|
|
99
|
-
tracked_paths: [],
|
|
100
|
-
tracked_path_count: 0,
|
|
101
|
-
remediation_command: null,
|
|
102
|
-
};
|
|
103
|
-
/* c8 ignore stop */
|
|
104
|
-
}
|
|
105
|
-
}
|
|
1
|
+
!(function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="be96ba6f-f848-58bf-8a3b-b6e3d6ab4b7a")}catch(e2){}})();import{execFile}from"node:child_process";import{realpath}from"node:fs/promises";import path from"node:path";import{promisify}from"node:util";import{PM_GITIGNORE_RUNTIME_DIRECTORIES}from"../workspace.js";import{findGitWorkspaceRoot}from"../merge/install.js";const execFileAsync=promisify(execFile);const GIT_LS_FILES_MAX_BUFFER=32*1024*1024;const GIT_LS_FILES_TIMEOUT_MS=1e4;const TRACKED_RUNTIME_AUTHORITATIVE_PATHS=["search/eval-queries.json"];function toPosixPath(value){return value.replaceAll("\\","/").replace(/\/+$/,"")}function quoteShellArgument(value){return`'${value.replaceAll("'","'\\''")}'`}async function resolveCanonicalTrackerRoot(pmRoot,resolver=realpath){return resolver(pmRoot).catch(()=>path.resolve(pmRoot))}async function scanTrackedRuntimeCache(pmRoot){const gitWorkspaceRoot=await findGitWorkspaceRoot(pmRoot);if(gitWorkspaceRoot===null){return{git_workspace_root:null,tracker_relative_root:null,tracked_paths:[],tracked_path_count:0,remediation_command:null}}const canonicalPmRoot=await resolveCanonicalTrackerRoot(pmRoot);const trackerRelativeRoot=toPosixPath(path.relative(gitWorkspaceRoot,canonicalPmRoot));if(trackerRelativeRoot.length===0){return{git_workspace_root:gitWorkspaceRoot,tracker_relative_root:null,tracked_paths:[],tracked_path_count:0,remediation_command:null}}const runtimeDirectories=PM_GITIGNORE_RUNTIME_DIRECTORIES.map(directory=>`${trackerRelativeRoot}/${toPosixPath(directory)}`);try{const{stdout}=await execFileAsync("git",["ls-files","-z","--",...runtimeDirectories.map(directory=>`:(literal)${directory}`)],{cwd:gitWorkspaceRoot,encoding:"utf8",maxBuffer:GIT_LS_FILES_MAX_BUFFER,windowsHide:true,timeout:GIT_LS_FILES_TIMEOUT_MS});const authoritativePaths=new Set(TRACKED_RUNTIME_AUTHORITATIVE_PATHS.map(relativePath=>`${trackerRelativeRoot}/${relativePath}`));const trackedPaths=[...new Set(stdout.split("\0").filter(entry=>entry.length>0&&!authoritativePaths.has(toPosixPath(entry))))].sort((left,right)=>left.localeCompare(right));const trackedRuntimeDirectories=runtimeDirectories.filter(directory=>trackedPaths.some(trackedPath=>trackedPath===directory||trackedPath.startsWith(`${directory}/`)));return{git_workspace_root:gitWorkspaceRoot,tracker_relative_root:trackerRelativeRoot,tracked_paths:trackedPaths,tracked_path_count:trackedPaths.length,remediation_command:trackedPaths.length===0?null:`git rm --cached -r -- ${trackedRuntimeDirectories.map(directory=>quoteShellArgument(`:(literal)${directory}`)).join(" ")}`}}catch{return{git_workspace_root:gitWorkspaceRoot,tracker_relative_root:trackerRelativeRoot,tracked_paths:[],tracked_path_count:0,remediation_command:null}}}export{resolveCanonicalTrackerRoot,scanTrackedRuntimeCache};
|
|
106
2
|
//# sourceMappingURL=tracked-runtime-cache.js.map
|
|
107
|
-
//# debugId=d18b51d7-294a-52da-b1cf-a10f24aefbc9
|