@unbrained/pm-cli 2026.8.9 → 2026.8.11

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 (249) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/CHANGELOG.md +142 -80
  3. package/dist/cli/commander-usage.js +94 -17
  4. package/dist/cli/error-guidance.d.ts +10 -0
  5. package/dist/cli/error-guidance.js +76 -25
  6. package/dist/cli/help-json-payload.js +51 -16
  7. package/dist/cli/main.js +11 -6
  8. package/dist/cli/register-assurance.d.ts +8 -0
  9. package/dist/cli/register-assurance.js +52 -0
  10. package/dist/cli/register-files-lookup.js +14 -3
  11. package/dist/cli/register-mutation.js +30 -9
  12. package/dist/cli/register-operations.js +16 -11
  13. package/dist/cli-bundle/bundle-manifest.json +163 -163
  14. package/dist/cli-bundle/chunks/{chunk-RJC7TPF4.js → chunk-2OOU2AFH.js} +2 -2
  15. package/dist/cli-bundle/chunks/chunk-2RA2YTHJ.js +33 -0
  16. package/dist/cli-bundle/chunks/chunk-A2SJGHSI.js +3 -0
  17. package/dist/cli-bundle/chunks/chunk-DSKYD4LG.js +13 -0
  18. package/dist/cli-bundle/chunks/chunk-HC3GM6YY.js +194 -0
  19. package/dist/cli-bundle/chunks/chunk-IUNRVDAI.js +2 -0
  20. package/dist/cli-bundle/chunks/chunk-W7CPZGSB.js +2 -0
  21. package/dist/cli-bundle/chunks/{chunk-YC3UF2IO.js → chunk-WMEZHCFI.js} +66 -60
  22. package/dist/cli-bundle/chunks/{chunk-GMX5YOI3.js → chunk-ZU34C3LH.js} +48 -48
  23. package/dist/cli-bundle/chunks/chunk-ZXOC6HG5.js +5 -0
  24. package/dist/cli-bundle/chunks/{register-list-query-BUE7PTCU.js → register-list-query-HAUXVUPY.js} +8 -8
  25. package/dist/cli-bundle/chunks/register-mutation-7Y5U7ABT.js +20 -0
  26. package/dist/cli-bundle/chunks/register-operations-EQX3DLAZ.js +2 -0
  27. package/dist/cli-bundle/chunks/{register-setup-UQDTNTLJ.js → register-setup-NOCOOWQY.js} +2 -2
  28. package/dist/cli-bundle/focused-chunks/{chunk-KNEHLPBF.js → chunk-23FTGO3W.js} +2 -2
  29. package/dist/cli-bundle/focused-chunks/{chunk-6DO4YQWZ.js → chunk-2DL3MRTD.js} +2 -2
  30. package/dist/cli-bundle/focused-chunks/chunk-3AYKXMYX.js +2 -0
  31. package/dist/cli-bundle/focused-chunks/chunk-4AHEC74N.js +2 -0
  32. package/dist/cli-bundle/focused-chunks/{chunk-MRWVJ3ZG.js → chunk-4H5IA6AV.js} +2 -2
  33. package/dist/cli-bundle/focused-chunks/chunk-4SV3ZKG3.js +16 -0
  34. package/dist/cli-bundle/focused-chunks/chunk-55BIB6DV.js +2 -0
  35. package/dist/cli-bundle/focused-chunks/chunk-6JW6Z2P5.js +8 -0
  36. package/dist/cli-bundle/focused-chunks/chunk-BKPIY34S.js +2 -0
  37. package/dist/cli-bundle/focused-chunks/chunk-D4PIWE6D.js +2 -0
  38. package/dist/cli-bundle/focused-chunks/chunk-DPO7TEFX.js +31 -0
  39. package/dist/cli-bundle/focused-chunks/{chunk-3WVHTUAW.js → chunk-E3KCL7AY.js} +2 -2
  40. package/dist/cli-bundle/focused-chunks/chunk-ERAAFLPS.js +153 -0
  41. package/dist/cli-bundle/focused-chunks/chunk-F6E4JZKG.js +2 -0
  42. package/dist/cli-bundle/focused-chunks/chunk-FPSYO5ZG.js +18 -0
  43. package/dist/cli-bundle/focused-chunks/{chunk-73FIJONU.js → chunk-J5EKAIVD.js} +2 -2
  44. package/dist/cli-bundle/focused-chunks/chunk-KDH5OX3D.js +4 -0
  45. package/dist/cli-bundle/focused-chunks/chunk-OJ3LVVIS.js +2 -0
  46. package/dist/cli-bundle/focused-chunks/chunk-TL5M2PAY.js +3 -0
  47. package/dist/cli-bundle/focused-chunks/chunk-UDAZWT25.js +6 -0
  48. package/dist/cli-bundle/focused-chunks/chunk-VABB4L5Y.js +17 -0
  49. package/dist/cli-bundle/main.js +13 -13
  50. package/dist/cli-bundle/sdk-authoring.js +1 -1
  51. package/dist/cli-bundle/sdk-contracts.js +1 -1
  52. package/dist/cli-bundle/sdk-core.js +41 -39
  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 +1 -1
  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 +2 -2
  60. package/dist/core/diagnostics/remediation.js +9 -9
  61. package/dist/core/fs/fs-utils.d.ts +10 -0
  62. package/dist/core/fs/fs-utils.js +16 -4
  63. package/dist/core/item/item-format.js +3 -32
  64. package/dist/core/schema/fields-file.d.ts +1 -2
  65. package/dist/core/schema/fields-file.js +4 -11
  66. package/dist/core/schema/runtime-schema.js +3 -10
  67. package/dist/core/schema/status-defs-file.d.ts +1 -2
  68. package/dist/core/schema/status-defs-file.js +4 -32
  69. package/dist/core/schema/status-token.d.ts +2 -0
  70. package/dist/core/schema/status-token.js +32 -0
  71. package/dist/core/schema/type-workflows.d.ts +1 -2
  72. package/dist/core/schema/type-workflows.js +4 -11
  73. package/dist/core/session/session-state.d.ts +47 -0
  74. package/dist/core/session/session-state.js +207 -6
  75. package/dist/core/shared/author.d.ts +8 -2
  76. package/dist/core/shared/author.js +85 -52
  77. package/dist/core/shared/errors.d.ts +12 -0
  78. package/dist/core/shared/errors.js +2 -2
  79. package/dist/core/shared/text-normalization.d.ts +1 -1
  80. package/dist/core/shared/text-normalization.js +2 -2
  81. package/dist/sdk/agent/command-recovery.d.ts +4 -0
  82. package/dist/sdk/agent/command-recovery.js +52 -0
  83. package/dist/sdk/agent/command-suggestions.d.ts +4 -0
  84. package/dist/sdk/agent/command-suggestions.js +67 -0
  85. package/dist/sdk/agent/create-option-policy.d.ts +12 -0
  86. package/dist/sdk/agent/create-option-policy.js +32 -0
  87. package/dist/sdk/agent/item-addressing.d.ts +19 -0
  88. package/dist/sdk/agent/item-addressing.js +208 -0
  89. package/dist/sdk/agent/refusal-reachability.d.ts +40 -0
  90. package/dist/sdk/agent/refusal-reachability.js +72 -0
  91. package/dist/sdk/agent/subcommand-recovery.d.ts +40 -0
  92. package/dist/sdk/agent/subcommand-recovery.js +84 -0
  93. package/dist/sdk/cli-bootstrap.d.ts +9 -1
  94. package/dist/sdk/cli-bootstrap.js +25 -10
  95. package/dist/sdk/cli-contracts/commander-mutation-options.js +16 -4
  96. package/dist/sdk/cli-contracts/completeness.js +13 -3
  97. package/dist/sdk/cli-contracts/enum-contracts.d.ts +1 -1
  98. package/dist/sdk/cli-contracts/enum-contracts.js +3 -2
  99. package/dist/sdk/cli-contracts/flag-contracts.d.ts +2 -0
  100. package/dist/sdk/cli-contracts/flag-contracts.js +77 -21
  101. package/dist/sdk/cli-contracts/registration-helpers.js +10 -2
  102. package/dist/sdk/cli-contracts/runtime-contracts.js +6 -3
  103. package/dist/sdk/cli-contracts/schemas/assurance-definition.d.ts +513 -0
  104. package/dist/sdk/cli-contracts/schemas/assurance-definition.js +251 -0
  105. package/dist/sdk/cli-contracts/tool-option-contracts.d.ts +6 -0
  106. package/dist/sdk/cli-contracts/tool-option-contracts.js +4 -2
  107. package/dist/sdk/cli-contracts/tool-parameter-tables.js +96 -4
  108. package/dist/sdk/cli-contracts/tool-schema.d.ts +2 -2
  109. package/dist/sdk/cli-contracts/tool-schema.js +49 -6
  110. package/dist/sdk/cli-contracts.d.ts +1 -1
  111. package/dist/sdk/cli-contracts.js +3 -3
  112. package/dist/sdk/completion.js +9 -3
  113. package/dist/sdk/config.js +9 -3
  114. package/dist/sdk/context/semantic-session-attribution.d.ts +32 -0
  115. package/dist/sdk/context/semantic-session-attribution.js +83 -0
  116. package/dist/sdk/context-intent-runtime.js +8 -5
  117. package/dist/sdk/context-signal-store.d.ts +34 -0
  118. package/dist/sdk/context-signal-store.js +24 -2
  119. package/dist/sdk/core-governance.d.ts +3 -1
  120. package/dist/sdk/core-governance.js +5 -3
  121. package/dist/sdk/core.d.ts +1 -1
  122. package/dist/sdk/core.js +2 -2
  123. package/dist/sdk/dependency-flag-validation.d.ts +15 -1
  124. package/dist/sdk/dependency-flag-validation.js +54 -2
  125. package/dist/sdk/error-code-catalog.d.ts +13 -0
  126. package/dist/sdk/error-code-catalog.js +35 -2
  127. package/dist/sdk/extension.js +18 -17
  128. package/dist/sdk/files.d.ts +11 -0
  129. package/dist/sdk/files.js +82 -24
  130. package/dist/sdk/generated-error-code-catalog.js +104 -13
  131. package/dist/sdk/governance/assurance-action-contracts.d.ts +7 -0
  132. package/dist/sdk/governance/assurance-action-contracts.js +5 -0
  133. package/dist/sdk/governance/assurance-action.d.ts +70 -0
  134. package/dist/sdk/governance/assurance-action.js +198 -0
  135. package/dist/sdk/governance/assurance-limits.d.ts +7 -0
  136. package/dist/sdk/governance/assurance-limits.js +11 -0
  137. package/dist/sdk/governance/assurance-runtime.d.ts +20 -0
  138. package/dist/sdk/governance/assurance-runtime.js +131 -0
  139. package/dist/sdk/governance/assurance.d.ts +432 -0
  140. package/dist/sdk/governance/assurance.js +689 -0
  141. package/dist/sdk/governance/health.js +14 -7
  142. package/dist/sdk/governance/provenance-health.d.ts +13 -0
  143. package/dist/sdk/governance/provenance-health.js +63 -17
  144. package/dist/sdk/governance/validate-item-reader.d.ts +13 -0
  145. package/dist/sdk/governance/validate-item-reader.js +18 -0
  146. package/dist/sdk/governance/validate.d.ts +2 -2
  147. package/dist/sdk/governance/validate.js +15 -6
  148. package/dist/sdk/graph/run.js +8 -3
  149. package/dist/sdk/index.d.ts +10 -1
  150. package/dist/sdk/index.js +12 -3
  151. package/dist/sdk/lifecycle/claim.js +18 -3
  152. package/dist/sdk/lifecycle/close.js +17 -14
  153. package/dist/sdk/lifecycle/create.d.ts +2 -0
  154. package/dist/sdk/lifecycle/create.js +62 -9
  155. package/dist/sdk/lifecycle/focus.js +13 -3
  156. package/dist/sdk/lifecycle/plan.js +8 -3
  157. package/dist/sdk/lifecycle/update-many.js +39 -27
  158. package/dist/sdk/lifecycle/update.d.ts +6 -1
  159. package/dist/sdk/lifecycle/update.js +47 -10
  160. package/dist/sdk/merge/index.d.ts +1 -1
  161. package/dist/sdk/merge/index.js +3 -3
  162. package/dist/sdk/merge/install.d.ts +4 -0
  163. package/dist/sdk/merge/install.js +28 -16
  164. package/dist/sdk/merge/receipts.d.ts +3 -0
  165. package/dist/sdk/merge/receipts.js +81 -17
  166. package/dist/sdk/output-projection.js +24 -4
  167. package/dist/sdk/provenance.d.ts +38 -0
  168. package/dist/sdk/provenance.js +64 -2
  169. package/dist/sdk/query/context.d.ts +2 -0
  170. package/dist/sdk/query/context.js +24 -10
  171. package/dist/sdk/query/light-metadata.d.ts +3 -0
  172. package/dist/sdk/query/light-metadata.js +19 -0
  173. package/dist/sdk/runtime-extended-actions.js +22 -5
  174. package/dist/sdk/runtime-primitives.d.ts +2 -0
  175. package/dist/sdk/runtime-primitives.js +4 -2
  176. package/dist/sdk/runtime.d.ts +8 -1
  177. package/dist/sdk/runtime.js +37 -28
  178. package/dist/sdk/schema-migration.js +7 -9
  179. package/dist/sdk/similarity-scoring.d.ts +1 -2
  180. package/dist/sdk/similarity-scoring.js +4 -16
  181. package/dist/sdk/telemetry.js +7 -4
  182. package/dist/sdk/traceability/runtime-files-lookup.d.ts +8 -0
  183. package/dist/sdk/traceability/runtime-files-lookup.js +33 -0
  184. package/dist/sdk/traceability/source-traceability.d.ts +102 -0
  185. package/dist/sdk/traceability/source-traceability.js +293 -0
  186. package/dist/sdk/workspace-snapshot.d.ts +4 -0
  187. package/dist/sdk/workspace-snapshot.js +24 -11
  188. package/dist/types.d.ts +8 -2
  189. package/dist/types.js +2 -2
  190. package/docs/AGENT_GUIDE.md +3 -1
  191. package/docs/ASSURANCE.md +132 -0
  192. package/docs/COMMANDS.md +8 -5
  193. package/docs/MERGE_SAFETY.md +7 -5
  194. package/docs/README.md +3 -5
  195. package/docs/READ_OUTPUT_CONTRACTS.md +2 -2
  196. package/docs/RELEASING.md +9 -5
  197. package/docs/SDK.md +44 -8
  198. package/docs/SDK_AGENT_SESSION_CONTEXT.md +43 -6
  199. package/docs/SDK_CONTEXT.md +97 -0
  200. package/docs/SDK_CONTEXT_INTEGRITY.md +18 -3
  201. package/docs/SDK_EVIDENCE_TRACEABILITY.md +39 -1
  202. package/docs/SDK_RUNTIME_BOUNDARIES.md +36 -1
  203. package/docs/TESTING.md +12 -9
  204. package/docs/agent-task-token-baseline.json +2 -2
  205. package/docs/generated/AGENT_COMMAND_SURFACE.md +1 -0
  206. package/marketplace.json +2 -2
  207. package/package.json +7 -6
  208. package/packages/pm-beads/package.json +1 -1
  209. package/packages/pm-calendar/package.json +1 -1
  210. package/packages/pm-command-kit/package.json +1 -1
  211. package/packages/pm-digital-twin/package.json +1 -1
  212. package/packages/pm-governance-audit/package.json +1 -1
  213. package/packages/pm-guide-shell/package.json +1 -1
  214. package/packages/pm-kanban/package.json +1 -1
  215. package/packages/pm-lifecycle-hooks/package.json +1 -1
  216. package/packages/pm-linked-test-adapters/package.json +1 -1
  217. package/packages/pm-search-advanced/package.json +1 -1
  218. package/packages/pm-templates/extensions/templates/index.ts +9 -3
  219. package/packages/pm-templates/package.json +1 -1
  220. package/packages/pm-todos/package.json +1 -1
  221. package/packages/pm-vcs/package.json +1 -1
  222. package/plugins/pm-claude/.claude-plugin/plugin.json +1 -1
  223. package/plugins/pm-codex/.codex-plugin/plugin.json +1 -1
  224. package/sdk/public-surface.json +1028 -48
  225. package/dist/cli-bundle/chunks/chunk-2DTCZXSD.js +0 -13
  226. package/dist/cli-bundle/chunks/chunk-5JO6R4BS.js +0 -3
  227. package/dist/cli-bundle/chunks/chunk-5KN4DZYV.js +0 -194
  228. package/dist/cli-bundle/chunks/chunk-EF43KODO.js +0 -2
  229. package/dist/cli-bundle/chunks/chunk-HUV2Z7IS.js +0 -28
  230. package/dist/cli-bundle/chunks/chunk-MHBVCUF2.js +0 -2
  231. package/dist/cli-bundle/chunks/chunk-PYO5GZU6.js +0 -5
  232. package/dist/cli-bundle/chunks/register-mutation-FC3XLVIK.js +0 -20
  233. package/dist/cli-bundle/chunks/register-operations-YH2WAOXU.js +0 -2
  234. package/dist/cli-bundle/focused-chunks/chunk-2VVP5RAA.js +0 -153
  235. package/dist/cli-bundle/focused-chunks/chunk-3GSFUDAI.js +0 -2
  236. package/dist/cli-bundle/focused-chunks/chunk-4H6MVCK3.js +0 -16
  237. package/dist/cli-bundle/focused-chunks/chunk-54TZJ4BM.js +0 -2
  238. package/dist/cli-bundle/focused-chunks/chunk-5NK5TJ5D.js +0 -2
  239. package/dist/cli-bundle/focused-chunks/chunk-C3GCHDSQ.js +0 -31
  240. package/dist/cli-bundle/focused-chunks/chunk-JGRSQZJT.js +0 -18
  241. package/dist/cli-bundle/focused-chunks/chunk-NL57J7BZ.js +0 -4
  242. package/dist/cli-bundle/focused-chunks/chunk-P6BBIQRG.js +0 -6
  243. package/dist/cli-bundle/focused-chunks/chunk-PZAGVQNN.js +0 -3
  244. package/dist/cli-bundle/focused-chunks/chunk-QDAO3XEK.js +0 -14
  245. package/dist/cli-bundle/focused-chunks/chunk-T4IGQCSY.js +0 -2
  246. package/dist/cli-bundle/focused-chunks/chunk-U46GQJNY.js +0 -2
  247. package/dist/cli-bundle/focused-chunks/chunk-VRXJSGIT.js +0 -8
  248. package/dist/cli-bundle/focused-chunks/chunk-XC2ZW3CJ.js +0 -2
  249. package/dist/cli-bundle/focused-chunks/chunk-ZG54B4XG.js +0 -2
@@ -4,9 +4,9 @@
4
4
  * Implements the pm close command surface and its agent-facing runtime behavior.
5
5
  */
6
6
 
7
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="6e39a90e-8a26-5789-9de6-288900b6b418")}catch(e){}}();
7
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="83affe54-a56c-5d84-b6b0-9634d4238ff5")}catch(e){}}();
8
8
  import { pathExists, toItemRecord, isTerminalStatus, resolveItemTypeRegistry, resolveRuntimeStatusRegistry, EXIT_CODE, PmCliError, buildItemNotFoundError, listAllItemMetadataLight, locateItem, mutateItem, readLocatedItem, getSettingsPath, resolvePmRoot, readSettings, resolveAuthor, resolveIsoOrRelative, shouldCompletePlanOnClose, getActiveExtensionRegistrations, } from "../runtime-primitives.js";
9
- import { collectBlockedByIds, indexBlockedByIds, } from "../actionability.js";
9
+ import { collectBlockedByIds, indexBlockedByIds } from "../actionability.js";
10
10
  import { applyTerminalOrderingPolicy, requireTerminalReason, } from "../lifecycle-policy.js";
11
11
  import { renderPmCommand } from "../command-line.js";
12
12
  const CLOSE_VALIDATION_FIELDS = [
@@ -40,7 +40,7 @@ function findMissingCloseValidationFields(itemMetadata) {
40
40
  for (const field of CLOSE_VALIDATION_FIELDS) {
41
41
  const rawValue = itemMetadata[field.key];
42
42
  if (typeof rawValue !== "string" || rawValue.trim().length === 0) {
43
- missing.push(field.label);
43
+ missing.push(field);
44
44
  }
45
45
  }
46
46
  return missing;
@@ -259,32 +259,34 @@ function applyDuplicateCloseMetadata(metadata, duplicateOf) {
259
259
  }
260
260
  return duplicateFallbackFields;
261
261
  }
262
- function collectCloseValidationWarnings(metadata, validateCloseMode, activeChildIds, closeReason) {
262
+ function collectCloseValidationWarnings(metadata, validateCloseMode, activeChildIds, pmRoot) {
263
263
  const warnings = [];
264
264
  if (validateCloseMode !== "off") {
265
265
  const missingFields = findMissingCloseValidationFields(metadata);
266
266
  if (missingFields.length > 0) {
267
+ const missingLabels = missingFields.map((field) => field.label);
267
268
  if (validateCloseMode === "strict") {
268
- const missingFlags = missingFields.map((field) => `--${field.replaceAll("_", "-")}`);
269
- const retryTokens = [
270
- "close",
269
+ const missingFlags = missingFields.map((field) => `--${field.key.replaceAll("_", "-")}`);
270
+ const updateTokens = [
271
+ "--pm-path",
272
+ pmRoot,
273
+ "update",
271
274
  metadata.id,
272
- closeReason ?? "<reason>",
273
275
  ...missingFlags.flatMap((flag) => [flag, "<value>"]),
274
276
  ];
275
- throw new PmCliError(`Cannot close item ${metadata.id}: missing ${missingFields.join(", ")}. Populate fields or use --validate-close warn.`, EXIT_CODE.USAGE, {
277
+ throw new PmCliError(`Cannot close item ${metadata.id}: missing ${missingLabels.join(", ")}. Populate fields or use --validate-close warn.`, EXIT_CODE.USAGE, {
276
278
  code: "close_validation_missing_fields",
277
279
  recovery: {
278
280
  missing: missingFlags,
279
- suggested_retry: renderPmCommand(retryTokens),
281
+ suggested_retry: renderPmCommand(updateTokens),
280
282
  },
281
283
  nextSteps: [
282
- "Use pm close with the missing closure fields populated.",
284
+ "Run the suggested pm update, then retry the original pm close invocation.",
283
285
  "Use --validate-close warn only when governance permits an evidenced exception.",
284
286
  ],
285
287
  });
286
288
  }
287
- warnings.push(`close_validation_missing_fields:${metadata.id}:${missingFields.join(",")}`);
289
+ warnings.push(`close_validation_missing_fields:${metadata.id}:${missingLabels.join(",")}`);
288
290
  }
289
291
  if (activeChildIds.length > 0) {
290
292
  if (validateCloseMode === "strict") {
@@ -320,7 +322,7 @@ function mutateCloseMetadata(metadata, context) {
320
322
  }
321
323
  const inlineChangedFields = applyInlineCloseFields(metadata, context.options);
322
324
  const duplicateFallbackFields = applyDuplicateCloseMetadata(metadata, context.duplicateOf);
323
- const mutationWarnings = collectCloseValidationWarnings(metadata, context.validateCloseMode, context.activeChildIds, context.closeReason);
325
+ const mutationWarnings = collectCloseValidationWarnings(metadata, context.validateCloseMode, context.activeChildIds, context.pmRoot);
324
326
  metadata.status = context.statusRegistry.close_status;
325
327
  metadata.closed_at = context.closedAt;
326
328
  const shouldWriteCompletedAt = context.options.completedAt !== undefined ||
@@ -428,6 +430,7 @@ export async function closeItem(id, closeReasonText, options, global) {
428
430
  force: options.force,
429
431
  mutate(document) {
430
432
  return mutateCloseMetadata(document.metadata, {
433
+ pmRoot,
431
434
  statusRegistry,
432
435
  force: options.force,
433
436
  options,
@@ -455,4 +458,4 @@ export function runClose(id, closeReasonText, options, global) {
455
458
  return closeItem(id, closeReasonText, options, global);
456
459
  }
457
460
  //# sourceMappingURL=close.js.map
458
- //# debugId=6e39a90e-8a26-5789-9de6-288900b6b418
461
+ //# debugId=83affe54-a56c-5d84-b6b0-9634d4238ff5
@@ -34,6 +34,8 @@ export interface CreateCommandOptions extends MutationMetadataCommandOptions, Sh
34
34
  body?: string;
35
35
  /** Value that configures or reports allow missing parent for this contract. */
36
36
  allowMissingParent?: boolean;
37
+ /** Explicitly permit unresolved local dependency targets with warning receipts. */
38
+ allowUnresolvedDeps?: boolean;
37
39
  /** Value that configures or reports template for this contract. */
38
40
  template?: string;
39
41
  /** Creates mode using the validated operation inputs. */
@@ -4,7 +4,7 @@
4
4
  * Implements the pm create command surface and its agent-facing runtime behavior.
5
5
  */
6
6
 
7
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="af455a7c-354f-54be-99e0-833c9f2710c5")}catch(e){}}();
7
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="ffa56c1a-d98c-566a-81c5-4ad5608aa26c")}catch(e){}}();
8
8
  import { pathExists, removeFileIfExists, writeFileAtomic, appendHistoryEntry, createHistoryEntry, generateItemId, normalizeItemId, canonicalDocument, normalizeItemMetadata, serializeItemDocument, assertParentReferenceIsNotSelf, isPlaceholderReferenceToken, normalizeParentReferenceValue, validateMissingParentReference, validateSprintOrReleaseValue, assertNoUnknownCsvKeys, createStdinTokenResolver, looksLikeGenericKeyValueEntry, mergeAdditiveTags, parseCsvKv, parseOptionalNonNegativeInteger, parseOptionalNumber, parseTags, resolvePriority, getFocusedItem, normalizeStatusInput, canonicalizeCommandOptionKey, commandOptionFlagLabel, resolveItemTypeRegistry, resolveCommandOptionPolicyState, resolveTypeDefinition, resolveTypeName, validateTypeOptions, acquireLock, printError, buildInvalidTypeError, resolveTypeSynonym, collectRuntimeCreateFieldValues, resolveItemTypesFilePath, resolveRuntimeFieldRegistry, resolveRuntimeStatusRegistry, EXIT_CODE, ITEM_METADATA_KEY_ORDER, PmCliError, nowIso, resolveIsoOrRelative, getActiveExtensionRegistrations, projectAfterCommandItemSnapshot, recordAfterCommandAffectedItem, runActiveCommandHandler, runActiveBeforeMutationHooks, runActiveOnWriteHooks, collectRegisteredItemFieldNames, applyRegisteredItemFieldDefaultsAndValidation, parseRegisteredItemFieldAssignments, listAllItemMetadataLight, locateItem, createMutationGuardSdk, getHistoryPath, getItemPath, getSettingsPath, resolvePmRoot, readSettings, resolveAuthor, } from "../runtime-primitives.js";
9
9
  import { requireTerminalReasonWithRecovery } from "../lifecycle-policy.js";
10
10
  import { evaluateSimilarityGovernance, similarityAdvisoryWarnings, } from "../similarity.js";
@@ -17,9 +17,10 @@ import { parseLinkedTestAssertionEqualsMap, parseLinkedTestAssertionGteMap, pars
17
17
  import { looksLikeStructuredLinkedTestEntry, normalizeStructuredLinkedTestEntry, } from "../test/entry.js";
18
18
  import { COMMON_UNSET_FIELD_DEFINITIONS_AFTER_AUTHOR, COMMON_UNSET_FIELD_DEFINITIONS_BEFORE_AUTHOR, parseCommandUnsetTargets, resolveRuntimeUnsetFieldDefinition, } from "./shared-unset-fields.js";
19
19
  import { ensureEnumValue } from "./recurrence-parsers.js";
20
- import { assertDependencyEdgesAllowed, assertValidBareDependencyFlagValue, } from "../dependency-flag-validation.js";
20
+ import { assertDependencyEdgesAllowed, assertDependencyTargetsResolvable, assertValidBareDependencyFlagValue, } from "../dependency-flag-validation.js";
21
21
  import { normalizeDependencySeedId, normalizeDependencySourceKind, } from "../dependency-provenance.js";
22
22
  import { resolveCanonicalRelationshipKind } from "../relationships.js";
23
+ import { supportsCreateExplicitEmpty } from "../agent/create-option-policy.js";
23
24
  import { parseEventEntries, parseReminderEntries, parseTypeOptionEntries, } from "./repeatable-metadata-parsers.js";
24
25
  import { DEPENDENCY_KIND_VALUES, ISSUE_SEVERITY_VALUES, RISK_VALUES, SCOPE_VALUES, } from "../../types/index.js";
25
26
  const CREATE_MODE_VALUES = ["strict", "progressive"];
@@ -515,7 +516,7 @@ function assertNoStrictRequiredOptionClears(requiredOptions, createMode, clearOp
515
516
  if (createMode !== "strict") {
516
517
  return;
517
518
  }
518
- const strictRequiredClears = requiredOptions.filter((required) => clearOptionKeys.has(required));
519
+ const strictRequiredClears = requiredOptions.filter((required) => clearOptionKeys.has(required) && !supportsCreateExplicitEmpty(required));
519
520
  if (strictRequiredClears.length === 0) {
520
521
  return;
521
522
  }
@@ -613,6 +614,10 @@ function requireCreateOptionByType(typeDefinition, options, createMode, clearOpt
613
614
  if (optionKey === "status" && typeDefinition.default_status !== undefined) {
614
615
  return true;
615
616
  }
617
+ if (clearOptionKeys.has(optionKey) &&
618
+ supportsCreateExplicitEmpty(optionKey)) {
619
+ return true;
620
+ }
616
621
  return hasCreateOptionValue(optionLookup, optionKey);
617
622
  };
618
623
  const missingRequiredOptions = policyState.required.filter((required) => !satisfiesRequiredOption(required));
@@ -1030,6 +1035,7 @@ function collectTemplateCustomTypeOptions(typeDefinition, resolvedOptions) {
1030
1035
  /** Resolve the target item type and creation mode for `pm create`: merge any `--template` options, apply the governance default-type fallback, map a near-miss `--type` to its canonical synonym (never blocking), and derive the schedule preset and effective create mode. Returns the (possibly template-merged) options alongside the resolved type definition, canonical type name, schedule preset, and create mode. */
1031
1036
  async function resolveCreateTypeSelection(options, global, pmRoot, settings, typeRegistry) {
1032
1037
  let resolvedOptions = options;
1038
+ const warnings = [];
1033
1039
  if (resolvedOptions.template !== undefined) {
1034
1040
  const templateName = resolvedOptions.template.trim();
1035
1041
  if (templateName.length === 0) {
@@ -1056,7 +1062,7 @@ async function resolveCreateTypeSelection(options, global, pmRoot, settings, typ
1056
1062
  ? resolveTypeName(synonymCanonical, typeRegistry)
1057
1063
  : undefined;
1058
1064
  if (synonymResolved) {
1059
- printError(`[pm] note: type '${resolvedOptions.type.trim()}' is not defined; using closest match '${synonymResolved}'. Run 'pm schema add-type "${resolvedOptions.type.trim()}"' to track it as a distinct type.`);
1065
+ warnings.push(`type_coercion:${resolvedOptions.type.trim()}:${synonymResolved}`);
1060
1066
  resolvedOptions.type = synonymResolved;
1061
1067
  resolvedTypeName = synonymResolved;
1062
1068
  }
@@ -1089,7 +1095,14 @@ async function resolveCreateTypeSelection(options, global, pmRoot, settings, typ
1089
1095
  throw new PmCliError(`--schedule-preset ${schedulePreset} is only supported for Reminder, Meeting, or Event types`, EXIT_CODE.USAGE);
1090
1096
  }
1091
1097
  const createMode = resolveEffectiveCreateMode(resolvedOptions.createMode, schedulePreset, settings.governance.create_mode_default);
1092
- return { resolvedOptions, typeDefinition, type, schedulePreset, createMode };
1098
+ return {
1099
+ resolvedOptions,
1100
+ typeDefinition,
1101
+ type,
1102
+ schedulePreset,
1103
+ createMode,
1104
+ warnings,
1105
+ };
1093
1106
  }
1094
1107
  /** Seed the explicit-unset and clear-option key sets from the parsed `--unset` targets, then fold in each enabled `--clear-<collection>` flag: it marks the collection's item-metadata key as explicitly unset and its option key as cleared, and rejects combining a clear flag with its own value flag. Returns the augmented sets used downstream for required-flag relaxation and history messaging. */
1095
1108
  function collectCreateClearTargets(resolvedOptions, unsetTargets) {
@@ -1310,11 +1323,31 @@ function assertNoCreateFieldUnsetConflicts(registeredItemFieldValues, runtimeCre
1310
1323
  }
1311
1324
  /** Throw the aggregated `missing_required_option` error when a type's required create options and/or required type-option keys were not all supplied in one invocation. Builds a type-aware valid example and staged-onboarding next steps (a strict-mode invocation also carries a compact recovery envelope). A no-op when nothing is missing. */
1312
1325
  function assertNoMissingRequiredCreateOptions(params) {
1313
- const { combinedMissingFlags, typeDefinition, missingRequiredCreateFlags, missingRequiredTypeOptionKeys, openStatus, type, createMode, } = params;
1326
+ const { combinedMissingFlags, typeDefinition, missingRequiredCreateFlags, missingRequiredTypeOptionKeys, openStatus, type, createMode, missingRequiredRuntimeFields, } = params;
1314
1327
  if (combinedMissingFlags.length === 0) {
1315
1328
  return;
1316
1329
  }
1317
- const nextValidExample = buildTypeSpecificCreateExample(typeDefinition, missingRequiredCreateFlags, missingRequiredTypeOptionKeys, openStatus);
1330
+ const runtimeFieldSyntax = missingRequiredRuntimeFields.map((field) => {
1331
+ const placeholder = field.type === "boolean"
1332
+ ? "<true|false>"
1333
+ : field.type === "array"
1334
+ ? "<json-array>"
1335
+ : field.type === "object"
1336
+ ? "<json-object>"
1337
+ : field.type === "number"
1338
+ ? "<number>"
1339
+ : field.type === "string_array" || field.repeatable
1340
+ ? "<value>"
1341
+ : "<string>";
1342
+ return {
1343
+ example: `--${field.cli_flag} ${placeholder}`,
1344
+ description: `--${field.cli_flag} maps to ${field.metadata_key} (${field.type}${field.repeatable ? ", repeatable" : ""})`,
1345
+ };
1346
+ });
1347
+ const nextValidExample = [
1348
+ buildTypeSpecificCreateExample(typeDefinition, missingRequiredCreateFlags, missingRequiredTypeOptionKeys, openStatus),
1349
+ ...runtimeFieldSyntax.map((field) => field.example),
1350
+ ].join(" ");
1318
1351
  const nextSteps = [
1319
1352
  `Run "pm create --help --type ${type}" for type-aware required option guidance.`,
1320
1353
  ];
@@ -1329,6 +1362,9 @@ function assertNoMissingRequiredCreateOptions(params) {
1329
1362
  nextSteps.push('For minimal scheduling inputs, try "--schedule-preset lightweight".');
1330
1363
  }
1331
1364
  }
1365
+ if (runtimeFieldSyntax.length > 0) {
1366
+ nextSteps.push(`Required custom field formats: ${runtimeFieldSyntax.map((field) => field.description).join("; ")}.`);
1367
+ }
1332
1368
  const errorMessage = combinedMissingFlags.length === 1
1333
1369
  ? `Missing required option ${combinedMissingFlags[0]} for type "${type}"`
1334
1370
  : `Missing required options ${combinedMissingFlags.join(", ")} for type "${type}"`;
@@ -1553,6 +1589,8 @@ export async function runCreate(options, global) {
1553
1589
  const extensionFieldNames = collectRegisteredItemFieldNames(extensionRegistrations);
1554
1590
  const registeredItemFieldValues = parseRegisteredItemFieldAssignments(resolvedOptions.field, extensionRegistrations);
1555
1591
  const runtimeCreateFieldValues = collectRuntimeCreateFieldValues(resolvedOptions, runtimeFieldRegistry, type);
1592
+ const missingRequiredRuntimeFlagSet = new Set(runtimeCreateFieldValues.missing_required_flags);
1593
+ const missingRequiredRuntimeFields = runtimeFieldRegistry.definitions.filter((field) => missingRequiredRuntimeFlagSet.has(`--${field.cli_flag}`));
1556
1594
  assertNoCreateFieldUnsetConflicts(registeredItemFieldValues, runtimeCreateFieldValues, unsetTargets);
1557
1595
  const missingRequiredTypeOptionKeys = collectMissingRequiredTypeOptionKeys(validatedTypeOptions.errors, type);
1558
1596
  const missingRequiredTypeOptionFlags = missingRequiredTypeOptionKeys.map((key) => `--type-option ${key}=<value>`);
@@ -1572,6 +1610,7 @@ export async function runCreate(options, global) {
1572
1610
  openStatus: statusRegistry.open_status,
1573
1611
  type,
1574
1612
  createMode,
1613
+ missingRequiredRuntimeFields,
1575
1614
  });
1576
1615
  assertNoInvalidTypeOptions(validatedTypeOptions.errors, type, typeDefinition, statusRegistry);
1577
1616
  const id = await resolveCreateItemId({
@@ -1619,7 +1658,10 @@ export async function runCreate(options, global) {
1619
1658
  ? "warn"
1620
1659
  : settings.validation.parent_reference;
1621
1660
  const sprintReleasePolicy = settings.validation.sprint_release_format;
1622
- const validationWarnings = collectCreateScheduleWarnings(type, id, deadline, reminders.values, events.values);
1661
+ const validationWarnings = [
1662
+ ...typeSelection.warnings,
1663
+ ...collectCreateScheduleWarnings(type, id, deadline, reminders.values, events.values),
1664
+ ];
1623
1665
  const parentValidation = await resolveCreateParentWithWarnings({
1624
1666
  itemId: id,
1625
1667
  parent,
@@ -1651,6 +1693,14 @@ export async function runCreate(options, global) {
1651
1693
  });
1652
1694
  const dependencyValues = blockedByResolution.dependencyValues;
1653
1695
  assertDependencyEdgesAllowed(id, dependencyValues);
1696
+ validationWarnings.push(...(await assertDependencyTargetsResolvable({
1697
+ pmRoot,
1698
+ dependencies: dependencyValues,
1699
+ idPrefix: settings.id_prefix,
1700
+ itemFormat: settings.item_format,
1701
+ typeToFolder: typeRegistry.type_to_folder,
1702
+ allowUnresolved: resolvedOptions.allowUnresolvedDeps,
1703
+ })));
1654
1704
  status = blockedByResolution.status;
1655
1705
  const blockedReason = resolveUnsettableOptionalString(unsetKeys, "blocked_reason", resolvedOptions.blockedReason);
1656
1706
  const unblockNote = resolveUnsettableOptionalString(unsetKeys, "unblock_note", resolvedOptions.unblockNote);
@@ -1788,6 +1838,9 @@ export async function runCreate(options, global) {
1788
1838
  allowDuplicate: resolvedOptions.allowDuplicate,
1789
1839
  });
1790
1840
  const outputItem = structuredClone(itemMetadata);
1841
+ if (createMode === "strict" && explicitUnsets.has("dependencies")) {
1842
+ outputItem.dependencies = [];
1843
+ }
1791
1844
  // GH-216: nudge agents toward the underutilized in_progress state instead of
1792
1845
  // jumping open -> closed. Only surfaces for workable types created in the open
1793
1846
  // status when the workflow defines a distinct in_progress status to move to.
@@ -1835,4 +1888,4 @@ export const _testOnlyCreateCommand = {
1835
1888
  typeOptionExampleValue,
1836
1889
  };
1837
1890
  //# sourceMappingURL=create.js.map
1838
- //# debugId=af455a7c-354f-54be-99e0-833c9f2710c5
1891
+ //# debugId=ffa56c1a-d98c-566a-81c5-4ad5608aa26c
@@ -4,8 +4,9 @@
4
4
  * Implements the SDK-owned focus lifecycle operation shared by every surface.
5
5
  */
6
6
 
7
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="d51ebf7a-d759-5a6b-9a4f-810139a1688c")}catch(e){}}();
8
- import { pathExists, getActiveExtensionRegistrations, normalizeItemId, resolveItemTypeRegistry, EXIT_CODE, PmCliError, clearFocusedItem, getFocusedItem, setFocusedItem, buildItemNotFoundError, locateItem, readLocatedItem, getSettingsPath, resolvePmRoot, readSettings, } from "../runtime-primitives.js";
7
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="0f43df79-0b27-53b3-b8bd-9f2a35561733")}catch(e){}}();
8
+ import { pathExists, getActiveExtensionRegistrations, normalizeItemId, resolveItemTypeRegistry, EXIT_CODE, PmCliError, clearFocusedItem, getFocusedItem, setFocusedItem, buildItemNotFoundError, locateItem, readLocatedItem, getSettingsPath, resolvePmRoot, readSettings, resolveAuthor, resolveClaimPrincipal, } from "../runtime-primitives.js";
9
+ import { recordFocusSemanticAttribution } from "../context/semantic-session-attribution.js";
9
10
  async function ensureInitialized(pmRoot) {
10
11
  if (!(await pathExists(getSettingsPath(pmRoot)))) {
11
12
  throw new PmCliError(`Tracker is not initialized at ${pmRoot}. Run pm init first.`, EXIT_CODE.NOT_FOUND);
@@ -20,7 +21,10 @@ export async function runFocus(id, options, global) {
20
21
  if (id !== undefined) {
21
22
  throw new PmCliError("pm focus --clear does not take an item id. Use 'pm focus --clear' to clear focus or 'pm focus <id>' to set it.", EXIT_CODE.USAGE);
22
23
  }
24
+ const settings = await readSettings(pmRoot);
25
+ const principal = resolveClaimPrincipal(resolveAuthor(undefined, settings.author_default));
23
26
  await clearFocusedItem(pmRoot);
27
+ await recordFocusSemanticAttribution({ pmRoot, settings, principal });
24
28
  return {
25
29
  action: "clear",
26
30
  focused_item: null,
@@ -56,6 +60,12 @@ export async function runFocus(id, options, global) {
56
60
  const loaded = await readLocatedItem(located, { schema: settings.schema });
57
61
  const title = nonEmptyTitleOrNull(loaded.document.metadata.title);
58
62
  await setFocusedItem(pmRoot, normalizedId);
63
+ await recordFocusSemanticAttribution({
64
+ pmRoot,
65
+ settings,
66
+ principal: resolveClaimPrincipal(resolveAuthor(undefined, settings.author_default)),
67
+ itemId: normalizedId,
68
+ });
59
69
  return {
60
70
  action: "set",
61
71
  focused_item: normalizedId,
@@ -80,4 +90,4 @@ function nonEmptyTitleOrNull(title) {
80
90
  return title.trim().length > 0 ? title : null;
81
91
  }
82
92
  //# sourceMappingURL=focus.js.map
83
- //# debugId=d51ebf7a-d759-5a6b-9a4f-810139a1688c
93
+ //# debugId=0f43df79-0b27-53b3-b8bd-9f2a35561733
@@ -4,10 +4,11 @@
4
4
  * Implements the pm plan command surface and its agent-facing runtime behavior.
5
5
  */
6
6
 
7
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="dc87393e-61e3-5d43-a756-d5f156faf29e")}catch(e){}}();
7
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="3d5ea029-26ef-51bc-bacc-b1d4d807a024")}catch(e){}}();
8
8
  import { pathExists, getActiveExtensionRegistrations, isTerminalStatus, resolveItemTypeRegistry, resolveRuntimeStatusRegistry, resolveTypeName, EXIT_CODE, PmCliError, splitCommaList, nowIso, locateItem, mutateItem, readLocatedItem, getSettingsPath, resolvePmRoot, readSettings, resolveAuthor, isTerminalPlanMode, } from "../runtime-primitives.js";
9
9
  import { PLAN_HARNESS_VALUES, PLAN_MODE_VALUES, PLAN_STEP_LINK_KIND_VALUES, PLAN_STEP_STATUS_VALUES, } from "../../types/index.js";
10
10
  import { runCreate, } from "./create.js";
11
+ import { createUnknownSubcommandError } from "../agent/subcommand-recovery.js";
11
12
  /** Public contract for plan subcommands, shared by SDK and presentation-layer consumers. */
12
13
  export const PLAN_SUBCOMMANDS = [
13
14
  "create",
@@ -1567,7 +1568,11 @@ const PLAN_DISPATCHERS = {
1567
1568
  function resolvePlanDispatcher(subcommand) {
1568
1569
  const dispatcher = PLAN_DISPATCHERS[subcommand];
1569
1570
  if (!dispatcher) {
1570
- throw new PmCliError(`Unknown pm plan subcommand "${subcommand}"`, EXIT_CODE.USAGE);
1571
+ throw createUnknownSubcommandError({
1572
+ command_path: "plan",
1573
+ token: subcommand,
1574
+ allowed: PLAN_SUBCOMMANDS,
1575
+ });
1571
1576
  }
1572
1577
  return dispatcher;
1573
1578
  }
@@ -1582,4 +1587,4 @@ export const _testOnlyPlanCommand = {
1582
1587
  changedPlanMetadataFields,
1583
1588
  };
1584
1589
  //# sourceMappingURL=plan.js.map
1585
- //# debugId=dc87393e-61e3-5d43-a756-d5f156faf29e
1590
+ //# debugId=3d5ea029-26ef-51bc-bacc-b1d4d807a024
@@ -4,13 +4,14 @@
4
4
  * Implements the pm update many command surface and its agent-facing runtime behavior.
5
5
  */
6
6
 
7
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="67f8958d-60d5-5657-93ce-9803859acd9e")}catch(e){}}();
7
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="0f91de58-2cbc-52ba-97ea-42482d0c6ce1")}catch(e){}}();
8
8
  import { pathExists, createCheckpointId, loadMutationCheckpoint, restoreCheckpointItems, writeMutationCheckpoint, toItemRecord, applyAcceptanceCriteriaMutations, applyTagRemovals, mergeAdditiveTags, parseOptionalNonNegativeInteger, parseTags, splitAcceptanceCriteria, resolvePriority, normalizeStatusInput, resolveItemTypeRegistry, resolveTypeName, collectRuntimeUpdateFieldValues, buildInvalidTypeError, resolveItemTypesFilePath, resolveRuntimeFieldRegistry, resolveRuntimeStatusRegistry, EXIT_CODE, PmCliError, toErrorMessage, stableValueEquals, nowIso, resolveIsoOrRelative, getActiveExtensionRegistrations, getSettingsPath, resolvePmRoot, readSettings, resolveAuthor, } from "../runtime-primitives.js";
9
+ import { assertDependencyTargetsResolvable } from "../dependency-flag-validation.js";
9
10
  import { parseStatusFilterCsv } from "../../core/item/status-filter.js";
10
11
  import { hasListFilters } from "../query/list-filter-shared.js";
11
12
  import { runList, } from "../query/list.js";
12
13
  import { runRestore } from "./restore.js";
13
- import { runUpdate } from "./update.js";
14
+ import { assertUpdateMutationOptionCombinations, parseDependencyAdditions, runUpdate, } from "./update.js";
14
15
  import { derivePmBulkMutationEffect, } from "../cli-contracts/command-exit-contracts.js";
15
16
  const UPDATE_MANY_CHECKPOINT_SCHEMA_VERSION = 1;
16
17
  const UPDATE_MANY_CHECKPOINT_SUBDIR = "update-many";
@@ -20,6 +21,7 @@ const NON_MUTATION_UPDATE_OPTION_KEYS = new Set([
20
21
  "force",
21
22
  "ownershipMetadataBypass",
22
23
  "ownershipDependencyBypass",
24
+ "allowUnresolvedDeps",
23
25
  ]);
24
26
  const UPDATE_MANY_MUTATION_FLAG_GUIDANCE = [
25
27
  "--status",
@@ -379,19 +381,20 @@ const buildTagMutationPlan = (row, update) => {
379
381
  // --add-ac-only bulk update must NOT be treated as a no-op skip).
380
382
  const buildAcceptanceCriteriaMutationPlan = (row, update) => {
381
383
  const before = row.acceptance_criteria;
382
- const base = update.acceptanceCriteria === undefined
383
- ? before
384
- : String(update.acceptanceCriteria).trim();
385
- const mutation = applyAcceptanceCriteriaMutations(splitAcceptanceCriteria(base), update.addAc, update.removeAc);
386
- const warnings = mutation.unmatchedRemovals.map((criterion) => `remove_ac_unmatched:${criterion}`);
384
+ const mutation = applyAcceptanceCriteriaMutations(splitAcceptanceCriteria(before), update.addAc, update.removeAc);
385
+ if (mutation.unmatchedRemovals.length > 0) {
386
+ throw new PmCliError(`Acceptance criteria removal did not match: ${mutation.unmatchedRemovals.join(", ")}`, EXIT_CODE.NOT_FOUND, {
387
+ code: "acceptance_criteria_remove_unmatched",
388
+ reason: "exact_match_not_found",
389
+ field: "acceptance_criteria",
390
+ unmatched: mutation.unmatchedRemovals,
391
+ });
392
+ }
387
393
  const after = mutation.criteria.join("; ");
388
- if (areValuesEqual(before, after) || (before === undefined && after === "")) {
389
- return { warnings };
394
+ if (areValuesEqual(typeof before === "string" ? before : "", after)) {
395
+ return undefined;
390
396
  }
391
- return {
392
- change: { field: "acceptance_criteria", before, after },
393
- warnings,
394
- };
397
+ return { field: "acceptance_criteria", before, after };
395
398
  };
396
399
  /** Adds changed scalar options to a planned item diff. */
397
400
  const appendScalarMutationPlans = (changes, row, update) => {
@@ -431,7 +434,6 @@ const appendUnsetMutationPlans = (changes, row, unset) => {
431
434
  const buildPlannedItemDiff = (item, runtimeFieldRegistry, update = {}) => {
432
435
  const row = toItemRecord(item);
433
436
  const changes = [];
434
- const warnings = [];
435
437
  const tagPlan = buildTagMutationPlan(row, update);
436
438
  if (tagPlan) {
437
439
  changes.push(tagPlan);
@@ -439,13 +441,10 @@ const buildPlannedItemDiff = (item, runtimeFieldRegistry, update = {}) => {
439
441
  appendScalarMutationPlans(changes, row, update);
440
442
  if (updateArrayValueCount(update.addAc) > 0 ||
441
443
  updateArrayValueCount(update.removeAc) > 0) {
442
- const composed = buildAcceptanceCriteriaMutationPlan(row, update);
443
- const withoutAc = changes.filter((change) => change.field !== "acceptance_criteria");
444
- changes.splice(0, changes.length, ...withoutAc);
445
- if (composed.change !== undefined) {
446
- changes.push(composed.change);
444
+ const acceptanceCriteriaChange = buildAcceptanceCriteriaMutationPlan(row, update);
445
+ if (acceptanceCriteriaChange !== undefined) {
446
+ changes.push(acceptanceCriteriaChange);
447
447
  }
448
- warnings.push(...composed.warnings);
449
448
  }
450
449
  changes.push(...buildCollectionMutationPlans(row, update));
451
450
  appendRuntimeFieldMutationPlans(changes, row, update, runtimeFieldRegistry);
@@ -453,7 +452,6 @@ const buildPlannedItemDiff = (item, runtimeFieldRegistry, update = {}) => {
453
452
  return {
454
453
  id: item.id,
455
454
  changes,
456
- ...(warnings.length > 0 ? { warnings } : {}),
457
455
  };
458
456
  };
459
457
  /** Normalizes an optional list status against the runtime schema. */
@@ -631,7 +629,15 @@ const buildUpdateManyPlan = async (params) => {
631
629
  includeBody: true,
632
630
  full: true,
633
631
  }, params.global);
634
- const planned = listed.items.map((item) => buildPlannedItemDiff(item, params.runtime.runtimeFieldRegistry, params.options.update));
632
+ const planned = listed.items.map((item) => {
633
+ const diff = buildPlannedItemDiff(item, params.runtime.runtimeFieldRegistry, params.options.update);
634
+ return params.dependencyWarnings.length === 0
635
+ ? diff
636
+ : {
637
+ ...diff,
638
+ warnings: [...params.dependencyWarnings],
639
+ };
640
+ });
635
641
  const existenceItems = params.options.list?.ids == null
636
642
  ? []
637
643
  : (await runList(undefined, {
@@ -679,7 +685,6 @@ const buildUpdateManyNoopResult = (plan) => ({
679
685
  rows: plan.planned.map((row) => ({
680
686
  id: row.id,
681
687
  status: "skipped",
682
- ...(row.warnings ? { warnings: row.warnings } : {}),
683
688
  })),
684
689
  ids: [],
685
690
  ...buildUnmatchedIdFields(plan),
@@ -689,15 +694,12 @@ const applyUpdateManyRows = async (params) => {
689
694
  const rows = [];
690
695
  const updatedIds = [];
691
696
  const updateMessage = params.options.update.message ?? `update-many apply ${params.checkpointId}`;
692
- const plannedById = new Map(params.plans.map((row) => [row.id, row]));
693
697
  const actionableById = new Set(params.plans.filter((row) => row.changes.length > 0).map((row) => row.id));
694
698
  for (const item of params.items) {
695
699
  if (!actionableById.has(item.id)) {
696
- const warnings = plannedById.get(item.id)?.warnings;
697
700
  rows.push({
698
701
  id: item.id,
699
702
  status: "skipped",
700
- ...(warnings ? { warnings } : {}),
701
703
  });
702
704
  continue;
703
705
  }
@@ -800,11 +802,21 @@ export const runUpdateMany = async (options, global) => {
800
802
  throw new PmCliError(`No update-many mutation flags provided. Add at least one mutation flag (for example: ${UPDATE_MANY_MUTATION_FLAG_GUIDANCE}).`, EXIT_CODE.USAGE);
801
803
  }
802
804
  assertPlannedUpdateValuesValid(options.update, runtime.settings, runtime.statusRegistry, runtime.pmRoot);
805
+ assertUpdateMutationOptionCombinations(options.update);
806
+ const dependencyWarnings = await assertDependencyTargetsResolvable({
807
+ pmRoot: runtime.pmRoot,
808
+ dependencies: parseDependencyAdditions(options.update.dep, runtime.settings.id_prefix, nowIso(), resolveAuthor(options.update.author, runtime.settings.author_default)).additions,
809
+ idPrefix: runtime.settings.id_prefix,
810
+ itemFormat: runtime.settings.item_format,
811
+ typeToFolder: resolveItemTypeRegistry(runtime.settings, getActiveExtensionRegistrations()).type_to_folder,
812
+ allowUnresolved: options.update.allowUnresolvedDeps,
813
+ });
803
814
  const plan = await buildUpdateManyPlan({
804
815
  options,
805
816
  global,
806
817
  runtime,
807
818
  updateSummary,
819
+ dependencyWarnings,
808
820
  });
809
821
  return options.dryRun === true
810
822
  ? buildUpdateManyDryRunResult(plan)
@@ -828,4 +840,4 @@ export const _testOnlyUpdateManyCommand = {
828
840
  toComparablePreviewValue,
829
841
  };
830
842
  //# sourceMappingURL=update-many.js.map
831
- //# debugId=67f8958d-60d5-5657-93ce-9803859acd9e
843
+ //# debugId=0f91de58-2cbc-52ba-97ea-42482d0c6ce1
@@ -40,6 +40,8 @@ export interface UpdateCommandOptions extends MutationMetadataCommandOptions, Sh
40
40
  force?: boolean;
41
41
  /** Permit an intentional unresolved parent reference under strict validation. */
42
42
  allowMissingParent?: boolean;
43
+ /** Explicitly permit unresolved local dependency targets with warning receipts. */
44
+ allowUnresolvedDeps?: boolean;
43
45
  /** Value that configures or reports dep remove for this contract. */
44
46
  depRemove?: string[];
45
47
  /** Value that configures or reports replace deps for this contract. */
@@ -96,7 +98,8 @@ interface DependencyRemovalSelector {
96
98
  kind?: (typeof DEPENDENCY_KIND_VALUES)[number];
97
99
  source_kind?: string;
98
100
  }
99
- declare function parseDependencyAdditions(raw: string[] | undefined, prefix: string, nowIso: string, fallbackAuthor: string): ParsedDependencyUpdates;
101
+ /** Parse dependency additions into their canonical storage representation. */
102
+ export declare function parseDependencyAdditions(raw: string[] | undefined, prefix: string, nowIso: string, fallbackAuthor: string): ParsedDependencyUpdates;
100
103
  declare function parseDependencyRemovals(raw: string[] | undefined, prefix: string): DependencyRemovalSelector[];
101
104
  declare function reconcileBlockedByDependency(current: Dependency[] | undefined, nextBlockedById: string | undefined, nowIsoValue: string, author: string): {
102
105
  dependencies: Dependency[] | undefined;
@@ -130,6 +133,8 @@ interface UpdateMutationContext {
130
133
  author: string;
131
134
  pmRoot: string;
132
135
  }
136
+ /** Validate mutually exclusive and required update mutation option combinations. */
137
+ export declare function assertUpdateMutationOptionCombinations(options: UpdateCommandOptions): void;
133
138
  type UpdateStatusMutationContext = Pick<UpdateMutationContext, "options" | "statusRegistry" | "clearItemMetadataKeys" | "nowIso">;
134
139
  declare function applyStatusAndCloseReasonMutations(document: ItemDocument, context: UpdateStatusMutationContext, previousStatusNormalized: string, changedFields: string[]): void;
135
140
  /** Implements run update for the public runtime surface of this module. */