@unbrained/pm-cli 2026.10.15 → 2026.10.18

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.
Files changed (275) hide show
  1. package/.agents/skills/pm-developer/references/COMMAND_PLAYBOOK.md +1 -1
  2. package/.claude-plugin/marketplace.json +1 -1
  3. package/AGENTS.md +1 -0
  4. package/CHANGELOG.md +45 -0
  5. package/dist/cli/extension-command-options.d.ts +3 -1
  6. package/dist/cli/extension-command-options.js +1 -1
  7. package/dist/cli/help-content.js +2 -2
  8. package/dist/cli/register-list-query.js +2 -2
  9. package/dist/cli/register-mutation.js +2 -2
  10. package/dist/cli/register-operations.js +1 -1
  11. package/dist/cli/register-structured-mutation.d.ts +0 -5
  12. package/dist/cli/register-structured-mutation.js +1 -1
  13. package/dist/cli/runtime/invocation-options.js +1 -1
  14. package/dist/cli-bundle/bundle-manifest.json +1 -1
  15. package/dist/cli-bundle/chunks/{chunk-7VHINXZP.js → chunk-4GA4MUTE.js} +2 -2
  16. package/dist/cli-bundle/chunks/{chunk-RJ5N44WY.js → chunk-4V6ONLI6.js} +2 -2
  17. package/dist/cli-bundle/chunks/{chunk-LNKLQYBG.js → chunk-6VZKYJW7.js} +2 -2
  18. package/dist/cli-bundle/chunks/chunk-7PATQWTH.js +20 -0
  19. package/dist/cli-bundle/chunks/chunk-7WIEAGDS.js +2 -0
  20. package/dist/cli-bundle/chunks/{chunk-52EZH2QQ.js → chunk-AETP4JEM.js} +2 -2
  21. package/dist/cli-bundle/chunks/{chunk-WBBW3WQX.js → chunk-FIJOSX2C.js} +28 -28
  22. package/dist/cli-bundle/chunks/chunk-LUKVNL72.js +2 -0
  23. package/dist/cli-bundle/chunks/{chunk-NC3QVGDD.js → chunk-OJ77ZQN3.js} +2 -2
  24. package/dist/cli-bundle/chunks/chunk-PYRREEUB.js +30 -0
  25. package/dist/cli-bundle/chunks/chunk-RHQJ6VWC.js +237 -0
  26. package/dist/cli-bundle/chunks/{chunk-N56CAQBU.js → chunk-RNABUEFB.js} +52 -52
  27. package/dist/cli-bundle/chunks/chunk-TO6CIV4C.js +2 -0
  28. package/dist/cli-bundle/chunks/{chunk-JGKTOBVB.js → chunk-ZZED447K.js} +4 -4
  29. package/dist/cli-bundle/chunks/{register-list-query-FKKFQ66D.js → register-list-query-PUCVYYBD.js} +7 -7
  30. package/dist/cli-bundle/chunks/register-mutation-GGGVBXD5.js +20 -0
  31. package/dist/cli-bundle/chunks/{register-operations-GEQ2H7PS.js → register-operations-NRZ6Q4QE.js} +2 -2
  32. package/dist/cli-bundle/chunks/{register-setup-PSJTQBBO.js → register-setup-MV3P3YSF.js} +2 -2
  33. package/dist/cli-bundle/focused-chunks/chunk-2MPQUMTF.js +2 -0
  34. package/dist/cli-bundle/focused-chunks/{chunk-H3P77KVU.js → chunk-5UKCSZWT.js} +2 -2
  35. package/dist/cli-bundle/focused-chunks/{chunk-4KQFMOM7.js → chunk-A4ZHHTEX.js} +5 -5
  36. package/dist/cli-bundle/focused-chunks/{chunk-5OO54BIV.js → chunk-B4YLP5ZB.js} +3 -3
  37. package/dist/cli-bundle/focused-chunks/chunk-BFEMT5U3.js +20 -0
  38. package/dist/cli-bundle/focused-chunks/{chunk-THYQR3ON.js → chunk-FW7CSSKL.js} +61 -61
  39. package/dist/cli-bundle/focused-chunks/{chunk-3RNUMVK4.js → chunk-HYPRPSYD.js} +2 -2
  40. package/dist/cli-bundle/focused-chunks/{chunk-FQKPOZKS.js → chunk-IRVL4UXR.js} +2 -2
  41. package/dist/cli-bundle/focused-chunks/{chunk-Q4VNCTR2.js → chunk-L55KQ2KT.js} +2 -2
  42. package/dist/cli-bundle/focused-chunks/{chunk-52I2SNKJ.js → chunk-MASIOFPG.js} +2 -2
  43. package/dist/cli-bundle/focused-chunks/chunk-RJ3EIHDU.js +26 -0
  44. package/dist/cli-bundle/focused-chunks/chunk-SEL4Z2OO.js +167 -0
  45. package/dist/cli-bundle/focused-chunks/{chunk-TYLG5VEB.js → chunk-TB7F4FCR.js} +2 -2
  46. package/dist/cli-bundle/focused-chunks/{chunk-KIIFVULU.js → chunk-TZUIBG3P.js} +2 -2
  47. package/dist/cli-bundle/focused-chunks/{chunk-N6FUKTZS.js → chunk-Z7YIFCNE.js} +2 -2
  48. package/dist/cli-bundle/focused-chunks/{chunk-5KRACGBK.js → chunk-ZDBS2DCT.js} +3 -3
  49. package/dist/cli-bundle/main.js +27 -27
  50. package/dist/cli-bundle/sdk-authoring.js +1 -1
  51. package/dist/cli-bundle/sdk-contracts.js +2 -2
  52. package/dist/cli-bundle/sdk-core.js +23 -23
  53. package/dist/cli-bundle/sdk-governance.js +1 -1
  54. package/dist/cli-bundle/sdk-graph.js +1 -1
  55. package/dist/cli-bundle/sdk-merge.js +55 -54
  56. package/dist/cli-bundle/sdk-query.js +1 -1
  57. package/dist/cli-bundle/sdk-runtime.js +1 -1
  58. package/dist/cli-bundle/sdk-testing.js +1 -1
  59. package/dist/cli-bundle/sdk.js +7 -7
  60. package/dist/core/extensions/extension-types.d.ts +15 -0
  61. package/dist/core/extensions/extension-types.js +1 -1
  62. package/dist/core/extensions/flag-value-types.d.ts +16 -0
  63. package/dist/core/extensions/flag-value-types.js +1 -1
  64. package/dist/core/extensions/registration-contracts.js +1 -1
  65. package/dist/core/history/event-index.d.ts +8 -1
  66. package/dist/core/history/event-index.js +19 -18
  67. package/dist/core/item/item-format.js +3 -3
  68. package/dist/core/lock/lock.d.ts +8 -1
  69. package/dist/core/lock/lock.js +3 -3
  70. package/dist/core/output/mutation-projection.d.ts +0 -21
  71. package/dist/core/output/mutation-projection.js +1 -1
  72. package/dist/core/output/output.js +2 -2
  73. package/dist/core/schema/type-workflows.d.ts +1 -1
  74. package/dist/core/schema/type-workflows.js +1 -1
  75. package/dist/core/shared/text-normalization.d.ts +2 -0
  76. package/dist/core/shared/text-normalization.js +1 -1
  77. package/dist/core/store/item-mutation-precondition.d.ts +11 -0
  78. package/dist/core/store/item-mutation-precondition.js +2 -0
  79. package/dist/core/store/item-store.js +1 -1
  80. package/dist/core/store/paths.js +1 -1
  81. package/dist/core/telemetry/policy.d.ts +2 -0
  82. package/dist/core/telemetry/policy.js +1 -1
  83. package/dist/core/telemetry/runtime.d.ts +5 -3
  84. package/dist/core/telemetry/runtime.js +3 -3
  85. package/dist/mcp/server.js +1 -1
  86. package/dist/mcp/tool-definitions.js +1 -1
  87. package/dist/sdk/cli-contracts/agent-output-contracts.js +1 -1
  88. package/dist/sdk/cli-contracts/flag-contracts.js +1 -1
  89. package/dist/sdk/cli-contracts/flag-lexicon-contracts.js +1 -1
  90. package/dist/sdk/cli-contracts/registration-helpers.d.ts +1 -1
  91. package/dist/sdk/cli-contracts/registration-helpers.js +1 -1
  92. package/dist/sdk/cli-contracts/tool-schema.d.ts +2 -2
  93. package/dist/sdk/cli-contracts/tool-schema.js +1 -1
  94. package/dist/sdk/context-intent-contracts.js +1 -1
  95. package/dist/sdk/core.d.ts +2 -1
  96. package/dist/sdk/core.js +1 -1
  97. package/dist/sdk/generated/generated-error-code-catalog-part-1.js +1 -1
  98. package/dist/sdk/generated/generated-error-code-catalog-part-2.js +1 -1
  99. package/dist/sdk/governance/health/projection.d.ts +37 -0
  100. package/dist/sdk/governance/health/projection.js +2 -0
  101. package/dist/sdk/governance/health.d.ts +7 -18
  102. package/dist/sdk/governance/health.js +2 -2
  103. package/dist/sdk/guide-topics.js +1 -1
  104. package/dist/sdk/index.d.ts +2 -1
  105. package/dist/sdk/index.js +1 -1
  106. package/dist/sdk/item-transaction.d.ts +72 -9
  107. package/dist/sdk/item-transaction.js +1 -1
  108. package/dist/sdk/lifecycle/claim.d.ts +15 -1
  109. package/dist/sdk/lifecycle/claim.js +1 -1
  110. package/dist/sdk/lifecycle/close.d.ts +2 -8
  111. package/dist/sdk/lifecycle/close.js +1 -1
  112. package/dist/sdk/lifecycle/core-item-fields.d.ts +6 -0
  113. package/dist/sdk/lifecycle/core-item-fields.js +2 -0
  114. package/dist/sdk/lifecycle/mcp-actions.js +1 -1
  115. package/dist/sdk/lifecycle/mutation-option-validation.d.ts +2 -0
  116. package/dist/sdk/lifecycle/mutation-option-validation.js +2 -0
  117. package/dist/sdk/lifecycle/release-handoff.d.ts +12 -0
  118. package/dist/sdk/lifecycle/release-handoff.js +2 -0
  119. package/dist/sdk/lifecycle/structured-mutation-plan.d.ts +33 -0
  120. package/dist/sdk/lifecycle/structured-mutation-plan.js +2 -0
  121. package/dist/sdk/lifecycle/task-composition.d.ts +2 -2
  122. package/dist/sdk/lifecycle/task-composition.js +1 -1
  123. package/dist/sdk/lifecycle/update.d.ts +3 -11
  124. package/dist/sdk/lifecycle/update.js +1 -1
  125. package/dist/sdk/lifecycle/workflow-transition.d.ts +13 -0
  126. package/dist/sdk/lifecycle/workflow-transition.js +2 -0
  127. package/dist/sdk/lifecycle-policy.d.ts +12 -2
  128. package/dist/sdk/lifecycle-policy.js +1 -1
  129. package/dist/sdk/mutation-events.js +1 -1
  130. package/dist/sdk/public-surface.json +1 -1
  131. package/dist/sdk/query/list.d.ts +2 -0
  132. package/dist/sdk/query/list.js +1 -1
  133. package/dist/sdk/read-output-budget.js +1 -1
  134. package/dist/sdk/runtime-input.js +1 -1
  135. package/dist/sdk/runtime-primitives.d.ts +1 -1
  136. package/dist/sdk/runtime-primitives.js +1 -1
  137. package/dist/sdk/runtime.d.ts +8 -8
  138. package/dist/sdk/runtime.js +1 -1
  139. package/dist/sdk/structured-mutations.d.ts +52 -1
  140. package/dist/sdk/structured-mutations.js +1 -1
  141. package/dist/sdk/workspace-transaction.js +2 -2
  142. package/dist/types.d.ts +2 -2
  143. package/dist/types.js +1 -1
  144. package/docs/AGENT_GUIDE.md +33 -4
  145. package/docs/CLOSE_EVIDENCE_RECOVERY.md +16 -7
  146. package/docs/COMMANDS.md +111 -10
  147. package/docs/CONFIGURATION.md +22 -1
  148. package/docs/DEVELOPMENT_DEPENDENCY_SECURITY.md +22 -3
  149. package/docs/ECOSYSTEM_PLANNING_REVIEW.md +5 -1
  150. package/docs/EXTENSIONS.md +1 -1
  151. package/docs/OUTPUT_PROJECTION_CONTRACTS.md +10 -0
  152. package/docs/RELEASING.md +8 -1
  153. package/docs/SDK.md +114 -2
  154. package/docs/SDK_CONTEXT_COORDINATION.md +71 -7
  155. package/docs/SDK_STORAGE_LIFECYCLE.md +24 -2
  156. package/docs/TESTING.md +23 -0
  157. package/docs/examples/ci/github-actions-pm-extension-gate.yml +1 -1
  158. package/docs/examples/ci/gitlab-ci-pm-extension-gate.yml +1 -1
  159. package/docs/examples/ci/jenkins-pm-extension-gate.Jenkinsfile +1 -1
  160. package/docs/generated/FLAG_LEXICON_BUDGETS.md +1 -1
  161. package/docs/generated/REFUSAL_CLOSURE_CENSUS.md +16 -3
  162. package/marketplace.json +1 -1
  163. package/node_modules/@opentelemetry/core/package.json +2 -1
  164. package/node_modules/@opentelemetry/instrumentation/package.json +2 -1
  165. package/node_modules/@opentelemetry/resources/package.json +2 -1
  166. package/node_modules/@opentelemetry/sdk-trace/package.json +2 -1
  167. package/node_modules/@opentelemetry/sdk-trace-base/package.json +2 -1
  168. package/node_modules/@sentry/core/build/cjs/client.js +5 -4
  169. package/node_modules/@sentry/core/build/cjs/tracing/ai/gen-ai-attributes.js +0 -4
  170. package/node_modules/@sentry/core/build/cjs/tracing/ai/utils.js +33 -23
  171. package/node_modules/@sentry/core/build/cjs/tracing/anthropic-ai/index.js +7 -6
  172. package/node_modules/@sentry/core/build/cjs/tracing/anthropic-ai/streaming.js +3 -1
  173. package/node_modules/@sentry/core/build/cjs/tracing/google-genai/index.js +13 -14
  174. package/node_modules/@sentry/core/build/cjs/tracing/google-genai/streaming.js +6 -1
  175. package/node_modules/@sentry/core/build/cjs/tracing/langchain/utils.js +71 -21
  176. package/node_modules/@sentry/core/build/cjs/tracing/langgraph/utils.js +23 -33
  177. package/node_modules/@sentry/core/build/cjs/tracing/openai/streaming.js +6 -0
  178. package/node_modules/@sentry/core/build/cjs/tracing/openai/utils.js +11 -0
  179. package/node_modules/@sentry/core/build/cjs/tracing/workers-ai/utils.js +1 -1
  180. package/node_modules/@sentry/core/build/cjs/utils/eventUtils.js +4 -0
  181. package/node_modules/@sentry/core/build/cjs/utils/prepareEvent.js +2 -2
  182. package/node_modules/@sentry/core/build/cjs/utils/version.js +1 -1
  183. package/node_modules/@sentry/core/build/esm/client.js +6 -5
  184. package/node_modules/@sentry/core/build/esm/package.json +1 -1
  185. package/node_modules/@sentry/core/build/esm/tracing/ai/gen-ai-attributes.js +1 -3
  186. package/node_modules/@sentry/core/build/esm/tracing/ai/utils.js +34 -24
  187. package/node_modules/@sentry/core/build/esm/tracing/anthropic-ai/index.js +8 -7
  188. package/node_modules/@sentry/core/build/esm/tracing/anthropic-ai/streaming.js +3 -1
  189. package/node_modules/@sentry/core/build/esm/tracing/google-genai/index.js +15 -16
  190. package/node_modules/@sentry/core/build/esm/tracing/google-genai/streaming.js +6 -1
  191. package/node_modules/@sentry/core/build/esm/tracing/langchain/utils.js +73 -24
  192. package/node_modules/@sentry/core/build/esm/tracing/langgraph/utils.js +24 -34
  193. package/node_modules/@sentry/core/build/esm/tracing/openai/streaming.js +6 -0
  194. package/node_modules/@sentry/core/build/esm/tracing/openai/utils.js +11 -0
  195. package/node_modules/@sentry/core/build/esm/tracing/workers-ai/utils.js +2 -2
  196. package/node_modules/@sentry/core/build/esm/utils/eventUtils.js +4 -1
  197. package/node_modules/@sentry/core/build/esm/utils/prepareEvent.js +2 -2
  198. package/node_modules/@sentry/core/build/esm/utils/version.js +1 -1
  199. package/node_modules/@sentry/core/build/types/tracing/ai/utils.d.ts +3 -7
  200. package/node_modules/@sentry/core/build/types/tracing/anthropic-ai/types.d.ts +2 -2
  201. package/node_modules/@sentry/core/build/types/tracing/langchain/types.d.ts +15 -0
  202. package/node_modules/@sentry/core/build/types/tracing/langchain/utils.d.ts +1 -0
  203. package/node_modules/@sentry/core/build/types/tracing/langgraph/utils.d.ts +2 -0
  204. package/node_modules/@sentry/core/build/types/tracing/openai/types.d.ts +2 -0
  205. package/node_modules/@sentry/core/build/types/utils/eventUtils.d.ts +2 -1
  206. package/node_modules/@sentry/core/build/types-ts3.8/tracing/ai/utils.d.ts +3 -7
  207. package/node_modules/@sentry/core/build/types-ts3.8/tracing/anthropic-ai/types.d.ts +2 -2
  208. package/node_modules/@sentry/core/build/types-ts3.8/tracing/langchain/types.d.ts +15 -0
  209. package/node_modules/@sentry/core/build/types-ts3.8/tracing/langchain/utils.d.ts +1 -0
  210. package/node_modules/@sentry/core/build/types-ts3.8/tracing/langgraph/utils.d.ts +2 -0
  211. package/node_modules/@sentry/core/build/types-ts3.8/tracing/openai/types.d.ts +2 -0
  212. package/node_modules/@sentry/core/build/types-ts3.8/utils/eventUtils.d.ts +2 -1
  213. package/node_modules/@sentry/core/package.json +1 -1
  214. package/node_modules/@sentry/node/build/esm/package.json +1 -1
  215. package/node_modules/@sentry/node/package.json +5 -5
  216. package/node_modules/@sentry/node-core/build/cjs/integrations/anr/index.js +1 -1
  217. package/node_modules/@sentry/node-core/build/cjs/integrations/local-variables/local-variables-async.js +1 -1
  218. package/node_modules/@sentry/node-core/build/esm/integrations/anr/index.js +1 -1
  219. package/node_modules/@sentry/node-core/build/esm/integrations/anr/worker-script.js +2 -2
  220. package/node_modules/@sentry/node-core/build/esm/integrations/local-variables/local-variables-async.js +1 -1
  221. package/node_modules/@sentry/node-core/build/esm/integrations/local-variables/worker-script.js +1 -1
  222. package/node_modules/@sentry/node-core/build/esm/package.json +1 -1
  223. package/node_modules/@sentry/node-core/package.json +10 -4
  224. package/node_modules/@sentry/opentelemetry/build/esm/package.json +1 -1
  225. package/node_modules/@sentry/opentelemetry/package.json +5 -2
  226. package/node_modules/@sentry/server-utils/build/THIRD-PARTY-LICENSES.txt +55 -55
  227. package/node_modules/@sentry/server-utils/build/esm/package.json +1 -1
  228. package/node_modules/@sentry/server-utils/package.json +2 -2
  229. package/node_modules/@toon-format/toon/README.md +10 -41
  230. package/node_modules/@toon-format/toon/dist/index.d.mts +12 -36
  231. package/node_modules/@toon-format/toon/dist/index.mjs +134 -202
  232. package/node_modules/@toon-format/toon/package.json +2 -2
  233. package/node_modules/debug/package.json +3 -0
  234. package/node_modules/fdir/package.json +3 -0
  235. package/node_modules/has-flag/index.d.ts +39 -0
  236. package/node_modules/has-flag/index.js +8 -0
  237. package/node_modules/has-flag/license +9 -0
  238. package/node_modules/has-flag/package.json +46 -0
  239. package/node_modules/has-flag/readme.md +89 -0
  240. package/node_modules/supports-color/browser.js +5 -0
  241. package/node_modules/supports-color/index.js +135 -0
  242. package/node_modules/supports-color/license +9 -0
  243. package/node_modules/supports-color/package.json +53 -0
  244. package/node_modules/supports-color/readme.md +76 -0
  245. package/package.json +5 -4
  246. package/packages/pm-beads/package.json +1 -1
  247. package/packages/pm-calendar/package.json +1 -1
  248. package/packages/pm-command-kit/package.json +1 -1
  249. package/packages/pm-digital-twin/package.json +1 -1
  250. package/packages/pm-governance-audit/package.json +1 -1
  251. package/packages/pm-guide-shell/package.json +1 -1
  252. package/packages/pm-kanban/package.json +1 -1
  253. package/packages/pm-lifecycle-hooks/package.json +1 -1
  254. package/packages/pm-linked-test-adapters/package.json +1 -1
  255. package/packages/pm-search-advanced/package.json +1 -1
  256. package/packages/pm-templates/package.json +1 -1
  257. package/packages/pm-todos/package.json +1 -1
  258. package/packages/pm-vcs/package.json +1 -1
  259. package/plugins/pm-claude/.claude-plugin/plugin.json +1 -1
  260. package/plugins/pm-claude/package.json +1 -1
  261. package/plugins/pm-codex/.codex-plugin/plugin.json +1 -1
  262. package/plugins/pm-codex/package.json +1 -1
  263. package/plugins/pm-codex/plugin.json +1 -1
  264. package/runtime-dependencies.json +1 -1
  265. package/dist/cli-bundle/chunks/chunk-7OEGNA4X.js +0 -20
  266. package/dist/cli-bundle/chunks/chunk-EMEEHV2Y.js +0 -2
  267. package/dist/cli-bundle/chunks/chunk-JSUJWIHQ.js +0 -30
  268. package/dist/cli-bundle/chunks/chunk-VIMQCFCK.js +0 -2
  269. package/dist/cli-bundle/chunks/chunk-X2H6UR26.js +0 -236
  270. package/dist/cli-bundle/chunks/register-mutation-EWMMVZJB.js +0 -20
  271. package/dist/cli-bundle/focused-chunks/chunk-5TBAVZDR.js +0 -20
  272. package/dist/cli-bundle/focused-chunks/chunk-HTA3TNC3.js +0 -26
  273. package/dist/cli-bundle/focused-chunks/chunk-JKBH7YGX.js +0 -2
  274. package/dist/cli-bundle/focused-chunks/chunk-PDYE7QDX.js +0 -166
  275. package/docs/ecosystem-review-2026-09-28.json +0 -1
@@ -1,2 +1,2 @@
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]="710f1406-c114-56c7-9f0b-4f7c20b1eea1")}catch{}})();import{AsyncLocalStorage}from"node:async_hooks";import{createEmptyExtensionCommandRegistry,createEmptyExtensionHookRegistry,createEmptyExtensionParserRegistry,createEmptyExtensionPreflightRegistry,createEmptyExtensionRegistrationRegistry,createEmptyExtensionRendererRegistry,createEmptyExtensionServiceRegistry}from"../core/extensions/extension-registries.js";import{activateExtensions,deactivateExtensions,loadExtensions,runActiveCommandHandler,runWithIsolatedExtensionRuntime,setActiveExtensionCommands,setActiveExtensionHooks,setActiveExtensionParsers,setActiveExtensionPreflight,setActiveExtensionRegistrations,setActiveExtensionRenderers,setActiveExtensionServices}from"../core/extensions/index.js";import{pathExists}from"../core/fs/fs-utils.js";import{EXIT_CODE}from"../core/shared/constants.js";import{PmCliError}from"../core/shared/errors.js";import{asRecordClone}from"../core/shared/primitives.js";import{createAsyncReadWriteGate}from"../core/shared/serial-queue.js";import{getSettingsPath,resolvePmRoot}from"../core/store/paths.js";import{readSettings}from"../core/store/settings.js";import{PM_TOOL_ACTIONS}from"./cli-contracts/enum-contracts.js";import{runContracts}from"./cli-contracts/runtime-contracts.js";import{attachReadOutputContracts}from"./context-intent-contracts.js";import{runWithDiscoveredContextIntentContracts}from"./context-intent-runtime.js";import{finalizeContextUsageEgress}from"./context/usage-egress.js";import{createExtensionCommandSdk}from"./extension-command-context.js";import{INIT_INVOCATION_CWD}from"./init.js";import{certifyCompleteListResult,createCompleteListOptions}from"./query/complete-list.js";import{listClientItemMetadataLight}from"./query/light-metadata.js";import{normalizeReadOutputIncludeModeOptions,validateReadOutputOptions}from"./read-output-contracts.js";import{SDK_ACTION_ALIASES}from"./runtime-action-aliases.js";import{closeManyOptionsFromFlat,extensionOptionsFromArgs,actionGlobalOptions as globalOptions,mutationListOptions,mutationOptionsWithOverrides,normalizeActionName,normalizeCommandPath,normalizeMcpOptionsArrays,normalizeMcpUpdateOptions,optionsWithAuthor,readRuntimeScalarString as readScalarString,readRuntimeScalarStringAllowBlank as readScalarStringAllowBlank,readRuntimeString as readString,readRuntimeStringArray as readStringArray,shouldInvalidateWorkspaceContractsCacheAfterAction,updateManyOptionsFromFlat,withAddNoteOption,withFilesDiscoveryOptions,withMutationCompaction}from"./runtime-input.js";import{SDK_ACTION_HANDLERS}from"./runtime/actions.js";import{getOwnHandler,readRequiredString}from"./runtime/context.js";import{clearWorkspaceContractsCache}from"./workspace-contracts-cache.js";import{PM_GITIGNORE_END,PM_GITIGNORE_START,ensurePmGitignore,getPmGitignoreBlock}from"./workspace.js";import{SEARCH_EXTENSION_FLAG_DEFINITIONS}from"./extension-contracts.js";export*from"./cli-contracts/agent-output-contracts.js";import{PmCompleteListValidationError,assertCompleteListResult,certifyCompleteListResult as certifyCompleteListResult2,createCompleteListOptions as createCompleteListOptions2,inspectCompleteListResult}from"./query/complete-list.js";import{getWorkspaceContracts}from"./query/workspace-contracts.js";import{clearWorkspaceContractsCache as clearWorkspaceContractsCache2}from"./workspace-contracts-cache.js";export*from"./governance/workflow-policy.js";import{runCloseTask,runPauseTask,runStartTask}from"./lifecycle/task-composition.js";import{getActiveExtensionRegistrations,runActiveOnReadHooks,runActiveOnWriteHooks}from"../core/extensions/index.js";import{pathExists as pathExists2,readFileIfExists,removeFileIfExists,writeFileAtomic}from"../core/fs/fs-utils.js";import{appendHistoryEntry,createHistoryEntry}from"../core/history/history.js";import{HISTORY_EVENT_CLASSIFICATION_VERSION,MAINTENANCE_HISTORY_OPERATIONS,SUBSTANTIVE_HISTORY_OPERATIONS,classifyHistoryEvent}from"../core/history/event-classification.js";import{generateItemId,normalizeItemId,normalizeRawItemId}from"../core/item/id.js";import{readBooleanOption,readCsvListOption,readStringOption}from"./package-runtime-options.js";import{PM_CLI_EXPECTED_ERROR_NAME,createPmCliExpectedError,isPmCliExpectedError}from"./errors.js";import{commitImportedItem,emptyImportedDocument,ensureTrackerInitialized,selectImportAuthor,toEstimatedMinutesValue,toImportBoolean,toImportConfidence,toImportInteger,toImportLinkedDocs,toImportLinkedFiles,toImportLinkedTests,toImportLogEntries,toImportNormalizedEnum,toImportNumberMap,toImportPriority,toImportStatus,toImportStringList,toImportStringMap,toImportTags,toNonEmptyImportString}from"./package-import-adapters.js";import{canonicalDocument,normalizeItemMetadata,serializeItemDocument,splitFrontMatter}from"../core/item/item-format.js";import{BASELINE_ITEM_FORMAT_VERSION,CURRENT_ITEM_FORMAT_VERSION,classifyItemFormatVersion,effectiveItemFormatVersion,normalizeItemFormatVersion,scanItemFormatVersions}from"../core/item/item-format-version.js";import{parseTags}from"../core/item/parse.js";import{isTerminalStatus,normalizeStatusInput}from"../core/item/status.js";import{resolveItemTypeRegistry}from"../core/item/type-registry.js";import{acquireLock}from"../core/lock/lock.js";import{resolveRuntimeFieldRegistry,resolveRuntimeStatusRegistry}from"../core/schema/runtime-schema.js";import{PmCliError as PmCliError2}from"../core/shared/errors.js";import{isTimestampLiteral,nowIso}from"../core/shared/time.js";import{jaccardSimilarity,normalizeSimilarityText,scoreItemSimilarity,tokenizeSimilarityText}from"./similarity-scoring.js";import{listAllItemMetadata,listAllItemMetadataLight,locateItem,readLocatedItem}from"../core/store/item-store.js";import{getHistoryPath,getItemPath,getSettingsPath as getSettingsPath2,resolveImplicitPmRoot,resolvePmRoot as resolvePmRoot2}from"../core/store/paths.js";import{readSettings as readSettings2}from"../core/store/settings.js";import{runAggregate}from"./query/aggregate.js";import{CONTEXT_OUTPUT_VALUES,runContext}from"./query/context.js";import{runGet}from"./query/get.js";import{runList}from"./query/list.js";import{closeItem,runClose}from"./lifecycle/close.js";import{runCopy}from"./lifecycle/copy.js";import{runDelete}from"./lifecycle/delete.js";import{runFocus}from"./lifecycle/focus.js";import{runRestore}from"./lifecycle/restore.js";import{DEFAULT_TERMINAL_TRANSITION_POLICY,applyTerminalOrderingPolicy,requireTerminalReason,resolveTerminalReason}from"./lifecycle-policy.js";import{runUpdate}from"./lifecycle/update.js";import{runReopen}from"./lifecycle/reopen.js";import{NEXT_OUTPUT_VALUES,runNext}from"./query/next.js";import{runSearch}from"./query/search.js";import{runStats}from"./stats.js";import{runDuplicates}from"./duplicates.js";import{renderCalendarMarkdown,renderCalendarToon,resolveCalendarOutputFormat,runCalendar}from"./query/calendar.js";import{renderGuideMarkdown,resolveGuideOutputFormat,runGuide}from"./guide.js";import{runCompletion}from"./completion.js";import{runReindex}from"./governance/reindex.js";import{loadCreateTemplateOptions,runTemplatesList,runTemplatesSave,runTemplatesShow}from"./templates.js";import{runTestRunsList,runTestRunsLogs,runTestRunsResume,runTestRunsStatus,runTestRunsStop}from"./test/runs.js";import{BUILTIN_ITEM_TYPE_VALUES,CONFIDENCE_TEXT_VALUES,DEPENDENCY_KIND_VALUES,ISSUE_SEVERITY_VALUES,ITEM_TYPE_VALUES,RISK_VALUES,STATUS_VALUES}from"../types/index.js";const ACTIVE_EXTENSION_HOST_CONTEXT=Symbol("pm.active-extension-host-context");function splitFullClientMutationOptions(options){return{fullChangedFields:!0,options}}class PmClient{defaults;constructor(options={}){this.defaults={...options.pmRoot===void 0?{}:{path:options.pmRoot},...options.cwd===void 0?{}:{cwd:options.cwd},...options.author===void 0?{}:{author:options.author},...options.noExtensions===void 0?{}:{noExtensions:options.noExtensions}}}static forActiveExtensionHost(options){const client=new PmClient({...options,noExtensions:!0});return client.defaults[ACTIVE_EXTENSION_HOST_CONTEXT]=!0,client}run(action,args={}){return runAction({...this.defaults,...args,action})}runTyped(action,args={}){return this.run(action,args)}context(options={}){return this.runTyped("context",{options})}listAllItemMetadataLight(){return listClientItemMetadataLight(this.defaults.path,this.defaults.cwd)}list(options={}){return this.runTyped("list",{options})}async listAllComplete(options={}){return certifyCompleteListResult(await this.list(createCompleteListOptions(options)))}search(query,options={}){return this.runTyped("search",{query,options})}get(id,options={}){return this.runTyped("get",{id,options})}next(options={}){return this.runTyped("next",{options})}aggregate(options={}){return this.runTyped("aggregate",{options})}stats(options={}){return this.runTyped("stats",{options})}duplicates(options={}){return this.runTyped("duplicates",{options})}comments(id,options={}){return this.runTyped("comments",{id,options})}notes(id,options={}){return this.runTyped("notes",{id,options})}learnings(id,options={}){return this.runTyped("learnings",{id,options})}files(id,options={}){return this.runTyped("files",{id,options})}filesDiscover(id,options={}){return this.runTyped("files-discover",{id,options})}filesLookup(options){return this.runTyped("files-lookup",{options})}docs(id,options={}){return this.runTyped("docs",{id,options})}deps(id,options={}){return this.runTyped("deps",{id,options})}graph(subcommand,ids={},options={}){return this.runTyped("graph",{subcommand,...ids,options})}append(id,body,options={}){return this.runTyped("append",{id,...splitFullClientMutationOptions(mutationOptionsWithOverrides(options,{body}))})}init(prefix,options={}){return this.runTyped("init",{...prefix===void 0?{}:{prefix},options})}config(scope,configAction,key,value,options={}){return this.runTyped("config",{scope,configAction,...key===void 0?{}:{key},...value===void 0?{}:{value},options})}schema(subcommand,options={}){return this.runTyped("schema",{options:{...options,subcommand}})}workflowPolicy(action,name,options={}){return this.runTyped("schema",{name,options:{...options,subcommand:action}})}schemaList(){return this.runTyped("schema",{options:{subcommand:"list"}})}schemaShow(name){return this.runTyped("schema",{name,options:{subcommand:"show"}})}schemaAddType(name,options={}){return this.runTyped("schema",{name,options:{...options,subcommand:"add-type"}})}schemaRemoveType(name,options={}){return this.runTyped("schema",{name,options:{...options,subcommand:"remove-type"}})}schemaAddStatus(name,options={}){return this.runTyped("schema",{name,options:{...options,subcommand:"add-status"}})}schemaRemoveStatus(name,options={}){return this.runTyped("schema",{name,options:{...options,subcommand:"remove-status"}})}schemaAddField(name,options={}){const{type,...mutationOptions}=options;return this.runTyped("schema",{name,options:{...mutationOptions,fieldType:type,subcommand:"add-field"}})}schemaRemoveField(name,options={}){return this.runTyped("schema",{name,options:{...options,subcommand:"remove-field"}})}schemaListFields(){return this.runTyped("schema",{options:{subcommand:"list-fields"}})}schemaShowField(name){return this.runTyped("schema",{name,options:{subcommand:"show-field"}})}schemaApplyPreset(typePreset,options={}){return this.runTyped("schema",{typePreset,options:{...options,subcommand:"apply-preset"}})}schemaInferTypes(options={}){return this.runTyped("schema",{options:{...options,subcommand:"add-type",infer:!0}})}schemaRenameType(from,to,options){return this.runTyped("schema",{name:from,options:{...options,subcommand:"rename-type",to}})}schemaRenameField(from,to,options,type){return this.runTyped("schema",{name:from,options:{...options,subcommand:"rename-field",to,...type?{fieldTypeScope:type}:{}}})}schemaRemapStatus(from,to,options){return this.runTyped("schema",{name:from,options:{...options,subcommand:"remap-status",to}})}schemaShowStatus(name){return this.runTyped("schema",{name,options:{subcommand:"show-status"}})}profile(subcommand,options={}){return this.runTyped("profile",{options:{...options,subcommand}})}profileList(){return this.runTyped("profile",{options:{subcommand:"list"}})}profileShow(name){return this.runTyped("profile",{name,options:{subcommand:"show"}})}profileApply(name,options={}){return this.runTyped("profile",{name,options:{...options,subcommand:"apply"}})}profileLint(name){return this.runTyped("profile",{name,options:{subcommand:"lint"}})}validate(options={}){return this.runTyped("validate",{options})}health(options={}){return this.runTyped("health",{options})}gc(options={}){return this.runTyped("gc",{options})}assurance(input){return this.runTyped("assurance",{options:{...input,subcommand:input.action}})}historyRedact(id,options){return this.runTyped("history-redact",{id,options})}historyRepair(id,options={}){return this.runTyped("history-repair",{id,options})}historyRepairAll(options={}){return this.runTyped("history-repair",{options:{...options,all:!0}})}historyAttest(options={}){return this.runTyped("history-attest",{options})}historyCompact(id,options={}){return this.runTyped("history-compact",{id,options})}historyCompactBulk(options){return this.runTyped("history-compact",{options})}historyAuthorAcknowledge(options){return this.runTyped("history-author-acknowledge",{historyEvent:(options.events??[]).map(event=>`${event.item_id}:${String(event.line)}`),allActionable:options.all_actionable===!0,dryRun:options.dry_run===!0,planFingerprint:options.plan_fingerprint,limit:options.coordinate_limit,attributedAuthor:options.attributed_author,reviewer:options.reviewer,reason:options.reason})}plan(subcommand,id,options={},stepRef,reorderTo){return this.runTyped("plan",{fullChangedFields:!0,...id===void 0?{}:{id},...stepRef===void 0?{}:{stepRef},...reorderTo===void 0?{}:{reorderTo},options:mutationOptionsWithOverrides(options,{subcommand})})}planCreate(options){return this.plan("create",void 0,options)}planShow(id,options={}){return this.plan("show",id,options)}planAddStep(id,options){return this.plan("add-step",id,options)}planUpdateStep(id,stepRef,options){return this.plan("update-step",id,options,stepRef)}planCompleteStep(id,stepRef,options={}){return this.plan("complete-step",id,options,stepRef)}planBlockStep(id,stepRef,options){return this.plan("block-step",id,options,stepRef)}planReorderStep(id,stepRef,reorderTo,options={}){return this.plan("reorder-step",id,options,stepRef,reorderTo)}planRemoveStep(id,stepRef,options={}){return this.plan("remove-step",id,options,stepRef)}planLink(id,stepRef,options){return this.plan("link",id,options,stepRef)}planUnlink(id,stepRef,options){return this.plan("unlink",id,options,stepRef)}planDecision(id,options){return this.plan("decision",id,options)}planDiscovery(id,options){return this.plan("discovery",id,options)}planValidation(id,options){return this.plan("validation",id,options)}planResume(id,options){return this.plan("resume",id,options)}planApprove(id,options={}){return this.plan("approve",id,options)}planMaterialize(id,options){return this.plan("materialize",id,options)}create(options={}){return this.runTyped("create",splitFullClientMutationOptions(options))}update(id,options={}){return this.runTyped("update",{id,...splitFullClientMutationOptions(options)})}reopen(id,reason,options={}){return this.runTyped("item-reopen",{id,reason,fullChangedFields:!0,options})}close(id,reason,options={}){return this.runTyped("close",{id,reason,...splitFullClientMutationOptions(options)})}claim(id,options={}){return this.runTyped("claim",{id,...splitFullClientMutationOptions(options)})}claimNext(options={}){return this.runTyped("claim",{next:!0,...splitFullClientMutationOptions(options)})}release(id,options={}){return this.runTyped("release",{id,...splitFullClientMutationOptions(options)})}copy(id,options={}){return this.runTyped("copy",{id,...splitFullClientMutationOptions(options)})}delete(id,options={}){return this.runTyped("delete",{id,...splitFullClientMutationOptions(options)})}restore(id,target,options={}){return this.runTyped("restore",{fullChangedFields:!0,id,options:{...options,target}})}focus(id,options={}){return this.runTyped("focus",{...id===void 0?{}:{id},...splitFullClientMutationOptions(options)})}startTask(id,options={}){return this.runTyped("start-task",{id,...splitFullClientMutationOptions(options)})}pauseTask(id,options={}){return this.runTyped("pause-task",{id,...splitFullClientMutationOptions(options)})}closeTask(id,reason,options={}){return this.runTyped("close-task",{id,reason,...splitFullClientMutationOptions(options)})}extension(target,options={}){return this.runTyped("extension",{...target===void 0?{}:{target},options})}extensionList(options={}){return this.extension("list",options)}extensionActivate(target,options={}){return this.runTyped("extension-activate",{target,options})}extensionDeactivate(target,options={}){return this.runTyped("extension-deactivate",{target,options})}package(target,options={}){return this.runTyped("package",{...target===void 0?{}:{target},options:{...options,vocabulary:"package"}})}packageList(options={}){return this.package("list",options)}packageInstall(target,options={}){return this.runTyped("package-install",{target,options})}packageUninstall(target,options={}){return this.runTyped("package-uninstall",{target,options})}packageDoctor(options={}){return this.runTyped("package-doctor",{options})}packageManage(target,options={}){return this.runTyped("package-manage",{...target===void 0?{}:{target},options})}packageDescribe(target,options={}){return this.runTyped("package-describe",{...target===void 0?{}:{target},options})}packageReload(options={}){return this.runTyped("package-reload",{options})}packageCatalog(options={}){return this.runTyped("package-catalog",{options})}packageActivate(target,options={}){return this.runTyped("package-activate",{target,options})}packageDeactivate(target,options={}){return this.runTyped("package-deactivate",{target,options})}packageMigrate(options={}){return this.package(void 0,{...options,migrate:!0})}upgrade(target,options={}){return this.runTyped("upgrade",{...target===void 0?{}:{target},options})}}function context(options={},clientOptions={}){return new PmClient(clientOptions).context(options)}function list(options={},clientOptions={}){return new PmClient(clientOptions).list(options)}function listAllComplete(options={},clientOptions={}){return new PmClient(clientOptions).listAllComplete(options)}function search(query,options={},clientOptions={}){return new PmClient(clientOptions).search(query,options)}function get(id,options={},clientOptions={}){return new PmClient(clientOptions).get(id,options)}function next(options={},clientOptions={}){return new PmClient(clientOptions).next(options)}function aggregate(options={},clientOptions={}){return new PmClient(clientOptions).aggregate(options)}function stats(options={},clientOptions={}){return new PmClient(clientOptions).stats(options)}function duplicates(options={},clientOptions={}){return new PmClient(clientOptions).duplicates(options)}function comments(id,options={},clientOptions={}){return new PmClient(clientOptions).comments(id,options)}function notes(id,options={},clientOptions={}){return new PmClient(clientOptions).notes(id,options)}function learnings(id,options={},clientOptions={}){return new PmClient(clientOptions).learnings(id,options)}function files(id,options={},clientOptions={}){return new PmClient(clientOptions).files(id,options)}function filesDiscover(id,options={},clientOptions={}){return new PmClient(clientOptions).filesDiscover(id,options)}function filesLookup(options,clientOptions={}){return new PmClient(clientOptions).filesLookup(options)}function docs(id,options={},clientOptions={}){return new PmClient(clientOptions).docs(id,options)}function deps(id,options={},clientOptions={}){return new PmClient(clientOptions).deps(id,options)}function graph(subcommand,ids={},options={},clientOptions={}){return new PmClient(clientOptions).graph(subcommand,ids,options)}function append(id,body,options={},clientOptions={}){return new PmClient(clientOptions).append(id,body,options)}function init(prefix,options={},clientOptions={}){return new PmClient(clientOptions).init(prefix,options)}function config(scope,configAction,key,value,options={},clientOptions={}){return new PmClient(clientOptions).config(scope,configAction,key,value,options)}function schema(subcommand,options={},clientOptions={}){return new PmClient(clientOptions).schema(subcommand,options)}function schemaList(clientOptions={}){return new PmClient(clientOptions).schemaList()}function schemaShow(name,clientOptions={}){return new PmClient(clientOptions).schemaShow(name)}function schemaAddType(name,options={},clientOptions={}){return new PmClient(clientOptions).schemaAddType(name,options)}function schemaRemoveType(name,options={},clientOptions={}){return new PmClient(clientOptions).schemaRemoveType(name,options)}function schemaAddStatus(name,options={},clientOptions={}){return new PmClient(clientOptions).schemaAddStatus(name,options)}function schemaRemoveStatus(name,options={},clientOptions={}){return new PmClient(clientOptions).schemaRemoveStatus(name,options)}function schemaAddField(name,options={},clientOptions={}){return new PmClient(clientOptions).schemaAddField(name,options)}function schemaRemoveField(name,options={},clientOptions={}){return new PmClient(clientOptions).schemaRemoveField(name,options)}function schemaListFields(clientOptions={}){return new PmClient(clientOptions).schemaListFields()}function schemaShowField(name,clientOptions={}){return new PmClient(clientOptions).schemaShowField(name)}function schemaApplyPreset(typePreset,options={},clientOptions={}){return new PmClient(clientOptions).schemaApplyPreset(typePreset,options)}function schemaInferTypes(options={},clientOptions={}){return new PmClient(clientOptions).schemaInferTypes(options)}function schemaRenameType(from,to,options,clientOptions={}){return new PmClient(clientOptions).schemaRenameType(from,to,options)}function schemaRenameField(from,to,options,type,clientOptions={}){return new PmClient(clientOptions).schemaRenameField(from,to,options,type)}function schemaRemapStatus(from,to,options,clientOptions={}){return new PmClient(clientOptions).schemaRemapStatus(from,to,options)}function schemaShowStatus(name,clientOptions={}){return new PmClient(clientOptions).schemaShowStatus(name)}function profile(subcommand,options={},clientOptions={}){return new PmClient(clientOptions).profile(subcommand,options)}function profileList(clientOptions={}){return new PmClient(clientOptions).profileList()}function profileShow(name,clientOptions={}){return new PmClient(clientOptions).profileShow(name)}function profileApply(name,options={},clientOptions={}){return new PmClient(clientOptions).profileApply(name,options)}function profileLint(name,clientOptions={}){return new PmClient(clientOptions).profileLint(name)}function validate(options={},clientOptions={}){return new PmClient(clientOptions).validate(options)}function health(options={},clientOptions={}){return new PmClient(clientOptions).health(options)}function gc(options={},clientOptions={}){return new PmClient(clientOptions).gc(options)}function historyRedact(id,options,clientOptions={}){return new PmClient(clientOptions).historyRedact(id,options)}function historyRepair(id,options={},clientOptions={}){return new PmClient(clientOptions).historyRepair(id,options)}function historyRepairAll(options={},clientOptions={}){return new PmClient(clientOptions).historyRepairAll(options)}function historyCompact(id,options={},clientOptions={}){return new PmClient(clientOptions).historyCompact(id,options)}function historyCompactBulk(options,clientOptions={}){return new PmClient(clientOptions).historyCompactBulk(options)}function create(options={},clientOptions={}){return new PmClient(clientOptions).create(options)}function update(id,options={},clientOptions={}){return new PmClient(clientOptions).update(id,options)}function reopen(id,reason,options={},clientOptions={}){return new PmClient(clientOptions).reopen(id,reason,options)}function close(id,reason,options={},clientOptions={}){return new PmClient(clientOptions).close(id,reason,options)}function claim(id,options={},clientOptions={}){return new PmClient(clientOptions).claim(id,options)}function claimNext(options={},clientOptions={}){return new PmClient(clientOptions).claimNext(options)}function release(id,options={},clientOptions={}){return new PmClient(clientOptions).release(id,options)}function copy(id,options={},clientOptions={}){return new PmClient(clientOptions).copy(id,options)}function deleteItem(id,options={},clientOptions={}){return new PmClient(clientOptions).delete(id,options)}function restore(id,target,options={},clientOptions={}){return new PmClient(clientOptions).restore(id,target,options)}function focus(id,options={},clientOptions={}){return new PmClient(clientOptions).focus(id,options)}function startTask(id,options={},clientOptions={}){return new PmClient(clientOptions).startTask(id,options)}function pauseTask(id,options={},clientOptions={}){return new PmClient(clientOptions).pauseTask(id,options)}function closeTask(id,reason,options={},clientOptions={}){return new PmClient(clientOptions).closeTask(id,reason,options)}function extension(target,options={},clientOptions={}){return new PmClient(clientOptions).extension(target,options)}function extensionList(options={},clientOptions={}){return new PmClient(clientOptions).extensionList(options)}function extensionActivate(target,options={},clientOptions={}){return new PmClient(clientOptions).extensionActivate(target,options)}function extensionDeactivate(target,options={},clientOptions={}){return new PmClient(clientOptions).extensionDeactivate(target,options)}function packageLifecycle(target,options={},clientOptions={}){return new PmClient(clientOptions).package(target,options)}function packageList(options={},clientOptions={}){return new PmClient(clientOptions).packageList(options)}function packageInstall(target,options={},clientOptions={}){return new PmClient(clientOptions).packageInstall(target,options)}function packageUninstall(target,options={},clientOptions={}){return new PmClient(clientOptions).packageUninstall(target,options)}function packageDoctor(options={},clientOptions={}){return new PmClient(clientOptions).packageDoctor(options)}function packageManage(target,options={},clientOptions={}){return new PmClient(clientOptions).packageManage(target,options)}function packageDescribe(target,options={},clientOptions={}){return new PmClient(clientOptions).packageDescribe(target,options)}function packageReload(options={},clientOptions={}){return new PmClient(clientOptions).packageReload(options)}function packageCatalog(options={},clientOptions={}){return new PmClient(clientOptions).packageCatalog(options)}function packageActivate(target,options={},clientOptions={}){return new PmClient(clientOptions).packageActivate(target,options)}function packageDeactivate(target,options={},clientOptions={}){return new PmClient(clientOptions).packageDeactivate(target,options)}function upgrade(target,options={},clientOptions={}){return new PmClient(clientOptions).upgrade(target,options)}async function getContracts(pmRootOrOptions,options={}){const resolvedOptions=typeof pmRootOrOptions=="string"?{...options,pmRoot:pmRootOrOptions}:pmRootOrOptions??options,global2={json:!0,quiet:resolvedOptions.quiet??!0,noExtensions:resolvedOptions.noExtensions??!1,noPager:!0,profile:resolvedOptions.profile??!1,path:resolvedOptions.pmRoot};return runContracts(resolvedOptions,global2)}const extensionActivationGate=createAsyncReadWriteGate(),activeExtensionScope=new AsyncLocalStorage;function resetActiveExtensionRegistries(){setActiveExtensionHooks(createEmptyExtensionHookRegistry()),setActiveExtensionCommands(createEmptyExtensionCommandRegistry()),setActiveExtensionParsers(createEmptyExtensionParserRegistry()),setActiveExtensionPreflight(createEmptyExtensionPreflightRegistry()),setActiveExtensionServices(createEmptyExtensionServiceRegistry()),setActiveExtensionRenderers(createEmptyExtensionRendererRegistry()),setActiveExtensionRegistrations(createEmptyExtensionRegistrationRegistry())}async function withActiveExtensions(global2,explicitCwd,resolutionCwd,run){return runWithIsolatedExtensionRuntime(()=>explicitCwd===void 0?extensionActivationGate.read(()=>withActiveExtensionsExclusively(global2,resolutionCwd,run)):extensionActivationGate.write(()=>withCwd(explicitCwd,()=>withActiveExtensionsExclusively(global2,resolutionCwd,run))))}async function runWithActiveExtensions(options,run){const explicitCwd=options.cwd;if(activeExtensionScope.getStore()===!0&&explicitCwd===void 0&&options.noExtensions===!0){const pmRoot=resolvePmRoot(process.cwd(),options.path);return runWithIsolatedExtensionRuntime(()=>runWithDiscoveredContextIntentContracts({pmRoot},run))}const resolutionCwd=explicitCwd??process.cwd();return withActiveExtensions(globalOptions({path:options.path,noExtensions:options.noExtensions}),explicitCwd,resolutionCwd,()=>activeExtensionScope.run(!0,run))}async function withActiveExtensionsExclusively(global2,cwd,run){const pmRoot=resolvePmRoot(cwd,global2.path);if(global2.noExtensions)return resetActiveExtensionRegistries(),runWithDiscoveredContextIntentContracts({pmRoot},()=>run(null));if(!await pathExists(getSettingsPath(pmRoot)))return resetActiveExtensionRegistries(),run(null);let active=null,activated;try{const settings=await readSettings(pmRoot),loadResult=await loadExtensions({pmRoot,settings,cwd,noExtensions:!1}),activationResult=await activateExtensions({...loadResult,loaded:loadResult.loaded});activated={loadResult,activationResult},setActiveExtensionHooks(activationResult.hooks),setActiveExtensionCommands(activationResult.commands),setActiveExtensionParsers(activationResult.parsers),setActiveExtensionPreflight(activationResult.preflight),setActiveExtensionServices(activationResult.services),setActiveExtensionRenderers(activationResult.renderers),setActiveExtensionRegistrations(activationResult.registrations),active={registrations:activationResult.registrations,commands:activationResult.commands,pmRoot,packages:loadResult.loaded}}catch(error){resetActiveExtensionRegistries(),console.error("[pm-sdk] extension activation failed; continuing without active extensions:",error)}try{return await runWithDiscoveredContextIntentContracts({pmRoot,packages:active?.packages},()=>run(active))}finally{resetActiveExtensionRegistries(),activated&&await deactivateExtensions(activated.loadResult,activated.activationResult).catch(()=>{})}}function resolveActiveExtensionActionCommand(action,active){const normalizedAction=normalizeActionName(action);return active?.registrations.commands.find(entry=>normalizeActionName(entry.action)===normalizedAction)?.command??active?.commands.handlers.find(entry=>normalizeActionName(entry.command)===normalizedAction)?.command}async function dispatchActiveExtensionAction(action,args,options,global2,active){if(!active)throw new PmCliError(`Unsupported native pm action: ${action}`,EXIT_CODE.USAGE);const command=resolveActiveExtensionActionCommand(action,active);if(!command)throw new PmCliError(`Unsupported native pm action: ${action}`,EXIT_CODE.USAGE);const extensionAuthor=typeof global2.author=="string"&&global2.author.trim()?global2.author.trim():"pm-extension",handlerResult=await runActiveCommandHandler({command:normalizeCommandPath(command),args:readStringArray(options.args??args.args),options:extensionOptionsFromArgs(args,options),global:global2,pm_root:active.pmRoot,sdk:createExtensionCommandSdk(active.pmRoot,PmClient.forActiveExtensionHost({pmRoot:active.pmRoot,author:extensionAuthor}),extensionAuthor,normalizeCommandPath(command))});if(!handlerResult.handled){const suffix=handlerResult.warnings.length>0?` (${handlerResult.warnings.join(", ")})`:"";throw new PmCliError(`Unsupported native pm action: ${action}${suffix}`,EXIT_CODE.USAGE)}return handlerResult.result}async function withCwd(cwd,run){const previous=process.cwd();process.chdir(cwd);try{return await run()}finally{process.chdir(previous)}}function resolveSdkActionInput(args){const rawAction=readRequiredString(args,"action"),normalizedAction=normalizeActionName(rawAction),alias=getOwnHandler(SDK_ACTION_ALIASES,normalizedAction),action=alias?.action??normalizedAction,resolvedArgs={...args,action};return alias?.options!==void 0&&(resolvedArgs.options={...alias.options,...asRecordClone(args.options)}),action==="package"&&(resolvedArgs.options={...asRecordClone(resolvedArgs.options),vocabulary:"package"}),{action,args:resolvedArgs}}async function runAction(args){const resolved=resolveSdkActionInput(args),global2=globalOptions(resolved.args),invalidateWorkspaceContractsCache=shouldInvalidateWorkspaceContractsCacheAfterAction(resolved.action),explicitCwd=readString(resolved.args,"cwd"),resolutionCwd=explicitCwd??process.cwd();resolved.action==="init"&&(global2[INIT_INVOCATION_CWD]=resolutionCwd),(resolved.action!=="init"||global2.path!==void 0||(process.env.PM_PATH?.trim().length??0)>0)&&(global2.path=resolvePmRoot(resolutionCwd,global2.path));try{return resolved.action==="history-attest"?await dispatchAction(resolved.action,resolved.args,global2,null):args[ACTIVE_EXTENSION_HOST_CONTEXT]===!0||activeExtensionScope.getStore()===!0?await dispatchAction(resolved.action,resolved.args,global2,null):await withActiveExtensions(global2,explicitCwd,resolutionCwd,activeExtensions=>dispatchAction(resolved.action,resolved.args,global2,activeExtensions))}finally{invalidateWorkspaceContractsCache&&clearWorkspaceContractsCache()}}function analyzeSdkActionCoverage(actions=PM_TOOL_ACTIONS){return actions.map(action=>{const normalized=normalizeActionName(action),alias=getOwnHandler(SDK_ACTION_ALIASES,normalized),resolvedAction=alias?.action??normalized,covered=getOwnHandler(SDK_ACTION_HANDLERS,resolvedAction)!==void 0;return{action,resolved_action:resolvedAction,covered,route:covered?alias?"alias":"native":"missing"}})}async function dispatchAction(action,args,global2,activeExtensions){const options=optionsWithAuthor(args,action),handler=getOwnHandler(SDK_ACTION_HANDLERS,action),extensionCommand=handler?void 0:resolveActiveExtensionActionCommand(action,activeExtensions),readCommand=extensionCommand===void 0?action:`extension:${extensionCommand}`;validateReadOutputOptions(readCommand,options),normalizeReadOutputIncludeModeOptions(readCommand,options);const ctx={action,args,options,id:readString(args,"id"),force:args.force===!0||options.force===!0,global:global2,activeExtensions},result=handler?await handler(ctx):await dispatchActiveExtensionAction(action,args,options,global2,activeExtensions);if(action==="history-attest")return result;{options.resolvedOutputFormat="json";const projected=attachReadOutputContracts(readCommand,options,result);return await finalizeContextUsageEgress(resolvePmRoot(process.cwd(),global2.path),projected),projected}}const actionRunnerTestHooks={closeManyOptionsFromFlat,extensionOptionsFromArgs,globalOptions,mutationListOptions,normalizeActionName,normalizeCommandPath,normalizeMcpUpdateOptions,normalizeMcpOptionsArrays,optionsWithAuthor,readRequiredString,readScalarString,readScalarStringAllowBlank,readStringArray,updateManyOptionsFromFlat,withAddNoteOption,withFilesDiscoveryOptions,withMutationCompaction};(process.env.NODE_ENV==="test"||process.env.VITEST!==void 0||process.env.VITEST_WORKER_ID!==void 0)&&(globalThis.__pmCliActionRunnerTestHooks=actionRunnerTestHooks);import{readRequiredString as readRequiredString2}from"./runtime/context.js";export{BASELINE_ITEM_FORMAT_VERSION,BUILTIN_ITEM_TYPE_VALUES,CONFIDENCE_TEXT_VALUES,CONTEXT_OUTPUT_VALUES,CURRENT_ITEM_FORMAT_VERSION,DEFAULT_TERMINAL_TRANSITION_POLICY,DEPENDENCY_KIND_VALUES,EXIT_CODE,HISTORY_EVENT_CLASSIFICATION_VERSION,ISSUE_SEVERITY_VALUES,ITEM_TYPE_VALUES,MAINTENANCE_HISTORY_OPERATIONS,NEXT_OUTPUT_VALUES,PM_CLI_EXPECTED_ERROR_NAME,PM_GITIGNORE_END,PM_GITIGNORE_START,PmCliError2 as PmCliError,PmClient,PmCompleteListValidationError,RISK_VALUES,SEARCH_EXTENSION_FLAG_DEFINITIONS,STATUS_VALUES,SUBSTANTIVE_HISTORY_OPERATIONS,acquireLock,aggregate,analyzeSdkActionCoverage,append,appendHistoryEntry,applyTerminalOrderingPolicy,assertCompleteListResult,canonicalDocument,certifyCompleteListResult2 as certifyCompleteListResult,claim,claimNext,classifyHistoryEvent,classifyItemFormatVersion,clearWorkspaceContractsCache2 as clearWorkspaceContractsCache,close,closeItem,closeTask,comments,commitImportedItem,config,context,copy,create,createCompleteListOptions2 as createCompleteListOptions,createHistoryEntry,createPmCliExpectedError,deleteItem,deps,docs,duplicates,effectiveItemFormatVersion,emptyImportedDocument,ensurePmGitignore,ensureTrackerInitialized,extension,extensionActivate,extensionDeactivate,extensionList,files,filesDiscover,filesLookup,focus,gc,generateItemId,get,getActiveExtensionRegistrations,getContracts,getHistoryPath,getItemPath,getPmGitignoreBlock,getSettingsPath2 as getSettingsPath,getWorkspaceContracts,graph,health,historyCompact,historyCompactBulk,historyRedact,historyRepair,historyRepairAll,init,inspectCompleteListResult,isPmCliExpectedError,isTerminalStatus,isTimestampLiteral,jaccardSimilarity,learnings,list,listAllComplete,listAllItemMetadata,listAllItemMetadataLight,loadCreateTemplateOptions,locateItem,next,normalizeItemFormatVersion,normalizeItemId,normalizeItemMetadata,normalizeRawItemId,normalizeSimilarityText,normalizeStatusInput,notes,nowIso,packageActivate,packageCatalog,packageDeactivate,packageDescribe,packageDoctor,packageInstall,packageLifecycle,packageList,packageManage,packageReload,packageUninstall,parseTags,pathExists2 as pathExists,pauseTask,profile,profileApply,profileLint,profileList,profileShow,readBooleanOption,readCsvListOption,readFileIfExists,readLocatedItem,readRequiredString2 as readRequiredString,readSettings2 as readSettings,readStringOption,release,removeFileIfExists,renderCalendarMarkdown,renderCalendarToon,renderGuideMarkdown,reopen,requireTerminalReason,resolveCalendarOutputFormat,resolveGuideOutputFormat,resolveImplicitPmRoot,resolveItemTypeRegistry,resolvePmRoot2 as resolvePmRoot,resolveRuntimeFieldRegistry,resolveRuntimeStatusRegistry,resolveTerminalReason,restore,runAction,runActiveOnReadHooks,runActiveOnWriteHooks,runAggregate,runCalendar,runClose,runCloseTask,runCompletion,runContext,runCopy,runDelete,runDuplicates,runFocus,runGet,runGuide,runList,runNext,runPauseTask,runReindex,runReopen,runRestore,runSearch,runStartTask,runStats,runTemplatesList,runTemplatesSave,runTemplatesShow,runTestRunsList,runTestRunsLogs,runTestRunsResume,runTestRunsStatus,runTestRunsStop,runUpdate,runWithActiveExtensions,scanItemFormatVersions,schema,schemaAddField,schemaAddStatus,schemaAddType,schemaApplyPreset,schemaInferTypes,schemaList,schemaListFields,schemaRemapStatus,schemaRemoveField,schemaRemoveStatus,schemaRemoveType,schemaRenameField,schemaRenameType,schemaShow,schemaShowField,schemaShowStatus,scoreItemSimilarity,search,selectImportAuthor,serializeItemDocument,splitFrontMatter,startTask,stats,toEstimatedMinutesValue,toImportBoolean,toImportConfidence,toImportInteger,toImportLinkedDocs,toImportLinkedFiles,toImportLinkedTests,toImportLogEntries,toImportNormalizedEnum,toImportNumberMap,toImportPriority,toImportStatus,toImportStringList,toImportStringMap,toImportTags,toNonEmptyImportString,tokenizeSimilarityText,update,upgrade,validate,writeFileAtomic};
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]="df97ccfc-a33f-595d-b4b7-673bfef412c9")}catch{}})();import{AsyncLocalStorage}from"node:async_hooks";import{createEmptyExtensionCommandRegistry,createEmptyExtensionHookRegistry,createEmptyExtensionParserRegistry,createEmptyExtensionPreflightRegistry,createEmptyExtensionRegistrationRegistry,createEmptyExtensionRendererRegistry,createEmptyExtensionServiceRegistry}from"../core/extensions/extension-registries.js";import{activateExtensions,deactivateExtensions,loadExtensions,runActiveCommandHandler,runWithIsolatedExtensionRuntime,setActiveExtensionCommands,setActiveExtensionHooks,setActiveExtensionParsers,setActiveExtensionPreflight,setActiveExtensionRegistrations,setActiveExtensionRenderers,setActiveExtensionServices}from"../core/extensions/index.js";import{pathExists}from"../core/fs/fs-utils.js";import{EXIT_CODE}from"../core/shared/constants.js";import{PmCliError}from"../core/shared/errors.js";import{asRecordClone}from"../core/shared/primitives.js";import{createAsyncReadWriteGate}from"../core/shared/serial-queue.js";import{getSettingsPath,resolvePmRoot}from"../core/store/paths.js";import{readSettings}from"../core/store/settings.js";import{PM_TOOL_ACTIONS}from"./cli-contracts/enum-contracts.js";import{runContracts}from"./cli-contracts/runtime-contracts.js";import{attachReadOutputContracts}from"./context-intent-contracts.js";import{runWithDiscoveredContextIntentContracts}from"./context-intent-runtime.js";import{finalizeContextUsageEgress}from"./context/usage-egress.js";import{createExtensionCommandSdk}from"./extension-command-context.js";import{INIT_INVOCATION_CWD}from"./init.js";import{certifyCompleteListResult,createCompleteListOptions}from"./query/complete-list.js";import{listClientItemMetadataLight}from"./query/light-metadata.js";import{normalizeReadOutputIncludeModeOptions,validateReadOutputOptions}from"./read-output-contracts.js";import{SDK_ACTION_ALIASES}from"./runtime-action-aliases.js";import{closeManyOptionsFromFlat,extensionOptionsFromArgs,actionGlobalOptions as globalOptions,mutationListOptions,mutationOptionsWithOverrides,normalizeActionName,normalizeCommandPath,normalizeMcpOptionsArrays,normalizeMcpUpdateOptions,optionsWithAuthor,readRuntimeScalarString as readScalarString,readRuntimeScalarStringAllowBlank as readScalarStringAllowBlank,readRuntimeString as readString,readRuntimeStringArray as readStringArray,shouldInvalidateWorkspaceContractsCacheAfterAction,updateManyOptionsFromFlat,withAddNoteOption,withFilesDiscoveryOptions,withMutationCompaction}from"./runtime-input.js";import{SDK_ACTION_HANDLERS}from"./runtime/actions.js";import{getOwnHandler,readRequiredString}from"./runtime/context.js";import{clearWorkspaceContractsCache}from"./workspace-contracts-cache.js";import{PM_GITIGNORE_END,PM_GITIGNORE_START,ensurePmGitignore,getPmGitignoreBlock}from"./workspace.js";import{SEARCH_EXTENSION_FLAG_DEFINITIONS}from"./extension-contracts.js";export*from"./cli-contracts/agent-output-contracts.js";import{PmCompleteListValidationError,assertCompleteListResult,certifyCompleteListResult as certifyCompleteListResult2,createCompleteListOptions as createCompleteListOptions2,inspectCompleteListResult}from"./query/complete-list.js";import{getWorkspaceContracts}from"./query/workspace-contracts.js";import{clearWorkspaceContractsCache as clearWorkspaceContractsCache2}from"./workspace-contracts-cache.js";export*from"./governance/workflow-policy.js";import{runCloseTask,runPauseTask,runStartTask}from"./lifecycle/task-composition.js";import{getActiveExtensionRegistrations,runActiveOnReadHooks,runActiveOnWriteHooks}from"../core/extensions/index.js";import{pathExists as pathExists2,readFileIfExists,removeFileIfExists,writeFileAtomic}from"../core/fs/fs-utils.js";import{appendHistoryEntry,createHistoryEntry}from"../core/history/history.js";import{HISTORY_EVENT_CLASSIFICATION_VERSION,MAINTENANCE_HISTORY_OPERATIONS,SUBSTANTIVE_HISTORY_OPERATIONS,classifyHistoryEvent}from"../core/history/event-classification.js";import{generateItemId,normalizeItemId,normalizeRawItemId}from"../core/item/id.js";import{readBooleanOption,readCsvListOption,readStringOption}from"./package-runtime-options.js";import{PM_CLI_EXPECTED_ERROR_NAME,createPmCliExpectedError,isPmCliExpectedError}from"./errors.js";import{commitImportedItem,emptyImportedDocument,ensureTrackerInitialized,selectImportAuthor,toEstimatedMinutesValue,toImportBoolean,toImportConfidence,toImportInteger,toImportLinkedDocs,toImportLinkedFiles,toImportLinkedTests,toImportLogEntries,toImportNormalizedEnum,toImportNumberMap,toImportPriority,toImportStatus,toImportStringList,toImportStringMap,toImportTags,toNonEmptyImportString}from"./package-import-adapters.js";import{canonicalDocument,normalizeItemMetadata,serializeItemDocument,splitFrontMatter}from"../core/item/item-format.js";import{BASELINE_ITEM_FORMAT_VERSION,CURRENT_ITEM_FORMAT_VERSION,classifyItemFormatVersion,effectiveItemFormatVersion,normalizeItemFormatVersion,scanItemFormatVersions}from"../core/item/item-format-version.js";import{parseTags}from"../core/item/parse.js";import{isTerminalStatus,normalizeStatusInput}from"../core/item/status.js";import{resolveItemTypeRegistry}from"../core/item/type-registry.js";import{acquireLock}from"../core/lock/lock.js";import{resolveRuntimeFieldRegistry,resolveRuntimeStatusRegistry}from"../core/schema/runtime-schema.js";import{PmCliError as PmCliError2}from"../core/shared/errors.js";import{isTimestampLiteral,nowIso}from"../core/shared/time.js";import{jaccardSimilarity,normalizeSimilarityText,scoreItemSimilarity,tokenizeSimilarityText}from"./similarity-scoring.js";import{listAllItemMetadata,listAllItemMetadataLight,locateItem,readLocatedItem}from"../core/store/item-store.js";import{getHistoryPath,getItemPath,getSettingsPath as getSettingsPath2,resolveImplicitPmRoot,resolvePmRoot as resolvePmRoot2}from"../core/store/paths.js";import{readSettings as readSettings2}from"../core/store/settings.js";import{runAggregate}from"./query/aggregate.js";import{CONTEXT_OUTPUT_VALUES,runContext}from"./query/context.js";import{runGet}from"./query/get.js";import{runList}from"./query/list.js";import{closeItem,runClose}from"./lifecycle/close.js";import{runCopy}from"./lifecycle/copy.js";import{runDelete}from"./lifecycle/delete.js";import{runFocus}from"./lifecycle/focus.js";import{runRestore}from"./lifecycle/restore.js";import{DEFAULT_TERMINAL_TRANSITION_POLICY,applyTerminalOrderingPolicy,requireTerminalReason,resolveTerminalReason}from"./lifecycle-policy.js";import{runUpdate}from"./lifecycle/update.js";import{runReopen}from"./lifecycle/reopen.js";import{NEXT_OUTPUT_VALUES,runNext}from"./query/next.js";import{runSearch}from"./query/search.js";import{runStats}from"./stats.js";import{runDuplicates}from"./duplicates.js";import{renderCalendarMarkdown,renderCalendarToon,resolveCalendarOutputFormat,runCalendar}from"./query/calendar.js";import{renderGuideMarkdown,resolveGuideOutputFormat,runGuide}from"./guide.js";import{runCompletion}from"./completion.js";import{runReindex}from"./governance/reindex.js";import{loadCreateTemplateOptions,runTemplatesList,runTemplatesSave,runTemplatesShow}from"./templates.js";import{runTestRunsList,runTestRunsLogs,runTestRunsResume,runTestRunsStatus,runTestRunsStop}from"./test/runs.js";import{BUILTIN_ITEM_TYPE_VALUES,CONFIDENCE_TEXT_VALUES,DEPENDENCY_KIND_VALUES,ISSUE_SEVERITY_VALUES,ITEM_TYPE_VALUES,RISK_VALUES,STATUS_VALUES}from"../types/index.js";const ACTIVE_EXTENSION_HOST_CONTEXT=Symbol("pm.active-extension-host-context");function splitFullClientMutationOptions(options){return{fullChangedFields:!0,options}}class PmClient{defaults;constructor(options={}){this.defaults={...options.pmRoot===void 0?{}:{path:options.pmRoot},...options.cwd===void 0?{}:{cwd:options.cwd},...options.author===void 0?{}:{author:options.author},...options.noExtensions===void 0?{}:{noExtensions:options.noExtensions}}}static forActiveExtensionHost(options){const client=new PmClient({...options,noExtensions:!0});return client.defaults[ACTIVE_EXTENSION_HOST_CONTEXT]=!0,client}run(action,args={}){return runAction({...this.defaults,...args,action})}runTyped(action,args={}){return this.run(action,args)}context(options={}){return this.runTyped("context",{options})}listAllItemMetadataLight(){return listClientItemMetadataLight(this.defaults.path,this.defaults.cwd)}list(options={}){return this.runTyped("list",{options})}async listAllComplete(options={}){return certifyCompleteListResult(await this.list(createCompleteListOptions(options)))}search(query,options={}){return this.runTyped("search",{query,options})}get(id,options={}){return this.runTyped("get",{id,options})}next(options={}){return this.runTyped("next",{options})}aggregate(options={}){return this.runTyped("aggregate",{options})}stats(options={}){return this.runTyped("stats",{options})}duplicates(options={}){return this.runTyped("duplicates",{options})}comments(id,options={}){return this.runTyped("comments",{id,options})}notes(id,options={}){return this.runTyped("notes",{id,options})}learnings(id,options={}){return this.runTyped("learnings",{id,options})}files(id,options={}){return this.runTyped("files",{id,options})}filesDiscover(id,options={}){return this.runTyped("files-discover",{id,options})}filesLookup(options){return this.runTyped("files-lookup",{options})}docs(id,options={}){return this.runTyped("docs",{id,options})}deps(id,options={}){return this.runTyped("deps",{id,options})}graph(subcommand,ids={},options={}){return this.runTyped("graph",{subcommand,...ids,options})}append(id,body,options={}){return this.runTyped("append",{id,...splitFullClientMutationOptions(mutationOptionsWithOverrides(options,{body}))})}init(prefix,options={}){return this.runTyped("init",{...prefix===void 0?{}:{prefix},options})}config(scope,configAction,key,value,options={}){return this.runTyped("config",{scope,configAction,...key===void 0?{}:{key},...value===void 0?{}:{value},options})}schema(subcommand,options={}){return this.runTyped("schema",{options:{...options,subcommand}})}workflowPolicy(action,name,options={}){return this.runTyped("schema",{name,options:{...options,subcommand:action}})}schemaList(){return this.runTyped("schema",{options:{subcommand:"list"}})}schemaShow(name){return this.runTyped("schema",{name,options:{subcommand:"show"}})}schemaAddType(name,options={}){return this.runTyped("schema",{name,options:{...options,subcommand:"add-type"}})}schemaRemoveType(name,options={}){return this.runTyped("schema",{name,options:{...options,subcommand:"remove-type"}})}schemaAddStatus(name,options={}){return this.runTyped("schema",{name,options:{...options,subcommand:"add-status"}})}schemaRemoveStatus(name,options={}){return this.runTyped("schema",{name,options:{...options,subcommand:"remove-status"}})}schemaAddField(name,options={}){const{type,...mutationOptions}=options;return this.runTyped("schema",{name,options:{...mutationOptions,fieldType:type,subcommand:"add-field"}})}schemaRemoveField(name,options={}){return this.runTyped("schema",{name,options:{...options,subcommand:"remove-field"}})}schemaListFields(){return this.runTyped("schema",{options:{subcommand:"list-fields"}})}schemaShowField(name){return this.runTyped("schema",{name,options:{subcommand:"show-field"}})}schemaApplyPreset(typePreset,options={}){return this.runTyped("schema",{typePreset,options:{...options,subcommand:"apply-preset"}})}schemaInferTypes(options={}){return this.runTyped("schema",{options:{...options,subcommand:"add-type",infer:!0}})}schemaRenameType(from,to,options){return this.runTyped("schema",{name:from,options:{...options,subcommand:"rename-type",to}})}schemaRenameField(from,to,options,type){return this.runTyped("schema",{name:from,options:{...options,subcommand:"rename-field",to,...type?{fieldTypeScope:type}:{}}})}schemaRemapStatus(from,to,options){return this.runTyped("schema",{name:from,options:{...options,subcommand:"remap-status",to}})}schemaShowStatus(name){return this.runTyped("schema",{name,options:{subcommand:"show-status"}})}profile(subcommand,options={}){return this.runTyped("profile",{options:{...options,subcommand}})}profileList(){return this.runTyped("profile",{options:{subcommand:"list"}})}profileShow(name){return this.runTyped("profile",{name,options:{subcommand:"show"}})}profileApply(name,options={}){return this.runTyped("profile",{name,options:{...options,subcommand:"apply"}})}profileLint(name){return this.runTyped("profile",{name,options:{subcommand:"lint"}})}validate(options={}){return this.runTyped("validate",{options})}health(options={}){return this.runTyped("health",{options})}gc(options={}){return this.runTyped("gc",{options})}assurance(input){return this.runTyped("assurance",{options:{...input,subcommand:input.action}})}historyRedact(id,options){return this.runTyped("history-redact",{id,options})}historyRepair(id,options={}){return this.runTyped("history-repair",{id,options})}historyRepairAll(options={}){return this.runTyped("history-repair",{options:{...options,all:!0}})}historyAttest(options={}){return this.runTyped("history-attest",{options})}historyCompact(id,options={}){return this.runTyped("history-compact",{id,options})}historyCompactBulk(options){return this.runTyped("history-compact",{options})}historyAuthorAcknowledge(options){return this.runTyped("history-author-acknowledge",{historyEvent:(options.events??[]).map(event=>`${event.item_id}:${String(event.line)}`),allActionable:options.all_actionable===!0,dryRun:options.dry_run===!0,planFingerprint:options.plan_fingerprint,limit:options.coordinate_limit,attributedAuthor:options.attributed_author,reviewer:options.reviewer,reason:options.reason})}plan(subcommand,id,options={},stepRef,reorderTo){return this.runTyped("plan",{fullChangedFields:!0,...id===void 0?{}:{id},...stepRef===void 0?{}:{stepRef},...reorderTo===void 0?{}:{reorderTo},options:mutationOptionsWithOverrides(options,{subcommand})})}planCreate(options){return this.plan("create",void 0,options)}planShow(id,options={}){return this.plan("show",id,options)}planAddStep(id,options){return this.plan("add-step",id,options)}planUpdateStep(id,stepRef,options){return this.plan("update-step",id,options,stepRef)}planCompleteStep(id,stepRef,options={}){return this.plan("complete-step",id,options,stepRef)}planBlockStep(id,stepRef,options){return this.plan("block-step",id,options,stepRef)}planReorderStep(id,stepRef,reorderTo,options={}){return this.plan("reorder-step",id,options,stepRef,reorderTo)}planRemoveStep(id,stepRef,options={}){return this.plan("remove-step",id,options,stepRef)}planLink(id,stepRef,options){return this.plan("link",id,options,stepRef)}planUnlink(id,stepRef,options){return this.plan("unlink",id,options,stepRef)}planDecision(id,options){return this.plan("decision",id,options)}planDiscovery(id,options){return this.plan("discovery",id,options)}planValidation(id,options){return this.plan("validation",id,options)}planResume(id,options){return this.plan("resume",id,options)}planApprove(id,options={}){return this.plan("approve",id,options)}planMaterialize(id,options){return this.plan("materialize",id,options)}create(options={}){return this.runTyped("create",splitFullClientMutationOptions(options))}update(id,options={}){return this.runTyped("update",{id,...splitFullClientMutationOptions(options)})}reopen(id,reason,options={}){return this.runTyped("item-reopen",{id,reason,fullChangedFields:!0,options})}close(id,reason,options={}){return this.runTyped("close",{id,reason,...splitFullClientMutationOptions(options)})}claim(id,options={}){return this.runTyped("claim",{id,...splitFullClientMutationOptions(options)})}claimNext(options={}){return this.runTyped("claim",{next:!0,...splitFullClientMutationOptions(options)})}release(id,options={}){return this.runTyped("release",{id,...splitFullClientMutationOptions(options)})}copy(id,options={}){return this.runTyped("copy",{id,...splitFullClientMutationOptions(options)})}delete(id,options={}){return this.runTyped("delete",{id,...splitFullClientMutationOptions(options)})}restore(id,target,options={}){return this.runTyped("restore",{fullChangedFields:!0,id,options:{...options,target}})}focus(id,options={}){return this.runTyped("focus",{...id===void 0?{}:{id},...splitFullClientMutationOptions(options)})}startTask(id,options={}){return this.runTyped("start-task",{id,...splitFullClientMutationOptions(options)})}pauseTask(id,options={}){return this.runTyped("pause-task",{id,...splitFullClientMutationOptions(options)})}closeTask(id,reason,options={}){return this.runTyped("close-task",{id,reason,...splitFullClientMutationOptions(options)})}extension(target,options={}){return this.runTyped("extension",{...target===void 0?{}:{target},options})}extensionList(options={}){return this.extension("list",options)}extensionActivate(target,options={}){return this.runTyped("extension-activate",{target,options})}extensionDeactivate(target,options={}){return this.runTyped("extension-deactivate",{target,options})}package(target,options={}){return this.runTyped("package",{...target===void 0?{}:{target},options:{...options,vocabulary:"package"}})}packageList(options={}){return this.package("list",options)}packageInstall(target,options={}){return this.runTyped("package-install",{target,options})}packageUninstall(target,options={}){return this.runTyped("package-uninstall",{target,options})}packageDoctor(options={}){return this.runTyped("package-doctor",{options})}packageManage(target,options={}){return this.runTyped("package-manage",{...target===void 0?{}:{target},options})}packageDescribe(target,options={}){return this.runTyped("package-describe",{...target===void 0?{}:{target},options})}packageReload(options={}){return this.runTyped("package-reload",{options})}packageCatalog(options={}){return this.runTyped("package-catalog",{options})}packageActivate(target,options={}){return this.runTyped("package-activate",{target,options})}packageDeactivate(target,options={}){return this.runTyped("package-deactivate",{target,options})}packageMigrate(options={}){return this.package(void 0,{...options,migrate:!0})}upgrade(target,options={}){return this.runTyped("upgrade",{...target===void 0?{}:{target},options})}}function context(options={},clientOptions={}){return new PmClient(clientOptions).context(options)}function list(options={},clientOptions={}){return new PmClient(clientOptions).list(options)}function listAllComplete(options={},clientOptions={}){return new PmClient(clientOptions).listAllComplete(options)}function search(query,options={},clientOptions={}){return new PmClient(clientOptions).search(query,options)}function get(id,options={},clientOptions={}){return new PmClient(clientOptions).get(id,options)}function next(options={},clientOptions={}){return new PmClient(clientOptions).next(options)}function aggregate(options={},clientOptions={}){return new PmClient(clientOptions).aggregate(options)}function stats(options={},clientOptions={}){return new PmClient(clientOptions).stats(options)}function duplicates(options={},clientOptions={}){return new PmClient(clientOptions).duplicates(options)}function comments(id,options={},clientOptions={}){return new PmClient(clientOptions).comments(id,options)}function notes(id,options={},clientOptions={}){return new PmClient(clientOptions).notes(id,options)}function learnings(id,options={},clientOptions={}){return new PmClient(clientOptions).learnings(id,options)}function files(id,options={},clientOptions={}){return new PmClient(clientOptions).files(id,options)}function filesDiscover(id,options={},clientOptions={}){return new PmClient(clientOptions).filesDiscover(id,options)}function filesLookup(options,clientOptions={}){return new PmClient(clientOptions).filesLookup(options)}function docs(id,options={},clientOptions={}){return new PmClient(clientOptions).docs(id,options)}function deps(id,options={},clientOptions={}){return new PmClient(clientOptions).deps(id,options)}function graph(subcommand,ids={},options={},clientOptions={}){return new PmClient(clientOptions).graph(subcommand,ids,options)}function append(id,body,options={},clientOptions={}){return new PmClient(clientOptions).append(id,body,options)}function init(prefix,options={},clientOptions={}){return new PmClient(clientOptions).init(prefix,options)}function config(scope,configAction,key,value,options={},clientOptions={}){return new PmClient(clientOptions).config(scope,configAction,key,value,options)}function schema(subcommand,options={},clientOptions={}){return new PmClient(clientOptions).schema(subcommand,options)}function schemaList(clientOptions={}){return new PmClient(clientOptions).schemaList()}function schemaShow(name,clientOptions={}){return new PmClient(clientOptions).schemaShow(name)}function schemaAddType(name,options={},clientOptions={}){return new PmClient(clientOptions).schemaAddType(name,options)}function schemaRemoveType(name,options={},clientOptions={}){return new PmClient(clientOptions).schemaRemoveType(name,options)}function schemaAddStatus(name,options={},clientOptions={}){return new PmClient(clientOptions).schemaAddStatus(name,options)}function schemaRemoveStatus(name,options={},clientOptions={}){return new PmClient(clientOptions).schemaRemoveStatus(name,options)}function schemaAddField(name,options={},clientOptions={}){return new PmClient(clientOptions).schemaAddField(name,options)}function schemaRemoveField(name,options={},clientOptions={}){return new PmClient(clientOptions).schemaRemoveField(name,options)}function schemaListFields(clientOptions={}){return new PmClient(clientOptions).schemaListFields()}function schemaShowField(name,clientOptions={}){return new PmClient(clientOptions).schemaShowField(name)}function schemaApplyPreset(typePreset,options={},clientOptions={}){return new PmClient(clientOptions).schemaApplyPreset(typePreset,options)}function schemaInferTypes(options={},clientOptions={}){return new PmClient(clientOptions).schemaInferTypes(options)}function schemaRenameType(from,to,options,clientOptions={}){return new PmClient(clientOptions).schemaRenameType(from,to,options)}function schemaRenameField(from,to,options,type,clientOptions={}){return new PmClient(clientOptions).schemaRenameField(from,to,options,type)}function schemaRemapStatus(from,to,options,clientOptions={}){return new PmClient(clientOptions).schemaRemapStatus(from,to,options)}function schemaShowStatus(name,clientOptions={}){return new PmClient(clientOptions).schemaShowStatus(name)}function profile(subcommand,options={},clientOptions={}){return new PmClient(clientOptions).profile(subcommand,options)}function profileList(clientOptions={}){return new PmClient(clientOptions).profileList()}function profileShow(name,clientOptions={}){return new PmClient(clientOptions).profileShow(name)}function profileApply(name,options={},clientOptions={}){return new PmClient(clientOptions).profileApply(name,options)}function profileLint(name,clientOptions={}){return new PmClient(clientOptions).profileLint(name)}function validate(options={},clientOptions={}){return new PmClient(clientOptions).validate(options)}function health(options={},clientOptions={}){return new PmClient(clientOptions).health(options)}function gc(options={},clientOptions={}){return new PmClient(clientOptions).gc(options)}function historyRedact(id,options,clientOptions={}){return new PmClient(clientOptions).historyRedact(id,options)}function historyRepair(id,options={},clientOptions={}){return new PmClient(clientOptions).historyRepair(id,options)}function historyRepairAll(options={},clientOptions={}){return new PmClient(clientOptions).historyRepairAll(options)}function historyCompact(id,options={},clientOptions={}){return new PmClient(clientOptions).historyCompact(id,options)}function historyCompactBulk(options,clientOptions={}){return new PmClient(clientOptions).historyCompactBulk(options)}function create(options={},clientOptions={}){return new PmClient(clientOptions).create(options)}function update(id,options={},clientOptions={}){return new PmClient(clientOptions).update(id,options)}function reopen(id,reason,options={},clientOptions={}){return new PmClient(clientOptions).reopen(id,reason,options)}function close(id,reason,options={},clientOptions={}){return new PmClient(clientOptions).close(id,reason,options)}function claim(id,options={},clientOptions={}){return new PmClient(clientOptions).claim(id,options)}function claimNext(options={},clientOptions={}){return new PmClient(clientOptions).claimNext(options)}function release(id,options={},clientOptions={}){return new PmClient(clientOptions).release(id,options)}function copy(id,options={},clientOptions={}){return new PmClient(clientOptions).copy(id,options)}function deleteItem(id,options={},clientOptions={}){return new PmClient(clientOptions).delete(id,options)}function restore(id,target,options={},clientOptions={}){return new PmClient(clientOptions).restore(id,target,options)}function focus(id,options={},clientOptions={}){return new PmClient(clientOptions).focus(id,options)}function startTask(id,options={},clientOptions={}){return new PmClient(clientOptions).startTask(id,options)}function pauseTask(id,options={},clientOptions={}){return new PmClient(clientOptions).pauseTask(id,options)}function closeTask(id,reason,options={},clientOptions={}){return new PmClient(clientOptions).closeTask(id,reason,options)}function extension(target,options={},clientOptions={}){return new PmClient(clientOptions).extension(target,options)}function extensionList(options={},clientOptions={}){return new PmClient(clientOptions).extensionList(options)}function extensionActivate(target,options={},clientOptions={}){return new PmClient(clientOptions).extensionActivate(target,options)}function extensionDeactivate(target,options={},clientOptions={}){return new PmClient(clientOptions).extensionDeactivate(target,options)}function packageLifecycle(target,options={},clientOptions={}){return new PmClient(clientOptions).package(target,options)}function packageList(options={},clientOptions={}){return new PmClient(clientOptions).packageList(options)}function packageInstall(target,options={},clientOptions={}){return new PmClient(clientOptions).packageInstall(target,options)}function packageUninstall(target,options={},clientOptions={}){return new PmClient(clientOptions).packageUninstall(target,options)}function packageDoctor(options={},clientOptions={}){return new PmClient(clientOptions).packageDoctor(options)}function packageManage(target,options={},clientOptions={}){return new PmClient(clientOptions).packageManage(target,options)}function packageDescribe(target,options={},clientOptions={}){return new PmClient(clientOptions).packageDescribe(target,options)}function packageReload(options={},clientOptions={}){return new PmClient(clientOptions).packageReload(options)}function packageCatalog(options={},clientOptions={}){return new PmClient(clientOptions).packageCatalog(options)}function packageActivate(target,options={},clientOptions={}){return new PmClient(clientOptions).packageActivate(target,options)}function packageDeactivate(target,options={},clientOptions={}){return new PmClient(clientOptions).packageDeactivate(target,options)}function upgrade(target,options={},clientOptions={}){return new PmClient(clientOptions).upgrade(target,options)}async function getContracts(pmRootOrOptions,options={}){const resolvedOptions=typeof pmRootOrOptions=="string"?{...options,pmRoot:pmRootOrOptions}:pmRootOrOptions??options,global2={json:!0,quiet:resolvedOptions.quiet??!0,noExtensions:resolvedOptions.noExtensions??!1,noPager:!0,profile:resolvedOptions.profile??!1,path:resolvedOptions.pmRoot};return runContracts(resolvedOptions,global2)}const extensionActivationGate=createAsyncReadWriteGate(),activeExtensionScope=new AsyncLocalStorage;function resetActiveExtensionRegistries(){setActiveExtensionHooks(createEmptyExtensionHookRegistry()),setActiveExtensionCommands(createEmptyExtensionCommandRegistry()),setActiveExtensionParsers(createEmptyExtensionParserRegistry()),setActiveExtensionPreflight(createEmptyExtensionPreflightRegistry()),setActiveExtensionServices(createEmptyExtensionServiceRegistry()),setActiveExtensionRenderers(createEmptyExtensionRendererRegistry()),setActiveExtensionRegistrations(createEmptyExtensionRegistrationRegistry())}async function withActiveExtensions(global2,explicitCwd,resolutionCwd,run){return runWithIsolatedExtensionRuntime(()=>explicitCwd===void 0?extensionActivationGate.read(()=>withActiveExtensionsExclusively(global2,resolutionCwd,run)):extensionActivationGate.write(()=>withCwd(explicitCwd,()=>withActiveExtensionsExclusively(global2,resolutionCwd,run))))}async function runWithActiveExtensions(options,run){const explicitCwd=options.cwd;if(activeExtensionScope.getStore()===!0&&explicitCwd===void 0&&options.noExtensions===!0){const pmRoot=resolvePmRoot(process.cwd(),options.path);return runWithIsolatedExtensionRuntime(()=>runWithDiscoveredContextIntentContracts({pmRoot},run))}const resolutionCwd=explicitCwd??process.cwd();return withActiveExtensions(globalOptions({path:options.path,noExtensions:options.noExtensions}),explicitCwd,resolutionCwd,()=>activeExtensionScope.run(!0,run))}async function withActiveExtensionsExclusively(global2,cwd,run){const pmRoot=resolvePmRoot(cwd,global2.path);if(global2.noExtensions)return resetActiveExtensionRegistries(),runWithDiscoveredContextIntentContracts({pmRoot},()=>run(null));if(!await pathExists(getSettingsPath(pmRoot)))return resetActiveExtensionRegistries(),run(null);let active=null,activated;try{const settings=await readSettings(pmRoot),loadResult=await loadExtensions({pmRoot,settings,cwd,noExtensions:!1}),activationResult=await activateExtensions({...loadResult,loaded:loadResult.loaded});activated={loadResult,activationResult},setActiveExtensionHooks(activationResult.hooks),setActiveExtensionCommands(activationResult.commands),setActiveExtensionParsers(activationResult.parsers),setActiveExtensionPreflight(activationResult.preflight),setActiveExtensionServices(activationResult.services),setActiveExtensionRenderers(activationResult.renderers),setActiveExtensionRegistrations(activationResult.registrations),active={registrations:activationResult.registrations,commands:activationResult.commands,pmRoot,packages:loadResult.loaded}}catch(error){resetActiveExtensionRegistries(),console.error("[pm-sdk] extension activation failed; continuing without active extensions:",error)}try{return await runWithDiscoveredContextIntentContracts({pmRoot,packages:active?.packages},()=>run(active))}finally{resetActiveExtensionRegistries(),activated&&await deactivateExtensions(activated.loadResult,activated.activationResult).catch(()=>{})}}function resolveActiveExtensionActionCommand(action,active){const normalizedAction=normalizeActionName(action);return active?.registrations.commands.find(entry=>normalizeActionName(entry.action)===normalizedAction)?.command??active?.commands.handlers.find(entry=>normalizeActionName(entry.command)===normalizedAction)?.command}async function dispatchActiveExtensionAction(action,args,options,global2,active){if(!active)throw new PmCliError(`Unsupported native pm action: ${action}`,EXIT_CODE.USAGE);const command=resolveActiveExtensionActionCommand(action,active);if(!command)throw new PmCliError(`Unsupported native pm action: ${action}`,EXIT_CODE.USAGE);const extensionAuthor=typeof global2.author=="string"&&global2.author.trim()?global2.author.trim():"pm-extension",handlerResult=await runActiveCommandHandler({command:normalizeCommandPath(command),args:readStringArray(options.args??args.args),options:extensionOptionsFromArgs(args,options),global:global2,pm_root:active.pmRoot,sdk:createExtensionCommandSdk(active.pmRoot,PmClient.forActiveExtensionHost({pmRoot:active.pmRoot,author:extensionAuthor}),extensionAuthor,normalizeCommandPath(command))});if(!handlerResult.handled){const suffix=handlerResult.warnings.length>0?` (${handlerResult.warnings.join(", ")})`:"";throw new PmCliError(`Unsupported native pm action: ${action}${suffix}`,EXIT_CODE.USAGE)}return handlerResult.result}async function withCwd(cwd,run){const previous=process.cwd();process.chdir(cwd);try{return await run()}finally{process.chdir(previous)}}function resolveSdkActionInput(args){const rawAction=readRequiredString(args,"action"),normalizedAction=normalizeActionName(rawAction),alias=getOwnHandler(SDK_ACTION_ALIASES,normalizedAction),action=alias?.action??normalizedAction,resolvedArgs={...args,action};return alias?.options!==void 0&&(resolvedArgs.options={...alias.options,...asRecordClone(args.options)}),action==="package"&&(resolvedArgs.options={...asRecordClone(resolvedArgs.options),vocabulary:"package"}),{action,args:resolvedArgs}}async function runAction(args){const resolved=resolveSdkActionInput(args),global2=globalOptions(resolved.args),invalidateWorkspaceContractsCache=shouldInvalidateWorkspaceContractsCacheAfterAction(resolved.action),explicitCwd=readString(resolved.args,"cwd"),resolutionCwd=explicitCwd??process.cwd();resolved.action==="init"&&(global2[INIT_INVOCATION_CWD]=resolutionCwd),(resolved.action!=="init"||global2.path!==void 0||(process.env.PM_PATH?.trim().length??0)>0)&&(global2.path=resolvePmRoot(resolutionCwd,global2.path));try{return resolved.action==="history-attest"?await dispatchAction(resolved.action,resolved.args,global2,null):args[ACTIVE_EXTENSION_HOST_CONTEXT]===!0||activeExtensionScope.getStore()===!0?await dispatchAction(resolved.action,resolved.args,global2,null):await withActiveExtensions(global2,explicitCwd,resolutionCwd,activeExtensions=>dispatchAction(resolved.action,resolved.args,global2,activeExtensions))}finally{invalidateWorkspaceContractsCache&&clearWorkspaceContractsCache()}}function analyzeSdkActionCoverage(actions=PM_TOOL_ACTIONS){return actions.map(action=>{const normalized=normalizeActionName(action),alias=getOwnHandler(SDK_ACTION_ALIASES,normalized),resolvedAction=alias?.action??normalized,covered=getOwnHandler(SDK_ACTION_HANDLERS,resolvedAction)!==void 0;return{action,resolved_action:resolvedAction,covered,route:covered?alias?"alias":"native":"missing"}})}async function dispatchAction(action,args,global2,activeExtensions){const options=optionsWithAuthor(args,action),handler=getOwnHandler(SDK_ACTION_HANDLERS,action),extensionCommand=handler?void 0:resolveActiveExtensionActionCommand(action,activeExtensions),readCommand=extensionCommand===void 0?action:`extension:${extensionCommand}`;validateReadOutputOptions(readCommand,options),normalizeReadOutputIncludeModeOptions(readCommand,options);const ctx={action,args,options,id:readString(args,"id"),force:args.force===!0||options.force===!0,global:global2,activeExtensions},result=handler?await handler(ctx):await dispatchActiveExtensionAction(action,args,options,global2,activeExtensions);if(action==="history-attest")return result;{options.resolvedOutputFormat="json";const projected=attachReadOutputContracts(readCommand,options,result);return await finalizeContextUsageEgress(resolvePmRoot(process.cwd(),global2.path),projected),projected}}const actionRunnerTestHooks={closeManyOptionsFromFlat,extensionOptionsFromArgs,globalOptions,mutationListOptions,normalizeActionName,normalizeCommandPath,normalizeMcpUpdateOptions,normalizeMcpOptionsArrays,optionsWithAuthor,readRequiredString,readScalarString,readScalarStringAllowBlank,readStringArray,updateManyOptionsFromFlat,withAddNoteOption,withFilesDiscoveryOptions,withMutationCompaction};(process.env.NODE_ENV==="test"||process.env.VITEST!==void 0||process.env.VITEST_WORKER_ID!==void 0)&&(globalThis.__pmCliActionRunnerTestHooks=actionRunnerTestHooks);import{readRequiredString as readRequiredString2}from"./runtime/context.js";export{BASELINE_ITEM_FORMAT_VERSION,BUILTIN_ITEM_TYPE_VALUES,CONFIDENCE_TEXT_VALUES,CONTEXT_OUTPUT_VALUES,CURRENT_ITEM_FORMAT_VERSION,DEFAULT_TERMINAL_TRANSITION_POLICY,DEPENDENCY_KIND_VALUES,EXIT_CODE,HISTORY_EVENT_CLASSIFICATION_VERSION,ISSUE_SEVERITY_VALUES,ITEM_TYPE_VALUES,MAINTENANCE_HISTORY_OPERATIONS,NEXT_OUTPUT_VALUES,PM_CLI_EXPECTED_ERROR_NAME,PM_GITIGNORE_END,PM_GITIGNORE_START,PmCliError2 as PmCliError,PmClient,PmCompleteListValidationError,RISK_VALUES,SEARCH_EXTENSION_FLAG_DEFINITIONS,STATUS_VALUES,SUBSTANTIVE_HISTORY_OPERATIONS,acquireLock,aggregate,analyzeSdkActionCoverage,append,appendHistoryEntry,applyTerminalOrderingPolicy,assertCompleteListResult,canonicalDocument,certifyCompleteListResult2 as certifyCompleteListResult,claim,claimNext,classifyHistoryEvent,classifyItemFormatVersion,clearWorkspaceContractsCache2 as clearWorkspaceContractsCache,close,closeItem,closeTask,comments,commitImportedItem,config,context,copy,create,createCompleteListOptions2 as createCompleteListOptions,createHistoryEntry,createPmCliExpectedError,deleteItem,deps,docs,duplicates,effectiveItemFormatVersion,emptyImportedDocument,ensurePmGitignore,ensureTrackerInitialized,extension,extensionActivate,extensionDeactivate,extensionList,files,filesDiscover,filesLookup,focus,gc,generateItemId,get,getActiveExtensionRegistrations,getContracts,getHistoryPath,getItemPath,getPmGitignoreBlock,getSettingsPath2 as getSettingsPath,getWorkspaceContracts,graph,health,historyCompact,historyCompactBulk,historyRedact,historyRepair,historyRepairAll,init,inspectCompleteListResult,isPmCliExpectedError,isTerminalStatus,isTimestampLiteral,jaccardSimilarity,learnings,list,listAllComplete,listAllItemMetadata,listAllItemMetadataLight,loadCreateTemplateOptions,locateItem,next,normalizeItemFormatVersion,normalizeItemId,normalizeItemMetadata,normalizeRawItemId,normalizeSimilarityText,normalizeStatusInput,notes,nowIso,packageActivate,packageCatalog,packageDeactivate,packageDescribe,packageDoctor,packageInstall,packageLifecycle,packageList,packageManage,packageReload,packageUninstall,parseTags,pathExists2 as pathExists,pauseTask,profile,profileApply,profileLint,profileList,profileShow,readBooleanOption,readCsvListOption,readFileIfExists,readLocatedItem,readRequiredString2 as readRequiredString,readSettings2 as readSettings,readStringOption,release,removeFileIfExists,renderCalendarMarkdown,renderCalendarToon,renderGuideMarkdown,reopen,requireTerminalReason,resolveCalendarOutputFormat,resolveGuideOutputFormat,resolveImplicitPmRoot,resolveItemTypeRegistry,resolvePmRoot2 as resolvePmRoot,resolveRuntimeFieldRegistry,resolveRuntimeStatusRegistry,resolveTerminalReason,restore,runAction,runActiveOnReadHooks,runActiveOnWriteHooks,runAggregate,runCalendar,runClose,runCloseTask,runCompletion,runContext,runCopy,runDelete,runDuplicates,runFocus,runGet,runGuide,runList,runNext,runPauseTask,runReindex,runReopen,runRestore,runSearch,runStartTask,runStats,runTemplatesList,runTemplatesSave,runTemplatesShow,runTestRunsList,runTestRunsLogs,runTestRunsResume,runTestRunsStatus,runTestRunsStop,runUpdate,runWithActiveExtensions,scanItemFormatVersions,schema,schemaAddField,schemaAddStatus,schemaAddType,schemaApplyPreset,schemaInferTypes,schemaList,schemaListFields,schemaRemapStatus,schemaRemoveField,schemaRemoveStatus,schemaRemoveType,schemaRenameField,schemaRenameType,schemaShow,schemaShowField,schemaShowStatus,scoreItemSimilarity,search,selectImportAuthor,serializeItemDocument,splitFrontMatter,startTask,stats,toEstimatedMinutesValue,toImportBoolean,toImportConfidence,toImportInteger,toImportLinkedDocs,toImportLinkedFiles,toImportLinkedTests,toImportLogEntries,toImportNormalizedEnum,toImportNumberMap,toImportPriority,toImportStatus,toImportStringList,toImportStringMap,toImportTags,toNonEmptyImportString,tokenizeSimilarityText,update,upgrade,validate,writeFileAtomic};
2
2
  //# sourceMappingURL=runtime.js.map
@@ -1,11 +1,47 @@
1
1
  import type { BulkItemMutation } from "./item-transaction.js";
2
2
  import { type RuntimeFieldDefinitionResolved } from "../core/schema/runtime-schema.js";
3
+ /** One existing workspace item considered by keyed upsert resolution. */
4
+ export interface ItemMutationUpsertCandidate {
5
+ /** Canonical id of the existing item. */
6
+ id:string;
7
+ /** Current value of the upsert key field on that item. */
8
+ value:unknown;
9
+ }
10
+ /** Keyed-upsert policy applied to create rows of one mutation document. */
11
+ export interface ItemMutationUpsertOptions {
12
+ /** Item field (core or declared custom metadata key) whose value identifies an existing item. */
13
+ key:string;
14
+ /**
15
+ * Existing items that carry a value for the key, read before the writer
16
+ * lock. Items this very document would create (its deterministic create
17
+ * ids) are never candidates, so a replay of a committed import keeps its
18
+ * original create plan instead of mutating into updates.
19
+ */
20
+ existing:readonly ItemMutationUpsertCandidate[];
21
+ }
3
22
  /** Controls for resolving one versioned mutation document. */
4
23
  export interface ResolveItemMutationDocumentOptions {
5
24
  /** Stable transaction identity used to derive replay-safe create ids. */
6
25
  transactionId:string;
7
26
  /** Workspace item-id prefix. */
8
27
  idPrefix:string;
28
+ /** Resolved schema fields that route document keys through declared option names. */
29
+ runtimeFields?:readonly RuntimeFieldDefinitionResolved[];
30
+ /** Optional keyed upsert: create rows matching one existing item become updates. */
31
+ upsert?:ItemMutationUpsertOptions;
32
+ }
33
+ /** Input-ordered receipt row mapping one source record to its resolved mutation. */
34
+ export interface ResolvedItemMutationRow {
35
+ /** Zero-based position of the source record in the document. */
36
+ index:number;
37
+ /** Batch-local alias when the row declared or received one. */
38
+ ref?:string;
39
+ /** Concrete item id the mutation targets. */
40
+ id:string;
41
+ /** Operation applied for this row after upsert resolution. */
42
+ op:BulkItemMutation["op"];
43
+ /** Whether keyed upsert turned a create row into an update of an existing item. */
44
+ upserted?:true;
9
45
  }
10
46
  /** Fully validated mutation document ready for preview or commit. */
11
47
  export interface ResolvedItemMutationDocument {
@@ -15,7 +51,15 @@ schema_version:1;
15
51
  mutations:BulkItemMutation[];
16
52
  /** Batch-local alias to concrete-id receipt. */
17
53
  references:Record<string,string>;
54
+ /** Input-ordered receipt mapping each source record to its resolved id and operation. */
55
+ rows:ResolvedItemMutationRow[];
18
56
  }
57
+ /**
58
+ * Derive a stable transaction id from the exact document bytes so that
59
+ * re-running an identical import resumes or replays the same journal instead
60
+ * of duplicating items. Any change to the document yields a new id.
61
+ */
62
+ export declare function deriveMutationTransactionId(input:string):string;
19
63
  /** Validated transaction controls shared by atomic CLI and MCP adapters. */
20
64
  export interface AtomicMutationControls {
21
65
  /** Compensation policy applied to created items when a later step fails. */
@@ -27,8 +71,15 @@ lockWaitMs?:number;
27
71
  }
28
72
  /** Validate and normalize atomic transaction controls at every transport boundary. */
29
73
  export declare function parseAtomicMutationControls(value:Record<string,unknown>):AtomicMutationControls;
74
+ /** Workspace schema context that widens the option keys a batch row may carry. */
75
+ export interface ParseItemMutationBatchOptions {
76
+ /** Declared schema fields whose option targets create/update rows may set. */
77
+ runtimeFields?:readonly RuntimeFieldDefinitionResolved[];
78
+ }
30
79
  /** Parse a JSON array, or an object containing `mutations`, into an atomic mutation batch. */
31
- export declare function parseItemMutationBatch(input:string):BulkItemMutation[];
80
+ export declare function parseItemMutationBatch(input:string,parseOptions?:ParseItemMutationBatchOptions):BulkItemMutation[];
81
+ /** Canonical comparison form of an upsert key value: trimmed strings, otherwise key-sorted JSON. Shared by the planner and the lock-held commit guard. */
82
+ export declare function stableUpsertValue(value:unknown):string;
32
83
  /**
33
84
  * Resolve a versioned heterogeneous mutation document. Create rows may declare
34
85
  * a unique `ref`; omitted ids are derived deterministically from the stable
@@ -1,2 +1,2 @@
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]="7599b1e6-1f28-597a-adda-ad856beb35bd")}catch{}})();import crypto from"node:crypto";import{ITEM_MUTATION_FACET_OPTION_MAPPINGS}from"./lifecycle/mutation-facet-contracts.js";import{normalizeItemId,normalizePrefix}from"../core/item/id.js";import{preserveMutationStdinTokenLiterals}from"../core/item/parse.js";import{EXIT_CODE,ITEM_PROJECT_CONTEXT_KEYS}from"../core/shared/constants.js";import{PmCliError}from"../core/shared/errors.js";import{levenshteinDistanceWithinLimit}from"../core/shared/levenshtein.js";import{CLOSE_FLAG_CONTRACTS,RELEASE_FLAG_CONTRACTS}from"./cli-contracts/flag-contracts.js";import{CREATE_COMMANDER_OPTION_REGISTRATION_CONTRACTS,UPDATE_COMMANDER_OPTION_REGISTRATION_CONTRACTS}from"./cli-contracts/commander-mutation-options.js";import{runtimeFieldOptionTarget}from"../core/schema/runtime-schema.js";import{readRuntimeFieldOptionValue}from"../core/schema/runtime-field-values.js";const MUTATION_ROW_KEYS=["op","id","reason","options"],REFERENCED_MUTATION_ROW_KEYS=[...MUTATION_ROW_KEYS,"ref"],MUTATION_DOCUMENT_KEYS=["schema_version","mutations"],MUTATION_REFERENCE_SOURCE="[a-z][a-z0-9._-]{0,63}",MUTATION_REFERENCE_PATTERN=new RegExp(`^${MUTATION_REFERENCE_SOURCE}$`,"u"),MUTATION_DEPENDENCY_REFERENCE_PATTERN=new RegExp(`(^|,)id=@(${MUTATION_REFERENCE_SOURCE})(?=,|$)`,"gu"),flagToOptionKey=flag=>flag.slice(2).replaceAll(/-([a-z])/gu,(_match,letter)=>letter.toUpperCase()),ITEM_ENVELOPE_KEYS=["item","linked","schedule","claim_state","children","omission_receipt","row_contract","context_intent"],READ_ONLY_ITEM_KEYS=new Set(["created_at","updated_at","closed_at","version","format_version","path","author","collection_counts","notes_count","tests_count"]),UPDATE_READ_ONLY_ITEM_KEYS=new Set([...READ_ONLY_ITEM_KEYS,"completed_at","id"]),ITEM_FIELD_KEYS=new Set(["id","title","description","type","status","priority","tags","body","deadline","estimated_minutes","acceptance_criteria","definition_of_ready","order","rank","assignee",...ITEM_PROJECT_CONTEXT_KEYS,"affected_version","fixed_version","component","regression","customer_impact","close_reason","completed_at","dependencies","comments","notes","learnings","files","tests","docs","reminders","events","type_options"]),MUTATION_OPTION_KEYS={create:CREATE_COMMANDER_OPTION_REGISTRATION_CONTRACTS.map(contract=>contract.target),update:UPDATE_COMMANDER_OPTION_REGISTRATION_CONTRACTS.map(contract=>contract.target),close:CLOSE_FLAG_CONTRACTS.map(contract=>flagToOptionKey(contract.flag)).filter(key=>key!=="reason"),release:RELEASE_FLAG_CONTRACTS.map(contract=>flagToOptionKey(contract.flag))};function parseAtomicMutationControls(value){const controls={},compensation=value.createCompensation;if(compensation!==void 0){if(compensation!=="close"&&compensation!=="delete")throw new PmCliError("createCompensation must be close or delete.",EXIT_CODE.USAGE);controls.createCompensation=compensation}for(const key of["lockTtlSeconds","lockWaitMs"]){const raw=value[key];if(raw===void 0)continue;const parsed=typeof raw=="number"||typeof raw=="string"&&raw.trim().length>0?Number(raw):Number.NaN;if(!Number.isSafeInteger(parsed)||parsed<=0)throw new PmCliError(`${key} must be a positive safe integer.`,EXIT_CODE.USAGE);controls[key]=parsed}return controls}function isPlainObject(value){if(typeof value!="object"||value===null||Array.isArray(value))return!1;const prototype=Object.getPrototypeOf(value);return prototype===Object.prototype||prototype===null}function nearestKey(key,candidates){const limit=Math.max(1,Math.min(3,Math.floor(key.length/4)+1));let best;for(const candidate of candidates){const distance=levenshteinDistanceWithinLimit(key,candidate,limit);distance!==null&&(best===void 0||distance<best.distance)&&(best={key:candidate,distance})}return best?.key}function unknownKeyError(scope,key,candidates){const suggestion=nearestKey(key,candidates);return new PmCliError(suggestion===void 0?`${scope} does not recognize key "${key}". Allowed keys: ${candidates.join(", ")}.`:`${scope} does not recognize key "${key}". Did you mean "${suggestion}"?`,EXIT_CODE.USAGE,{code:"stdin_json_unknown_key",required:`Use documented ${scope} keys only.`,why:"Strict structured input prevents silent typos from creating incomplete or unintended mutations.",nextSteps:[suggestion===void 0?`Remove or correct "${key}".`:`Replace "${key}" with "${suggestion}".`]})}function parseJsonValue(input,label){try{return JSON.parse(input)}catch(error){const detail=error instanceof Error?error.message:String(error);throw new PmCliError(`${label} must be valid JSON: ${detail}`,EXIT_CODE.USAGE,{code:"stdin_json_invalid",required:`Pipe one valid JSON ${label.toLowerCase()} into stdin.`,why:"Structured mutation input must parse deterministically before any tracker write begins."})}}function validateMutationObject(value,index){if(!isPlainObject(value))throw new PmCliError(`Mutation ${index+1} must be an object.`,EXIT_CODE.USAGE);for(const key of Object.keys(value))if(!MUTATION_ROW_KEYS.includes(key))throw unknownKeyError(`mutation ${index+1}`,key,MUTATION_ROW_KEYS);return value}function validateMutationOptions(options,op,index){if(options!==void 0){if(!isPlainObject(options))throw new PmCliError(`Mutation ${index+1} options must be an object.`,EXIT_CODE.USAGE);for(const key of Object.keys(options))if(!MUTATION_OPTION_KEYS[op].includes(key))throw unknownKeyError(`mutation ${index+1} ${op} options`,key,MUTATION_OPTION_KEYS[op]);return options}}function validateMutationRow(value,index){const mutation=validateMutationObject(value,index),{op,id,reason}=mutation;if(op!=="create"&&op!=="update"&&op!=="close"&&op!=="release")throw new PmCliError(`Mutation ${index+1} op must be create, update, close, or release.`,EXIT_CODE.USAGE);const options=validateMutationOptions(mutation.options,op,index);if(typeof id!="string"||id.trim().length===0)throw new PmCliError(`Mutation ${index+1} requires a non-empty id.`,EXIT_CODE.USAGE);const normalizedId=id.trim();if(op==="close"){if(typeof reason!="string"||reason.trim().length===0)throw new PmCliError(`Mutation ${index+1} close requires a non-empty reason.`,EXIT_CODE.USAGE);return{op,id:normalizedId,reason:reason.trim(),...options===void 0?{}:{options}}}if(op==="release")return{op,id:normalizedId,...options===void 0?{}:{options}};if(!isPlainObject(options))throw new PmCliError(`Mutation ${index+1} ${op} requires an options object.`,EXIT_CODE.USAGE);return{op,id:normalizedId,options}}function parseItemMutationBatch(input){const parsed=parseJsonValue(input,"Mutation batch"),rows=Array.isArray(parsed)?parsed:isPlainObject(parsed)&&Array.isArray(parsed.mutations)?parsed.mutations:void 0;if(rows===void 0||rows.length===0)throw new PmCliError("Mutation batch must be a non-empty JSON array or an object with a non-empty mutations array.",EXIT_CODE.USAGE);return rows.map((row,index)=>{const mutation=validateMutationRow(row,index);return mutation.options!==void 0&&preserveMutationStdinTokenLiterals(mutation.options),mutation})}function deriveReferencedItemId(transactionId,reference,idPrefix){const digest=crypto.createHash("sha256").update(transactionId).update("\0").update(reference).digest("hex"),token=BigInt(`0x${digest.slice(0,16)}`).toString(36).padStart(13,"0").slice(-12);return`${normalizePrefix(idPrefix)}${token}`}function replaceExactMutationReference(value,references){if(typeof value!="string"||!value.startsWith("@"))return value;const reference=value.slice(1),resolved=references[reference];if(resolved===void 0)throw new PmCliError(`Unknown mutation reference "${value}".`,EXIT_CODE.USAGE);return resolved}function replaceDependencyReference(value,references){if(typeof value!="string")return value;const resolvedValue=value.replace(MUTATION_DEPENDENCY_REFERENCE_PATTERN,(_match,prefix,reference)=>{const resolved=references[reference];if(resolved===void 0)throw new PmCliError(`Unknown mutation reference "@${reference}".`,EXIT_CODE.USAGE);return`${prefix}id=${resolved}`});if(/(^|,)id=@/u.test(resolvedValue))throw new PmCliError(`Malformed mutation reference in dependency "${value}".`,EXIT_CODE.USAGE);return resolvedValue}function referencedAliases(value){return typeof value!="string"?[]:value.startsWith("@")?[value.slice(1)]:[...value.matchAll(MUTATION_DEPENDENCY_REFERENCE_PATTERN)].map(match=>match[1]).filter(reference=>reference!==void 0)}function assertAcyclicCreateReferences(rows){const graph=new Map;for(const row of rows){if(row.op!=="create"||typeof row.ref!="string")continue;const mutationOptions=isPlainObject(row.options)?row.options:{},dependencies=Array.isArray(mutationOptions.dep)?mutationOptions.dep:mutationOptions.dep===void 0?[]:[mutationOptions.dep];graph.set(row.ref,[mutationOptions.parent,mutationOptions.blockedBy,...dependencies].flatMap(referencedAliases))}const visiting=new Set,visited=new Set,visit=reference=>{if(visiting.has(reference))throw new PmCliError(`Mutation reference cycle includes "@${reference}".`,EXIT_CODE.USAGE);if(!visited.has(reference)){visiting.add(reference);for(const dependency of graph.get(reference))graph.has(dependency)&&visit(dependency);visiting.delete(reference),visited.add(reference)}};for(const reference of graph.keys())visit(reference)}function parseMutationDocumentRows(input){const parsed=parseJsonValue(input,"Mutation document"),envelope=Array.isArray(parsed)?{schema_version:1,mutations:parsed}:parsed;if(!isPlainObject(envelope))throw new PmCliError("Mutation document must be a JSON array or object.",EXIT_CODE.USAGE);for(const key of Object.keys(envelope))if(!MUTATION_DOCUMENT_KEYS.includes(key))throw unknownKeyError("mutation document",key,MUTATION_DOCUMENT_KEYS);if(envelope.schema_version!==void 0&&envelope.schema_version!==1)throw new PmCliError("Mutation document schema_version must be 1.",EXIT_CODE.USAGE);if(!Array.isArray(envelope.mutations)||envelope.mutations.length===0)throw new PmCliError("Mutation document requires a non-empty mutations array.",EXIT_CODE.USAGE);return envelope.mutations.map((row,index)=>{if(!isPlainObject(row))throw new PmCliError(`Mutation ${index+1} must be an object.`,EXIT_CODE.USAGE);for(const key of Object.keys(row))if(!REFERENCED_MUTATION_ROW_KEYS.includes(key))throw unknownKeyError(`mutation ${index+1}`,key,REFERENCED_MUTATION_ROW_KEYS);return{...row}})}function collectMutationReferences(rows,options){const references=Object.create(null);for(const[index,row]of rows.entries())if(row.ref!==void 0){if(row.op!=="create")throw new PmCliError(`Mutation ${index+1} ref is only valid for create operations.`,EXIT_CODE.USAGE);if(typeof row.ref!="string"||!MUTATION_REFERENCE_PATTERN.test(row.ref))throw new PmCliError(`Mutation ${index+1} ref must match ${MUTATION_REFERENCE_PATTERN.source}.`,EXIT_CODE.USAGE);if(references[row.ref]!==void 0)throw new PmCliError(`Duplicate mutation ref "${row.ref}".`,EXIT_CODE.USAGE);references[row.ref]=typeof row.id=="string"&&row.id.trim().length>0?normalizeItemId(row.id,options.idPrefix):deriveReferencedItemId(options.transactionId,row.ref,options.idPrefix)}return references}function resolveItemMutationDocument(input,options){const rows=parseMutationDocumentRows(input),references=collectMutationReferences(rows,options);assertAcyclicCreateReferences(rows);const resolvedRows=rows.map(row=>{const resolved={...row},reference=typeof resolved.ref=="string"?resolved.ref:void 0;if(delete resolved.ref,reference!==void 0?resolved.id=references[reference]:resolved.id=replaceExactMutationReference(resolved.id,references),isPlainObject(resolved.options)){const mutationOptions={...resolved.options};for(const key of["parent","blockedBy"])mutationOptions[key]!==void 0&&(mutationOptions[key]=replaceExactMutationReference(mutationOptions[key],references));Array.isArray(mutationOptions.dep)?mutationOptions.dep=mutationOptions.dep.map(entry=>replaceDependencyReference(entry,references)):mutationOptions.dep!==void 0&&(mutationOptions.dep=replaceDependencyReference(mutationOptions.dep,references)),resolved.options=mutationOptions}return resolved}),mutations=parseItemMutationBatch(JSON.stringify(resolvedRows)),createIds=mutations.filter(mutation=>mutation.op==="create").map(mutation=>mutation.id);if(new Set(createIds).size!==createIds.length)throw new PmCliError("Duplicate resolved create id in mutation document.",EXIT_CODE.USAGE);return{schema_version:1,mutations,references}}function serializePairs(value,keys){return keys.filter(key=>value[key]!==void 0&&value[key]!==null).map(key=>{const rendered=String(value[key]);return`${key}=${/[",\n\r\\]/u.test(rendered)?JSON.stringify(rendered):rendered}`}).join(",")}function serializeObjectArray(value,keys,label){if(value!==void 0){if(!Array.isArray(value)||!value.every(isPlainObject))throw new PmCliError(`${label} must be an array of objects.`,EXIT_CODE.USAGE);return value.map(entry=>serializePairs(entry,keys))}}function scalarItemOption(key,value){return key==="tags"&&Array.isArray(value)&&value.every(entry=>typeof entry=="string")?JSON.stringify(value):typeof value=="number"||typeof value=="boolean"?String(value):value}function appendFacetOptions(target,source,skipPersistedAnnotations=!1){for(const[sourceKey,targetKey,keys]of ITEM_MUTATION_FACET_OPTION_MAPPINGS){const sourceValue=source[sourceKey],serialized=serializeObjectArray(skipPersistedAnnotations&&["comments","notes","learnings"].includes(sourceKey)&&Array.isArray(sourceValue)?sourceValue.filter(entry=>!isPlainObject(entry)||entry.created_at===void 0):sourceValue,keys,sourceKey);serialized!==void 0&&serialized.length>0&&(target[targetKey]=serialized)}}function validateItemDocumentKeys(parsed,envelope){for(const key of Object.keys(parsed)){if(envelope){if(!ITEM_ENVELOPE_KEYS.includes(key))throw unknownKeyError("item envelope",key,ITEM_ENVELOPE_KEYS);continue}if(!ITEM_FIELD_KEYS.has(key)&&nearestKey(key,[...ITEM_FIELD_KEYS])===void 0&&nearestKey(key,ITEM_ENVELOPE_KEYS)==="item")throw unknownKeyError("item envelope",key,ITEM_ENVELOPE_KEYS)}}function resolveItemDocument(parsed){const envelope=Object.hasOwn(parsed,"item");validateItemDocumentKeys(parsed,envelope);const item=envelope?parsed.item:parsed;if(!isPlainObject(item))throw new PmCliError("Item document item must be an object.",EXIT_CODE.USAGE);return{item,...envelope&&isPlainObject(parsed.linked)?{linked:parsed.linked}:{}}}function appendItemDocumentEntry(documentOptions,key,value,mode,runtimeFields,explicitOptions){if((mode==="update"?UPDATE_READ_ONLY_ITEM_KEYS:READ_ONLY_ITEM_KEYS).has(key))return;const definition=runtimeFields.find(field=>field.metadata_key===key&&field.commands.includes(mode));if(definition!==void 0){const explicitValue=readRuntimeFieldOptionValue(explicitOptions,definition);documentOptions[runtimeFieldOptionTarget(definition)]=explicitValue!==void 0?explicitValue:definition.type==="array"||definition.type==="object"?JSON.stringify(value):value;return}if(!ITEM_FIELD_KEYS.has(key)){if(nearestKey(key,[...ITEM_FIELD_KEYS])!==void 0)throw unknownKeyError("item document",key,[...ITEM_FIELD_KEYS]);const fields=Array.isArray(documentOptions.field)?documentOptions.field:[];fields.push(`${key}=${typeof value=="string"?value:JSON.stringify(value)}`),documentOptions.field=fields;return}["dependencies","comments","notes","learnings","files","tests","docs","reminders","events","type_options"].includes(key)||(documentOptions[key.replaceAll(/_([a-z])/gu,(_match,letter)=>letter.toUpperCase())]=scalarItemOption(key,value))}function itemDocumentToMutationOptions(input,mode,explicitOptions={},runtimeFields=[]){const parsed=parseJsonValue(input,"Item document");if(!isPlainObject(parsed))throw new PmCliError("Item document must be a JSON object.",EXIT_CODE.USAGE);const{item,linked}=resolveItemDocument(parsed),documentOptions={};for(const[key,value]of Object.entries(item))appendItemDocumentEntry(documentOptions,key,value,mode,runtimeFields,explicitOptions);if(appendFacetOptions(documentOptions,item,mode==="update"),linked!==void 0&&appendFacetOptions(documentOptions,linked),mode==="update"){const annotations=Object.fromEntries(["comments","notes","learnings"].filter(key=>Object.hasOwn(item,key)).map(key=>[key,item[key].filter(entry=>isPlainObject(entry)&&entry.created_at!==void 0)]));Object.keys(annotations).length>0&&(documentOptions.documentAnnotationSnapshot=annotations)}return{...documentOptions,...Object.fromEntries(Object.entries(explicitOptions).filter(([,value])=>value!==void 0)),...Array.isArray(documentOptions.field)&&Array.isArray(explicitOptions.field)?{field:[...documentOptions.field,...explicitOptions.field]}:{},stdinJson:void 0}}function validateItemMutationRows(value){return parseItemMutationBatch(JSON.stringify(value))}export{itemDocumentToMutationOptions,parseAtomicMutationControls,parseItemMutationBatch,resolveItemMutationDocument,validateItemMutationRows};
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]="78df5b0f-51cd-5c24-a1ee-a1d8433be5df")}catch{}})();import crypto from"node:crypto";import{ITEM_MUTATION_FACET_OPTION_MAPPINGS}from"./lifecycle/mutation-facet-contracts.js";import{normalizeItemId,normalizePrefix}from"../core/item/id.js";import{preserveMutationStdinTokenLiterals}from"../core/item/parse.js";import{EXIT_CODE}from"../core/shared/constants.js";import{PmCliError}from"../core/shared/errors.js";import{levenshteinDistanceWithinLimit}from"../core/shared/levenshtein.js";import{describeUnknownError}from"./error-runtime.js";import{CLOSE_FLAG_CONTRACTS,RELEASE_FLAG_CONTRACTS}from"./cli-contracts/flag-contracts.js";import{CREATE_COMMANDER_OPTION_REGISTRATION_CONTRACTS,UPDATE_COMMANDER_OPTION_REGISTRATION_CONTRACTS}from"./cli-contracts/commander-mutation-options.js";import{runtimeFieldOptionTarget}from"../core/schema/runtime-schema.js";import{CORE_ITEM_FIELD_KEYS as ITEM_FIELD_KEYS,resolveCoreUpsertMetadataKey}from"./lifecycle/core-item-fields.js";import{readRuntimeFieldOptionValue}from"../core/schema/runtime-field-values.js";import{assertMutationOptionValueTypes}from"./lifecycle/mutation-option-validation.js";const MUTATION_ROW_KEYS=["op","id","reason","options","unique","match"],REFERENCED_MUTATION_ROW_KEYS=[...MUTATION_ROW_KEYS,"ref"],DOCUMENT_MUTATION_ROW_KEYS=[...REFERENCED_MUTATION_ROW_KEYS,"item"],DERIVED_TRANSACTION_ID_PREFIX="mutate-",SYNTHESIZED_REFERENCE_PREFIX="row-",MUTATION_DOCUMENT_KEYS=["schema_version","mutations"],MUTATION_REFERENCE_SOURCE="[a-z][a-z0-9._-]{0,63}",MUTATION_REFERENCE_PATTERN=new RegExp(`^${MUTATION_REFERENCE_SOURCE}$`,"u"),MUTATION_DEPENDENCY_REFERENCE_PATTERN=new RegExp(`(^|,)id=@(${MUTATION_REFERENCE_SOURCE})(?=,|$)`,"gu"),flagToOptionKey=flag=>flag.slice(2).replaceAll(/-([a-z])/gu,(_match,letter)=>letter.toUpperCase()),ITEM_ENVELOPE_KEYS=["item","linked","schedule","claim_state","children","omission_receipt","row_contract","context_intent"],READ_ONLY_ITEM_KEYS=new Set(["created_at","updated_at","closed_at","version","format_version","path","author","collection_counts","notes_count","tests_count"]),UPDATE_READ_ONLY_ITEM_KEYS=new Set([...READ_ONLY_ITEM_KEYS,"completed_at","id"]),MUTATION_OPTION_KEYS={create:CREATE_COMMANDER_OPTION_REGISTRATION_CONTRACTS.map(contract=>contract.target),update:UPDATE_COMMANDER_OPTION_REGISTRATION_CONTRACTS.map(contract=>contract.target),close:CLOSE_FLAG_CONTRACTS.map(contract=>flagToOptionKey(contract.flag)).filter(key=>key!=="reason"),release:RELEASE_FLAG_CONTRACTS.map(contract=>flagToOptionKey(contract.flag))};function deriveMutationTransactionId(input){const digest=crypto.createHash("sha256").update(input).digest("hex");return`${DERIVED_TRANSACTION_ID_PREFIX}${digest.slice(0,24)}`}function parseAtomicMutationControls(value){const controls={},compensation=value.createCompensation;if(compensation!==void 0){if(compensation!=="close"&&compensation!=="delete")throw new PmCliError("createCompensation must be close or delete.",EXIT_CODE.USAGE);controls.createCompensation=compensation}for(const key of["lockTtlSeconds","lockWaitMs"]){const raw=value[key];if(raw===void 0)continue;const parsed=typeof raw=="number"||typeof raw=="string"&&raw.trim().length>0?Number(raw):Number.NaN;if(!Number.isSafeInteger(parsed)||parsed<=0)throw new PmCliError(`${key} must be a positive safe integer.`,EXIT_CODE.USAGE);controls[key]=parsed}return controls}function isPlainObject(value){if(typeof value!="object"||value===null||Array.isArray(value))return!1;const prototype=Object.getPrototypeOf(value);return prototype===Object.prototype||prototype===null}function nearestKey(key,candidates){const limit=Math.max(1,Math.min(3,Math.floor(key.length/4)+1));let best;for(const candidate of candidates){const distance=levenshteinDistanceWithinLimit(key,candidate,limit);distance!==null&&(best===void 0||distance<best.distance)&&(best={key:candidate,distance})}return best?.key}function unknownKeyError(scope,key,candidates){const suggestion=nearestKey(key,candidates);return new PmCliError(suggestion===void 0?`${scope} does not recognize key "${key}". Allowed keys: ${candidates.join(", ")}.`:`${scope} does not recognize key "${key}". Did you mean "${suggestion}"?`,EXIT_CODE.USAGE,{code:"stdin_json_unknown_key",required:`Use documented ${scope} keys only.`,why:"Strict structured input prevents silent typos from creating incomplete or unintended mutations.",nextSteps:[suggestion===void 0?`Remove or correct "${key}".`:`Replace "${key}" with "${suggestion}".`]})}function parseJsonValue(input,label){try{return JSON.parse(input)}catch(error){const detail=error instanceof Error?error.message:String(error);throw new PmCliError(`${label} must be valid JSON: ${detail}`,EXIT_CODE.USAGE,{code:"stdin_json_invalid",required:`Pipe one valid JSON ${label.toLowerCase()} into stdin.`,why:"Structured mutation input must parse deterministically before any tracker write begins."})}}function validateMutationObject(value,index){if(!isPlainObject(value))throw new PmCliError(`Mutation ${index+1} must be an object.`,EXIT_CODE.USAGE);for(const key of Object.keys(value))if(!MUTATION_ROW_KEYS.includes(key))throw unknownKeyError(`mutation ${index+1}`,key,MUTATION_ROW_KEYS);return value}function validateMutationOptions(options,op,index,runtimeFields){if(options===void 0)return;if(!isPlainObject(options))throw new PmCliError(`Mutation ${index+1} options must be an object.`,EXIT_CODE.USAGE);const allowed=[...MUTATION_OPTION_KEYS[op],...runtimeFieldOptionKeys(op,runtimeFields)];for(const key of Object.keys(options))if(!allowed.includes(key))throw unknownKeyError(`mutation ${index+1} ${op} options`,key,allowed);return assertMutationOptionValueTypes(options,op,index),options}function validateMutationKeyGuard(value,op,index,field){if(value===void 0)return;const allowedOp=field==="unique"?"create":"update";if(op!==allowedOp)throw new PmCliError(`Mutation ${index+1} ${field} is only valid for ${allowedOp} operations.`,EXIT_CODE.USAGE);const key=isPlainObject(value)&&typeof value.key=="string"?value.key.trim():"";if(!isPlainObject(value)||key.length===0||value.value===void 0||value.value===null)throw new PmCliError(`Mutation ${index+1} ${field} must be an object with a non-empty key and a value.`,EXIT_CODE.USAGE);return{key,value:value.value}}function validateMutationRow(value,index,runtimeFields){const mutation=validateMutationObject(value,index),{op,id,reason}=mutation;if(op!=="create"&&op!=="update"&&op!=="close"&&op!=="release")throw new PmCliError(`Mutation ${index+1} op must be create, update, close, or release.`,EXIT_CODE.USAGE);const options=validateMutationOptions(mutation.options,op,index,runtimeFields),unique=validateMutationKeyGuard(mutation.unique,op,index,"unique"),match=validateMutationKeyGuard(mutation.match,op,index,"match");if(typeof id!="string"||id.trim().length===0)throw new PmCliError(`Mutation ${index+1} requires a non-empty id.`,EXIT_CODE.USAGE);const normalizedId=id.trim();if(op==="close"){if(typeof reason!="string"||reason.trim().length===0)throw new PmCliError(`Mutation ${index+1} close requires a non-empty reason.`,EXIT_CODE.USAGE);return{op,id:normalizedId,reason:reason.trim(),...options===void 0?{}:{options}}}if(op==="release")return{op,id:normalizedId,...options===void 0?{}:{options}};if(!isPlainObject(options))throw new PmCliError(`Mutation ${index+1} ${op} requires an options object.`,EXIT_CODE.USAGE);return{op,id:normalizedId,options,...unique===void 0?{}:{unique},...match===void 0?{}:{match}}}function parseItemMutationBatch(input,parseOptions={}){const parsed=parseJsonValue(input,"Mutation batch"),rows=Array.isArray(parsed)?parsed:isPlainObject(parsed)&&Array.isArray(parsed.mutations)?parsed.mutations:void 0;if(rows===void 0||rows.length===0)throw new PmCliError("Mutation batch must be a non-empty JSON array or an object with a non-empty mutations array.",EXIT_CODE.USAGE);const runtimeFields=parseOptions.runtimeFields??[];return rows.map((row,index)=>{const mutation=validateMutationRow(row,index,runtimeFields);return mutation.options!==void 0&&preserveMutationStdinTokenLiterals(mutation.options),mutation})}function deriveReferencedItemId(transactionId,reference,idPrefix){const digest=crypto.createHash("sha256").update(transactionId).update("\0").update(reference).digest("hex"),token=BigInt(`0x${digest.slice(0,16)}`).toString(36).padStart(13,"0").slice(-12);return`${normalizePrefix(idPrefix)}${token}`}function replaceExactMutationReference(value,references){if(typeof value!="string"||!value.startsWith("@"))return value;const reference=value.slice(1),resolved=references[reference];if(resolved===void 0)throw new PmCliError(`Unknown mutation reference "${value}".`,EXIT_CODE.USAGE);return resolved}function replaceDependencyReference(value,references){if(typeof value!="string")return value;const resolvedValue=value.replace(MUTATION_DEPENDENCY_REFERENCE_PATTERN,(_match,prefix,reference)=>{const resolved=references[reference];if(resolved===void 0)throw new PmCliError(`Unknown mutation reference "@${reference}".`,EXIT_CODE.USAGE);return`${prefix}id=${resolved}`});if(/(^|,)id=@/u.test(resolvedValue))throw new PmCliError(`Malformed mutation reference in dependency "${value}".`,EXIT_CODE.USAGE);return resolvedValue}function referencedAliases(value){return typeof value!="string"?[]:value.startsWith("@")?[value.slice(1)]:[...value.matchAll(MUTATION_DEPENDENCY_REFERENCE_PATTERN)].map(match=>match[1]).filter(reference=>reference!==void 0)}function assertAcyclicCreateReferences(rows,inputReferences){const graph=new Map;for(const[index,row]of rows.entries()){const reference=inputReferences[index];if(reference===void 0)continue;const mutationOptions=isPlainObject(row.options)?row.options:{},dependencies=Array.isArray(mutationOptions.dep)?mutationOptions.dep:mutationOptions.dep===void 0?[]:[mutationOptions.dep];graph.set(reference,[mutationOptions.parent,mutationOptions.blockedBy,...dependencies].flatMap(referencedAliases))}const visiting=new Set,visited=new Set,visit=reference=>{if(visiting.has(reference))throw new PmCliError(`Mutation reference cycle includes "@${reference}".`,EXIT_CODE.USAGE);if(!visited.has(reference)){visiting.add(reference);for(const dependency of graph.get(reference))graph.has(dependency)&&visit(dependency);visiting.delete(reference),visited.add(reference)}};for(const reference of graph.keys())visit(reference)}function parseJsonLinesRows(input){const candidates=input.split(/\r?\n/u).map((line,index)=>({line:line.trim(),number:index+1})).filter(entry=>entry.line.length>0);if(candidates.length<2)return null;const parsed=candidates.map(entry=>{try{return{...entry,ok:!0,value:JSON.parse(entry.line)}}catch(error){return{...entry,ok:!1,error}}}),first=parsed[0];if(!first.ok&&(first.line.startsWith("[")||first.line==="{"||parsed.at(-1).line==="}")||!parsed.some(entry=>entry.ok&&isPlainObject(entry.value)))return null;const rows=[];for(const entry of parsed){if(!entry.ok)throw new PmCliError(`Mutation document line ${entry.number} must be one valid JSON object: ${describeUnknownError(entry.error)}`,EXIT_CODE.USAGE,{code:"stdin_json_invalid",required:"Provide one JSON object per line (JSON Lines), a JSON array, or a {schema_version, mutations} document.",why:"Structured mutation input must parse deterministically before any tracker write begins."});if(!isPlainObject(entry.value))throw new PmCliError(`Mutation document line ${entry.number} must be a JSON object.`,EXIT_CODE.USAGE);rows.push(entry.value)}return rows}function isMutationEnvelope(value){return Object.hasOwn(value,"mutations")||Object.hasOwn(value,"schema_version")}function parseMutationDocumentEnvelope(input){let parsed;try{parsed=parseJsonValue(input,"Mutation document")}catch(error){const rows=parseJsonLinesRows(input);if(rows===null)throw error;return{schema_version:1,mutations:rows}}return Array.isArray(parsed)?{schema_version:1,mutations:parsed}:isPlainObject(parsed)&&!isMutationEnvelope(parsed)?{schema_version:1,mutations:[parsed]}:parsed}function normalizeDocumentRow(row,index){const normalized=Object.hasOwn(row,"op")?validateOperationRow(row,index):normalizeCreateDocumentRow(row,index);if(normalized.op==="create"&&normalized.id===void 0&&isPlainObject(normalized.item)&&normalized.item.id!==void 0){if(typeof normalized.item.id!="string")throw new PmCliError(`Mutation ${index+1} item id must be a string.`,EXIT_CODE.USAGE);normalized.id=normalized.item.id}return normalized}function validateOperationRow(row,index){for(const key of Object.keys(row))if(!DOCUMENT_MUTATION_ROW_KEYS.includes(key))throw unknownKeyError(`mutation ${index+1}`,key,DOCUMENT_MUTATION_ROW_KEYS);if(row.item!==void 0&&row.op!=="create")throw new PmCliError(`Mutation ${index+1} item documents are only valid for create operations.`,EXIT_CODE.USAGE);if(row.item!==void 0&&row.options!==void 0)throw new PmCliError(`Mutation ${index+1} must declare either item or options, not both.`,EXIT_CODE.USAGE);return{...row}}function normalizeCreateDocumentRow(row,index){const{ref,id,item,...fields}=row,document=item!==void 0?item:fields;if(item!==void 0&&Object.keys(fields).length>0)throw new PmCliError(`Mutation ${index+1} must not mix item document keys with top-level fields.`,EXIT_CODE.USAGE);if(!isPlainObject(document))throw new PmCliError(`Mutation ${index+1} item document must be an object.`,EXIT_CODE.USAGE);return{op:"create",...ref===void 0?{}:{ref},...id===void 0?{}:{id},item:document}}function parseMutationDocumentRows(input){const envelope=parseMutationDocumentEnvelope(input);if(!isPlainObject(envelope))throw new PmCliError("Mutation document must be a JSON array or object.",EXIT_CODE.USAGE);for(const key of Object.keys(envelope))if(!MUTATION_DOCUMENT_KEYS.includes(key))throw unknownKeyError("mutation document",key,MUTATION_DOCUMENT_KEYS);if(envelope.schema_version!==void 0&&envelope.schema_version!==1)throw new PmCliError("Mutation document schema_version must be 1.",EXIT_CODE.USAGE);if(!Array.isArray(envelope.mutations)||envelope.mutations.length===0)throw new PmCliError("Mutation document requires a non-empty mutations array.",EXIT_CODE.USAGE);return envelope.mutations.map((row,index)=>{if(!isPlainObject(row))throw new PmCliError(`Mutation ${index+1} must be an object.`,EXIT_CODE.USAGE);return normalizeDocumentRow(row,index)})}function excludeOwnCreateIds(upsert,rows,options){const ownIds=new Set(Object.values(collectMutationReferences(rows,options,Object.create(null))));for(const row of rows)row.op==="create"&&typeof row.id=="string"&&row.id.trim().length>0&&ownIds.add(normalizeItemId(row.id,options.idPrefix));return{...upsert,existing:upsert.existing.filter(candidate=>!ownIds.has(candidate.id))}}function synthesizeMissingReferences(rows){const declared=new Set(rows.map(row=>row.ref).filter(ref=>typeof ref=="string"));for(const[index,row]of rows.entries()){if(row.op!=="create"||row.ref!==void 0||typeof row.id=="string"&&row.id.trim().length>0)continue;const synthesized=`${SYNTHESIZED_REFERENCE_PREFIX}${index+1}`;if(declared.has(synthesized))throw new PmCliError(`Mutation ${index+1} receives the synthesized ref "${synthesized}", but another row declares that ref. Rename it or give mutation ${index+1} its own ref; ${SYNTHESIZED_REFERENCE_PREFIX}<n> aliases are reserved for rows without one.`,EXIT_CODE.USAGE);row.ref=synthesized}}function itemDocumentToBatchOptions(item,mode,runtimeFields){const converted=itemDocumentToMutationOptions(JSON.stringify(item),mode,{},runtimeFields);return delete converted.stdinJson,delete converted.documentAnnotationSnapshot,converted}function runtimeFieldOptionKeys(op,runtimeFields){return op!=="create"&&op!=="update"?[]:runtimeFields.filter(definition=>definition.commands.includes(op)).map(definition=>runtimeFieldOptionTarget(definition))}function convertItemDocumentRows(rows,runtimeFields){for(const row of rows)isPlainObject(row.item)&&(row.options=itemDocumentToBatchOptions(row.item,"create",runtimeFields),delete row.item)}function itemDocumentMetadataKey(key,runtimeFields){return runtimeFields.some(field=>field.metadata_key===key)?key:resolveCoreUpsertMetadataKey(key)}function readUpsertKeyValue(row,key,runtimeFields){const camel=key.replaceAll(/_([a-z])/gu,(_match,letter)=>letter.toUpperCase());if(isPlainObject(row.item)){if(row.item[key]!==void 0)return row.item[key];if(itemDocumentMetadataKey(camel,runtimeFields)===key&&row.item[camel]!==void 0)return row.item[camel]}const options=isPlainObject(row.options)?row.options:{},declared=runtimeFields.find(field=>field.metadata_key===key);return declared!==void 0&&options[runtimeFieldOptionTarget(declared)]!==void 0?options[runtimeFieldOptionTarget(declared)]:options[key]!==void 0?options[key]:options[camel]!==void 0?options[camel]:(Array.isArray(options.field)?options.field:[]).map(String).find(entry=>entry.startsWith(`${key}=`))?.slice(key.length+1)}function compareCodeUnits(left,right){return left<right?-1:+(left!==right)}function canonicalizeUpsertValue(value){return Array.isArray(value)?value.map(canonicalizeUpsertValue):isPlainObject(value)?Object.fromEntries(Object.entries(value).sort(([left],[right])=>compareCodeUnits(left,right)).map(([key,nested])=>[key,canonicalizeUpsertValue(nested)])):value}function stableUpsertValue(value){return typeof value=="string"?value.trim():JSON.stringify(canonicalizeUpsertValue(value))}function applyKeyedUpsert(rows,upsert,idPrefix,runtimeFields,references){const key=upsert.key.trim();if(key.length===0)throw new PmCliError("Upsert key must be a non-empty field name.",EXIT_CODE.USAGE);const existingByValue=indexUpsertCandidates(upsert.existing),seen=new Map,upserted=new Set;for(const[index,row]of rows.entries()){if(row.op!=="create")continue;const stable=readStableUpsertKey(row,key,index,seen,runtimeFields),match=resolveUpsertMatch(existingByValue.get(stable)??[],key,stable);if(match===void 0){row.unique={key,value:readUpsertKeyValue(row,key,runtimeFields)};continue}const id=normalizeItemId(match,idPrefix);typeof row.ref=="string"&&(references[row.ref]=id),convertRowToUpsertUpdate(row,id,runtimeFields,{key,value:readUpsertKeyValue(row,key,runtimeFields)}),upserted.add(index)}return upserted}function indexUpsertCandidates(existing){const existingByValue=new Map;for(const candidate of existing){if(candidate.value===void 0||candidate.value===null)continue;const stable=stableUpsertValue(candidate.value);existingByValue.set(stable,[...existingByValue.get(stable)??[],candidate.id])}return existingByValue}function readStableUpsertKey(row,key,index,seen,runtimeFields){const value=readUpsertKeyValue(row,key,runtimeFields);if(value==null||value==="")throw new PmCliError(`Mutation ${index+1} is missing the upsert key "${key}".`,EXIT_CODE.USAGE,{code:"upsert_key_missing",required:`Every create record must carry a non-empty "${key}" value when --upsert-key ${key} is set.`,why:"Keyed upsert identifies existing items by that field; a record without it cannot be matched or safely created."});const stable=stableUpsertValue(value),previous=seen.get(stable);if(previous!==void 0)throw new PmCliError(`Mutations ${previous+1} and ${index+1} share the upsert key value ${JSON.stringify(stable)} for "${key}".`,EXIT_CODE.USAGE,{code:"upsert_key_duplicate",required:"Each record must carry a distinct upsert key value within one batch.",why:"Two records with the same key would race for the same existing item."});return seen.set(stable,index),stable}function resolveUpsertMatch(matches,key,stable){if(matches.length>1)throw new PmCliError(`Upsert key "${key}" value ${JSON.stringify(stable)} matches ${matches.length} existing items: ${matches.join(", ")}.`,EXIT_CODE.CONFLICT,{code:"upsert_key_ambiguous",required:"Resolve the duplicate existing items or choose a key that is unique per item.",why:"An ambiguous key cannot select one item to update without guessing."});return matches[0]}function convertRowToUpsertUpdate(row,id,runtimeFields,match){const updateKeys=new Set([...MUTATION_OPTION_KEYS.update,...runtimeFieldOptionKeys("update",runtimeFields)]),options=isPlainObject(row.item)?itemDocumentToBatchOptions(row.item,"update",runtimeFields):Object.fromEntries(Object.entries(row.options).filter(([optionKey])=>updateKeys.has(optionKey)));delete row.item,delete row.ref,row.op="update",row.id=id,row.options=options,row.match=match}function collectMutationReferences(rows,options,references){for(const[index,row]of rows.entries())if(row.ref!==void 0){if(row.op!=="create")throw new PmCliError(`Mutation ${index+1} ref is only valid for create operations.`,EXIT_CODE.USAGE);if(typeof row.ref!="string"||!MUTATION_REFERENCE_PATTERN.test(row.ref))throw new PmCliError(`Mutation ${index+1} ref must match ${MUTATION_REFERENCE_PATTERN.source}.`,EXIT_CODE.USAGE);if(references[row.ref]!==void 0)throw new PmCliError(`Duplicate mutation ref "${row.ref}".`,EXIT_CODE.USAGE);references[row.ref]=typeof row.id=="string"&&row.id.trim().length>0?normalizeItemId(row.id,options.idPrefix):deriveReferencedItemId(options.transactionId,row.ref,options.idPrefix)}return references}function resolveItemMutationDocument(input,options){const rows=parseMutationDocumentRows(input);synthesizeMissingReferences(rows);const inputReferences=rows.map(row=>typeof row.ref=="string"?row.ref:void 0),references=Object.create(null),upserted=options.upsert===void 0?new Set:applyKeyedUpsert(rows,excludeOwnCreateIds(options.upsert,rows,options),options.idPrefix,options.runtimeFields??[],references);convertItemDocumentRows(rows,options.runtimeFields??[]),collectMutationReferences(rows,options,references),assertAcyclicCreateReferences(rows,inputReferences);const resolvedRows=rows.map(row=>{const resolved={...row},reference=typeof resolved.ref=="string"?resolved.ref:void 0;if(delete resolved.ref,reference!==void 0?resolved.id=references[reference]:resolved.id=replaceExactMutationReference(resolved.id,references),isPlainObject(resolved.options)){const mutationOptions={...resolved.options};for(const key of["parent","blockedBy"])mutationOptions[key]!==void 0&&(mutationOptions[key]=replaceExactMutationReference(mutationOptions[key],references));Array.isArray(mutationOptions.dep)?mutationOptions.dep=mutationOptions.dep.map(entry=>replaceDependencyReference(entry,references)):mutationOptions.dep!==void 0&&(mutationOptions.dep=replaceDependencyReference(mutationOptions.dep,references)),resolved.options=mutationOptions}return resolved}),mutations=parseItemMutationBatch(JSON.stringify(resolvedRows),{runtimeFields:options.runtimeFields??[]}),createIds=mutations.filter(mutation=>mutation.op==="create").map(mutation=>mutation.id);if(new Set(createIds).size!==createIds.length)throw new PmCliError("Duplicate resolved create id in mutation document.",EXIT_CODE.USAGE);const receiptRows=mutations.map((mutation,index)=>{const reference=inputReferences[index];return{index,...typeof reference=="string"?{ref:reference}:{},id:mutation.id,op:mutation.op,...upserted.has(index)?{upserted:!0}:{}}});return{schema_version:1,mutations,references,rows:receiptRows}}function serializePairs(value,keys){return keys.filter(key=>value[key]!==void 0&&value[key]!==null).map(key=>{const rendered=String(value[key]);return`${key}=${/[",\n\r\\]/u.test(rendered)?JSON.stringify(rendered):rendered}`}).join(",")}function serializeObjectArray(value,keys,label){if(value!==void 0){if(!Array.isArray(value)||!value.every(isPlainObject))throw new PmCliError(`${label} must be an array of objects.`,EXIT_CODE.USAGE);return value.map(entry=>serializePairs(entry,keys))}}function scalarItemOption(key,value){return key==="tags"&&Array.isArray(value)&&value.every(entry=>typeof entry=="string")?JSON.stringify(value):typeof value=="number"||typeof value=="boolean"?String(value):value}function appendFacetOptions(target,source,skipPersistedAnnotations=!1){for(const[sourceKey,targetKey,keys]of ITEM_MUTATION_FACET_OPTION_MAPPINGS){const sourceValue=source[sourceKey],serialized=serializeObjectArray(skipPersistedAnnotations&&["comments","notes","learnings"].includes(sourceKey)&&Array.isArray(sourceValue)?sourceValue.filter(entry=>!isPlainObject(entry)||entry.created_at===void 0):sourceValue,keys,sourceKey);serialized!==void 0&&serialized.length>0&&(target[targetKey]=serialized)}}function validateItemDocumentKeys(parsed,envelope){for(const key of Object.keys(parsed)){if(envelope){if(!ITEM_ENVELOPE_KEYS.includes(key))throw unknownKeyError("item envelope",key,ITEM_ENVELOPE_KEYS);continue}if(!ITEM_FIELD_KEYS.has(key)&&nearestKey(key,[...ITEM_FIELD_KEYS])===void 0&&nearestKey(key,ITEM_ENVELOPE_KEYS)==="item")throw unknownKeyError("item envelope",key,ITEM_ENVELOPE_KEYS)}}function resolveItemDocument(parsed){const envelope=Object.hasOwn(parsed,"item");validateItemDocumentKeys(parsed,envelope);const item=envelope?parsed.item:parsed;if(!isPlainObject(item))throw new PmCliError("Item document item must be an object.",EXIT_CODE.USAGE);return{item,...envelope&&isPlainObject(parsed.linked)?{linked:parsed.linked}:{}}}function appendItemDocumentEntry(documentOptions,key,value,mode,runtimeFields,explicitOptions){if((mode==="update"?UPDATE_READ_ONLY_ITEM_KEYS:READ_ONLY_ITEM_KEYS).has(key))return;const definition=runtimeFields.find(field=>field.metadata_key===key&&field.commands.includes(mode));if(definition!==void 0){const explicitValue=readRuntimeFieldOptionValue(explicitOptions,definition);documentOptions[runtimeFieldOptionTarget(definition)]=explicitValue!==void 0?explicitValue:definition.type==="array"||definition.type==="object"?JSON.stringify(value):value;return}if(!ITEM_FIELD_KEYS.has(key)){if(nearestKey(key,[...ITEM_FIELD_KEYS])!==void 0)throw unknownKeyError("item document",key,[...ITEM_FIELD_KEYS]);const fields=Array.isArray(documentOptions.field)?documentOptions.field:[];fields.push(`${key}=${typeof value=="string"?value:JSON.stringify(value)}`),documentOptions.field=fields;return}["dependencies","comments","notes","learnings","files","tests","docs","reminders","events","type_options"].includes(key)||(documentOptions[key.replaceAll(/_([a-z])/gu,(_match,letter)=>letter.toUpperCase())]=scalarItemOption(key,value))}function itemDocumentToMutationOptions(input,mode,explicitOptions={},runtimeFields=[]){const parsed=parseJsonValue(input,"Item document");if(!isPlainObject(parsed))throw new PmCliError("Item document must be a JSON object.",EXIT_CODE.USAGE);const{item,linked}=resolveItemDocument(parsed),documentOptions={};for(const[key,value]of Object.entries(item)){const metadataKey=itemDocumentMetadataKey(key,runtimeFields);metadataKey!==key&&Object.hasOwn(item,metadataKey)||appendItemDocumentEntry(documentOptions,metadataKey,value,mode,runtimeFields,explicitOptions)}if(appendFacetOptions(documentOptions,item,mode==="update"),linked!==void 0&&appendFacetOptions(documentOptions,linked),mode==="update"){const annotations=Object.fromEntries(["comments","notes","learnings"].filter(key=>Object.hasOwn(item,key)).map(key=>[key,item[key].filter(entry=>isPlainObject(entry)&&entry.created_at!==void 0)]));Object.keys(annotations).length>0&&(documentOptions.documentAnnotationSnapshot=annotations)}return{...documentOptions,...Object.fromEntries(Object.entries(explicitOptions).filter(([,value])=>value!==void 0)),...Array.isArray(documentOptions.field)&&Array.isArray(explicitOptions.field)?{field:[...documentOptions.field,...explicitOptions.field]}:{},stdinJson:void 0}}function validateItemMutationRows(value){return parseItemMutationBatch(JSON.stringify(value))}export{deriveMutationTransactionId,itemDocumentToMutationOptions,parseAtomicMutationControls,parseItemMutationBatch,resolveItemMutationDocument,stableUpsertValue,validateItemMutationRows};
2
2
  //# sourceMappingURL=structured-mutations.js.map
@@ -1,3 +1,3 @@
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]="0bd9a904-c076-5c2a-a9d8-42a543625e33")}catch{}})();import{mkdir,readFile}from"node:fs/promises";import path from"node:path";import{acquireLock}from"../core/lock/lock.js";import{isFileMissingError,writeFileAtomic}from"../core/fs/fs-utils.js";import{nowIso}from"../core/shared/time.js";class WorkspaceTransactionInterruptedError extends Error{constructor(message="Workspace transaction interrupted"){super(message),this.name="WorkspaceTransactionInterruptedError"}}const WORKSPACE_TRANSACTION_LOCK_ID="sdk-workspace-transaction",TRANSACTION_ID_PATTERN=/^[a-zA-Z0-9._-]+$/,DEFAULT_LOCK_TTL_SECONDS=30,DEFAULT_LOCK_WAIT_MS=3e3;function requiredIdentifier(value,label){if(typeof value!="string")throw new TypeError(`${label} must be a string`);const normalized=value.trim();if(!normalized||!TRANSACTION_ID_PATTERN.test(normalized))throw new TypeError(`${label} must match [a-zA-Z0-9._-]+`);return normalized}function requiredText(value,label){if(typeof value!="string")throw new TypeError(`${label} must be a string`);const normalized=value.trim();if(!normalized)throw new TypeError(`${label} must be non-empty`);return normalized}function validateWorkspaceTransactionIdentity(options){return{pmRoot:requiredText(options.pmRoot,"Transaction pmRoot"),transactionId:requiredIdentifier(options.transactionId,"Transaction id"),author:requiredText(options.author,"Transaction author")}}function positiveInteger(value,fallback,label){const resolved=value??fallback;if(!Number.isInteger(resolved)||resolved<=0)throw new TypeError(`${label} must be a positive integer`);return resolved}function journalPath(pmRoot,transactionId){return path.join(pmRoot,"transactions","sdk",`${transactionId}.json`)}async function writeJournal(pmRoot,journal){journal.updatedAt=nowIso();const target=journalPath(pmRoot,journal.transactionId);await mkdir(path.dirname(target),{recursive:!0}),await writeFileAtomic(target,`${JSON.stringify(journal,null,2)}
2
- `)}function hasValidJournalMetadata(journal){return Number.isInteger(journal.attempt)&&typeof journal.author=="string"&&typeof journal.createdAt=="string"&&typeof journal.updatedAt=="string"}function createResultMap(source){return Object.assign(Object.create(null),source)}function cloneJournalValue(value,label){try{const serialized=JSON.stringify(value,(_key,nestedValue)=>{if(typeof nestedValue=="number"&&!Number.isFinite(nestedValue))throw new TypeError(`${label} contains a non-finite number`);if(nestedValue===void 0||typeof nestedValue=="function"||typeof nestedValue=="symbol")throw new TypeError(`${label} contains a non-JSON value`);return nestedValue});return JSON.parse(serialized)}catch(error){throw new TypeError(`${label} must be JSON serializable`,{cause:error})}}function cloneOptionalJournalValue(value,label){return value===void 0?void 0:cloneJournalValue(value,label)}function setJournalEntry(target,stepId,value,label){const cloned=cloneOptionalJournalValue(value,label);cloned===void 0?delete target[stepId]:target[stepId]=cloned}function isJournalMap(value){return value!==null&&typeof value=="object"&&!Array.isArray(value)}function hasUniqueKnownStepIds(value,stepIds){return Array.isArray(value)&&new Set(value).size===value.length&&value.every(stepId=>typeof stepId=="string"&&stepIds.includes(stepId))}function hasValidJournalLifecycle(journal,stepIds){if(!hasUniqueKnownStepIds(journal.startedStepIds,stepIds)||!hasUniqueKnownStepIds(journal.completedStepIds,stepIds)||!isJournalMap(journal.results)||!isJournalMap(journal.compensationData))return!1;const startedStepIds=journal.startedStepIds,started=new Set(startedStepIds),completedStepIds=journal.completedStepIds,completed=new Set(completedStepIds);return Object.keys(journal.compensationData).some(stepId=>!started.has(stepId))||Object.keys(journal.results).some(stepId=>!completed.has(stepId))?!1:journal.status==="committed"?stepIds.every(stepId=>completed.has(stepId)):journal.status!=="compensated"||completed.size===0&&started.size===0}function parseJournal(raw,transactionId,stepIds){let parsed;try{parsed=JSON.parse(raw)}catch{throw new TypeError(`Workspace transaction ${transactionId} journal is invalid JSON`)}if(!parsed||typeof parsed!="object"||Array.isArray(parsed))throw new TypeError(`Workspace transaction ${transactionId} journal is invalid`);const journal=parsed,identityMatches=journal.schemaVersion===1&&journal.transactionId===transactionId,stepsMatch=Array.isArray(journal.stepIds)&&journal.stepIds.length===stepIds.length&&journal.stepIds.every((stepId,index)=>stepId===stepIds[index]),lifecycleMatches=hasValidJournalLifecycle(journal,stepIds),metadataMatches=hasValidJournalMetadata(journal),statusMatches=["applying","compensating","compensated","committed"].includes(String(journal.status));if(!identityMatches||!stepsMatch||!lifecycleMatches||!metadataMatches||!statusMatches)throw new TypeError(`Workspace transaction ${transactionId} journal does not match the supplied plan`);return{...journal,results:createResultMap(journal.results),compensationData:createResultMap(journal.compensationData)}}async function prepareJournalForApply(options,transactionId,author,stepIds,existing){let journal=existing;const recovered=journal!==void 0;if(journal?.status==="compensating"&&await compensateAppliedSteps(options,journal),journal===void 0||journal.status==="compensated"){const timestamp=nowIso();journal={schemaVersion:1,transactionId,author,status:"applying",attempt:(journal?.attempt??0)+1,createdAt:journal?.createdAt??timestamp,updatedAt:timestamp,stepIds,startedStepIds:[],completedStepIds:[],results:createResultMap(),compensationData:createResultMap()},await writeJournal(options.pmRoot,journal),await emitTransition(options,journal,"prepared")}return{journal,recovered}}async function applyPreparedTransaction(options,journal,recovered){try{await discoverAppliedSteps(journal,options.steps),await writeJournal(options.pmRoot,journal);const completed=new Set(journal.completedStepIds),started=new Set(journal.startedStepIds);for(const step of options.steps){if(completed.has(step.id))continue;const inspection=await step.inspect();let result=cloneOptionalJournalValue(inspection.result,`Step ${step.id} result`);if(inspection.state!=="applied"){const compensationData=await step.prepareCompensation?.();setJournalEntry(journal.compensationData,step.id,compensationData,`Step ${step.id} compensation data`),started.add(step.id),journal.startedStepIds=options.steps.map(candidate=>candidate.id).filter(stepId=>started.has(stepId)),await writeJournal(options.pmRoot,journal);const appliedResult=await step.apply();result=cloneOptionalJournalValue(appliedResult,`Step ${step.id} result`)}await emitTransition(options,journal,"step_applied",step.id),completed.add(step.id),journal.completedStepIds=options.steps.map(candidate=>candidate.id).filter(stepId=>completed.has(stepId)),setJournalEntry(journal.results,step.id,result,`Step ${step.id} result`),await writeJournal(options.pmRoot,journal),await emitTransition(options,journal,"step_recorded",step.id)}return await emitTransition(options,journal,"committing"),journal.status="committed",await writeJournal(options.pmRoot,journal),await emitTransition(options,journal,"committed"),{transactionId:journal.transactionId,status:"committed",recovered,results:createResultMap(journal.results)}}catch(error){if(error instanceof WorkspaceTransactionInterruptedError||journal.status==="committed")throw error;try{await compensateAppliedSteps(options,journal)}catch(compensationError){throw new AggregateError([error,compensationError],`Workspace transaction failed and compensation failed: ${String(compensationError)}`,{cause:compensationError})}throw error}}async function loadJournal(pmRoot,transactionId,stepIds){try{return parseJournal(await readFile(journalPath(pmRoot,transactionId),"utf8"),transactionId,stepIds)}catch(error){if(error!==null&&typeof error=="object"&&"code"in error&&isFileMissingError(error))return;throw error}}async function emitTransition(options,journal,transition,stepId){await options.onTransition?.({transactionId:journal.transactionId,attempt:journal.attempt,transition,...stepId===void 0?{}:{stepId}})}async function discoverAppliedSteps(journal,steps){const completed=new Set,results=createResultMap();for(const step of steps){const inspection=await step.inspect();inspection.state==="applied"&&(completed.add(step.id),setJournalEntry(results,step.id,inspection.result,`Step ${step.id} result`))}journal.results=results,journal.completedStepIds=steps.map(step=>step.id).filter(stepId=>completed.has(stepId))}async function compensateAppliedSteps(options,journal){journal.status="compensating",await writeJournal(options.pmRoot,journal),await emitTransition(options,journal,"compensating");const completed=new Set(journal.completedStepIds),started=new Set(journal.startedStepIds);for(const step of[...options.steps].reverse()){if(!started.has(step.id)&&!completed.has(step.id))continue;let shouldCompensate;try{shouldCompensate=started.has(step.id)&&(await step.inspect()).state==="applied"}catch{shouldCompensate=started.has(step.id)}shouldCompensate&&(await emitTransition(options,journal,"step_compensating",step.id),await step.compensate(journal.compensationData[step.id])),completed.delete(step.id),started.delete(step.id),journal.completedStepIds=options.steps.map(candidate=>candidate.id).filter(stepId=>completed.has(stepId)),journal.startedStepIds=options.steps.map(candidate=>candidate.id).filter(stepId=>started.has(stepId)),delete journal.results[step.id],delete journal.compensationData[step.id],await writeJournal(options.pmRoot,journal),await emitTransition(options,journal,"step_compensated",step.id)}journal.status="compensated",await writeJournal(options.pmRoot,journal),await emitTransition(options,journal,"compensated")}async function commitWorkspaceTransaction(options){const{pmRoot,transactionId,author}=validateWorkspaceTransactionIdentity(options),lockTtlSeconds=positiveInteger(options.lockTtlSeconds,DEFAULT_LOCK_TTL_SECONDS,"Transaction lock TTL"),lockWaitMs=positiveInteger(options.lockWaitMs,DEFAULT_LOCK_WAIT_MS,"Transaction lock wait"),steps=[...options.steps];if(steps.length===0)throw new TypeError("Workspace transaction requires at least one step");const stepIds=steps.map(step=>{const stepId=requiredIdentifier(step.id,"Transaction step id");if(stepId!==step.id)throw new TypeError("Transaction step id must not contain surrounding whitespace");return stepId});if(new Set(stepIds).size!==stepIds.length)throw new TypeError("Workspace transaction step ids must be unique");const stableOptions={...options,pmRoot,transactionId,author,steps,lockTtlSeconds,lockWaitMs},release=await acquireLock(pmRoot,WORKSPACE_TRANSACTION_LOCK_ID,lockTtlSeconds,author,!1,!1,lockWaitMs);try{const existing=await loadJournal(pmRoot,transactionId,stepIds),recovered=existing!==void 0;if(existing?.status==="committed")return{transactionId,status:"committed",recovered:!0,results:createResultMap(existing.results)};const prepared=await prepareJournalForApply(stableOptions,transactionId,author,stepIds,existing);return await applyPreparedTransaction(stableOptions,prepared.journal,recovered||prepared.recovered)}finally{await release()}}export{WorkspaceTransactionInterruptedError,commitWorkspaceTransaction,validateWorkspaceTransactionIdentity};
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]="1fae5539-4eb8-5eba-bfd6-a191c89448ec")}catch{}})();import{mkdir,readFile}from"node:fs/promises";import path from"node:path";import{acquireLock}from"../core/lock/lock.js";import{isFileMissingError,writeFileAtomic}from"../core/fs/fs-utils.js";import{nowIso}from"../core/shared/time.js";import{EXIT_CODE}from"../core/shared/constants.js";import{PmCliError}from"../core/shared/errors.js";class WorkspaceTransactionInterruptedError extends Error{constructor(message="Workspace transaction interrupted"){super(message),this.name="WorkspaceTransactionInterruptedError"}}const WORKSPACE_TRANSACTION_LOCK_ID="sdk-workspace-transaction",TRANSACTION_ID_PATTERN=/^[a-zA-Z0-9._-]+$/,DEFAULT_LOCK_TTL_SECONDS=30,DEFAULT_LOCK_WAIT_MS=3e3;function requiredIdentifier(value,label){if(typeof value!="string")throw new TypeError(`${label} must be a string`);const normalized=value.trim();if(!normalized||!TRANSACTION_ID_PATTERN.test(normalized))throw new TypeError(`${label} must match [a-zA-Z0-9._-]+`);return normalized}function requiredText(value,label){if(typeof value!="string")throw new TypeError(`${label} must be a string`);const normalized=value.trim();if(!normalized)throw new TypeError(`${label} must be non-empty`);return normalized}function validateWorkspaceTransactionIdentity(options){return{pmRoot:requiredText(options.pmRoot,"Transaction pmRoot"),transactionId:requiredIdentifier(options.transactionId,"Transaction id"),author:requiredText(options.author,"Transaction author")}}function positiveInteger(value,fallback,label){const resolved=value??fallback;if(!Number.isInteger(resolved)||resolved<=0)throw new TypeError(`${label} must be a positive integer`);return resolved}function journalPath(pmRoot,transactionId){return path.join(pmRoot,"transactions","sdk",`${transactionId}.json`)}async function writeJournal(pmRoot,journal){journal.updatedAt=nowIso();const target=journalPath(pmRoot,journal.transactionId);await mkdir(path.dirname(target),{recursive:!0}),await writeFileAtomic(target,`${JSON.stringify(journal,null,2)}
2
+ `)}function hasValidJournalMetadata(journal){return Number.isInteger(journal.attempt)&&typeof journal.author=="string"&&typeof journal.createdAt=="string"&&typeof journal.updatedAt=="string"}function createResultMap(source){return Object.assign(Object.create(null),source)}function cloneJournalValue(value,label){try{const serialized=JSON.stringify(value,(_key,nestedValue)=>{if(typeof nestedValue=="number"&&!Number.isFinite(nestedValue))throw new TypeError(`${label} contains a non-finite number`);if(nestedValue===void 0||typeof nestedValue=="function"||typeof nestedValue=="symbol")throw new TypeError(`${label} contains a non-JSON value`);return nestedValue});return JSON.parse(serialized)}catch(error){throw new TypeError(`${label} must be JSON serializable`,{cause:error})}}function cloneOptionalJournalValue(value,label){return value===void 0?void 0:cloneJournalValue(value,label)}function setJournalEntry(target,stepId,value,label){const cloned=cloneOptionalJournalValue(value,label);cloned===void 0?delete target[stepId]:target[stepId]=cloned}function isJournalMap(value){return value!==null&&typeof value=="object"&&!Array.isArray(value)}function hasUniqueKnownStepIds(value,stepIds){return Array.isArray(value)&&new Set(value).size===value.length&&value.every(stepId=>typeof stepId=="string"&&stepIds.includes(stepId))}function hasValidJournalLifecycle(journal,stepIds){if(!hasUniqueKnownStepIds(journal.startedStepIds,stepIds)||!hasUniqueKnownStepIds(journal.completedStepIds,stepIds)||!isJournalMap(journal.results)||!isJournalMap(journal.compensationData))return!1;const startedStepIds=journal.startedStepIds,started=new Set(startedStepIds),completedStepIds=journal.completedStepIds,completed=new Set(completedStepIds);return Object.keys(journal.compensationData).some(stepId=>!started.has(stepId))||Object.keys(journal.results).some(stepId=>!completed.has(stepId))?!1:journal.status==="committed"?stepIds.every(stepId=>completed.has(stepId)):journal.status!=="compensated"||completed.size===0&&started.size===0}function invalidJournal(transactionId,detail){return new PmCliError(`Workspace transaction ${transactionId} journal is invalid (${detail})`,EXIT_CODE.CONFLICT,{code:"transaction_journal_invalid",required:"A valid durable journal is required before transaction recovery can continue.",why:"Corrupt journal data cannot establish which steps applied or still require compensation.",nextSteps:["Preserve the journal and inspect its integrity or restore a verified backup before retrying.","Do not switch to a new transaction id to bypass an unreadable journal; previously applied work may remain."]})}function journalPlanMismatch(transactionId){return new PmCliError(`Workspace transaction ${transactionId} journal does not match the supplied plan`,EXIT_CODE.CONFLICT,{code:"transaction_plan_mismatch",required:"Replay the exact plan that started this transaction, or start a new transaction with a different id.",why:"A journal records the plan it is resuming; applying a different plan under the same id could skip or duplicate steps.",nextSteps:["Re-run with the original document to resume or replay it.","Pass --transaction-id <new-id> (or a new transactionId over MCP) to commit the changed plan as its own transaction.","Run pm ops gc --scope transactions --dry-run to inspect abandoned journals before pruning them."]})}function parseJournal(raw,transactionId,stepIds){let parsed;try{parsed=JSON.parse(raw)}catch{throw invalidJournal(transactionId,"invalid JSON")}if(!parsed||typeof parsed!="object"||Array.isArray(parsed))throw invalidJournal(transactionId,"expected an object");const journal=parsed;if(!(journal.schemaVersion===1&&journal.transactionId===transactionId))throw invalidJournal(transactionId,"schema version or transaction id does not match the journal file");const recordedStepIds=journal.stepIds;if(!Array.isArray(recordedStepIds)||!hasUniqueKnownStepIds(recordedStepIds,recordedStepIds)||!hasValidJournalLifecycle(journal,recordedStepIds)||!hasValidJournalMetadata(journal)||typeof journal.status!="string"||!["applying","compensating","compensated","committed"].includes(journal.status))throw invalidJournal(transactionId,"invalid lifecycle, metadata, status or step ids");if(!(journal.status==="compensated"||recordedStepIds.length===stepIds.length&&recordedStepIds.every((stepId,index)=>stepId===stepIds[index])))throw journalPlanMismatch(transactionId);return{...journal,results:createResultMap(journal.results),compensationData:createResultMap(journal.compensationData)}}async function prepareJournalForApply(options,transactionId,author,stepIds,existing){let journal=existing;const recovered=journal!==void 0;if(journal?.status==="compensating"&&await compensateAppliedSteps(options,journal),journal===void 0||journal.status==="compensated"){const timestamp=nowIso();journal={schemaVersion:1,transactionId,author,status:"applying",attempt:(journal?.attempt??0)+1,createdAt:journal?.createdAt??timestamp,updatedAt:timestamp,stepIds,startedStepIds:[],completedStepIds:[],results:createResultMap(),compensationData:createResultMap()},await writeJournal(options.pmRoot,journal),await emitTransition(options,journal,"prepared")}return{journal,recovered}}async function applyPreparedTransaction(options,journal,recovered){try{await discoverAppliedSteps(journal,options.steps),await writeJournal(options.pmRoot,journal);const completed=new Set(journal.completedStepIds),started=new Set(journal.startedStepIds);for(const step of options.steps){if(completed.has(step.id))continue;const inspection=await step.inspect();let result=cloneOptionalJournalValue(inspection.result,`Step ${step.id} result`);if(inspection.state!=="applied"){const compensationData=await step.prepareCompensation?.();setJournalEntry(journal.compensationData,step.id,compensationData,`Step ${step.id} compensation data`),started.add(step.id),journal.startedStepIds=options.steps.map(candidate=>candidate.id).filter(stepId=>started.has(stepId)),await writeJournal(options.pmRoot,journal);const appliedResult=await step.apply();result=cloneOptionalJournalValue(appliedResult,`Step ${step.id} result`)}await emitTransition(options,journal,"step_applied",step.id),completed.add(step.id),journal.completedStepIds=options.steps.map(candidate=>candidate.id).filter(stepId=>completed.has(stepId)),setJournalEntry(journal.results,step.id,result,`Step ${step.id} result`),await writeJournal(options.pmRoot,journal),await emitTransition(options,journal,"step_recorded",step.id)}return await emitTransition(options,journal,"committing"),journal.status="committed",await writeJournal(options.pmRoot,journal),await emitTransition(options,journal,"committed"),{transactionId:journal.transactionId,status:"committed",recovered,results:createResultMap(journal.results)}}catch(error){if(error instanceof WorkspaceTransactionInterruptedError||journal.status==="committed")throw error;try{await compensateAppliedSteps(options,journal)}catch(compensationError){throw new AggregateError([error,compensationError],`Workspace transaction failed and compensation failed: ${String(compensationError)}`,{cause:compensationError})}throw error}}async function loadJournal(pmRoot,transactionId,stepIds){try{return parseJournal(await readFile(journalPath(pmRoot,transactionId),"utf8"),transactionId,stepIds)}catch(error){if(error!==null&&typeof error=="object"&&"code"in error&&isFileMissingError(error))return;throw error}}async function emitTransition(options,journal,transition,stepId){await options.onTransition?.({transactionId:journal.transactionId,attempt:journal.attempt,transition,...stepId===void 0?{}:{stepId}})}async function discoverAppliedSteps(journal,steps){const completed=new Set,results=createResultMap();for(const step of steps){const inspection=await step.inspect();inspection.state==="applied"&&(completed.add(step.id),setJournalEntry(results,step.id,inspection.result,`Step ${step.id} result`))}journal.results=results,journal.completedStepIds=steps.map(step=>step.id).filter(stepId=>completed.has(stepId))}async function compensateAppliedSteps(options,journal){journal.status="compensating",await writeJournal(options.pmRoot,journal),await emitTransition(options,journal,"compensating");const completed=new Set(journal.completedStepIds),started=new Set(journal.startedStepIds);for(const step of[...options.steps].reverse()){if(!started.has(step.id)&&!completed.has(step.id))continue;let shouldCompensate;try{shouldCompensate=started.has(step.id)&&(await step.inspect()).state==="applied"}catch{shouldCompensate=started.has(step.id)}shouldCompensate&&(await emitTransition(options,journal,"step_compensating",step.id),await step.compensate(journal.compensationData[step.id])),completed.delete(step.id),started.delete(step.id),journal.completedStepIds=options.steps.map(candidate=>candidate.id).filter(stepId=>completed.has(stepId)),journal.startedStepIds=options.steps.map(candidate=>candidate.id).filter(stepId=>started.has(stepId)),delete journal.results[step.id],delete journal.compensationData[step.id],await writeJournal(options.pmRoot,journal),await emitTransition(options,journal,"step_compensated",step.id)}journal.status="compensated",await writeJournal(options.pmRoot,journal),await emitTransition(options,journal,"compensated")}async function commitWorkspaceTransaction(options){const{pmRoot,transactionId,author}=validateWorkspaceTransactionIdentity(options),lockTtlSeconds=positiveInteger(options.lockTtlSeconds,DEFAULT_LOCK_TTL_SECONDS,"Transaction lock TTL"),lockWaitMs=positiveInteger(options.lockWaitMs,DEFAULT_LOCK_WAIT_MS,"Transaction lock wait"),steps=[...options.steps];if(steps.length===0)throw new TypeError("Workspace transaction requires at least one step");const stepIds=steps.map(step=>{const stepId=requiredIdentifier(step.id,"Transaction step id");if(stepId!==step.id)throw new TypeError("Transaction step id must not contain surrounding whitespace");return stepId});if(new Set(stepIds).size!==stepIds.length)throw new TypeError("Workspace transaction step ids must be unique");const stableOptions={...options,pmRoot,transactionId,author,steps,lockTtlSeconds,lockWaitMs},release=await acquireLock(pmRoot,WORKSPACE_TRANSACTION_LOCK_ID,lockTtlSeconds,author,!1,!1,lockWaitMs);try{const existing=await loadJournal(pmRoot,transactionId,stepIds),recovered=existing!==void 0;if(existing?.status==="committed")return{transactionId,status:"committed",recovered:!0,results:createResultMap(existing.results)};const prepared=await prepareJournalForApply(stableOptions,transactionId,author,stepIds,existing);return await applyPreparedTransaction(stableOptions,prepared.journal,recovered||prepared.recovered)}finally{await release()}}export{WorkspaceTransactionInterruptedError,commitWorkspaceTransaction,validateWorkspaceTransactionIdentity};
3
3
  //# sourceMappingURL=workspace-transaction.js.map
package/dist/types.d.ts CHANGED
@@ -113,8 +113,8 @@ export interface Dependency {
113
113
  id:string;
114
114
  /** Value that configures or reports kind for this contract. */
115
115
  kind:DependencyKind;
116
- /** ISO 8601 timestamp recording when created occurred. */
117
- created_at:string;
116
+ /** Creation timestamp when provenance is available; legacy dependency reads may omit it. New edge writers supply it. */
117
+ created_at?:string;
118
118
  /** Value that configures or reports author for this contract. */
119
119
  author?:string;
120
120
  /** Value that configures or reports source kind for this contract. */
package/dist/types.js CHANGED
@@ -1,2 +1,2 @@
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]="459c0cce-212f-5285-9c3b-13676d2388af")}catch{}})();const BUILTIN_ITEM_TYPE_VALUES=["Epic","Feature","Task","Chore","Issue","Decision","Event","Reminder","Milestone","Meeting","Plan"],ITEM_TYPE_VALUES=BUILTIN_ITEM_TYPE_VALUES,STATUS_VALUES=["draft","open","in_progress","blocked","closed","canceled"],RUNTIME_STATUS_ROLE_VALUES=["draft","active","blocked","terminal","terminal_done","terminal_canceled","default_open","default_close","default_cancel"],RUNTIME_FIELD_TYPE_VALUES=["string","number","boolean","string_array","array","object"],RUNTIME_FIELD_COMMAND_VALUES=["create","update","update_many","list","search","calendar","context"],RUNTIME_UNKNOWN_FIELD_POLICY_VALUES=["allow","warn","reject"],DEPENDENCY_KIND_VALUES=["blocks","parent","child","parent_child","child_of","related","related_to","discovered_from","blocked_by","incident_from","epic","implements","recurs_from","supersedes","task","verifies"],SCOPE_VALUES=["project","global"],RISK_VALUES=["low","medium","high","critical"],ISSUE_SEVERITY_VALUES=["low","medium","high","critical"],CONFIDENCE_TEXT_VALUES=["low","medium","high"],ITEM_FORMAT_VALUES=["toon","json_markdown"],SPRINT_RELEASE_FORMAT_POLICY_VALUES=["warn","strict_error"],PARENT_REFERENCE_POLICY_VALUES=["warn","strict_error"],VALIDATE_METADATA_PROFILE_VALUES=["core","strict","custom"],GOVERNANCE_PRESET_VALUES=["minimal","default","strict","custom"],GOVERNANCE_OWNERSHIP_ENFORCEMENT_VALUES=["none","warn","strict"],GOVERNANCE_CREATE_MODE_DEFAULT_VALUES=["progressive","strict"],GOVERNANCE_CLOSE_VALIDATION_DEFAULT_VALUES=["off","warn","strict"],GOVERNANCE_WORKFLOW_ENFORCEMENT_VALUES=["off","warn","strict"],GOVERNANCE_DUPLICATE_DETECTION_MODE_VALUES=["off","advisory","strict"],VALIDATE_METADATA_REQUIRED_FIELD_VALUES=["author","acceptance_criteria","estimated_minutes","close_reason","reviewer","risk","confidence","sprint","release"],RECURRENCE_FREQUENCY_VALUES=["daily","weekly","monthly","yearly"],RECURRENCE_WEEKDAY_VALUES=["mon","tue","wed","thu","fri","sat","sun"];function weekdayOrderIndex(value){return RECURRENCE_WEEKDAY_VALUES.indexOf(value)}const PLAN_MODE_VALUES=["draft","research","review","approved","executing","paused","completed","superseded"],PLAN_STEP_STATUS_VALUES=["pending","in_progress","completed","blocked","skipped","superseded"],PLAN_HARNESS_VALUES=["codex","claude-code","cursor","generic"],PLAN_STEP_LINK_KIND_VALUES=["related","blocks","blocked_by","depends_on","discovered_from","implements","recurs_from","verifies","supersedes"],CONTEXT_DEPTH_VALUES=["brief","standard","deep","full"],CONTEXT_SECTION_VALUES=["hierarchy","activity","progress","recently_created","unparented","blockers","files","workload","staleness","tests"];export{BUILTIN_ITEM_TYPE_VALUES,CONFIDENCE_TEXT_VALUES,CONTEXT_DEPTH_VALUES,CONTEXT_SECTION_VALUES,DEPENDENCY_KIND_VALUES,GOVERNANCE_CLOSE_VALIDATION_DEFAULT_VALUES,GOVERNANCE_CREATE_MODE_DEFAULT_VALUES,GOVERNANCE_DUPLICATE_DETECTION_MODE_VALUES,GOVERNANCE_OWNERSHIP_ENFORCEMENT_VALUES,GOVERNANCE_PRESET_VALUES,GOVERNANCE_WORKFLOW_ENFORCEMENT_VALUES,ISSUE_SEVERITY_VALUES,ITEM_FORMAT_VALUES,ITEM_TYPE_VALUES,PARENT_REFERENCE_POLICY_VALUES,PLAN_HARNESS_VALUES,PLAN_MODE_VALUES,PLAN_STEP_LINK_KIND_VALUES,PLAN_STEP_STATUS_VALUES,RECURRENCE_FREQUENCY_VALUES,RECURRENCE_WEEKDAY_VALUES,RISK_VALUES,RUNTIME_FIELD_COMMAND_VALUES,RUNTIME_FIELD_TYPE_VALUES,RUNTIME_STATUS_ROLE_VALUES,RUNTIME_UNKNOWN_FIELD_POLICY_VALUES,SCOPE_VALUES,SPRINT_RELEASE_FORMAT_POLICY_VALUES,STATUS_VALUES,VALIDATE_METADATA_PROFILE_VALUES,VALIDATE_METADATA_REQUIRED_FIELD_VALUES,weekdayOrderIndex};
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]="c05a5a9e-282c-5ca7-97dc-e48c8df7977e")}catch{}})();const BUILTIN_ITEM_TYPE_VALUES=["Epic","Feature","Task","Chore","Issue","Decision","Event","Reminder","Milestone","Meeting","Plan"],ITEM_TYPE_VALUES=BUILTIN_ITEM_TYPE_VALUES,STATUS_VALUES=["draft","open","in_progress","blocked","closed","canceled"],RUNTIME_STATUS_ROLE_VALUES=["draft","active","blocked","terminal","terminal_done","terminal_canceled","default_open","default_close","default_cancel"],RUNTIME_FIELD_TYPE_VALUES=["string","number","boolean","string_array","array","object"],RUNTIME_FIELD_COMMAND_VALUES=["create","update","update_many","list","search","calendar","context"],RUNTIME_UNKNOWN_FIELD_POLICY_VALUES=["allow","warn","reject"],DEPENDENCY_KIND_VALUES=["blocks","parent","child","parent_child","child_of","related","related_to","discovered_from","blocked_by","incident_from","epic","implements","recurs_from","supersedes","task","verifies"],SCOPE_VALUES=["project","global"],RISK_VALUES=["low","medium","high","critical"],ISSUE_SEVERITY_VALUES=["low","medium","high","critical"],CONFIDENCE_TEXT_VALUES=["low","medium","high"],ITEM_FORMAT_VALUES=["toon","json_markdown"],SPRINT_RELEASE_FORMAT_POLICY_VALUES=["warn","strict_error"],PARENT_REFERENCE_POLICY_VALUES=["warn","strict_error"],VALIDATE_METADATA_PROFILE_VALUES=["core","strict","custom"],GOVERNANCE_PRESET_VALUES=["minimal","default","strict","custom"],GOVERNANCE_OWNERSHIP_ENFORCEMENT_VALUES=["none","warn","strict"],GOVERNANCE_CREATE_MODE_DEFAULT_VALUES=["progressive","strict"],GOVERNANCE_CLOSE_VALIDATION_DEFAULT_VALUES=["off","warn","strict"],GOVERNANCE_WORKFLOW_ENFORCEMENT_VALUES=["off","warn","strict"],GOVERNANCE_DUPLICATE_DETECTION_MODE_VALUES=["off","advisory","strict"],VALIDATE_METADATA_REQUIRED_FIELD_VALUES=["author","acceptance_criteria","estimated_minutes","close_reason","reviewer","risk","confidence","sprint","release"],RECURRENCE_FREQUENCY_VALUES=["daily","weekly","monthly","yearly"],RECURRENCE_WEEKDAY_VALUES=["mon","tue","wed","thu","fri","sat","sun"];function weekdayOrderIndex(value){return RECURRENCE_WEEKDAY_VALUES.indexOf(value)}const PLAN_MODE_VALUES=["draft","research","review","approved","executing","paused","completed","superseded"],PLAN_STEP_STATUS_VALUES=["pending","in_progress","completed","blocked","skipped","superseded"],PLAN_HARNESS_VALUES=["codex","claude-code","cursor","generic"],PLAN_STEP_LINK_KIND_VALUES=["related","blocks","blocked_by","depends_on","discovered_from","implements","recurs_from","verifies","supersedes"],CONTEXT_DEPTH_VALUES=["brief","standard","deep","full"],CONTEXT_SECTION_VALUES=["hierarchy","activity","progress","recently_created","unparented","blockers","files","workload","staleness","tests"];export{BUILTIN_ITEM_TYPE_VALUES,CONFIDENCE_TEXT_VALUES,CONTEXT_DEPTH_VALUES,CONTEXT_SECTION_VALUES,DEPENDENCY_KIND_VALUES,GOVERNANCE_CLOSE_VALIDATION_DEFAULT_VALUES,GOVERNANCE_CREATE_MODE_DEFAULT_VALUES,GOVERNANCE_DUPLICATE_DETECTION_MODE_VALUES,GOVERNANCE_OWNERSHIP_ENFORCEMENT_VALUES,GOVERNANCE_PRESET_VALUES,GOVERNANCE_WORKFLOW_ENFORCEMENT_VALUES,ISSUE_SEVERITY_VALUES,ITEM_FORMAT_VALUES,ITEM_TYPE_VALUES,PARENT_REFERENCE_POLICY_VALUES,PLAN_HARNESS_VALUES,PLAN_MODE_VALUES,PLAN_STEP_LINK_KIND_VALUES,PLAN_STEP_STATUS_VALUES,RECURRENCE_FREQUENCY_VALUES,RECURRENCE_WEEKDAY_VALUES,RISK_VALUES,RUNTIME_FIELD_COMMAND_VALUES,RUNTIME_FIELD_TYPE_VALUES,RUNTIME_STATUS_ROLE_VALUES,RUNTIME_UNKNOWN_FIELD_POLICY_VALUES,SCOPE_VALUES,SPRINT_RELEASE_FORMAT_POLICY_VALUES,STATUS_VALUES,VALIDATE_METADATA_PROFILE_VALUES,VALIDATE_METADATA_REQUIRED_FIELD_VALUES,weekdayOrderIndex};
2
2
  //# sourceMappingURL=types.js.map
@@ -109,8 +109,9 @@ pm close <item-id> "Acceptance criteria met; verification passed." --resolution
109
109
  pm release <item-id>
110
110
  ```
111
111
 
112
- If a warning close omitted evidence, use its `recovery.suggested_retry_args`
113
- to append an evidence update while preserving the original close event. See
112
+ If a successful warning close omitted evidence, use its `follow_up.suggested_command_args`
113
+ to append an evidence update while preserving the original close event. Failed closes
114
+ retain `recovery.suggested_retry_args`. See
114
115
  [Close Evidence Recovery](CLOSE_EVIDENCE_RECOVERY.md).
115
116
 
116
117
  For real subprocess tests, set `cwd`, `PM_PATH`, and `PM_GLOBAL_PATH` to the
@@ -180,6 +181,10 @@ Over MCP the mutation tools (`pm_create`/`pm_update`/`pm_append`/`pm_close`, and
180
181
 
181
182
  `pm create --parent <id>` fails fast when the parent cannot be found. Use `--allow-missing-parent` only for deliberate imports or staged backlog reconstruction.
182
183
 
184
+ To record many items at once (triage imports, review-thread capture, plan expansion), do not loop `pm create`: write one record per line and commit them in one workspace transaction with `pm item mutate --from items.jsonl --json` (`--dry-run` first). Records use `pm create` field names, `@row-<n>`/`@ref` references link records to each other, and `--upsert-key <field>` turns records that match an existing item into updates. `pm create many` refuses with this route.
185
+
186
+ The default transaction id derives from the exact document bytes, so even a formatting-only edit selects a new id. To replay a committed import, reuse its transaction id and keep the resolved mutation plan unchanged. For formatting-only edits, pass the original id explicitly with `--transaction-id <id>`; replay still requires the same resolved plan. See [Bulk creation](COMMANDS.md#bulk-creation-pm-create-many-route).
187
+
183
188
  ## Guide Routing for Agents
184
189
 
185
190
  Use the canonical [guide topic map](README.md#guide-topic-map) when local in-CLI documentation routing is useful.
@@ -187,10 +192,34 @@ Use the canonical [guide topic map](README.md#guide-topic-map) when local in-CLI
187
192
  ## Ownership Rules
188
193
 
189
194
  - Claim before heavy edits.
190
- - `pm claim <id>` can take over non-terminal work from another owner.
191
- - Use `--force` only for explicit override paths.
195
+ - `pm claim <id>` is an atomic test-and-set. A non-terminal item already held by a different principal refuses with `already_claimed_by`; the same principal re-claiming is a no-op.
196
+ - Pass `--if-available` to treat a held item as a skip (`skipped: true`, exit 0) instead of a failure, for example when several agents pull from one queue. The terminal check runs first, so a terminal item still refuses without `--force` even when `--if-available` is set.
197
+ - Use `--force` only for a coordinated takeover of another owner's claim; it is also required to claim terminal items, and to override stale locks when the `governance.force_required_for_stale_lock` policy is enabled (the `minimal` and custom governance presets can disable it). Never force a takeover without explicit approval.
192
198
  - Release when pausing, handing off, or after close.
193
199
 
200
+ ### Implementation-to-verification handoff
201
+
202
+ Tracked by [pm-gh1465](../.agents/pm/features/pm-gh1465.toon).
203
+ Projects define their own queues using the existing schema primitives:
204
+
205
+ ```bash
206
+ pm schema add-status review --role active --description "Implementation complete; awaiting verification"
207
+ pm release <item-id> --handoff review --message "Implemented X; verify with the linked regression"
208
+ pm list --status review
209
+ ```
210
+
211
+ Handoff requires a claimed, non-terminal item and an evidence message. It changes
212
+ the status and releases ownership in one history event, preserving workflow
213
+ transition and approval policies. It cannot be combined with `--pause` or target
214
+ the configured in-progress or a terminal status. The result includes `handoff`
215
+ with the source status, destination status, and evidence message. No fixed review
216
+ state is added to projects. `pm context` retains the queue's status while counting
217
+ it separately from in-progress work; use `pm list --status review` to select the
218
+ verification queue. A verifier can claim it, close with normal evidence, or use
219
+ `pm claim <item-id> --start` when rework begins. `pm item reopen` remains for
220
+ terminal items. SDK `client.release(id, { handoff: "review", message: "..." })`
221
+ and MCP release options use the same atomic transition.
222
+
194
223
  ## Reviewed Delivery Closeout
195
224
 
196
225
  Before closing repository defects, set `escape_class` and structured