@unbrained/pm-cli 2026.10.3 → 2026.10.5
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/.claude-plugin/marketplace.json +2 -2
- package/CHANGELOG.md +28 -2
- package/dist/cli/after-command-context-usage.js +1 -1
- package/dist/cli/argv-utils.js +1 -1
- package/dist/cli/bootstrap-args.js +1 -1
- package/dist/cli/bundle-integrity.js +2 -2
- package/dist/cli/command-namespaces.js +1 -1
- package/dist/cli/commander-usage.d.ts +1 -1
- package/dist/cli/commander-usage.js +7 -4
- package/dist/cli/commands/annotations/comments.js +1 -1
- package/dist/cli/commands/annotations/docs.js +1 -1
- package/dist/cli/commands/annotations/files.js +1 -1
- package/dist/cli/commands/annotations/learnings.js +1 -1
- package/dist/cli/commands/annotations/notes.js +1 -1
- package/dist/cli/commands/extension/describe.js +1 -1
- package/dist/cli/commands/extension/extension.js +1 -1
- package/dist/cli/commands/extension/scaffold.js +1 -1
- package/dist/cli/commands/extension/shared.js +1 -1
- package/dist/cli/commands/governance/gc.js +1 -1
- package/dist/cli/commands/governance/health.js +1 -1
- package/dist/cli/commands/governance/telemetry.js +1 -1
- package/dist/cli/commands/governance/validate.js +1 -1
- package/dist/cli/commands/history/activity.js +1 -1
- package/dist/cli/commands/history/history-compact.js +1 -1
- package/dist/cli/commands/history/history-redact.js +1 -1
- package/dist/cli/commands/history/history-repair.js +1 -1
- package/dist/cli/commands/history/history.js +1 -1
- package/dist/cli/commands/history/restore.js +1 -1
- package/dist/cli/commands/lifecycle/append.js +1 -1
- package/dist/cli/commands/lifecycle/claim.js +1 -1
- package/dist/cli/commands/lifecycle/close-many.js +1 -1
- package/dist/cli/commands/lifecycle/close.js +1 -1
- package/dist/cli/commands/lifecycle/copy.js +1 -1
- package/dist/cli/commands/lifecycle/create.js +1 -1
- package/dist/cli/commands/lifecycle/delete.js +1 -1
- package/dist/cli/commands/lifecycle/focus.js +1 -1
- package/dist/cli/commands/lifecycle/plan.js +1 -1
- package/dist/cli/commands/lifecycle/update-many.js +1 -1
- package/dist/cli/commands/lifecycle/update.js +1 -1
- package/dist/cli/commands/query/aggregate.js +1 -1
- package/dist/cli/commands/query/context.js +1 -1
- package/dist/cli/commands/query/deps.js +1 -1
- package/dist/cli/commands/query/duplicates.js +1 -1
- package/dist/cli/commands/query/eval.js +1 -1
- package/dist/cli/commands/query/get.js +1 -1
- package/dist/cli/commands/query/graph.js +1 -1
- package/dist/cli/commands/query/list.js +1 -1
- package/dist/cli/commands/query/next.js +1 -1
- package/dist/cli/commands/query/search.js +1 -1
- package/dist/cli/commands/query/stats.js +1 -1
- package/dist/cli/commands/test/test-all.js +1 -1
- package/dist/cli/commands/test/test-runs.js +1 -1
- package/dist/cli/commands/test/test.js +1 -1
- package/dist/cli/commands/workspace/config.js +1 -1
- package/dist/cli/commands/workspace/contracts.js +1 -1
- package/dist/cli/commands/workspace/init.js +1 -1
- package/dist/cli/commands/workspace/merge.js +1 -1
- package/dist/cli/commands/workspace/profile.js +1 -1
- package/dist/cli/commands/workspace/schema.js +1 -1
- package/dist/cli/commands/workspace/upgrade.js +1 -1
- package/dist/cli/context-intent-invocation.js +1 -1
- package/dist/cli/description-stdin.js +1 -1
- package/dist/cli/error-guidance.js +3 -1
- package/dist/cli/extension-command-help.js +5 -3
- package/dist/cli/extension-command-options.js +1 -1
- package/dist/cli/extension-recovery.js +1 -1
- package/dist/cli/help-content.js +5 -2
- package/dist/cli/help-json-payload.js +6 -3
- package/dist/cli/invocation-profile.js +2 -2
- package/dist/cli/main.js +5 -5
- package/dist/cli/migration-gates.js +1 -1
- package/dist/cli/option-values.js +1 -1
- package/dist/cli/public.js +1 -1
- package/dist/cli/register-annotations.js +1 -1
- package/dist/cli/register-assurance.js +1 -1
- package/dist/cli/register-files-lookup.js +1 -1
- package/dist/cli/register-history-activity.js +1 -1
- package/dist/cli/register-history-author.js +1 -1
- package/dist/cli/register-history-maintenance.js +2 -2
- package/dist/cli/register-list-query.js +10 -10
- package/dist/cli/register-mutation-options.js +1 -1
- package/dist/cli/register-mutation.js +2 -2
- package/dist/cli/register-operations.js +1 -1
- package/dist/cli/register-setup.js +1 -1
- package/dist/cli/register-structured-mutation.js +1 -1
- package/dist/cli/registration-helpers.js +1 -1
- package/dist/cli/runtime/activation.js +1 -1
- package/dist/cli/runtime/invocation-options.js +1 -1
- package/dist/cli/runtime/projection-retry.js +1 -1
- package/dist/cli/runtime/selection.js +1 -1
- package/dist/cli/runtime/telemetry-outcome.js +1 -1
- package/dist/cli/runtime-compatibility-boundary.d.ts +1 -1
- package/dist/cli/runtime-compatibility-boundary.js +4 -4
- package/dist/cli/schema/registration.js +2 -2
- package/dist/cli/schema-registration-helpers.js +1 -1
- package/dist/cli/search-refresh.js +1 -1
- package/dist/cli/stats-analytics-json.js +1 -1
- package/dist/cli/telemetry-flush.js +1 -1
- package/dist/cli-bundle/bundle-manifest.json +162 -162
- package/dist/cli-bundle/chunks/chunk-3CYOBJUK.js +3 -0
- package/dist/cli-bundle/chunks/chunk-5MNOWZPN.js +3 -0
- package/dist/cli-bundle/chunks/chunk-AJ7H6XUF.js +20 -0
- package/dist/cli-bundle/chunks/chunk-D332RXZ7.js +80 -0
- package/dist/cli-bundle/chunks/chunk-HRJ6G6ZG.js +31 -0
- package/dist/cli-bundle/chunks/chunk-KRVI56QE.js +6 -0
- package/dist/cli-bundle/chunks/chunk-N4YGSG6F.js +238 -0
- package/dist/cli-bundle/chunks/chunk-OOLYASYJ.js +2 -0
- package/dist/cli-bundle/chunks/chunk-R7CG2DB7.js +2 -0
- package/dist/cli-bundle/chunks/chunk-TGMONGWX.js +2 -0
- package/dist/cli-bundle/chunks/chunk-UZ7BIUCI.js +2 -0
- package/dist/cli-bundle/chunks/{chunk-44UGMMQ6.js → chunk-VZ63DEVJ.js} +3 -3
- package/dist/cli-bundle/chunks/chunk-WFZ4UEOB.js +2 -0
- package/dist/cli-bundle/chunks/chunk-YVBRASXO.js +8 -0
- package/dist/cli-bundle/chunks/{chunk-5XKF5SQV.js → chunk-Z66DWDAU.js} +91 -91
- package/dist/cli-bundle/chunks/{register-list-query-DYCGUQEW.js → register-list-query-75QXHIFH.js} +11 -11
- package/dist/cli-bundle/chunks/register-mutation-YS54SCHG.js +20 -0
- package/dist/cli-bundle/chunks/register-operations-6KHZQSYJ.js +2 -0
- package/dist/cli-bundle/chunks/register-setup-RTATEN2M.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-3BIYG72P.js → chunk-2CVX3KR3.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-5C3IDDW7.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-DBD4W4QP.js → chunk-ABV67XCC.js} +3 -3
- package/dist/cli-bundle/focused-chunks/chunk-B5RSLVE6.js +3 -0
- package/dist/cli-bundle/focused-chunks/chunk-C224METM.js +20 -0
- package/dist/cli-bundle/focused-chunks/chunk-CLDPTMQY.js +6 -0
- package/dist/cli-bundle/focused-chunks/chunk-DDRN42PB.js +8 -0
- package/dist/cli-bundle/focused-chunks/{chunk-EJN7DY3B.js → chunk-DOVTUKJQ.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-ECBOPEJE.js +75 -0
- package/dist/cli-bundle/focused-chunks/chunk-GITOYRUW.js +165 -0
- package/dist/cli-bundle/focused-chunks/chunk-GUIF3WVC.js +30 -0
- package/dist/cli-bundle/focused-chunks/chunk-LE4JUCRR.js +3 -0
- package/dist/cli-bundle/focused-chunks/{chunk-HFAW3FJQ.js → chunk-PSXFFQFT.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-RHIH6XIW.js +12 -0
- package/dist/cli-bundle/focused-chunks/chunk-UDYRVBOZ.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-XV5RV4ZT.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-XRSCIYHR.js → chunk-YMU42COG.js} +2 -2
- package/dist/cli-bundle/main.js +28 -28
- 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 +32 -32
- 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 +55 -55
- 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 +10 -10
- package/dist/cli.js +1 -1
- package/dist/core/checkpoint/checkpoint-gc.js +1 -1
- package/dist/core/checkpoint/mutation-checkpoint.js +2 -2
- package/dist/core/config/nested-settings.js +1 -1
- package/dist/core/config/positional-value.js +1 -1
- package/dist/core/diagnostics/remediation.js +1 -1
- package/dist/core/extensions/activation-summary-markdown.js +2 -1
- package/dist/core/extensions/activation-summary.js +1 -1
- package/dist/core/extensions/activation-transaction.js +1 -1
- package/dist/core/extensions/capability-usage.js +1 -1
- package/dist/core/extensions/command-hook-context.js +1 -1
- package/dist/core/extensions/command-metadata-contract.js +1 -1
- package/dist/core/extensions/command-visibility-tier.js +1 -1
- package/dist/core/extensions/contribution-inventory.js +1 -1
- package/dist/core/extensions/exporter-output-contract.js +1 -1
- package/dist/core/extensions/extension-candidate.js +1 -1
- package/dist/core/extensions/extension-capability-aliases.js +1 -1
- package/dist/core/extensions/extension-hook-runtime.js +1 -1
- package/dist/core/extensions/extension-policy.js +1 -1
- package/dist/core/extensions/extension-registries.js +1 -1
- package/dist/core/extensions/extension-runtime-helpers.js +1 -1
- package/dist/core/extensions/extension-types.d.ts +8 -1
- package/dist/core/extensions/extension-types.js +1 -1
- package/dist/core/extensions/flag-definition-validation.js +1 -1
- package/dist/core/extensions/flag-value-types.js +1 -1
- package/dist/core/extensions/index.js +1 -1
- package/dist/core/extensions/item-field-types.js +1 -1
- package/dist/core/extensions/item-fields.js +1 -1
- package/dist/core/extensions/loader.js +1 -1
- package/dist/core/extensions/manifest-parser.js +1 -1
- package/dist/core/extensions/manifest-schema.js +1 -1
- package/dist/core/extensions/module-graph-snapshot.js +1 -1
- package/dist/core/extensions/preflight-ownership.js +1 -1
- package/dist/core/extensions/registration-contracts.js +1 -1
- package/dist/core/extensions/registration-validation.js +1 -1
- package/dist/core/extensions/registration-values.js +1 -1
- package/dist/core/extensions/reserved-host-flags.js +1 -1
- package/dist/core/extensions/runtime-registrations.js +1 -1
- package/dist/core/extensions/service-ownership.js +1 -1
- package/dist/core/extensions/version-compat.js +1 -1
- package/dist/core/fs/atomic-create.js +1 -1
- package/dist/core/fs/fs-utils.js +2 -2
- package/dist/core/fs/host-environment-errors.js +1 -1
- package/dist/core/fs/index.js +1 -1
- package/dist/core/fs/path-utils.js +1 -1
- package/dist/core/governance/content-fields.js +1 -1
- package/dist/core/governance/issue-codes.js +1 -1
- package/dist/core/governance/metadata-coverage.js +1 -1
- package/dist/core/history/digest.js +1 -1
- package/dist/core/history/drift-cache.js +3 -3
- package/dist/core/history/drift-scan.d.ts +4 -0
- package/dist/core/history/drift-scan.js +1 -1
- package/dist/core/history/event-classification.js +1 -1
- package/dist/core/history/event-index.js +8 -7
- package/dist/core/history/history-compact-bulk.js +1 -1
- package/dist/core/history/history-diff.js +1 -1
- package/dist/core/history/history-rewrite.js +1 -1
- package/dist/core/history/history-storage-stats.js +1 -1
- package/dist/core/history/history-stream-policy.js +1 -1
- package/dist/core/history/history.js +2 -2
- package/dist/core/history/identity.js +1 -1
- package/dist/core/history/index.js +1 -1
- package/dist/core/history/operation-contract.js +1 -1
- package/dist/core/history/projection.js +1 -1
- package/dist/core/history/read.js +1 -1
- package/dist/core/history/replay.js +2 -1
- package/dist/core/history/tombstone.js +1 -1
- package/dist/core/history/version-address.js +1 -1
- package/dist/core/history/workspace-history.js +2 -2
- package/dist/core/io/body-file.js +1 -1
- package/dist/core/io/bulk-ids-input.js +2 -1
- package/dist/core/item/actionability.js +1 -1
- package/dist/core/item/dependency-reference.js +1 -1
- package/dist/core/item/id.js +1 -1
- package/dist/core/item/index.js +1 -1
- package/dist/core/item/item-format-version.js +1 -1
- package/dist/core/item/item-format.js +6 -4
- package/dist/core/item/item-record.js +1 -1
- package/dist/core/item/item-type-definition.js +1 -1
- package/dist/core/item/parent-reference-policy.js +1 -1
- package/dist/core/item/parse.js +8 -2
- package/dist/core/item/plan-lifecycle.js +1 -1
- package/dist/core/item/priority.js +1 -1
- package/dist/core/item/sprint-release-format.js +1 -1
- package/dist/core/item/status-filter.js +1 -1
- package/dist/core/item/status.js +1 -1
- package/dist/core/item/toon-decode.js +1 -1
- package/dist/core/item/type-registry.js +1 -1
- package/dist/core/item/type-synonyms.js +1 -1
- package/dist/core/lock/index.js +1 -1
- package/dist/core/lock/lock-gc.js +1 -1
- package/dist/core/lock/lock.js +3 -3
- package/dist/core/output/mutation-projection.js +1 -1
- package/dist/core/output/output-control.js +1 -1
- package/dist/core/output/output.js +22 -10
- package/dist/core/output/query-summary.js +1 -1
- package/dist/core/output/tabular.js +3 -1
- package/dist/core/packages/manifest.js +1 -1
- package/dist/core/packages/root.js +1 -1
- package/dist/core/policy/workflow-policy-schema.js +1 -1
- package/dist/core/policy/workflow-policy-store.js +1 -1
- package/dist/core/policy/workflow-policy.js +1 -1
- package/dist/core/profile/profile-describe.js +1 -1
- package/dist/core/profile/profile-lint.js +1 -1
- package/dist/core/profile/profile-plan.js +1 -1
- package/dist/core/profile/profile-presets.js +25 -1
- package/dist/core/reproducibility/context.js +1 -1
- package/dist/core/schema/fields-file.js +2 -2
- package/dist/core/schema/item-types-file.js +2 -2
- package/dist/core/schema/runtime-field-filters.js +1 -1
- package/dist/core/schema/runtime-field-values.js +1 -1
- package/dist/core/schema/runtime-schema.js +2 -2
- package/dist/core/schema/status-defs-file.js +2 -2
- package/dist/core/schema/status-token.js +1 -1
- package/dist/core/schema/type-inference.js +1 -1
- package/dist/core/schema/type-presets.js +1 -1
- package/dist/core/schema/type-workflows.js +1 -1
- package/dist/core/search/background-refresh.js +2 -2
- package/dist/core/search/bm25.js +1 -1
- package/dist/core/search/cache.js +2 -2
- package/dist/core/search/corpus.js +1 -1
- package/dist/core/search/embedding-batches.js +1 -1
- package/dist/core/search/eval-thresholds.js +1 -1
- package/dist/core/search/eval.js +1 -1
- package/dist/core/search/http-client.js +1 -1
- package/dist/core/search/providers.js +1 -1
- package/dist/core/search/relevance.js +1 -1
- package/dist/core/search/semantic-defaults.js +1 -1
- package/dist/core/search/staleness.js +1 -1
- package/dist/core/search/vector-stores.js +2 -2
- package/dist/core/search/vectorization-metadata.js +1 -1
- package/dist/core/sentry/helpers.js +1 -1
- package/dist/core/sentry/instrument.js +1 -1
- package/dist/core/session/session-state.js +1 -1
- package/dist/core/shared/agent-session-context.js +1 -1
- package/dist/core/shared/author.js +5 -1
- package/dist/core/shared/command-line.js +1 -1
- package/dist/core/shared/command-types.js +1 -1
- package/dist/core/shared/conflict-markers.js +1 -1
- package/dist/core/shared/constants.js +1 -1
- package/dist/core/shared/errors.js +1 -1
- package/dist/core/shared/html-entity-decode.js +1 -1
- package/dist/core/shared/index.js +1 -1
- package/dist/core/shared/item-metadata-contract.js +1 -1
- package/dist/core/shared/lazy-module.js +1 -1
- package/dist/core/shared/levenshtein.js +1 -1
- package/dist/core/shared/memo.js +1 -1
- package/dist/core/shared/numeric-parsers.js +1 -1
- package/dist/core/shared/option-alias-visibility.js +1 -1
- package/dist/core/shared/primitives.js +1 -1
- package/dist/core/shared/secret-rules.js +1 -1
- package/dist/core/shared/serial-queue.js +1 -1
- package/dist/core/shared/serialization.js +1 -1
- package/dist/core/shared/split-comma-list.js +1 -1
- package/dist/core/shared/text-normalization.js +1 -1
- package/dist/core/shared/time.js +2 -1
- package/dist/core/store/index.js +1 -1
- package/dist/core/store/item-format-migration.js +1 -1
- package/dist/core/store/item-metadata-cache.js +1 -1
- package/dist/core/store/item-metadata-query-index.js +7 -7
- package/dist/core/store/item-metadata-read-work.js +1 -1
- package/dist/core/store/item-store.js +1 -1
- package/dist/core/store/paths.js +1 -1
- package/dist/core/store/settings-concurrency.js +1 -1
- package/dist/core/store/settings-read-cache.js +1 -1
- package/dist/core/store/settings-validator.js +1 -1
- package/dist/core/store/settings.d.ts +11 -2
- package/dist/core/store/settings.js +3 -3
- package/dist/core/store/tracker-preflight.js +1 -1
- package/dist/core/telemetry/consent.js +2 -2
- package/dist/core/telemetry/observability.js +1 -1
- package/dist/core/telemetry/policy.js +1 -1
- package/dist/core/telemetry/read-sampling.js +2 -2
- package/dist/core/telemetry/runtime.js +9 -5
- package/dist/core/test/background-runs.js +3 -3
- package/dist/core/test/item-test-run-tracking.js +1 -1
- package/dist/core/test/run-selectors.js +1 -1
- package/dist/core/validate/estimate-defaults.js +1 -1
- package/dist/core/validate/fix-planning.js +1 -1
- package/dist/core/validate/linked-artifact-reference.js +1 -1
- package/dist/core/validate/missing-by-type.js +1 -1
- package/dist/core/validate/missing-link-owners.js +1 -1
- package/dist/core/validate/stale-file-classification.js +1 -1
- package/dist/mcp/http-server.js +6 -4
- package/dist/mcp/legacy-adapter.js +1 -1
- package/dist/mcp/runtime-capabilities.js +1 -1
- package/dist/mcp/server.js +4 -4
- package/dist/mcp/tool-definitions.js +1 -1
- package/dist/sdk/actionability.js +1 -1
- package/dist/sdk/agent/closed-domain-contracts.js +1 -1
- package/dist/sdk/agent/command-recovery.js +1 -1
- package/dist/sdk/agent/command-suggestions.js +1 -1
- package/dist/sdk/agent/create-option-policy.js +1 -1
- package/dist/sdk/agent/identity-config.js +1 -1
- package/dist/sdk/agent/item-addressing.js +1 -1
- package/dist/sdk/agent/refusal-closure-census.js +2 -1
- package/dist/sdk/agent/refusal-closure.js +1 -1
- package/dist/sdk/agent/refusal-corpus-contracts.js +1 -1
- package/dist/sdk/agent/refusal-reachability.js +3 -1
- package/dist/sdk/agent/subcommand-recovery.js +1 -1
- package/dist/sdk/agent/task-transcript-contracts.js +1 -1
- package/dist/sdk/agent/tracker-preflight-contracts.js +1 -1
- package/dist/sdk/agent-capability-contracts.js +3 -1
- package/dist/sdk/agent-session-context.js +1 -1
- package/dist/sdk/annotations.js +1 -1
- package/dist/sdk/author-attribution.js +1 -1
- package/dist/sdk/authoring.js +1 -1
- package/dist/sdk/cli-bootstrap.js +1 -1
- package/dist/sdk/cli-contracts/agent-output-contracts.js +5 -3
- package/dist/sdk/cli-contracts/bootstrap-command-scanner.js +1 -1
- package/dist/sdk/cli-contracts/command-aliases.js +1 -1
- package/dist/sdk/cli-contracts/command-exit-contracts.js +1 -1
- package/dist/sdk/cli-contracts/commander-mutation-options.js +1 -1
- package/dist/sdk/cli-contracts/commander-types.js +1 -1
- package/dist/sdk/cli-contracts/completeness.js +1 -1
- package/dist/sdk/cli-contracts/enum-contracts.js +1 -1
- package/dist/sdk/cli-contracts/flag-contracts.js +1 -1
- package/dist/sdk/cli-contracts/flag-lexicon-contracts.js +2 -1
- package/dist/sdk/cli-contracts/grammar-contracts.js +1 -1
- package/dist/sdk/cli-contracts/registration-helpers.js +7 -7
- package/dist/sdk/cli-contracts/runtime-contracts.js +1 -1
- package/dist/sdk/cli-contracts/schemas/assurance-definition.js +1 -1
- package/dist/sdk/cli-contracts/string-lists.js +1 -1
- package/dist/sdk/cli-contracts/tool-option-contracts.js +1 -1
- package/dist/sdk/cli-contracts/tool-parameter-tables.js +1 -1
- package/dist/sdk/cli-contracts/tool-schema.js +1 -1
- package/dist/sdk/cli-contracts/typed-action-inputs.js +1 -1
- package/dist/sdk/cli-contracts.js +1 -1
- package/dist/sdk/cli-program.js +1 -1
- package/dist/sdk/command-line.js +1 -1
- package/dist/sdk/comments.js +1 -1
- package/dist/sdk/compile-cache.js +1 -1
- package/dist/sdk/completion/bash.js +2 -1
- package/dist/sdk/completion/fish.js +13 -7
- package/dist/sdk/completion/shared.js +1 -1
- package/dist/sdk/completion/zsh.js +14 -8
- package/dist/sdk/completion.js +1 -1
- package/dist/sdk/compose.js +1 -1
- package/dist/sdk/config.js +1 -1
- package/dist/sdk/context/recency.js +1 -1
- package/dist/sdk/context/semantic-session-attribution.js +1 -1
- package/dist/sdk/context/usage-egress.js +1 -1
- package/dist/sdk/context/usage-ledger.js +6 -3
- package/dist/sdk/context-intent-contracts.js +1 -1
- package/dist/sdk/context-intent-runtime.js +1 -1
- package/dist/sdk/context-packing.js +1 -1
- package/dist/sdk/context-relevance.js +1 -1
- package/dist/sdk/context-signal-store.js +2 -2
- package/dist/sdk/context-usage.js +1 -1
- package/dist/sdk/contracts.js +1 -1
- package/dist/sdk/core-governance.js +1 -1
- package/dist/sdk/core.js +1 -1
- package/dist/sdk/corpus-shape.js +1 -1
- package/dist/sdk/define.js +1 -1
- package/dist/sdk/dependencies.js +1 -1
- package/dist/sdk/dependency-flag-validation.js +1 -1
- package/dist/sdk/dependency-provenance.js +1 -1
- package/dist/sdk/docs.js +1 -1
- package/dist/sdk/duplicates.js +1 -1
- package/dist/sdk/environment/agent-environment.js +1 -1
- package/dist/sdk/environment/host-environment-errors.js +1 -1
- package/dist/sdk/environment/project-runtime-compatibility.js +2 -1
- package/dist/sdk/environment/source-context.js +1 -1
- package/dist/sdk/environment/tracker-preflight.js +1 -1
- package/dist/sdk/error-code-catalog.js +1 -1
- package/dist/sdk/error-runtime.js +1 -1
- package/dist/sdk/errors.js +1 -1
- package/dist/sdk/eval.js +1 -1
- package/dist/sdk/extension/author-manifest.js +1 -1
- package/dist/sdk/extension/bundled-catalog.js +1 -1
- package/dist/sdk/extension/concurrency.js +1 -1
- package/dist/sdk/extension/copy-scope.js +1 -1
- package/dist/sdk/extension/custom-field-collisions.js +1 -1
- package/dist/sdk/extension/describe.js +4 -2
- package/dist/sdk/extension/doctor.js +1 -1
- package/dist/sdk/extension/install-plan.js +1 -1
- package/dist/sdk/extension/install-receipts.js +1 -1
- package/dist/sdk/extension/install-runtime.js +3 -3
- package/dist/sdk/extension/install-snapshot.js +1 -1
- package/dist/sdk/extension/install-sources.js +5 -5
- package/dist/sdk/extension/managed-state.js +2 -2
- package/dist/sdk/extension/migrations.js +2 -2
- package/dist/sdk/extension/output-ownership.js +1 -1
- package/dist/sdk/extension/runtime-summary.js +1 -1
- package/dist/sdk/extension/scaffold.js +11 -4
- package/dist/sdk/extension/shared.js +1 -1
- package/dist/sdk/extension/source-resolution.js +1 -1
- package/dist/sdk/extension/static-inventory.js +1 -1
- package/dist/sdk/extension/update-check.js +1 -1
- package/dist/sdk/extension-command-context.js +1 -1
- package/dist/sdk/extension-contracts.js +1 -1
- package/dist/sdk/extension.js +1 -1
- package/dist/sdk/files.js +1 -1
- package/dist/sdk/flag-invocation-contracts.js +1 -1
- package/dist/sdk/generated/generated-error-code-catalog-part-1.js +1 -1
- package/dist/sdk/generated/generated-error-code-catalog-part-2.js +1 -1
- package/dist/sdk/generated-error-code-catalog.js +1 -1
- package/dist/sdk/governance/assurance-action-contracts.js +1 -1
- package/dist/sdk/governance/assurance-action.js +1 -1
- package/dist/sdk/governance/assurance-limits.js +1 -1
- package/dist/sdk/governance/assurance-mutation-error.js +1 -1
- package/dist/sdk/governance/assurance-presets.js +1 -1
- package/dist/sdk/governance/assurance-runtime.js +1 -1
- package/dist/sdk/governance/assurance.js +4 -4
- package/dist/sdk/governance/boundary-fixtures.js +1 -1
- package/dist/sdk/governance/closure-timestamps.js +1 -1
- package/dist/sdk/governance/coverage-assurance.js +1 -1
- package/dist/sdk/governance/defect-recurrence-coverage.js +1 -1
- package/dist/sdk/governance/defect-recurrence-graph.js +1 -1
- package/dist/sdk/governance/defect-recurrence-signals.js +1 -1
- package/dist/sdk/governance/defect-recurrence.js +1 -1
- package/dist/sdk/governance/extension-host-version.js +1 -1
- package/dist/sdk/governance/gc.js +1 -1
- package/dist/sdk/governance/health-merge-evidence.js +1 -1
- package/dist/sdk/governance/health.js +2 -1
- package/dist/sdk/governance/hierarchy-validation.js +1 -1
- package/dist/sdk/governance/linked-file-report.js +1 -1
- package/dist/sdk/governance/merge-receipt-history.js +1 -1
- package/dist/sdk/governance/provenance-health.js +4 -1
- package/dist/sdk/governance/reindex.js +5 -4
- package/dist/sdk/governance/stale-work.js +1 -1
- package/dist/sdk/governance/status-role-diagnostics.js +1 -1
- package/dist/sdk/governance/storage-integrity.js +1 -1
- package/dist/sdk/governance/tracked-runtime-cache.js +1 -1
- package/dist/sdk/governance/upgrade.js +2 -2
- package/dist/sdk/governance/validate-history-drift.js +1 -1
- package/dist/sdk/governance/validate-item-reader.js +1 -1
- package/dist/sdk/governance/validate-normalization.js +1 -1
- package/dist/sdk/governance/validate.js +1 -1
- package/dist/sdk/governance/workflow-completeness.js +1 -1
- package/dist/sdk/governance/workflow-policy.js +3 -3
- package/dist/sdk/governance/workspace-position.js +2 -1
- package/dist/sdk/governance.js +1 -1
- package/dist/sdk/graph/adapter.js +1 -1
- package/dist/sdk/graph/analytics.js +1 -1
- package/dist/sdk/graph/assembly.js +1 -1
- package/dist/sdk/graph/cache.js +1 -1
- package/dist/sdk/graph/centrality.js +1 -1
- package/dist/sdk/graph/conformance.js +1 -1
- package/dist/sdk/graph/deadline-scheduling.js +1 -1
- package/dist/sdk/graph/durable-cache.js +1 -1
- package/dist/sdk/graph/governance-contracts.js +1 -1
- package/dist/sdk/graph/governance.js +1 -1
- package/dist/sdk/graph/hierarchy-integrity.js +1 -1
- package/dist/sdk/graph/index.js +1 -1
- package/dist/sdk/graph/lifecycle-coverage.js +1 -1
- package/dist/sdk/graph/mutation-advisory.js +1 -1
- package/dist/sdk/graph/query-contracts.js +1 -1
- package/dist/sdk/graph/remediation.js +1 -1
- package/dist/sdk/graph/run.js +1 -1
- package/dist/sdk/graph/scheduling.js +1 -1
- package/dist/sdk/graph/traversal.js +1 -1
- package/dist/sdk/graph/workspace-relationship-kind-registry.js +1 -1
- package/dist/sdk/graph.js +1 -1
- package/dist/sdk/guide-topics.js +1 -1
- package/dist/sdk/guide.js +8 -1
- package/dist/sdk/history/attestation-command.js +1 -1
- package/dist/sdk/history/attestation-contract.js +1 -1
- package/dist/sdk/history/attestation-scan.js +1 -1
- package/dist/sdk/history/attestation.js +1 -1
- package/dist/sdk/history/maintenance.js +1 -1
- package/dist/sdk/history/salvage.js +3 -2
- package/dist/sdk/history/subject.js +1 -1
- package/dist/sdk/history-analytics.js +1 -1
- package/dist/sdk/history-compact.js +1 -1
- package/dist/sdk/history-mcp.js +1 -1
- package/dist/sdk/history-provenance.js +1 -1
- package/dist/sdk/history-read.js +1 -1
- package/dist/sdk/history-redact.js +1 -1
- package/dist/sdk/history-repair.js +1 -1
- package/dist/sdk/improvement-ledger-validation.js +1 -1
- package/dist/sdk/improvement-ledger.js +2 -2
- package/dist/sdk/index.js +1 -1
- package/dist/sdk/init-agent-guidance.js +16 -2
- package/dist/sdk/init.js +16 -2
- package/dist/sdk/invocation-author.js +1 -1
- package/dist/sdk/item-children.js +1 -1
- package/dist/sdk/item-metadata-index.js +1 -1
- package/dist/sdk/item-schedule.js +1 -1
- package/dist/sdk/item-transaction.js +1 -1
- package/dist/sdk/learnings.js +1 -1
- package/dist/sdk/lifecycle/append.js +4 -2
- package/dist/sdk/lifecycle/claim.js +1 -1
- package/dist/sdk/lifecycle/close-many.js +1 -1
- package/dist/sdk/lifecycle/close.js +1 -1
- package/dist/sdk/lifecycle/copy.js +1 -1
- package/dist/sdk/lifecycle/create.js +1 -1
- package/dist/sdk/lifecycle/delete.js +1 -1
- package/dist/sdk/lifecycle/event-validation-messages.js +1 -1
- package/dist/sdk/lifecycle/focus.js +1 -1
- package/dist/sdk/lifecycle/hierarchy-mutation-lock.js +1 -1
- package/dist/sdk/lifecycle/legacy-none-tokens.js +1 -1
- package/dist/sdk/lifecycle/lifecycle-transitions.js +1 -1
- package/dist/sdk/lifecycle/mcp-actions.js +1 -1
- package/dist/sdk/lifecycle/metadata-normalizers.js +1 -1
- package/dist/sdk/lifecycle/mutation-command-options.js +1 -1
- package/dist/sdk/lifecycle/plan-mutation-receipt.js +1 -1
- package/dist/sdk/lifecycle/plan.js +1 -1
- package/dist/sdk/lifecycle/recurrence-parsers.js +1 -1
- package/dist/sdk/lifecycle/reopen.js +1 -1
- package/dist/sdk/lifecycle/repeatable-metadata-parsers.js +2 -1
- package/dist/sdk/lifecycle/restore.js +1 -1
- package/dist/sdk/lifecycle/shared-unset-fields.js +1 -1
- package/dist/sdk/lifecycle/task-composition.js +1 -1
- package/dist/sdk/lifecycle/update-many.js +1 -1
- package/dist/sdk/lifecycle/update.js +2 -1
- package/dist/sdk/lifecycle-completion.js +1 -1
- package/dist/sdk/lifecycle-policy.js +1 -1
- package/dist/sdk/linked-artifacts.js +2 -1
- package/dist/sdk/mcp/apps.js +1 -1
- package/dist/sdk/mcp/authorization.js +1 -1
- package/dist/sdk/mcp/discovery.js +1 -1
- package/dist/sdk/mcp/interactions.js +1 -1
- package/dist/sdk/mcp/protocol.js +1 -1
- package/dist/sdk/mcp/skills.js +3 -1
- package/dist/sdk/mcp/subscriptions.js +1 -1
- package/dist/sdk/mcp/tasks.js +2 -2
- package/dist/sdk/mcp/transport.js +1 -1
- package/dist/sdk/merge/abandoned-receipts.js +1 -1
- package/dist/sdk/merge/driver.js +1 -1
- package/dist/sdk/merge/index.js +1 -1
- package/dist/sdk/merge/install.js +4 -2
- package/dist/sdk/merge/receipt-file-boundary.js +1 -1
- package/dist/sdk/merge/receipt-operation.js +1 -1
- package/dist/sdk/merge/receipt-schema.js +1 -1
- package/dist/sdk/merge/receipts.js +4 -4
- package/dist/sdk/merge/reconcile.js +1 -1
- package/dist/sdk/merge/three-way.js +3 -2
- package/dist/sdk/merge/worktree-config.js +1 -1
- package/dist/sdk/merge.js +1 -1
- package/dist/sdk/mutation-events.js +1 -1
- package/dist/sdk/mutation-guard.js +1 -1
- package/dist/sdk/notes.js +1 -1
- package/dist/sdk/output-contracts.js +1 -1
- package/dist/sdk/output-projection.js +1 -1
- package/dist/sdk/output-token-accounting.js +1 -1
- package/dist/sdk/output.js +2 -1
- package/dist/sdk/ownership-source.js +1 -1
- package/dist/sdk/package-import-adapters.js +1 -1
- package/dist/sdk/package-migrations.js +1 -1
- package/dist/sdk/package-runtime-options.js +1 -1
- package/dist/sdk/pagination.js +1 -1
- package/dist/sdk/profile.js +5 -1
- package/dist/sdk/provenance.js +1 -1
- package/dist/sdk/public-surface.json +1 -1
- package/dist/sdk/query/activity.js +1 -1
- package/dist/sdk/query/aggregate.js +1 -1
- package/dist/sdk/query/calendar.js +4 -1
- package/dist/sdk/query/complete-list.js +1 -1
- package/dist/sdk/query/context.js +2 -1
- package/dist/sdk/query/duplicate-candidates.js +1 -1
- package/dist/sdk/query/get.d.ts +14 -2
- package/dist/sdk/query/get.js +1 -1
- package/dist/sdk/query/history.js +1 -1
- package/dist/sdk/query/item-filter-options.js +1 -1
- package/dist/sdk/query/light-metadata.js +1 -1
- package/dist/sdk/query/list-filter-shared.js +1 -1
- package/dist/sdk/query/list.js +1 -1
- package/dist/sdk/query/multi-value-filters.js +1 -1
- package/dist/sdk/query/next-ready-budget.js +1 -1
- package/dist/sdk/query/next.js +2 -1
- package/dist/sdk/query/parsers.js +1 -1
- package/dist/sdk/query/projection-contracts.js +1 -1
- package/dist/sdk/query/search/corpus.js +2 -1
- package/dist/sdk/query/search/filters.js +1 -1
- package/dist/sdk/query/search/input.js +1 -1
- package/dist/sdk/query/search/lexical.js +1 -1
- package/dist/sdk/query/search/response.js +1 -1
- package/dist/sdk/query/search/semantic.js +3 -2
- package/dist/sdk/query/search/types.js +1 -1
- package/dist/sdk/query/search-contracts.js +1 -1
- package/dist/sdk/query/search-pagination.d.ts +1 -1
- package/dist/sdk/query/search-pagination.js +1 -1
- package/dist/sdk/query/search-rendering.js +1 -1
- package/dist/sdk/query/search.js +1 -1
- package/dist/sdk/query/workspace-contracts.js +1 -1
- package/dist/sdk/query.js +1 -1
- package/dist/sdk/read-output/continuation.js +1 -1
- package/dist/sdk/read-output/options.js +1 -1
- package/dist/sdk/read-output/provenance.js +1 -1
- package/dist/sdk/read-output-budget.js +1 -1
- package/dist/sdk/read-output-contracts.js +1 -1
- package/dist/sdk/read-output-rows.js +1 -1
- package/dist/sdk/read-output-session.js +1 -1
- package/dist/sdk/relationship-analytics.js +1 -1
- package/dist/sdk/relationship-context.js +1 -1
- package/dist/sdk/relationship-history.js +7 -4
- package/dist/sdk/relationship-kinds/contract.js +1 -1
- package/dist/sdk/relationship-migration.js +1 -1
- package/dist/sdk/relationships.js +1 -1
- package/dist/sdk/reproducibility/process.js +1 -1
- package/dist/sdk/runtime/actions.js +1 -1
- package/dist/sdk/runtime/context.js +1 -1
- package/dist/sdk/runtime/schema-preview.js +1 -1
- package/dist/sdk/runtime/schema.js +1 -1
- package/dist/sdk/runtime-action-aliases.js +1 -1
- package/dist/sdk/runtime-extended-actions.js +1 -1
- package/dist/sdk/runtime-input.js +1 -1
- package/dist/sdk/runtime-primitives.js +1 -1
- package/dist/sdk/runtime-public-contracts.js +1 -1
- package/dist/sdk/runtime-stats-options.js +1 -1
- package/dist/sdk/runtime.js +1 -1
- package/dist/sdk/scheduling-shortcuts.js +1 -1
- package/dist/sdk/schema-migration.js +4 -3
- package/dist/sdk/schema.js +7 -1
- package/dist/sdk/search-refresh-worker.js +1 -1
- package/dist/sdk/similarity-scoring.js +1 -1
- package/dist/sdk/similarity.js +1 -1
- package/dist/sdk/start-task-status.js +1 -1
- package/dist/sdk/stats.js +1 -1
- package/dist/sdk/structured-mutations.js +1 -1
- package/dist/sdk/telemetry-flush.js +1 -1
- package/dist/sdk/telemetry.js +4 -3
- package/dist/sdk/templates.js +26 -2
- package/dist/sdk/test/batch.js +2 -2
- package/dist/sdk/test/entry.js +1 -1
- package/dist/sdk/test/execution.js +6 -5
- package/dist/sdk/test/json-path.js +1 -1
- package/dist/sdk/test/linked-command-detection.js +1 -1
- package/dist/sdk/test/measurements.js +1 -1
- package/dist/sdk/test/parsers.js +1 -1
- package/dist/sdk/test/runs.js +1 -1
- package/dist/sdk/test/trust.js +2 -2
- package/dist/sdk/test/workspace-snapshot.js +1 -1
- package/dist/sdk/testing.js +7 -4
- package/dist/sdk/traceability/runtime-files-lookup.js +1 -1
- package/dist/sdk/traceability/source-traceability.js +2 -1
- package/dist/sdk/tracker-root-discovery.js +1 -1
- package/dist/sdk/workspace-contracts-cache.js +1 -1
- package/dist/sdk/workspace-contracts.js +1 -1
- package/dist/sdk/workspace-memory.js +2 -2
- package/dist/sdk/workspace-recipe.js +1 -1
- package/dist/sdk/workspace-snapshot.js +5 -4
- package/dist/sdk/workspace-transaction-gc.js +1 -1
- package/dist/sdk/workspace-transaction.js +2 -2
- package/dist/sdk/workspace.js +3 -2
- package/dist/types/index.js +1 -1
- package/dist/types.js +1 -1
- package/docs/AGENT_EVIDENCE_CONSISTENCY.md +88 -0
- package/docs/DIAGNOSTIC_OUTPUT_CONTRACTS.md +25 -0
- package/docs/GET_READ_EVIDENCE.md +68 -0
- package/docs/OUTPUT_PROJECTION_CONTRACTS.md +23 -0
- package/docs/README.md +2 -0
- package/docs/SDK_AUDITED_MUTATIONS.md +35 -0
- package/docs/TESTING.md +8 -0
- package/docs/ecosystem-review-2026-09-28.json +2864 -3157
- 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/extensions/vcs/index.ts +4 -2
- package/packages/pm-vcs/package.json +1 -1
- package/plugins/pm-claude/.claude-plugin/plugin.json +1 -1
- package/plugins/pm-claude/package.json +2 -2
- package/plugins/pm-codex/.codex-plugin/plugin.json +1 -1
- package/plugins/pm-codex/package.json +2 -2
- package/plugins/pm-codex/plugin.json +1 -1
- package/scripts/finalize-build.mjs +3 -2
- package/dist/cli-bundle/chunks/chunk-3AF2R3Y6.js +0 -6
- package/dist/cli-bundle/chunks/chunk-6ST3SCQ6.js +0 -2
- package/dist/cli-bundle/chunks/chunk-6Z4IV2MC.js +0 -8
- package/dist/cli-bundle/chunks/chunk-DEZPZOQ7.js +0 -2
- package/dist/cli-bundle/chunks/chunk-FW5LJXQY.js +0 -31
- package/dist/cli-bundle/chunks/chunk-H2DZW6I6.js +0 -3
- package/dist/cli-bundle/chunks/chunk-H7CXQBGQ.js +0 -2
- package/dist/cli-bundle/chunks/chunk-KP7NBQK3.js +0 -80
- package/dist/cli-bundle/chunks/chunk-MKXBCBAN.js +0 -20
- package/dist/cli-bundle/chunks/chunk-QPKQKSQU.js +0 -238
- package/dist/cli-bundle/chunks/chunk-SGFQQXFD.js +0 -2
- package/dist/cli-bundle/chunks/chunk-YCBGZF3T.js +0 -2
- package/dist/cli-bundle/chunks/chunk-YDWKGUQU.js +0 -3
- package/dist/cli-bundle/chunks/register-mutation-5PT3NW3A.js +0 -20
- package/dist/cli-bundle/chunks/register-operations-QDDQOAAV.js +0 -2
- package/dist/cli-bundle/chunks/register-setup-BBX67YMA.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-4FFPGNCJ.js +0 -6
- package/dist/cli-bundle/focused-chunks/chunk-73DA7ISY.js +0 -75
- package/dist/cli-bundle/focused-chunks/chunk-E754JDLY.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-FKK2HI3S.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-GMYUNHST.js +0 -3
- package/dist/cli-bundle/focused-chunks/chunk-HIA2ZF64.js +0 -12
- package/dist/cli-bundle/focused-chunks/chunk-UTRSM3ZK.js +0 -8
- package/dist/cli-bundle/focused-chunks/chunk-VVWYI2X7.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-WAJNX4RN.js +0 -20
- package/dist/cli-bundle/focused-chunks/chunk-WCY6HRZO.js +0 -30
- package/dist/cli-bundle/focused-chunks/chunk-YC32ZSLS.js +0 -165
- package/dist/cli-bundle/focused-chunks/chunk-ZIXFMIUL.js +0 -3
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
(function(){try{var e=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="50f77f3f-b2b0-5ae2-b669-6ed50bbdd530")}catch{}})();const TYPE_SYNONYMS={bug:"Issue",bugfix:"Issue",defect:"Issue",incident:"Issue",enhancement:"Feature",story:"Feature",userstory:"Feature","user-story":"Feature","user story":"Feature",change:"Chore",ticket:"Task",todo:"Task"};function resolveTypeSynonym(rawType){if(rawType!==void 0)return TYPE_SYNONYMS[rawType.trim().toLowerCase()]}export{TYPE_SYNONYMS,resolveTypeSynonym};
|
|
2
2
|
//# sourceMappingURL=type-synonyms.js.map
|
package/dist/core/lock/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
(function(){try{var e=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="6569a063-f3b5-5067-88c8-d88b552c5f4c")}catch{}})();export*from"./lock.js";
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
(function(){try{var e=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="b5974276-3b45-5ad6-a7aa-e05a33807ee7")}catch{}})();import{isFileMissingError}from"../fs/fs-utils.js";import fs from"node:fs/promises";import path from"node:path";function parseLock(raw){let parsed;try{parsed=JSON.parse(raw)}catch{return null}if(typeof parsed!="object"||parsed===null||Array.isArray(parsed))return null;const candidate=parsed,{id,owner,created_at,ttl_seconds}=candidate;return typeof id!="string"||typeof owner!="string"||typeof created_at!="string"||typeof ttl_seconds!="number"||!Number.isFinite(ttl_seconds)?null:{id,owner,created_at,ttl_seconds}}function classifyLockContent(file,raw,nowMs){const lock=parseLock(raw);if(lock===null)return{detail:"unparseable_json",entry:{file,id:null,owner:null,created_at:null,ttl_seconds:null,age_seconds:null,stale:!1,reason:"unparseable"}};const createdAtMs=Date.parse(lock.created_at);if(!Number.isFinite(createdAtMs))return{detail:"invalid_timestamp",entry:{file,id:lock.id,owner:lock.owner,created_at:lock.created_at,ttl_seconds:lock.ttl_seconds,age_seconds:null,stale:!1,reason:"unparseable"}};const ageMs=nowMs-createdAtMs,age_seconds=Math.floor(ageMs/1e3),stale=ageMs>lock.ttl_seconds*1e3;return{detail:stale?"expired":"active",entry:{file,id:lock.id,owner:lock.owner,created_at:lock.created_at,ttl_seconds:lock.ttl_seconds,age_seconds,stale,reason:stale?"expired":"active"}}}async function scanLockHealth(pmRoot,now){const nowMs=now??Date.now(),locksDir=path.join(pmRoot,"locks"),scan={scanned:0,active_lock_count:0,stale_lock_count:0,unreadable_lock_count:0,unparseable_lock_count:0};let dirEntries;try{dirEntries=(await fs.readdir(locksDir)).filter(f=>f.endsWith(".lock")).sort()}catch(error){if(isFileMissingError(error))return scan;throw error}for(const file of dirEntries){let raw;try{raw=await fs.readFile(path.join(locksDir,file),"utf8")}catch(readError){if(isFileMissingError(readError))continue;scan.scanned+=1,scan.unreadable_lock_count+=1;continue}scan.scanned+=1;const{detail}=classifyLockContent(file,raw,nowMs);detail==="active"?scan.active_lock_count+=1:detail==="expired"?scan.stale_lock_count+=1:scan.unparseable_lock_count+=1}return scan}async function runLockGc(pmRoot,options){const{dryRun,hooks}=options,nowMs=options.now??Date.now(),locksDir=path.join(pmRoot,"locks"),result={scanned:0,removed:[],retained:[],warnings:[],entries:[]};let dirEntries;try{dirEntries=(await fs.readdir(locksDir)).filter(f=>f.endsWith(".lock")).sort()}catch(error){if(isFileMissingError(error))return result;throw error}for(const file of dirEntries){result.scanned+=1;const absPath=path.join(locksDir,file),relPath=`locks/${file}`;if(hooks?.onRead){const hookWarnings=await hooks.onRead(absPath);result.warnings.push(...hookWarnings)}let raw;try{raw=await fs.readFile(absPath,"utf8")}catch(readError){if(isFileMissingError(readError)){result.scanned-=1;continue}result.warnings.push(`lock_unreadable:${file}`),result.retained.push(relPath),result.entries.push({file,id:null,owner:null,created_at:null,ttl_seconds:null,age_seconds:null,stale:!1,reason:"unparseable"});continue}const classified=classifyLockContent(file,raw,nowMs);if(classified.detail==="unparseable_json"){result.warnings.push(`lock_unparseable:${file}`),result.retained.push(relPath),result.entries.push(classified.entry);continue}if(classified.detail==="invalid_timestamp"){result.warnings.push(`lock_invalid_timestamp:${file}`),result.retained.push(relPath),result.entries.push(classified.entry);continue}if(classified.detail==="active"){result.retained.push(relPath),result.entries.push(classified.entry);continue}if(!dryRun){try{await fs.unlink(absPath)}catch(unlinkError){if(!isFileMissingError(unlinkError)){result.warnings.push(`lock_remove_failed:${file}`),result.retained.push(relPath),result.entries.push(classified.entry);continue}}if(hooks?.onWrite){const hookWarnings=await hooks.onWrite(absPath);result.warnings.push(...hookWarnings)}}result.removed.push(relPath),result.entries.push(classified.entry)}return result}export{classifyLockContent,runLockGc,scanLockHealth};
|
|
2
2
|
//# sourceMappingURL=lock-gc.js.map
|
package/dist/core/lock/lock.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
`,"utf8")}finally{await handle.close()}}catch(error){await unlinkLockWithHook(lockPath,"lock:release")
|
|
3
|
-
`,"utf8")}catch{await removeStaleCleanupGateDirectory(gatePath)
|
|
1
|
+
(function(){try{var e=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="0128939c-bb33-5929-acd2-686f6437ca27")}catch{}})();import{isFileMissingError}from"../fs/fs-utils.js";import{constants as fsConstants}from"node:fs";import fs from"node:fs/promises";import path from"node:path";import{randomUUID}from"node:crypto";import{runActiveOnReadHooks,runActiveOnWriteHooks,runActiveServiceOverride}from"../extensions/index.js";import{EXIT_CODE}from"../shared/constants.js";import{PmCliError}from"../shared/errors.js";import{toErrorMessage}from"../shared/primitives.js";import{getLockPath}from"../store/paths.js";import{nowIso}from"../shared/time.js";function parseLockInfo(raw){let parsed;try{parsed=JSON.parse(raw)}catch{return{info:null,warnings:["lock_info_invalid_json"]}}if(typeof parsed!="object"||parsed===null||Array.isArray(parsed))return{info:null,warnings:["lock_info_invalid_shape"]};const candidate=parsed,id=candidate.id,pid=candidate.pid,owner=candidate.owner,token=candidate.token,createdAt=candidate.created_at,ttlSeconds=candidate.ttl_seconds;return typeof id!="string"||typeof pid!="number"||!Number.isFinite(pid)||typeof owner!="string"||token!==void 0&&(typeof token!="string"||token.trim().length===0)||typeof createdAt!="string"||typeof ttlSeconds!="number"||!Number.isFinite(ttlSeconds)?{info:null,warnings:["lock_info_invalid_shape"]}:{info:{id,pid,owner,...typeof token=="string"?{token}:{},created_at:createdAt,ttl_seconds:ttlSeconds},warnings:[]}}async function readLockInfo(lockPath,emitReadHook=!0){try{const raw=await fs.readFile(lockPath,"utf8");return emitReadHook&&await runActiveOnReadHooks({path:lockPath,scope:"project"}),parseLockInfo(raw)}catch(error){return isFileMissingError(error)?{info:null,warnings:[]}:{info:null,warnings:["lock_info_read_failed"]}}}function isErrno(error,code){return typeof error=="object"&&error!==null&&"code"in error&&error.code===code}async function isLockCreateContention(error,lockPath,platform=process.platform){if(isErrno(error,"EEXIST"))return!0;if(!isErrno(error,"EPERM")&&!isErrno(error,"EACCES")&&!isErrno(error,"EBUSY"))return!1;try{return await fs.lstat(lockPath),!0}catch(probeError){if(platform!=="win32"||!isFileMissingError(probeError)&&!isErrno(probeError,"EPERM")&&!isErrno(probeError,"EACCES")&&!isErrno(probeError,"EBUSY"))return!1}try{return await fs.access(path.dirname(lockPath),fsConstants.W_OK),!0}catch{return!1}}async function emitLockWriteHook(lockPath,op){await runActiveOnWriteHooks({path:lockPath,scope:"project",op})}function buildLockPayload(id,owner,ttlSeconds,token=randomUUID()){return{id,pid:process.pid,owner,token,created_at:nowIso(),ttl_seconds:ttlSeconds}}async function createLockFile(lockPath,id,owner,ttlSeconds,token){await fs.mkdir(path.dirname(lockPath),{recursive:!0});const releaseCleanupGate=await acquireStaleCleanupGate(lockPath,id);if(releaseCleanupGate===null)throw Object.assign(new Error("Lock initialization is contended"),{code:"EEXIST"});try{const handle=await fs.open(lockPath,"wx");try{try{await handle.writeFile(`${JSON.stringify(buildLockPayload(id,owner,ttlSeconds,token),null,2)}
|
|
2
|
+
`,"utf8")}finally{await handle.close()}}catch(error){throw await unlinkLockWithHook(lockPath,"lock:release"),error}}finally{await releaseCleanupGate()}await emitLockWriteHook(lockPath,"lock:create")}async function unlinkLockWithHook(lockPath,op){try{return await fs.unlink(lockPath),await emitLockWriteHook(lockPath,op),!0}catch{return!1}}async function releaseOwnedLock(lockPath,id,owner,token){const startedAtMs=Date.now();let backoffMs=LOCK_WAIT_INITIAL_DELAY_MS;for(;;){const releaseCleanupGate=await acquireStaleCleanupGate(lockPath,id);if(releaseCleanupGate!==null){try{const current2=await readLockInfo(lockPath,!1);isOwnedLock(current2.info,id,owner,token)&&await unlinkLockWithHook(lockPath,"lock:release")}finally{await releaseCleanupGate()}return}const current=await readLockInfo(lockPath,!1);if(!isOwnedLock(current.info,id,owner,token))return;const elapsedMs=Date.now()-startedAtMs;if(elapsedMs>=LOCK_RELEASE_GATE_WAIT_MS)return;await sleepWithJitter(Math.min(backoffMs,LOCK_RELEASE_GATE_WAIT_MS-elapsedMs)),backoffMs=Math.min(backoffMs*2,LOCK_WAIT_MAX_DELAY_MS)}}function isOwnedLock(info,id,owner,token){return info?.id===id&&info.pid===process.pid&&info.owner===owner&&info.token===token}function isStaleLock(info,ttlSeconds){const createdAtMs=info?.created_at?Date.parse(info.created_at):Number.NaN;return(Number.isFinite(createdAtMs)?Date.now()-createdAtMs:Number.POSITIVE_INFINITY)>ttlSeconds*1e3}function lockOwnerSuffix(info){return info?.owner?` (owner ${info.owner})`:""}const LOCK_WAIT_INITIAL_DELAY_MS=25,LOCK_WAIT_MAX_DELAY_MS=200,LOCK_CONFLICT_RETRY_HINT_MS=250,MAX_STALE_LOCK_REMOVALS=3,STALE_CLEANUP_GATE_SUFFIX=".stale-cleanup",STALE_CLEANUP_GATE_OWNER_FILE="owner.json",STALE_CLEANUP_GATE_STALE_MS=1e4,LOCK_RELEASE_GATE_WAIT_MS=STALE_CLEANUP_GATE_STALE_MS+LOCK_WAIT_MAX_DELAY_MS,STALE_CLEANUP_GATE_MAX_UNVERIFIED_MS=60*6e4;function parseNonNegativeIntegerWaitMs(value){if(typeof value=="string"){const trimmed=value.trim();if(!/^\d+$/.test(trimmed))return;const parsed=Number(trimmed);return Number.isSafeInteger(parsed)?parsed:void 0}if(typeof value=="number"&&Number.isFinite(value)&&value>=0)return Math.trunc(value)}function resolveLockWaitMs(waitMs){const envRaw=process.env.PM_LOCK_WAIT_MS,envParsed=parseNonNegativeIntegerWaitMs(envRaw);if(envParsed!==void 0)return envParsed;const callerParsed=parseNonNegativeIntegerWaitMs(waitMs);return callerParsed!==void 0?callerParsed:0}function sleepWithJitter(baseDelayMs){const jitteredMs=Math.max(1,Math.round(baseDelayMs*(.5+Math.random())));return new Promise(resolve=>setTimeout(resolve,jitteredMs))}function buildLockConflictError(id,info,waitedMs){const waitedSuffix=waitedMs>0?` after waiting ${waitedMs}ms`:"";return new PmCliError(`Item ${id} is locked${lockOwnerSuffix(info)}${waitedSuffix}`,EXIT_CODE.CONFLICT,{code:"lock_conflict",recovery:{retry_after_ms:LOCK_CONFLICT_RETRY_HINT_MS}})}function resolveLockOverrideRelease(result){if(typeof result=="function")return result;if(typeof result=="object"&&result!==null&&"release"in result){const release=result.release;return typeof release=="function"?release:null}return null}function throwIfStaleLockNeedsForce(id,lockInfo,force,forceRequired){if(!force&&forceRequired){const warningSuffix=lockInfo.warnings.length>0?` (${lockInfo.warnings.join(",")})`:"";throw new PmCliError(`Item ${id} lock is stale${warningSuffix}; rerun with --force when supported for this command`,EXIT_CODE.CONFLICT)}}function parseStaleCleanupGateOwner(raw){let parsed;try{parsed=JSON.parse(raw)}catch{return null}if(typeof parsed!="object"||parsed===null||Array.isArray(parsed))return null;const candidate=parsed,pid=candidate.pid,token=candidate.token,processStartIdentity=candidate.process_start_identity;return typeof pid!="number"||!Number.isInteger(pid)||pid<=0||typeof token!="string"||token.length===0||processStartIdentity!==void 0&&(typeof processStartIdentity!="string"||!/^\d+$/u.test(processStartIdentity))?null:{pid,token,...typeof processStartIdentity=="string"?{process_start_identity:processStartIdentity}:{}}}async function readStaleCleanupGateOwner(gatePath){try{return parseStaleCleanupGateOwner(await fs.readFile(path.join(gatePath,STALE_CLEANUP_GATE_OWNER_FILE),"utf8"))}catch{return null}}function isProcessAlive(pid){if(!Number.isSafeInteger(pid)||pid<=0)return!1;try{return process.kill(pid,0),!0}catch(error){return!isErrno(error,"ESRCH")}}function parseLinuxProcessStartIdentity(raw){const closeParenIndex=raw.lastIndexOf(")");if(closeParenIndex<0)return null;const startTime=raw.slice(closeParenIndex+2).trim().split(/\s+/u)[19];return startTime!==void 0&&/^\d+$/u.test(startTime)?startTime:null}async function readProcessStartIdentity(pid){try{return parseLinuxProcessStartIdentity(await fs.readFile(`/proc/${pid}/stat`,"utf8"))}catch{return null}}async function captureProcessIdentity(pid=process.pid){const processStartIdentity=await readProcessStartIdentity(pid);return{pid,...processStartIdentity===null?{}:{process_start_identity:processStartIdentity}}}async function isProcessIdentityAlive(identity,unverifiedAgeMs,maxUnverifiedAgeMs){if(!isProcessAlive(identity.pid))return!1;const currentStartIdentity=await readProcessStartIdentity(identity.pid);return identity.process_start_identity!==void 0&¤tStartIdentity!==null?currentStartIdentity===identity.process_start_identity:unverifiedAgeMs<=maxUnverifiedAgeMs}async function removeStaleCleanupGateDirectory(gatePath){try{return await fs.rm(gatePath,{recursive:!0,force:!0}),!0}catch{return!1}}async function releaseStaleCleanupGate(gatePath,token){const owner=await readStaleCleanupGateOwner(gatePath);owner===null||owner.token!==token||await removeStaleCleanupGateDirectory(gatePath)}async function tryCreateStaleCleanupGate(gatePath){try{await fs.mkdir(gatePath)}catch(error){return isErrno(error,"EEXIST"),null}const owner={...await captureProcessIdentity(),token:randomUUID()};try{await fs.writeFile(path.join(gatePath,STALE_CLEANUP_GATE_OWNER_FILE),`${JSON.stringify(owner)}
|
|
3
|
+
`,"utf8")}catch{return await removeStaleCleanupGateDirectory(gatePath),null}return owner}async function removeExpiredStaleCleanupGate(gatePath){let gateAgeMs;try{const stats=await fs.stat(gatePath);if(gateAgeMs=Date.now()-stats.mtimeMs,gateAgeMs<=STALE_CLEANUP_GATE_STALE_MS)return!1}catch(error){return isFileMissingError(error)}const owner=await readStaleCleanupGateOwner(gatePath);return owner!==null&&await isProcessIdentityAlive(owner,gateAgeMs,STALE_CLEANUP_GATE_MAX_UNVERIFIED_MS)?!1:removeStaleCleanupGateDirectory(gatePath)}async function acquireStaleCleanupGate(lockPath,_id){const gatePath=`${lockPath}${STALE_CLEANUP_GATE_SUFFIX}`,owner=await tryCreateStaleCleanupGate(gatePath);if(owner!==null)return async()=>releaseStaleCleanupGate(gatePath,owner.token);if(!await removeExpiredStaleCleanupGate(gatePath))return null;const recoveredOwner=await tryCreateStaleCleanupGate(gatePath);return recoveredOwner===null?null:async()=>releaseStaleCleanupGate(gatePath,recoveredOwner.token)}async function removeConfirmedStaleLock(params){const releaseCleanupGate=await acquireStaleCleanupGate(params.lockPath,params.id);if(releaseCleanupGate===null)return{lockInfo:params.fallbackLockInfo,shouldRetryCreate:!1,staleRemovalCounted:!1};try{const currentLockInfo=await readLockInfo(params.lockPath);if(currentLockInfo.info===null&¤tLockInfo.warnings.length===0)return{lockInfo:currentLockInfo,shouldRetryCreate:!0,staleRemovalCounted:!1};if(!isStaleLock(currentLockInfo.info,params.ttlSeconds))return{lockInfo:currentLockInfo,shouldRetryCreate:!1,staleRemovalCounted:!1};if(throwIfStaleLockNeedsForce(params.id,currentLockInfo,params.force,params.forceRequiredForStaleLock),params.staleRemovals>=MAX_STALE_LOCK_REMOVALS)throw buildLockConflictError(params.id,currentLockInfo.info,Date.now()-params.startedAtMs);return{lockInfo:currentLockInfo,shouldRetryCreate:await unlinkLockWithHook(params.lockPath,"lock:stale_remove"),staleRemovalCounted:!0}}finally{await releaseCleanupGate()}}const _testOnly={parseLockInfo,readLockInfo,isErrno,isLockCreateContention,buildLockPayload,isStaleLock,lockOwnerSuffix,resolveLockWaitMs,parseLinuxProcessStartIdentity,readProcessStartIdentity,acquireStaleCleanupGate,removeConfirmedStaleLock};async function acquireLock(pmRoot,id,ttlSeconds,owner,force=!1,forceRequiredForStaleLock=!0,waitMs){const lockOverride=await runActiveServiceOverride("lock_acquire",{pm_root:pmRoot,id,ttl_seconds:ttlSeconds,owner,force,force_required_for_stale_lock:forceRequiredForStaleLock});if(lockOverride.handled){const release=resolveLockOverrideRelease(lockOverride.result);if(release)return async()=>{await Promise.resolve(release()),await runActiveServiceOverride("lock_release",{pm_root:pmRoot,id,owner})}}const lockPath=getLockPath(pmRoot,id),waitBudgetMs=resolveLockWaitMs(waitMs),startedAtMs=Date.now();let staleRemovals=0,backoffMs=LOCK_WAIT_INITIAL_DELAY_MS;const token=randomUUID();for(;;)try{return await createLockFile(lockPath,id,owner,ttlSeconds,token),async()=>{await releaseOwnedLock(lockPath,id,owner,token),await runActiveServiceOverride("lock_release",{pm_root:pmRoot,id,owner})}}catch(error){if(!await isLockCreateContention(error,lockPath))throw new PmCliError(`Failed to acquire lock for ${id}: ${toErrorMessage(error)}`,EXIT_CODE.GENERIC_FAILURE);let lockInfo=await readLockInfo(lockPath);if(isStaleLock(lockInfo.info,ttlSeconds)){const staleRemoval=await removeConfirmedStaleLock({lockPath,id,ttlSeconds,force,forceRequiredForStaleLock,staleRemovals,waitBudgetMs,startedAtMs,fallbackLockInfo:lockInfo});if(lockInfo=staleRemoval.lockInfo,staleRemoval.staleRemovalCounted&&(staleRemovals+=1),staleRemoval.shouldRetryCreate)continue}const elapsedMs=Date.now()-startedAtMs;if(waitBudgetMs===0||elapsedMs>=waitBudgetMs)throw buildLockConflictError(id,lockInfo.info,waitBudgetMs===0?0:elapsedMs);await sleepWithJitter(Math.min(backoffMs,waitBudgetMs-elapsedMs)),backoffMs=Math.min(backoffMs*2,LOCK_WAIT_MAX_DELAY_MS)}}export{_testOnly,acquireLock,captureProcessIdentity,isProcessIdentityAlive,readProcessStartIdentity};
|
|
4
4
|
//# sourceMappingURL=lock.js.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
(function(){try{var e=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="71a40065-6b91-54bb-ad90-4a4b018de3b4")}catch{}})();const CHANGED_FIELDS_KEY="changed_fields",CHANGED_FIELD_COUNT_KEY="changed_field_count",ROWS_KEY="rows",UPDATE_MANY_MUTATION_MODES=new Set(["apply","rollback"]),DELETE_OUTCOMES=new Set(["deleted","would_delete"]),COMPACT_RECURRENCE_TEXT_LIMIT=256,COMPOUND_MUTATION_STEPS={start_task:["claim","update"],pause_task:["update","release"],close_task:["close","release"]};function projectCompoundMutation(result,options){if(!isPlainObject(result)||typeof result.action!="string"||typeof result.id!="string"||result.id.length===0)return null;const steps=Object.hasOwn(COMPOUND_MUTATION_STEPS,result.action)?COMPOUND_MUTATION_STEPS[result.action]:void 0;if(!steps||!steps.every(step=>{const value=result[step];return isPlainObject(value)&&isPlainObject(value.item)&&value.item.id===result.id&&Array.isArray(value.changed_fields)&&value.changed_fields.every(field=>typeof field=="string")}))return null;const final=result[steps.at(-1)],identity=projectIdOnlyResult(final);return options.idOnly?identity:!options.compactEnvelope&&options.changedFields!=="compact"?null:{...result,...options.compactEnvelope?{...identity,changed_field_count:new Set(steps.flatMap(step=>result[step].changed_fields)).size}:{},...Object.fromEntries(steps.map(step=>[step,projectMutationResult(result[step],options)]))}}function truncateCompactRecurrenceText(value){return typeof value!="string"||value.length<=COMPACT_RECURRENCE_TEXT_LIMIT?value:`${value.slice(0,COMPACT_RECURRENCE_TEXT_LIMIT-1)}\u2026`}function projectCompactRecurrence(value){if(!isPlainObject(value))return null;const recurrence={...value};return recurrence.reason=truncateCompactRecurrenceText(recurrence.reason),isPlainObject(recurrence.previous_terminal)&&(recurrence.previous_terminal=Object.fromEntries(Object.entries(recurrence.previous_terminal).map(([key,entry])=>[key,truncateCompactRecurrenceText(entry)]))),recurrence}function isPlainObject(value){if(typeof value!="object"||value===null||Array.isArray(value))return!1;const proto=Object.getPrototypeOf(value);return proto===null||proto===Object.prototype}function compactOwnChangedFields(envelope){const changedFields=envelope[CHANGED_FIELDS_KEY];if(!Array.isArray(changedFields))return null;const projected=Object.getPrototypeOf(envelope)===null?Object.create(null):{};for(const[key,value]of Object.entries(envelope))key!==CHANGED_FIELDS_KEY&&(projected[key]=value);return projected[CHANGED_FIELD_COUNT_KEY]=changedFields.length,projected}function isMutationEnvelope(value){return"item"in value&&Array.isArray(value[CHANGED_FIELDS_KEY])}function isUpdateManyMutationEnvelope(value){return typeof value.mode=="string"&&UPDATE_MANY_MUTATION_MODES.has(value.mode)&&Array.isArray(value[ROWS_KEY])}function replaceRows(envelope,rows){const projected=Object.getPrototypeOf(envelope)===null?Object.create(null):{};return Object.assign(projected,envelope),projected[ROWS_KEY]=rows,projected}function projectIdOnlyResult(result){if(!isPlainObject(result))return null;const subject=isPlainObject(result.item)?result.item:isPlainObject(result.plan)?result.plan:null;if(subject===null)return null;const id=typeof subject.id=="string"?subject.id:void 0,status=typeof result.outcome=="string"&&DELETE_OUTCOMES.has(result.outcome)?result.outcome:typeof subject.status=="string"?subject.status:void 0;return id?status?{id,status,...typeof result.deleted=="boolean"?{deleted:result.deleted}:{}}:{id}:null}function projectCompactMutationEnvelope(result,includeItem){if(!isPlainObject(result))return null;if(isPlainObject(result.plan)&&isPlainObject(result.mutation_receipt)&&result.mutation_receipt.kind==="plan_mutation"&&result.mutation_receipt.id===result.plan.id&&result.mutation_receipt.action===result.action)return result.mutation_receipt;if(!includeItem||!isPlainObject(result.item)||typeof result.item.id!="string")return null;const changedFields=result[CHANGED_FIELDS_KEY];if(!Array.isArray(changedFields))return null;const compact={id:result.item.id,...typeof result.outcome=="string"&&DELETE_OUTCOMES.has(result.outcome)?{status:result.outcome}:typeof result.item.status=="string"?{status:result.item.status}:{},...typeof result.deleted=="boolean"?{deleted:result.deleted}:{},...typeof result.previous_status=="string"?{previous_status:result.previous_status}:{},changed_field_count:changedFields.length};return appendCompactMutationEvidence(result,result.item,compact),compact}function appendCompactMutationEvidence(result,item,compact){const closeReason=typeof result.close_reason=="string"?result.close_reason:typeof item.close_reason=="string"?item.close_reason:void 0;closeReason!==void 0&&(compact.close_reason=closeReason);const recurrence=projectCompactRecurrence(result.recurrence);if(recurrence!==null&&(compact.recurrence=recurrence),Array.isArray(result.warnings)&&result.warnings.length>0&&(compact.warnings=result.warnings),isPlainObject(result.recovery)&&(compact.recovery=result.recovery),typeof result.claimed_by=="string"||typeof result.released_by=="string")for(const key of["claimed_by","released_by","previous_assignee","forced","skipped","available","attempts","suggestions"])Object.hasOwn(result,key)&&(compact[key]=result[key])}function compactUpdateManyRows(envelope){const rows=isUpdateManyMutationEnvelope(envelope)?envelope[ROWS_KEY]:void 0;if(!Array.isArray(rows))return{projected:envelope,changed:!1};let rowsChanged=!1;const nextRows=rows.map(row=>{if(!isPlainObject(row))return row;const compactedRow=compactOwnChangedFields(row);return compactedRow?(rowsChanged=!0,compactedRow):row});return rowsChanged?{projected:replaceRows(envelope,nextRows),changed:!0}:{projected:envelope,changed:!1}}function projectMutationResult(result,options={}){const compound=projectCompoundMutation(result,options);if(compound!==null)return compound;if(options.idOnly===!0){const idOnly=projectIdOnlyResult(result);if(idOnly!==null)return idOnly}if(options.compactEnvelope===!0||options.changedFields==="compact"){const compact=projectCompactMutationEnvelope(result,options.compactEnvelope===!0);if(compact!==null)return compact}if((options.changedFields??"full")==="full"||!isPlainObject(result))return result;let changed=!1,projected=result;const compactedTop=isMutationEnvelope(result)?compactOwnChangedFields(result):null;compactedTop!==null&&(projected=compactedTop,changed=!0);const rowProjection=compactUpdateManyRows(projected);return rowProjection.changed&&(projected=rowProjection.projected,changed=!0),changed?projected:result}export{projectMutationResult};
|
|
2
2
|
//# sourceMappingURL=mutation-projection.js.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
(function(){try{var e=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="32aa20df-edf7-543d-b733-841130466f00")}catch{}})();const SUPPRESS_HOST_OUTPUT_KEY="__pm_suppress_host_output",SUPPRESS_HOST_OUTPUT_MARKER="@unbrained/pm-cli:suppress-host-output:v1";function suppressHostOutput(result){return result===void 0?{__pm_suppress_host_output:SUPPRESS_HOST_OUTPUT_MARKER}:{__pm_suppress_host_output:SUPPRESS_HOST_OUTPUT_MARKER,result}}function isHostOutputSuppressed(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)&&value[SUPPRESS_HOST_OUTPUT_KEY]===SUPPRESS_HOST_OUTPUT_MARKER}export{SUPPRESS_HOST_OUTPUT_MARKER,isHostOutputSuppressed,suppressHostOutput};
|
|
2
2
|
//# sourceMappingURL=output-control.js.map
|
|
@@ -1,12 +1,24 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
`}
|
|
5
|
-
`
|
|
6
|
-
|
|
7
|
-
`
|
|
8
|
-
`)
|
|
9
|
-
|
|
10
|
-
`
|
|
1
|
+
(function(){try{var e=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="226eaad9-e87a-5ee9-a35b-e1a6f05b8965")}catch{}})();import{getActiveCommandContext,runActiveCommandOverride,runActiveRendererOverride,runActiveServiceOverrideSync,setActiveCommandResult}from"../extensions/index.js";import{EXIT_CODE}from"../shared/constants.js";import{isHostOutputSuppressed}from"./output-control.js";import{projectMutationResult}from"./mutation-projection.js";import{attachReadOutputContracts}from"../../sdk/context-intent-contracts.js";import{attachOutputTokenAccounting}from"../../sdk/output-token-accounting.js";import{propagateContextUsageServingReceipt}from"../../sdk/context-usage.js";import{isReadOutputBudgetExceeded,resolveReadOutputEncoding}from"../../sdk/read-output-contracts.js";import{encode as encodeToon}from"@toon-format/toon";const DECLARED_PROCESS_EXIT_CODES=new Set(Object.values(EXIT_CODE)),NATIVE_OUTPUT_MARKER="__pm_native_output";let streamErrorHandlersInstalled=!1;function isPlainObject(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}function setActiveCommandResultOmitted(source){const omitted={read_output:{result_omitted:!0}};propagateContextUsageServingReceipt(source,omitted),setActiveCommandResult(omitted)}function setActiveCommandDeliveryResult(result,receiptSource,structuredDeliveryPreserved){if(structuredDeliveryPreserved){setActiveCommandResult(result);return}setActiveCommandResultOmitted(receiptSource)}function shouldUseNativeOutput(result){return isPlainObject(result)&&result[NATIVE_OUTPUT_MARKER]===!0}function stripNativeOutputMarker(result){if(!isPlainObject(result)||result[NATIVE_OUTPUT_MARKER]!==!0)return result;const{[NATIVE_OUTPUT_MARKER]:_marker,...rest}=result;return rest}function isBrokenPipeError(error){return typeof error=="object"&&error!==null&&error.code==="EPIPE"}function markStdoutBrokenPipeExitCode(){(process.exitCode===void 0||process.exitCode===EXIT_CODE.SUCCESS)&&(process.exitCode=EXIT_CODE.SUCCESS)}function markStderrBrokenPipeExitCode(){(process.exitCode===void 0||process.exitCode===EXIT_CODE.SUCCESS)&&(process.exitCode=EXIT_CODE.GENERIC_FAILURE)}function markBrokenPipeExitCode(target){if(target==="stdout"){markStdoutBrokenPipeExitCode();return}markStderrBrokenPipeExitCode()}function handleUnhandledStreamError(error){const unhandled=error instanceof Error?error:new Error(String(error));setImmediate(()=>{throw unhandled})}function installStreamErrorHandlers(){streamErrorHandlersInstalled||(streamErrorHandlersInstalled=!0,process.stdout.on("error",error=>{if(isBrokenPipeError(error)){markBrokenPipeExitCode("stdout");return}handleUnhandledStreamError(error)}),process.stderr.on("error",error=>{if(isBrokenPipeError(error)){markBrokenPipeExitCode("stderr");return}handleUnhandledStreamError(error)}))}function writeToStream(target,text){installStreamErrorHandlers();try{return target==="stdout"?process.stdout.write(text):process.stderr.write(text),!0}catch(error){if(isBrokenPipeError(error))return markBrokenPipeExitCode(target),!1;throw error}}function writeStdout(text){return writeToStream("stdout",text)}function writeStderr(text){return writeToStream("stderr",text)}function renderScalar(value){return typeof value=="string"?JSON.stringify(value):typeof value=="number"||typeof value=="boolean"?String(value):value===null?"null":JSON.stringify(value)}function isToonPrimitive(value){return value===null||typeof value=="string"||typeof value=="number"||typeof value=="boolean"}function tabularObjectArray(value){if(value.length===0||!value.every(isPlainObject))return!1;const keys=Object.keys(value[0]);return keys.length>0&&value.every(entry=>Object.keys(entry).length===keys.length&&keys.every(key=>Object.hasOwn(entry,key)&&isToonPrimitive(entry[key])))}function indentToon(encoded,depth){const indent=" ".repeat(depth);return encoded.split(`
|
|
2
|
+
`).map(line=>`${indent}${line}`).join(`
|
|
3
|
+
`)}function renderToonObjectEntry(key,entry,depth){const indent=" ".repeat(depth);return!isPlainObject(entry)&&!Array.isArray(entry)?`${indent}${key}: ${renderScalar(entry)}`:Array.isArray(entry)&&entry.length===0?`${indent}${key}: []`:Array.isArray(entry)&&tabularObjectArray(entry)?indentToon(encodeToon({[key]:entry}),depth):isPlainObject(entry)&&Object.keys(entry).length===0?`${indent}${key}: {}`:`${indent}${key}:
|
|
4
|
+
${renderToonValue(entry,depth+1)}`}function compactToonValue(value){if(value!=null){if(Array.isArray(value)){const compactedEntries=value.map(entry=>compactToonValue(entry)).filter(entry=>entry!==void 0);return compactedEntries.length>0?compactedEntries:void 0}if(isPlainObject(value)){const compacted={};for(const[key,entry]of Object.entries(value)){if(key==="omitted_field_groups"&&Array.isArray(entry)&&entry.length===0){compacted[key]=[];continue}const compactedEntry=compactToonValue(entry);compactedEntry!==void 0&&(compacted[key]=compactedEntry)}return Object.keys(compacted).length>0?compacted:void 0}return value}}function renderToonValue(value,depth){const indent=" ".repeat(depth);if(Array.isArray(value))return value.length===0?"[]":tabularObjectArray(value)?indentToon(encodeToon(value),depth):value.map(entry=>{if(!isPlainObject(entry)&&!Array.isArray(entry))return`${indent}- ${renderScalar(entry)}`;const lines=renderToonValue(entry,depth+1).split(`
|
|
5
|
+
`),[firstLine,...rest]=lines;return rest.length===0?`${indent}- ${firstLine.trimStart()}`:`${indent}- ${firstLine.trimStart()}
|
|
6
|
+
${rest.join(`
|
|
7
|
+
`)}`}).join(`
|
|
8
|
+
`);if(isPlainObject(value)){const entries=Object.entries(value);return entries.length===0?"{}":entries.map(([key,entry])=>renderToonObjectEntry(key,entry,depth)).join(`
|
|
9
|
+
`)}return`${indent}${renderScalar(value)}`}function renderDefaultMarkdownResult(value){if(!isPlainObject(value)||value.output_default!=="markdown"||typeof value.view!="string"||!Array.isArray(value.events)||!Array.isArray(value.days))return null;const lines=[`# pm calendar (${value.view})`,""],summary=isPlainObject(value.summary)?value.summary:{};if(lines.push(`- events: ${String(summary.events??0)}`),lines.push(""),value.events.length===0)return lines.push("No calendar events matched the selected filters."),`${lines.join(`
|
|
10
|
+
`)}
|
|
11
|
+
`;for(const event of value.events){if(!isPlainObject(event))continue;const kind=typeof event.kind=="string"?event.kind:"event",title=typeof event.item_title=="string"?event.item_title:"",itemId=typeof event.item_id=="string"?event.item_id:"",reminderText=typeof event.reminder_text=="string"&&event.reminder_text.length>0?` ${event.reminder_text}`:"";lines.push(`- [${kind}] ${itemId} ${title}${reminderText}`.trim())}return`${lines.join(`
|
|
12
|
+
`)}
|
|
13
|
+
`}function resolveOutputFormat(options){return options.json===!0||options.json===void 0&&options.defaultOutputFormat==="json"?"json":"toon"}const LEAN_READ_ENVELOPE_ECHO_KEYS=new Set(["filters","now","projection","sorting"]);function projectLeanJsonValue(value){const compacted=compactToonValue(value);if(!isPlainObject(compacted)||!Array.isArray(compacted.items))return compacted??null;const projected=Object.fromEntries(Object.entries(compacted).filter(([key])=>!LEAN_READ_ENVELOPE_ECHO_KEYS.has(key)));return projected.has_more!==!0&&delete projected.next_cursor,projected}function projectLinkedTestEvidence(value,lean){if(!isPlainObject(value)||!Array.isArray(value.run_results)||!value.run_results.every(isPlainObject))return value;const rows=value.run_results,contexts=rows.map(row=>row.execution_context).filter(context=>context!==void 0),sharedContext=contexts.length===rows.length&&contexts.length>0&&contexts.every(context=>JSON.stringify(context)===JSON.stringify(contexts[0]))?contexts[0]:void 0,runResults=rows.map(row=>{const{execution_context:_executionContext,stdout,stderr,...rest}=row;return sharedContext===void 0?row:!lean||row.status!=="passed"?{...rest,stdout,stderr}:rest});return{...value,...sharedContext===void 0?{}:{execution_context:sharedContext},run_results:runResults}}function projectCompleteBriefList(value){if(!isPlainObject(value)||!Array.isArray(value.items)||Object.hasOwn(value,"details")||!isPlainObject(value.projection)||value.projection.mode!=="brief"||!isPlainObject(value.completeness)||value.completeness.status!=="complete"||[value.completeness.unreadable_item_count,value.completeness.unreadable_directory_count].some(count=>count!==0)||[value.has_more,value.truncated].some(flag=>flag!==!1)||value.count!==value.items.length||value.total!==value.count||!isPlainObject(value.omission_receipt)||JSON.stringify(value.omission_receipt.omitted_field_groups)!==JSON.stringify([{name:"full_item_fields",restore_with:"--full"}]))return value;const{total:_total,has_more:_hasMore,truncated:_truncated,next_cursor:_nextCursor,completeness:_completeness,projection:_projection,now:_now,omission_receipt:_omissions,sorting,...rest}=value;return{...rest,...isPlainObject(sorting)&&sorting.sort==="default"?{}:{sorting},details:"--full"}}function formatBuiltInOutput(result,format){if(format==="json")return`${JSON.stringify(result,null,2)}
|
|
14
|
+
`;const compactedToon=compactToonValue(projectCompleteBriefList(result));return compactedToon===void 0?`{}
|
|
15
|
+
`:`${renderToonValue(compactedToon,0)}
|
|
16
|
+
`}function resolveOutputService(effectiveResult,nativeOutput,options,format){const serviceOverride=nativeOutput?{handled:!1,result:effectiveResult,warnings:[]}:runActiveServiceOverrideSync("output_format",{command:options.command,args:options.commandArgs,command_options:options.commandOptions,global:{...options},pm_root:options.pmRoot,format,options:{...options},result:effectiveResult}),legacyPayloadEchoWarning=serviceOverride.warnings.find(warning=>warning.startsWith("extension_output_format_payload_echo_deprecated:"));return legacyPayloadEchoWarning!==void 0&&writeStderr(`Warning: ${legacyPayloadEchoWarning}. Returning context.payload now declines safely for compatibility; migrate the override to declineServiceOverride() or { handled: false }.
|
|
17
|
+
`),serviceOverride.handled&&typeof serviceOverride.result=="string"?{result:serviceOverride.result,rendered:serviceOverride.result.endsWith(`
|
|
18
|
+
`)?serviceOverride.result:`${serviceOverride.result}
|
|
19
|
+
`,structuredDeliveryPreserved:!1}:{result:serviceOverride.handled?serviceOverride.result:effectiveResult,rendered:null,structuredDeliveryPreserved:!serviceOverride.handled||isPlainObject(serviceOverride.result)}}function formatEffectiveOutput(effectiveResult,nativeOutput,options){const activeCommandContext=getActiveCommandContext(),command=options.command??activeCommandContext?.command,commandOptions={...activeCommandContext?.options,...options.commandOptions,...Object.fromEntries([["outputInclude",options.outputInclude],["outputLimit",options.outputLimit],["outputBudget",options.outputBudget],["outputFormat",options.outputFormat],["outputSession",options.outputSession],["outputCursor",options.outputCursor],["outputRowContract",options.outputRowContract]].filter(entry=>entry[1]!==void 0))},format=resolveReadOutputEncoding(command??"",commandOptions)??resolveOutputFormat(options),resolvedCommandOptions={...commandOptions,resolvedOutputFormat:format},effectiveOptions={...options,command,commandOptions:resolvedCommandOptions},service=resolveOutputService(effectiveResult,nativeOutput,effectiveOptions,format);if(service.rendered!==null)return setActiveCommandResultOmitted(effectiveResult),service.rendered;const outputResult=service.result;propagateContextUsageServingReceipt(effectiveResult,outputResult);const projectedOutputResult=command==="test"?projectLinkedTestEvidence(outputResult,options.lean===!0):outputResult,intentOutputResult=attachReadOutputContracts(command,resolvedCommandOptions,projectedOutputResult);isReadOutputBudgetExceeded(intentOutputResult)&&(process.exitCode||=EXIT_CODE.USAGE);let{structuredDeliveryPreserved}=service;const renderResolvedOutput=value=>{if(format==="toon"){const markdownDefault=renderDefaultMarkdownResult(value);if(markdownDefault!==null)return markdownDefault}const rendererOverride=nativeOutput?{rendered:null}:runActiveRendererOverride(format,value);return rendererOverride.rendered!==null?(structuredDeliveryPreserved=!1,rendererOverride.rendered.endsWith(`
|
|
20
|
+
`)?rendererOverride.rendered:`${rendererOverride.rendered}
|
|
21
|
+
`):format==="json"?formatBuiltInOutput(options.lean===!0?projectLeanJsonValue(value):value,"json"):formatBuiltInOutput(value,"toon")},accountedOutputResult=options.tokenAccounting===!0?attachOutputTokenAccounting(intentOutputResult,renderResolvedOutput):intentOutputResult,rendered=renderResolvedOutput(accountedOutputResult);return setActiveCommandDeliveryResult(accountedOutputResult,effectiveResult,options.quiet!==!0&&structuredDeliveryPreserved),rendered}function formatOutput(result,options){const commandOverride=runActiveCommandOverride(result),suppressedOutput=isHostOutputSuppressed(commandOverride.result)?commandOverride.result:null,nativeOutput=shouldUseNativeOutput(commandOverride.result),effectiveResult=suppressedOutput?suppressedOutput.result:stripNativeOutputMarker(commandOverride.result);return setActiveCommandResult(effectiveResult),suppressedOutput?(setActiveCommandResultOmitted(effectiveResult),""):formatEffectiveOutput(effectiveResult,nativeOutput,options)}function printResult(result,options){isPlainObject(result)&&Number.isInteger(result.exit_code)&&DECLARED_PROCESS_EXIT_CODES.has(Number(result.exit_code))&&(process.exitCode===void 0||process.exitCode===EXIT_CODE.SUCCESS)&&(process.exitCode=Number(result.exit_code));const projected=options.idOnly?projectMutationResult(result,{idOnly:!0}):options.fullChangedFields?result:options.noChangedFields?projectMutationResult(result,{changedFields:"compact"}):projectMutationResult(result,{compactEnvelope:!0}),rendered=formatOutput(projected,options);options.quiet||writeStdout(rendered)}function printError(message){const override=runActiveServiceOverrideSync("error_format",{message}),rendered=override.handled&&typeof override.result=="string"?override.result:message;writeStderr(rendered.endsWith(`
|
|
22
|
+
`)?rendered:`${rendered}
|
|
11
23
|
`)}const outputTestOnly={compactToonValue,renderToonValue};export{formatBuiltInOutput,formatOutput,outputTestOnly,printError,printResult,writeStderr,writeStdout};
|
|
12
24
|
//# sourceMappingURL=output.js.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
(function(){try{var e=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="baa27a48-c538-574c-9d05-1f1c0f4f429c")}catch{}})();function isRecord(value){return value!==null&&typeof value=="object"&&!Array.isArray(value)}function resolveQueryProjectionLabel(options){return options.brief===!0?"brief":typeof options.fields=="string"&&options.fields.trim().length>0||Array.isArray(options.fields)&&options.fields.length>0?"fields":options.compact===!0?"compact":"full"}function withQuerySummary(result,options){const requestedLabel=resolveQueryProjectionLabel(options),projection=requestedLabel==="brief"?requestedLabel:isRecord(result.projection)&&typeof result.projection.mode=="string"?result.projection.mode:requestedLabel;return{...result,query_summary:{filters:isRecord(result.filters)?result.filters:{},projection}}}export{resolveQueryProjectionLabel,withQuerySummary};
|
|
2
2
|
//# sourceMappingURL=query-summary.js.map
|
|
@@ -1,2 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
(function(){try{var e=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="c628dcf9-d98f-566e-9f93-cc81e737691c")}catch{}})();function resolveColumns(rows){const columns=[],seen=new Set;for(const row of rows)for(const key of Object.keys(row))seen.has(key)||(seen.add(key),columns.push(key));return columns}function renderCell(value){return value==null?"":Array.isArray(value)?value.map(entry=>renderCell(entry)).join(";"):typeof value=="object"?JSON.stringify(value):String(value)}function escapeCsvField(value){return/[",\r\n]/.test(value)?`"${value.replace(/"/g,'""')}"`:value}function renderRowsAsCsv(rows){if(rows.length===0)return"";const columns=resolveColumns(rows),lines=[columns.map(column=>escapeCsvField(column)).join(",")];for(const row of rows)lines.push(columns.map(column=>escapeCsvField(renderCell(row[column]))).join(","));return lines.join(`
|
|
2
|
+
`)}function renderRowsAsTable(rows){if(rows.length===0)return"";const columns=resolveColumns(rows),cells=rows.map(row=>columns.map(column=>renderCell(row[column]))),widths=columns.map((column,index)=>Math.max(column.length,...cells.map(rowCells=>rowCells[index].length))),pad=(value,index)=>value.padEnd(widths[index]),lines=[columns.map((column,index)=>pad(column,index)).join(" | ")];lines.push(widths.map(width=>"-".repeat(width)).join("-+-"));for(const rowCells of cells)lines.push(rowCells.map((value,index)=>pad(value,index)).join(" | "));return lines.join(`
|
|
3
|
+
`)}export{renderRowsAsCsv,renderRowsAsTable};
|
|
2
4
|
//# sourceMappingURL=tabular.js.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
(function(){try{var e=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="74b72dd8-0877-55a4-9c80-d043f19e1f96")}catch{}})();import fs from"node:fs/promises";import path from"node:path";import{pathExists}from"../fs/fs-utils.js";import{isPathWithinDirectory}from"../fs/path-utils.js";import{EXIT_CODE}from"../shared/constants.js";import{PmCliError}from"../shared/errors.js";const PM_PACKAGE_RESOURCE_KINDS=["extensions","docs","examples","assets","prompts"],PM_PACKAGE_CONVENTIONAL_RESOURCE_ROOTS=Object.freeze({extensions:Object.freeze([".agents/pm/extensions","extensions",".custom/pm-extensions",".custom/pm-extension"]),docs:Object.freeze(["docs","documentation"]),examples:Object.freeze(["examples","docs/examples"]),assets:Object.freeze(["assets",".agents/pm/assets"]),prompts:Object.freeze(["prompts",".agents/pm/prompts"])});function isKnownPackageResourceKind(value){return PM_PACKAGE_RESOURCE_KINDS.includes(value)}function normalizePackageResourceEntries(kind,raw){if(raw==null)return[];const entries=Array.isArray(raw)?raw:[raw],normalized=[];for(const entry of entries){if(typeof entry!="string"||entry.trim().length===0)throw new PmCliError(`Package manifest field pm.${kind} must contain string paths.`,EXIT_CODE.USAGE);normalized.push(entry.trim())}return[...new Set(normalized)].sort((left,right)=>left.localeCompare(right))}function normalizePackageResourceMap(raw){if(raw==null)return{};if(typeof raw!="object"||Array.isArray(raw))throw new PmCliError("Package manifest field pm must be an object.",EXIT_CODE.USAGE);const resources={},candidate=raw;for(const[key,value]of Object.entries(candidate)){if(!isKnownPackageResourceKind(key))continue;const entries=normalizePackageResourceEntries(key,value);entries.length>0&&(resources[key]=entries)}return resources}function readStringField(source,key){const value=source[key];return typeof value=="string"&&value.trim().length>0?value.trim():void 0}function normalizeStringArray(raw){if(!Array.isArray(raw))return;const values=raw.map(value=>typeof value=="string"?value.trim():"").filter(value=>value.length>0);return values.length>0?[...new Set(values)].sort((left,right)=>left.localeCompare(right)):void 0}function readUrlLikeField(raw){if(typeof raw=="string"&&raw.trim().length>0)return raw.trim();if(typeof raw=="object"&&raw!==null&&!Array.isArray(raw)){const value=raw.url;return typeof value=="string"&&value.trim().length>0?value.trim():void 0}}function normalizeCatalogLinks(raw){if(typeof raw!="object"||raw===null||Array.isArray(raw))return;const source=raw,links={docs:readStringField(source,"docs"),npm:readStringField(source,"npm"),repository:readStringField(source,"repository"),report:readStringField(source,"report")};return Object.values(links).some(value=>typeof value=="string")?links:void 0}function normalizeCatalogMedia(raw){if(typeof raw!="object"||raw===null||Array.isArray(raw))return;const source=raw,media={image:readStringField(source,"image"),video:readStringField(source,"video")};return Object.values(media).some(value=>typeof value=="string")?media:void 0}function normalizePackageCatalogMetadata(raw){if(typeof raw!="object"||raw===null||Array.isArray(raw))return;const source=raw,catalog={display_name:readStringField(source,"display_name")??readStringField(source,"displayName"),category:readStringField(source,"category"),summary:readStringField(source,"summary"),links:normalizeCatalogLinks(source.links),media:normalizeCatalogMedia(source.media),tags:normalizeStringArray(source.tags)};return Object.values(catalog).some(value=>value!==void 0)?catalog:void 0}async function readPmPackageManifest(packageRoot){const packageJsonPath=path.join(packageRoot,"package.json");if(!await pathExists(packageJsonPath))return{source:"convention",resources:{}};let parsed;try{parsed=JSON.parse(await fs.readFile(packageJsonPath,"utf8"))}catch(error){throw new PmCliError(`Failed to parse package manifest at "${packageJsonPath}": ${String(error)}`,EXIT_CODE.USAGE)}if(typeof parsed!="object"||parsed===null||Array.isArray(parsed))throw new PmCliError(`Package manifest at "${packageJsonPath}" must be a JSON object.`,EXIT_CODE.USAGE);const packageJson=parsed,pmManifest=packageJson.pm,hasPmManifest=pmManifest!=null,pmManifestRecord=typeof pmManifest=="object"&&pmManifest!==null&&!Array.isArray(pmManifest)?pmManifest:{};return{source:hasPmManifest?"pm":"convention",package_json_path:packageJsonPath,package_name:typeof packageJson.name=="string"?packageJson.name:void 0,package_version:typeof packageJson.version=="string"?packageJson.version:void 0,package_private:packageJson.private===!0,package_description:typeof packageJson.description=="string"?packageJson.description:void 0,package_keywords:normalizeStringArray(packageJson.keywords),package_homepage:typeof packageJson.homepage=="string"?packageJson.homepage:void 0,package_repository_url:readUrlLikeField(packageJson.repository),package_bugs_url:readUrlLikeField(packageJson.bugs),aliases:normalizeStringArray(pmManifestRecord.aliases),resources:normalizePackageResourceMap(pmManifest),catalog:normalizePackageCatalogMetadata(pmManifestRecord.catalog)}}async function listExtensionManifestDirectories(parentDirectory){if(!await pathExists(parentDirectory))return[];const entries=await fs.readdir(parentDirectory,{withFileTypes:!0}),candidates=[];for(const entry of entries){if(!entry.isDirectory())continue;const directory=path.join(parentDirectory,entry.name);await pathExists(path.join(directory,"manifest.json"))&&candidates.push(directory)}return candidates.sort((left,right)=>left.localeCompare(right))}async function collectPackageExtensionDirectories(packageRoot){if(await pathExists(path.join(packageRoot,"manifest.json")))return[packageRoot];const manifestEntries=(await readPmPackageManifest(packageRoot)).resources.extensions??[],discovered=new Set;for(const entry of manifestEntries){if(entry.includes("*")||entry.startsWith("!"))throw new PmCliError(`Package extension entry "${entry}" uses a glob/exclusion pattern. pm package installs currently require concrete extension paths or directories.`,EXIT_CODE.USAGE);const absolute=path.resolve(packageRoot,entry);if(!isPathWithinDirectory(packageRoot,absolute))throw new PmCliError(`Package extension entry "${entry}" resolves outside package root.`,EXIT_CODE.USAGE);if(await pathExists(path.join(absolute,"manifest.json"))){discovered.add(absolute);continue}for(const child of await listExtensionManifestDirectories(absolute))discovered.add(child)}if(manifestEntries.length===0)for(const root of PM_PACKAGE_CONVENTIONAL_RESOURCE_ROOTS.extensions)for(const child of await listExtensionManifestDirectories(path.join(packageRoot,root)))discovered.add(child);return[...discovered].sort((left,right)=>left.localeCompare(right))}export{PM_PACKAGE_CONVENTIONAL_RESOURCE_ROOTS,PM_PACKAGE_RESOURCE_KINDS,collectPackageExtensionDirectories,readPmPackageManifest};
|
|
2
2
|
//# sourceMappingURL=manifest.js.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
(function(){try{var e=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="efea1aa1-1ad1-5f53-a3a5-b83803d9deb1")}catch{}})();import fs from"node:fs";import path from"node:path";import{fileURLToPath}from"node:url";const PM_CLI_PACKAGE_NAME="@unbrained/pm-cli";function packageJsonNamesPmCli(packageJsonPath){try{return JSON.parse(fs.readFileSync(packageJsonPath,"utf8")).name===PM_CLI_PACKAGE_NAME}catch{return!1}}function findPmPackageRootFromPath(startPath){let current=fs.existsSync(startPath)&&fs.statSync(startPath).isDirectory()?path.resolve(startPath):path.dirname(path.resolve(startPath));for(;;){const packageJsonPath=path.join(current,"package.json");if(fs.existsSync(packageJsonPath)&&packageJsonNamesPmCli(packageJsonPath))return current;const parent=path.dirname(current);if(parent===current)return;current=parent}}function resolvePmPackageRootFromModule(metaUrl,fallbackRelativeSegments=[]){const modulePath=fileURLToPath(metaUrl);return findPmPackageRootFromPath(modulePath)||path.resolve(path.dirname(modulePath),...fallbackRelativeSegments)}function resolvePmCliVersion(metaUrl,fallbackRelativeSegments=[]){try{const packageJsonPath=path.join(resolvePmPackageRootFromModule(metaUrl,fallbackRelativeSegments),"package.json");if(!fs.existsSync(packageJsonPath))return;const parsed=JSON.parse(fs.readFileSync(packageJsonPath,"utf8"));return typeof parsed.version=="string"&&parsed.version.trim().length>0?parsed.version:void 0}catch{return}}function resolveConfiguredPmPackageRoot(env=process.env,envName="PM_CLI_PACKAGE_ROOT",metaUrl,fallbackRelativeSegments=[]){const envRoot=env[envName];return typeof envRoot=="string"&&envRoot.trim().length>0?path.resolve(envRoot.trim()):metaUrl?resolvePmPackageRootFromModule(metaUrl,fallbackRelativeSegments):process.cwd()}export{findPmPackageRootFromPath,resolveConfiguredPmPackageRoot,resolvePmCliVersion,resolvePmPackageRootFromModule};
|
|
2
2
|
//# sourceMappingURL=root.js.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
(function(){try{var e=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="caa9f916-c7ce-5e74-a00b-dd0fc6a41b5d")}catch{}})();import{MAX_WORKFLOW_POLICIES,MAX_WORKFLOW_POLICY_TERMS}from"./workflow-policy.js";const text={type:"string",minLength:1,maxLength:128,pattern:"\\S"},terms={type:"array",minItems:1,maxItems:MAX_WORKFLOW_POLICY_TERMS,items:text},fields={...terms,items:{...text,pattern:"^(?!(?:.*\\.)?(?:__proto__|constructor|prototype)(?:\\.|$))[a-zA-Z_][a-zA-Z0-9_]*(?:\\.[a-zA-Z_][a-zA-Z0-9_]*){0,7}$"}},WORKFLOW_POLICY_SCHEMA={type:"object",additionalProperties:!1,required:["id","rule"],properties:{id:{type:"string",minLength:1,maxLength:128,pattern:"^[a-zA-Z0-9][a-zA-Z0-9._-]*$"},description:{type:"string",minLength:1,maxLength:500,pattern:"\\S"},effect:{enum:["advise","warn","refuse"]},subject:{type:"object",additionalProperties:!1,properties:{...Object.fromEntries(["types","tags","statuses","operations","parents"].map(key=>[key,terms])),dependency:{type:"object",additionalProperties:!1,required:["kind"],properties:{kind:text,id:text}}}},rule:{oneOf:[{type:"object",additionalProperties:!1,required:["kind","fields"],properties:{kind:{const:"require_fields"},fields}},{type:"object",additionalProperties:!1,required:["kind","authors"],properties:{kind:{const:"authors"},authors:terms}},...["field_writers","approval"].map(kind=>({type:"object",additionalProperties:!1,required:["kind","fields","authors"],properties:{kind:{const:kind},fields,authors:terms}})),{type:"object",additionalProperties:!1,required:["kind","allowed"],properties:{kind:{const:"transition"},allowed:{type:"array",maxItems:MAX_WORKFLOW_POLICY_TERMS,items:{type:"array",minItems:2,maxItems:2,items:text}}}}]}}},WORKFLOW_POLICY_DOCUMENT_SCHEMA={$schema:"https://json-schema.org/draft/2020-12/schema",title:"pm workflow policy registry",type:"object",additionalProperties:!1,required:["version","policies"],properties:{version:{const:1},enforcement:{enum:["advise","refuse"],default:"advise"},policies:{type:"array",maxItems:MAX_WORKFLOW_POLICIES,items:WORKFLOW_POLICY_SCHEMA}}};export{WORKFLOW_POLICY_DOCUMENT_SCHEMA,WORKFLOW_POLICY_SCHEMA};
|
|
2
2
|
//# sourceMappingURL=workflow-policy-schema.js.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
(function(){try{var e=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="7db1d069-0038-57f8-8c3e-0b0ba66579ca")}catch{}})();import fs from"node:fs/promises";import path from"node:path";import{renderPmCommand}from"../shared/command-line.js";import{canonicalizeCommandOptionKey,commandOptionFlagLabel}from"../item/type-registry.js";import{isUtf8}from"node:buffer";import{isFileMissingError}from"../fs/fs-utils.js";import{appendWorkspaceAuditEvent}from"../history/workspace-history.js";import{verifyHistoryChain}from"../history/replay.js";import{PmCliError}from"../shared/errors.js";import{EXIT_CODE}from"../shared/constants.js";import{getHistoryPath}from"../store/paths.js";import{evaluateWorkflowPolicies,parseWorkflowPolicyDocument,workflowPolicyApplies}from"./workflow-policy.js";const MAX_WORKFLOW_POLICY_BYTES=1048576,MAX_WORKFLOW_APPROVAL_HISTORY_BYTES=4194304;async function readBoundedPolicyFile(file,maxBytes){let ancestor=path.dirname(file);for(;ancestor!==path.parse(file).root;){const stats=await fs.stat(ancestor).catch(error=>{if(isFileMissingError(error))return null;throw error});if(stats!==null){if(!stats.isDirectory())throw new PmCliError("Workflow policy storage ancestor must be a directory.",EXIT_CODE.CONFLICT,{code:"workflow_policy_input_unreadable",nextSteps:["Restore the policy or approval history directory before retrying."]});break}ancestor=path.dirname(ancestor)}const handle=await fs.open(file,"r").catch(error=>{if(isFileMissingError(error))return null;throw error});if(handle===null)return null;try{const size=(await handle.stat()).size,buffer=Buffer.alloc(Math.min(maxBytes,size)+1);let offset=0;for(;offset<buffer.length;){const read=await handle.read(buffer,offset,buffer.length-offset,offset);if(read.bytesRead===0)break;offset+=read.bytesRead}if(offset===buffer.length||!isUtf8(buffer.subarray(0,offset)))throw new PmCliError("Workflow policy input exceeds its byte bound or is not valid UTF-8.",EXIT_CODE.CONFLICT,{code:"workflow_policy_input_unreadable",nextSteps:["Inspect the policy and approval history; reduce the declaration or use verified history compaction before retrying."]});return buffer.toString("utf8",0,offset)}finally{await handle.close()}}function decodeWorkflowPolicyDocument(raw){if(raw===null)return{version:1,enforcement:"advise",policies:[]};let value;try{value=JSON.parse(raw)}catch{throw new PmCliError("schema/policies.json must contain valid JSON.",EXIT_CODE.CONFLICT,{code:"workflow_policy_registry_invalid",nextSteps:["Restore valid policy JSON before retrying the mutation."]})}return parseWorkflowPolicyDocument(value)}async function readWorkflowPolicies(pmRoot){return decodeWorkflowPolicyDocument(await readBoundedPolicyFile(path.join(pmRoot,"schema","policies.json"),MAX_WORKFLOW_POLICY_BYTES))}async function readWorkflowApprovals(pmRoot,id){const raw=await readBoundedPolicyFile(getHistoryPath(pmRoot,id),MAX_WORKFLOW_APPROVAL_HISTORY_BYTES);if(raw===null)return[];let entries;try{if(entries=raw.split(/\r?\n/).filter(line=>line.trim()).map(line=>JSON.parse(line)),!verifyHistoryChain(entries).ok)throw new Error("invalid chain")}catch{throw new PmCliError("Approval evidence requires a valid item history chain.",EXIT_CODE.CONFLICT,{code:"workflow_policy_approval_history_invalid",nextSteps:[`Run pm history ${id} --verify before recording or using an approval.`]})}return entries.flatMap(entry=>{const approval=entry.context?.workflow_approval;if(entry.op!=="policy_approve"||entry.record_hash_version!==1||typeof entry.record_hash!="string"||typeof approval!="object"||approval===null)return[];const record=approval;return typeof record.policy_fingerprint!="string"||typeof record.content_fingerprint!="string"?[]:[{policy_fingerprint:record.policy_fingerprint,content_fingerprint:record.content_fingerprint,author:entry.author}]})}async function evaluateWorkspacePolicies(pmRoot,document,input){const needsApproval=input.before?.status!==input.after?.status&&document.policies.some(policy=>policy.rule.kind==="approval"&&workflowPolicyApplies(policy,input)),id=input.before?.id??input.after?.id,approvals=needsApproval&&typeof id=="string"?await readWorkflowApprovals(pmRoot,id):[];return evaluateWorkflowPolicies(document,{...input,approvals})}async function enforceWorkflowMutation(params){const document=await readWorkflowPolicies(params.pmRoot),result=await evaluateWorkspacePolicies(params.pmRoot,document,{operation:params.operation,author:params.author,before:params.before?{...params.before.metadata,body:params.before.body}:null,after:params.after?{...params.after.metadata,body:params.after.body}:null});if(result.allowed)return result;const refused=result.decisions.filter(decision=>!decision.satisfied&&decision.effect==="refuse");if(!params.dryRun)try{await appendWorkspaceAuditEvent({pmRoot:params.pmRoot,op:"policy_refused",author:params.author,context:{item_id:params.after?.metadata.id??params.before?.metadata.id,operation:params.operation,workflow_policies:result.decisions},message:"Workflow policy refused a proposed item mutation.",lockTtlSeconds:params.settings.locks.ttl_seconds,lockWaitMs:params.settings.locks.wait_ms})}catch(cause){const error=new PmCliError("Workflow policy refusal could not be recorded in workspace history.",EXIT_CODE.CONFLICT,{code:"workflow_policy_audit_failed",nextSteps:["Resolve workspace-history lock or storage failures, then retry the refused mutation; no item changes were written."]});throw error.cause=cause,error}const violations=refused.slice(0,3).map(decision=>({policy_id:decision.policy_id,rule:decision.rule,description:document.policies.find(policy=>policy.id===decision.policy_id).description,missing_fields:decision.missing_fields})),missing=[...new Set(violations.flatMap(decision=>decision.missing_fields))],summary=violations.map(decision=>`${decision.policy_id} (${decision.rule})`).join(", "),remaining=refused.length>3?` and ${refused.length-3} more`:"",itemId=params.after?.metadata.id??params.before.metadata.id,fieldSteps=missing.map(field=>{if(params.before===null)return`Supply ${field} in the original ${params.operation} request, then retry; the item was not created.`;const option=canonicalizeCommandOptionKey("update",field);return option===void 0?`Supply ${field} using its declared SDK or package mutation contract, then retry.`:renderPmCommand(["update",itemId,commandOptionFlagLabel("update",option),`<${field}>`,"--pm-path",path.resolve(params.pmRoot)])});throw new PmCliError(`Workflow policy refused ${params.operation}: ${summary}${remaining}.${missing.length?` Missing: ${missing.join(", ")}.`:""}`,EXIT_CODE.CONFLICT,{code:"workflow_policy_refused",reason:violations.map(decision=>decision.policy_id).join(","),policy_violations:violations,policy_violation_count:refused.length,required:missing.length?`Supply missing fields: ${missing.join(", ")}, then retry the refused mutation.`:"Satisfy the declared workflow policy before retrying.",why:violations.map(decision=>decision.description).filter(Boolean).join(" ")||void 0,recovery:{missing_required_fields:missing},nextSteps:[...fieldSteps,...new Set(refused.slice(0,3).filter(decision=>decision.missing_fields.length===0).map(decision=>decision.remediation)),...refused.length>3?[`Inspect all policies with pm schema policies before retrying ${params.operation}.`]:[]]})}export{MAX_WORKFLOW_APPROVAL_HISTORY_BYTES,MAX_WORKFLOW_POLICY_BYTES,decodeWorkflowPolicyDocument,enforceWorkflowMutation,evaluateWorkspacePolicies,readWorkflowApprovals,readWorkflowPolicies};
|
|
2
2
|
//# sourceMappingURL=workflow-policy-store.js.map
|
|
@@ -1,2 +1,2 @@
|
|
|
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]="8b0d8654-211b-57bf-852f-8a153849e8fd")}catch(e2){}})();import{createHash}from"node:crypto";import{stableStringify,stableValueEquals}from"../shared/serialization.js";import{PmCliError}from"../shared/errors.js";import{EXIT_CODE}from"../shared/constants.js";const WORKFLOW_POLICY_ACTIONS=["policies","policy-put","policy-remove","policy-mode","policy-check","policy-approve","policy-presets"];const MAX_WORKFLOW_POLICIES=256;const MAX_WORKFLOW_POLICY_TERMS=64;function invalidPolicy(detail){throw new PmCliError(`Invalid workflow policy: ${detail}`,EXIT_CODE.USAGE,{code:"workflow_policy_invalid",nextSteps:["Inspect pm schema policies and correct the declaration using pm schema policy-put."]})}function policyObject(value,keys,label){if(typeof value!=="object"||value===null||Array.isArray(value))return invalidPolicy(`${label} must be an object`);const record=value;if(Object.keys(record).some(key=>!keys.includes(key)))return invalidPolicy(`${label} contains an unknown key`);return record}function policyText(value,label,max=128){if(typeof value!=="string"||!value.trim()||value.length>max)return invalidPolicy(`${label} must be nonempty text of at most ${max} characters`);return value.trim()}function policyTerms(value,label){if(!Array.isArray(value)||value.length===0||value.length>MAX_WORKFLOW_POLICY_TERMS)return invalidPolicy(`${label} requires 1-${MAX_WORKFLOW_POLICY_TERMS} terms`);const terms=value.map(entry=>policyText(entry,label));if(label==="fields"&&terms.some(term=>!/^[a-zA-Z_][a-zA-Z0-9_]*(?:\.[a-zA-Z_][a-zA-Z0-9_]*){0,7}$/.test(term)||term.split(".").some(part=>["__proto__","constructor","prototype"].includes(part))))return invalidPolicy("fields must be safe metadata paths of at most eight segments");return[...new Set(terms)]}function parsePolicyRule(value){const common=policyObject(value,["kind","fields","authors","allowed"],"rule");if(common.kind==="transition"){policyObject(common,["kind","allowed"],"transition rule");if(!Array.isArray(common.allowed)||common.allowed.length>MAX_WORKFLOW_POLICY_TERMS)return invalidPolicy("transition.allowed must be a bounded array");return{kind:"transition",allowed:common.allowed.map(pair=>{if(!Array.isArray(pair)||pair.length!==2)return invalidPolicy("transition pairs need two statuses");return[policyText(pair[0],"from"),policyText(pair[1],"to")]})}}if(common.kind==="authors"){policyObject(common,["kind","authors"],"authors rule");return{kind:"authors",authors:policyTerms(common.authors,"authors")}}if(common.kind==="require_fields"){policyObject(common,["kind","fields"],"require_fields rule");return{kind:"require_fields",fields:policyTerms(common.fields,"fields")}}if(common.kind==="field_writers"||common.kind==="approval"){policyObject(common,["kind","fields","authors"],"field rule");return{kind:common.kind,fields:policyTerms(common.fields,"fields"),authors:policyTerms(common.authors,"authors")}}return invalidPolicy("unknown rule kind")}function parsePolicySubject(value){const subject={};const source=policyObject(value,["types","tags","statuses","operations","parents","dependency"],"subject");for(const key of["types","tags","statuses","operations","parents"]){if(source[key]!==void 0)subject[key]=policyTerms(source[key],key)}if(source.dependency!==void 0){const edge=policyObject(source.dependency,["kind","id"],"dependency");subject.dependency={kind:policyText(edge.kind,"dependency kind"),...edge.id===void 0?{}:{id:policyText(edge.id,"dependency id")}}}return subject}function parseWorkflowPolicy(value){const raw=policyObject(value,["id","description","subject","effect","rule"],"policy");const id=policyText(raw.id,"id");if(!/^[a-zA-Z0-9][a-zA-Z0-9._-]*$/.test(id))return invalidPolicy("id must be a stable token");if(raw.effect!==void 0&&(typeof raw.effect!=="string"||!["advise","warn","refuse"].includes(raw.effect)))return invalidPolicy("effect must be advise, warn, or refuse");return{id,rule:parsePolicyRule(raw.rule),...raw.subject===void 0?{}:{subject:parsePolicySubject(raw.subject)},...raw.description===void 0?{}:{description:policyText(raw.description,"description",500)},...raw.effect===void 0?{}:{effect:raw.effect}}}function parseWorkflowPolicyDocument(value){const raw=policyObject(value,["version","enforcement","policies"],"document");if(raw.version!==1)return invalidPolicy("unsupported version");if(raw.enforcement!==void 0&&raw.enforcement!=="advise"&&raw.enforcement!=="refuse")return invalidPolicy("enforcement must be advise or refuse");if(!Array.isArray(raw.policies)||raw.policies.length>MAX_WORKFLOW_POLICIES)return invalidPolicy(`policies must contain at most ${MAX_WORKFLOW_POLICIES} declarations`);const policies=raw.policies.map(parseWorkflowPolicy);if(new Set(policies.map(policy=>policy.id)).size!==policies.length)return invalidPolicy("duplicate policy id");return{version:1,enforcement:raw.enforcement??"advise",policies}}function readWorkflowPolicyField(record,field){let value=record;for(const key of field.split(".")){if(typeof value!=="object"||value===null||!Object.hasOwn(value,key))return void 0;value=value[key]}return value}function hasPolicyValue(value){if(value===void 0||value===null)return false;if(typeof value==="string")return value.trim().length>0;if(typeof value==="number")return Number.isFinite(value);if(Array.isArray(value))return value.length>0;if(typeof value==="object")return Object.keys(value).length>0;return true}function workflowPolicyFingerprint(policy){return createHash("sha256").update(stableStringify(policy)).digest("hex")}function workflowApprovalFingerprint(policy,record){const fields=policy.rule.kind==="approval"?policy.rule.fields:[];return createHash("sha256").update(stableStringify({id:record.id,fields:fields.map(field=>[field,readWorkflowPolicyField(record,field)])})).digest("hex")}function matchesPolicyDependency(expected,dependencies){return Array.isArray(dependencies)&&dependencies.some(edge=>typeof edge==="object"&&edge!==null&&"kind"in edge&&edge.kind===expected.kind&&(expected.id===void 0||"id"in edge&&edge.id===expected.id))}function matchesPolicySubject(subject,record,operation){if(subject.types&&!subject.types.some(type=>type.toLowerCase()===String(record.type).toLowerCase()))return false;if(subject.statuses&&!subject.statuses.includes(String(record.status)))return false;if(subject.operations&&!subject.operations.includes(operation))return false;if(subject.parents&&!subject.parents.includes(String(record.parent)))return false;if(subject.tags&&(!Array.isArray(record.tags)||!subject.tags.some(tag=>record.tags.includes(tag))))return false;if(subject.dependency&&!matchesPolicyDependency(subject.dependency,record.dependencies))return false;return true}function workflowPolicyApplies(policy,input){if(input.completeness_only&&(policy.rule.kind!=="require_fields"||policy.subject?.operations!==void 0))return false;if(policy.rule.kind==="approval"&&input.before===null)return false;const subject=policy.subject??{};const status=input.after?.status??input.before?.status;return[input.before,input.after].some(record=>record!==null&&matchesPolicySubject(subject,{...record,status},input.operation))}function missingRequiredPolicyFields(fields,input,changedStatus,fieldsChanged){const scopeChanged=["type","tags","parent","dependencies"].some(field=>!stableValueEquals(input.before?.[field],input.after?.[field]));const missing=input.after&&(input.completeness_only||changedStatus||fieldsChanged||scopeChanged)?fields.filter(field=>!hasPolicyValue(readWorkflowPolicyField(input.after,field))):[];return missing}function hasMatchingWorkflowApproval(policy,input,authors,policyFingerprint){const record=input.after??input.before;const contentFingerprint=workflowApprovalFingerprint(policy,record);return input.approvals?.some(approval=>approval.policy_fingerprint===policyFingerprint&&approval.content_fingerprint===contentFingerprint&&approval.author!==input.author&&authors.includes(approval.author))??false}function evaluatePolicyRule(policy,input,policyFingerprint){const rule=policy.rule;const changedStatus=input.before?.status!==input.after?.status;const fieldsChanged="fields"in rule&&rule.fields.some(field=>!stableValueEquals(readWorkflowPolicyField(input.before,field),readWorkflowPolicyField(input.after,field)));switch(rule.kind){case"require_fields":{const missing=missingRequiredPolicyFields(rule.fields,input,changedStatus,fieldsChanged);return{satisfied:missing.length===0,missing_fields:missing,remediation:"Supply the declared required fields before this lifecycle transition."}}case"transition":return{satisfied:!changedStatus||rule.allowed.some(([from,to])=>from===String(input.before?.status??"$create")&&to===String(input.after?.status??"$delete")),missing_fields:[],remediation:"Choose a declared allowed transition; inspect pm schema policies."};case"authors":return{satisfied:rule.authors.includes(input.author),missing_fields:[],remediation:"Have a declared workflow actor perform this operation."};case"field_writers":return{satisfied:!fieldsChanged||rule.authors.includes(input.author),missing_fields:[],remediation:"Have a declared field writer change the protected fields."};case"approval":return{satisfied:!changedStatus||hasMatchingWorkflowApproval(policy,input,rule.authors,policyFingerprint),missing_fields:[],remediation:`Record an independent approval with pm schema policy-approve <item-id> --policy ${policy.id} after preparing the reviewed fields.`}}}function evaluateWorkflowPolicySnapshot(document,input,fingerprint){const decisions=document.policies.filter(policy=>workflowPolicyApplies(policy,input)).map(policy=>{const requested=policy.effect??"advise";const policyFingerprint=fingerprint(policy);return{policy_id:policy.id,policy_fingerprint:policyFingerprint,rule:policy.rule.kind,effect:requested==="refuse"&&document.enforcement!=="refuse"?"warn":requested,...evaluatePolicyRule(policy,input,policyFingerprint)}});return{allowed:!decisions.some(decision=>!decision.satisfied&&decision.effect==="refuse"),decisions,warnings:decisions.filter(decision=>!decision.satisfied).map(decision=>`workflow_policy:${decision.effect}:${decision.policy_id}:${decision.rule}`)}}function evaluateWorkflowPolicies(document,input){return evaluateWorkflowPolicySnapshot(document,input,workflowPolicyFingerprint)}function createWorkflowPolicyEvaluator(document){const snapshot=parseWorkflowPolicyDocument(document);const fingerprints=new Map(snapshot.policies.map(policy=>[policy,workflowPolicyFingerprint(policy)]));return input=>evaluateWorkflowPolicySnapshot(snapshot,input,policy=>fingerprints.get(policy))}export{MAX_WORKFLOW_POLICIES,MAX_WORKFLOW_POLICY_TERMS,WORKFLOW_POLICY_ACTIONS,createWorkflowPolicyEvaluator,evaluateWorkflowPolicies,parseWorkflowPolicy,parseWorkflowPolicyDocument,readWorkflowPolicyField,workflowApprovalFingerprint,workflowPolicyApplies,workflowPolicyFingerprint};
|
|
1
|
+
(function(){try{var e=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="f675993f-c483-5751-baed-d968b4fd24c0")}catch{}})();import{createHash}from"node:crypto";import{stableStringify,stableValueEquals}from"../shared/serialization.js";import{PmCliError}from"../shared/errors.js";import{EXIT_CODE}from"../shared/constants.js";const WORKFLOW_POLICY_ACTIONS=["policies","policy-put","policy-remove","policy-mode","policy-check","policy-approve","policy-presets"],MAX_WORKFLOW_POLICIES=256,MAX_WORKFLOW_POLICY_TERMS=64;function invalidPolicy(detail){throw new PmCliError(`Invalid workflow policy: ${detail}`,EXIT_CODE.USAGE,{code:"workflow_policy_invalid",nextSteps:["Inspect pm schema policies and correct the declaration using pm schema policy-put."]})}function policyObject(value,keys,label){if(typeof value!="object"||value===null||Array.isArray(value))return invalidPolicy(`${label} must be an object`);const record=value;return Object.keys(record).some(key=>!keys.includes(key))?invalidPolicy(`${label} contains an unknown key`):record}function policyText(value,label,max=128){return typeof value!="string"||!value.trim()||value.length>max?invalidPolicy(`${label} must be nonempty text of at most ${max} characters`):value.trim()}function policyTerms(value,label){if(!Array.isArray(value)||value.length===0||value.length>MAX_WORKFLOW_POLICY_TERMS)return invalidPolicy(`${label} requires 1-${MAX_WORKFLOW_POLICY_TERMS} terms`);const terms=value.map(entry=>policyText(entry,label));return label==="fields"&&terms.some(term=>!/^[a-zA-Z_][a-zA-Z0-9_]*(?:\.[a-zA-Z_][a-zA-Z0-9_]*){0,7}$/.test(term)||term.split(".").some(part=>["__proto__","constructor","prototype"].includes(part)))?invalidPolicy("fields must be safe metadata paths of at most eight segments"):[...new Set(terms)]}function parsePolicyRule(value){const common=policyObject(value,["kind","fields","authors","allowed"],"rule");return common.kind==="transition"?(policyObject(common,["kind","allowed"],"transition rule"),!Array.isArray(common.allowed)||common.allowed.length>MAX_WORKFLOW_POLICY_TERMS?invalidPolicy("transition.allowed must be a bounded array"):{kind:"transition",allowed:common.allowed.map(pair=>!Array.isArray(pair)||pair.length!==2?invalidPolicy("transition pairs need two statuses"):[policyText(pair[0],"from"),policyText(pair[1],"to")])}):common.kind==="authors"?(policyObject(common,["kind","authors"],"authors rule"),{kind:"authors",authors:policyTerms(common.authors,"authors")}):common.kind==="require_fields"?(policyObject(common,["kind","fields"],"require_fields rule"),{kind:"require_fields",fields:policyTerms(common.fields,"fields")}):common.kind==="field_writers"||common.kind==="approval"?(policyObject(common,["kind","fields","authors"],"field rule"),{kind:common.kind,fields:policyTerms(common.fields,"fields"),authors:policyTerms(common.authors,"authors")}):invalidPolicy("unknown rule kind")}function parsePolicySubject(value){const subject={},source=policyObject(value,["types","tags","statuses","operations","parents","dependency"],"subject");for(const key of["types","tags","statuses","operations","parents"])source[key]!==void 0&&(subject[key]=policyTerms(source[key],key));if(source.dependency!==void 0){const edge=policyObject(source.dependency,["kind","id"],"dependency");subject.dependency={kind:policyText(edge.kind,"dependency kind"),...edge.id===void 0?{}:{id:policyText(edge.id,"dependency id")}}}return subject}function parseWorkflowPolicy(value){const raw=policyObject(value,["id","description","subject","effect","rule"],"policy"),id=policyText(raw.id,"id");return/^[a-zA-Z0-9][a-zA-Z0-9._-]*$/.test(id)?raw.effect!==void 0&&(typeof raw.effect!="string"||!["advise","warn","refuse"].includes(raw.effect))?invalidPolicy("effect must be advise, warn, or refuse"):{id,rule:parsePolicyRule(raw.rule),...raw.subject===void 0?{}:{subject:parsePolicySubject(raw.subject)},...raw.description===void 0?{}:{description:policyText(raw.description,"description",500)},...raw.effect===void 0?{}:{effect:raw.effect}}:invalidPolicy("id must be a stable token")}function parseWorkflowPolicyDocument(value){const raw=policyObject(value,["version","enforcement","policies"],"document");if(raw.version!==1)return invalidPolicy("unsupported version");if(raw.enforcement!==void 0&&raw.enforcement!=="advise"&&raw.enforcement!=="refuse")return invalidPolicy("enforcement must be advise or refuse");if(!Array.isArray(raw.policies)||raw.policies.length>MAX_WORKFLOW_POLICIES)return invalidPolicy(`policies must contain at most ${MAX_WORKFLOW_POLICIES} declarations`);const policies=raw.policies.map(parseWorkflowPolicy);return new Set(policies.map(policy=>policy.id)).size!==policies.length?invalidPolicy("duplicate policy id"):{version:1,enforcement:raw.enforcement??"advise",policies}}function readWorkflowPolicyField(record,field){let value=record;for(const key of field.split(".")){if(typeof value!="object"||value===null||!Object.hasOwn(value,key))return;value=value[key]}return value}function hasPolicyValue(value){return value==null?!1:typeof value=="string"?value.trim().length>0:typeof value=="number"?Number.isFinite(value):Array.isArray(value)?value.length>0:typeof value=="object"?Object.keys(value).length>0:!0}function workflowPolicyFingerprint(policy){return createHash("sha256").update(stableStringify(policy)).digest("hex")}function workflowApprovalFingerprint(policy,record){const fields=policy.rule.kind==="approval"?policy.rule.fields:[];return createHash("sha256").update(stableStringify({id:record.id,fields:fields.map(field=>[field,readWorkflowPolicyField(record,field)])})).digest("hex")}function matchesPolicyDependency(expected,dependencies){return Array.isArray(dependencies)&&dependencies.some(edge=>typeof edge=="object"&&edge!==null&&"kind"in edge&&edge.kind===expected.kind&&(expected.id===void 0||"id"in edge&&edge.id===expected.id))}function matchesPolicySubject(subject,record,operation){return!(subject.types&&!subject.types.some(type=>type.toLowerCase()===String(record.type).toLowerCase())||subject.statuses&&!subject.statuses.includes(String(record.status))||subject.operations&&!subject.operations.includes(operation)||subject.parents&&!subject.parents.includes(String(record.parent))||subject.tags&&(!Array.isArray(record.tags)||!subject.tags.some(tag=>record.tags.includes(tag)))||subject.dependency&&!matchesPolicyDependency(subject.dependency,record.dependencies))}function workflowPolicyApplies(policy,input){if(input.completeness_only&&(policy.rule.kind!=="require_fields"||policy.subject?.operations!==void 0)||policy.rule.kind==="approval"&&input.before===null)return!1;const subject=policy.subject??{},status=input.after?.status??input.before?.status;return[input.before,input.after].some(record=>record!==null&&matchesPolicySubject(subject,{...record,status},input.operation))}function missingRequiredPolicyFields(fields,input,changedStatus,fieldsChanged){const scopeChanged=["type","tags","parent","dependencies"].some(field=>!stableValueEquals(input.before?.[field],input.after?.[field]));return input.after&&(input.completeness_only||changedStatus||fieldsChanged||scopeChanged)?fields.filter(field=>!hasPolicyValue(readWorkflowPolicyField(input.after,field))):[]}function hasMatchingWorkflowApproval(policy,input,authors,policyFingerprint){const record=input.after??input.before,contentFingerprint=workflowApprovalFingerprint(policy,record);return input.approvals?.some(approval=>approval.policy_fingerprint===policyFingerprint&&approval.content_fingerprint===contentFingerprint&&approval.author!==input.author&&authors.includes(approval.author))??!1}function evaluatePolicyRule(policy,input,policyFingerprint){const rule=policy.rule,changedStatus=input.before?.status!==input.after?.status,fieldsChanged="fields"in rule&&rule.fields.some(field=>!stableValueEquals(readWorkflowPolicyField(input.before,field),readWorkflowPolicyField(input.after,field)));switch(rule.kind){case"require_fields":{const missing=missingRequiredPolicyFields(rule.fields,input,changedStatus,fieldsChanged);return{satisfied:missing.length===0,missing_fields:missing,remediation:"Supply the declared required fields before this lifecycle transition."}}case"transition":return{satisfied:!changedStatus||rule.allowed.some(([from,to])=>from===String(input.before?.status??"$create")&&to===String(input.after?.status??"$delete")),missing_fields:[],remediation:"Choose a declared allowed transition; inspect pm schema policies."};case"authors":return{satisfied:rule.authors.includes(input.author),missing_fields:[],remediation:"Have a declared workflow actor perform this operation."};case"field_writers":return{satisfied:!fieldsChanged||rule.authors.includes(input.author),missing_fields:[],remediation:"Have a declared field writer change the protected fields."};case"approval":return{satisfied:!changedStatus||hasMatchingWorkflowApproval(policy,input,rule.authors,policyFingerprint),missing_fields:[],remediation:`Record an independent approval with pm schema policy-approve <item-id> --policy ${policy.id} after preparing the reviewed fields.`}}}function evaluateWorkflowPolicySnapshot(document,input,fingerprint){const decisions=document.policies.filter(policy=>workflowPolicyApplies(policy,input)).map(policy=>{const requested=policy.effect??"advise",policyFingerprint=fingerprint(policy);return{policy_id:policy.id,policy_fingerprint:policyFingerprint,rule:policy.rule.kind,effect:requested==="refuse"&&document.enforcement!=="refuse"?"warn":requested,...evaluatePolicyRule(policy,input,policyFingerprint)}});return{allowed:!decisions.some(decision=>!decision.satisfied&&decision.effect==="refuse"),decisions,warnings:decisions.filter(decision=>!decision.satisfied).map(decision=>`workflow_policy:${decision.effect}:${decision.policy_id}:${decision.rule}`)}}function evaluateWorkflowPolicies(document,input){return evaluateWorkflowPolicySnapshot(document,input,workflowPolicyFingerprint)}function createWorkflowPolicyEvaluator(document){const snapshot=parseWorkflowPolicyDocument(document),fingerprints=new Map(snapshot.policies.map(policy=>[policy,workflowPolicyFingerprint(policy)]));return input=>evaluateWorkflowPolicySnapshot(snapshot,input,policy=>fingerprints.get(policy))}export{MAX_WORKFLOW_POLICIES,MAX_WORKFLOW_POLICY_TERMS,WORKFLOW_POLICY_ACTIONS,createWorkflowPolicyEvaluator,evaluateWorkflowPolicies,parseWorkflowPolicy,parseWorkflowPolicyDocument,readWorkflowPolicyField,workflowApprovalFingerprint,workflowPolicyApplies,workflowPolicyFingerprint};
|
|
2
2
|
//# sourceMappingURL=workflow-policy.js.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
(function(){try{var e=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="ab26bcb3-fb2a-5f2f-96e7-7965787b924e")}catch{}})();import{normalizeAddFieldInput}from"../schema/fields-file.js";import{normalizeAddStatusInput}from"../schema/status-defs-file.js";import{normalizeAddTypeInput}from"../schema/item-types-file.js";function describeProfileComposition(profile){return{types:profile.types.length,statuses:profile.statuses.length,fields:profile.fields.length,workflows:profile.workflows.length,config:profile.config.length,templates:profile.templates.length,packages:profile.packages.length}}function describeProjectProfile(profile){return{name:profile.name,title:profile.title,summary:profile.summary,composition:describeProfileComposition(profile),types:profile.types.map(type=>lenientIdentifier(()=>normalizeAddTypeInput(type).name,()=>String(type.name??""))),statuses:profile.statuses.map(status=>lenientIdentifier(()=>normalizeAddStatusInput(status).id,()=>String(status.id??""))),fields:profile.fields.map(field=>lenientIdentifier(()=>normalizeAddFieldInput(field).key,()=>String(field.key??""))),workflows:profile.workflows.map(workflow=>workflow.type),config:profile.config.map(entry=>`${entry.key}=${entry.value}`),templates:profile.templates.map(template=>template.name),packages:profile.packages.map(recommendation=>({spec:recommendation.spec,reason:recommendation.reason}))}}function lenientIdentifier(normalize,raw){try{return normalize()}catch{return raw()}}export{describeProfileComposition,describeProjectProfile};
|
|
2
2
|
//# sourceMappingURL=profile-describe.js.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
(function(){try{var e=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="0b04624c-2096-55dc-9dde-b8c76ead72d6")}catch{}})();import{BUILTIN_ITEM_TYPE_VALUES}from"../../types/index.js";import{parseNestedSettingValue,resolveNestedSettingDescriptor}from"../config/nested-settings.js";import{normalizeAddFieldInput}from"../schema/fields-file.js";import{normalizeAddStatusInput}from"../schema/status-defs-file.js";import{normalizeAddTypeInput}from"../schema/item-types-file.js";import{normalizeStatusToken}from"../schema/type-workflows.js";import{DEFAULT_RUNTIME_STATUS_DEFINITIONS}from"../schema/runtime-schema.js";import{toErrorMessage}from"../shared/primitives.js";import{resolvePmToolCustomFieldCollision}from"../../sdk/cli-contracts/tool-schema.js";import{normalizeProfileLookupKey}from"./profile-presets.js";const PROFILE_LINT_DIMENSIONS=["profile","types","statuses","fields","workflows","config","templates","packages"],PROFILE_LINT_CODES=["profile_name_empty","profile_name_not_normalized","profile_title_empty","profile_summary_empty","type_invalid","type_duplicate","status_invalid","status_duplicate","field_invalid","field_duplicate","field_mcp_input_collision","workflow_type_empty","workflow_type_unknown","workflow_duplicate_type","workflow_transition_malformed","workflow_status_unknown","config_key_unknown","config_value_invalid","config_duplicate","template_type_unknown","package_spec_empty"],BUILTIN_STATUS_TOKENS=new Set(DEFAULT_RUNTIME_STATUS_DEFINITIONS.flatMap(definition=>[normalizeStatusToken(definition.id),...(definition.aliases??[]).map(alias=>normalizeStatusToken(alias))]).filter(token=>token.length>0)),BUILTIN_TYPE_KEYS=new Set(BUILTIN_ITEM_TYPE_VALUES.map(name=>name.toLowerCase()));function lintProfileIdentity(profile,findings){profile.name.trim().length===0?findings.push({severity:"error",code:"profile_name_empty",dimension:"profile",message:"Profile name must not be empty; profile resolution requires a non-blank name."}):profile.name!==normalizeProfileLookupKey(profile.name)&&findings.push({severity:"warning",code:"profile_name_not_normalized",dimension:"profile",target:profile.name,message:`Profile name "${profile.name}" is not in canonical form; resolution folds it to "${normalizeProfileLookupKey(profile.name)}" (lowercase, hyphens as underscores).`}),profile.title.trim().length===0&&findings.push({severity:"warning",code:"profile_title_empty",dimension:"profile",message:"Profile title is empty; list and show surfaces will render a blank title."}),profile.summary.trim().length===0&&findings.push({severity:"warning",code:"profile_summary_empty",dimension:"profile",message:"Profile summary is empty; list and show surfaces will render a blank archetype description."})}function lintTypes(profile,findings){const declared=new Set,seen=new Set;for(const[index,type]of profile.types.entries()){let name;try{name=normalizeAddTypeInput(type).name}catch(error){findings.push({severity:"error",code:"type_invalid",dimension:"types",target:typeof type.name=="string"?type.name:`#${index}`,message:toErrorMessage(error)});continue}const key=name.toLowerCase();if(seen.has(key)){findings.push({severity:"error",code:"type_duplicate",dimension:"types",target:name,message:`Item type "${name}" is declared more than once; the later definition silently overwrites the earlier upsert.`});continue}seen.add(key),declared.add(key)}return declared}function lintStatuses(profile,findings){const declared=new Set,seen=new Set;for(const[index,status]of profile.statuses.entries()){let normalized;try{normalized=normalizeAddStatusInput(status)}catch(error){findings.push({severity:"error",code:"status_invalid",dimension:"statuses",target:typeof status.id=="string"?status.id:`#${index}`,message:toErrorMessage(error)});continue}if(seen.has(normalized.id)){findings.push({severity:"error",code:"status_duplicate",dimension:"statuses",target:normalized.id,message:`Status "${normalized.id}" is declared more than once; the later definition silently overwrites the earlier upsert.`});continue}seen.add(normalized.id),declared.add(normalized.id);for(const alias of normalized.aliases??[])declared.add(normalizeStatusToken(alias))}return declared}function lintFields(profile,findings){const seen=new Set;for(const[index,field]of profile.fields.entries()){let key;try{key=normalizeAddFieldInput(field).key}catch(error){findings.push({severity:"error",code:"field_invalid",dimension:"fields",target:typeof field.key=="string"?field.key:`#${index}`,message:toErrorMessage(error)});continue}if(seen.has(key)){findings.push({severity:"error",code:"field_duplicate",dimension:"fields",target:key,message:`Field "${key}" is declared more than once; the later definition silently overwrites the earlier upsert.`});continue}seen.add(key);const collision=resolvePmToolCustomFieldCollision(key);collision&&findings.push({severity:"warning",code:"field_mcp_input_collision",dimension:"fields",target:key,message:`Field "${key}" collides with canonical MCP property "${collision.property}" owned by ${collision.owner}; callers must pass the custom value through ${collision.nested_path}.`})}}function lintWorkflows(profile,declaredTypes,declaredStatuses,findings){const seenTypes=new Set;for(const[index,workflow]of profile.workflows.entries()){const typeKey=workflow.type.trim().toLowerCase();if(typeKey.length===0){findings.push({severity:"error",code:"workflow_type_empty",dimension:"workflows",target:`#${index}`,message:"Workflow has an empty type; the workflow resolver drops entries without a type."});continue}const duplicate=seenTypes.has(typeKey);seenTypes.add(typeKey),duplicate?findings.push({severity:"warning",code:"workflow_duplicate_type",dimension:"workflows",target:workflow.type,message:`Workflow type "${workflow.type}" is declared more than once; the later transition set wins.`}):!BUILTIN_TYPE_KEYS.has(typeKey)&&!declaredTypes.has(typeKey)&&findings.push({severity:"warning",code:"workflow_type_unknown",dimension:"workflows",target:workflow.type,message:`Workflow governs type "${workflow.type}" which is neither a built-in type nor declared by this profile; it has no effect unless that type already exists.`});const reportedUnknownStatuses=new Set;for(const pair of workflow.allowed_transitions){const from=normalizeStatusToken(pair[0]),to=normalizeStatusToken(pair[1]);if(from.length===0||to.length===0){findings.push({severity:"error",code:"workflow_transition_malformed",dimension:"workflows",target:workflow.type,message:`Workflow "${workflow.type}" has a transition with an empty status; the workflow resolver silently drops it.`});continue}for(const token of[from,to])BUILTIN_STATUS_TOKENS.has(token)||declaredStatuses.has(token)||reportedUnknownStatuses.has(token)||(reportedUnknownStatuses.add(token),findings.push({severity:"warning",code:"workflow_status_unknown",dimension:"workflows",target:token,message:`Workflow "${workflow.type}" references status "${token}" which is neither a built-in status nor declared by this profile; transitions to or from it are unreachable.`}))}}}function lintConfig(profile,findings){const seen=new Set;for(const entry of profile.config){const descriptor=resolveNestedSettingDescriptor(entry.key);if(descriptor===void 0){findings.push({severity:"error",code:"config_key_unknown",dimension:"config",target:entry.key,message:`Config knob "${entry.key}" is not a recognized setting; apply rejects it with a usage error.`});continue}seen.has(descriptor.key)?findings.push({severity:"error",code:"config_duplicate",dimension:"config",target:descriptor.key,message:`Config knob "${descriptor.key}" is set more than once; the later value silently overwrites the earlier one.`}):seen.add(descriptor.key);const parsed=parseNestedSettingValue(descriptor,entry.value);parsed.ok||findings.push({severity:"error",code:"config_value_invalid",dimension:"config",target:entry.key,message:parsed.error.message})}}function lintTemplates(profile,declaredTypes,findings){for(const template of profile.templates){const typeOption=template.options.type;if(typeof typeOption!="string"||typeOption.trim().length===0)continue;const typeKey=typeOption.trim().toLowerCase();!BUILTIN_TYPE_KEYS.has(typeKey)&&!declaredTypes.has(typeKey)&&findings.push({severity:"warning",code:"template_type_unknown",dimension:"templates",target:template.name,message:`Template "${template.name}" creates type "${typeOption}" which is neither a built-in type nor declared by this profile.`})}}function lintPackages(profile,findings){for(const[index,recommendation]of profile.packages.entries())recommendation.spec.trim().length===0&&findings.push({severity:"warning",code:"package_spec_empty",dimension:"packages",target:`#${index}`,message:"Package recommendation has an empty spec; it cannot be surfaced as an install hint."})}function lintProjectProfile(profile){const findings=[];lintProfileIdentity(profile,findings);const declaredTypes=lintTypes(profile,findings),declaredStatuses=lintStatuses(profile,findings);lintFields(profile,findings),lintWorkflows(profile,declaredTypes,declaredStatuses,findings),lintConfig(profile,findings),lintTemplates(profile,declaredTypes,findings),lintPackages(profile,findings);const errorCount=findings.filter(finding=>finding.severity==="error").length,warningCount=findings.length-errorCount;return{profile:profile.name,ok:errorCount===0,findings,errorCount,warningCount}}export{PROFILE_LINT_CODES,PROFILE_LINT_DIMENSIONS,lintProjectProfile};
|
|
2
2
|
//# sourceMappingURL=profile-lint.js.map
|