@unbrained/pm-cli 2026.8.4 → 2026.8.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (214) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/CHANGELOG.md +39 -13
  3. package/dist/cli/error-guidance.js +4 -4
  4. package/dist/cli/register-structured-mutation.d.ts +2 -0
  5. package/dist/cli/register-structured-mutation.js +124 -12
  6. package/dist/cli-bundle/bundle-manifest.json +407 -407
  7. package/dist/cli-bundle/chunks/append-VXXGOXSG.js +2 -0
  8. package/dist/cli-bundle/chunks/{chunk-QVO3VTA4.js → chunk-2WFXWAYX.js} +2 -2
  9. package/dist/cli-bundle/chunks/{chunk-NM5G7RLU.js → chunk-3FTILRJ2.js} +2 -2
  10. package/dist/cli-bundle/chunks/{chunk-VH2EAGUG.js → chunk-42E7YPLG.js} +2 -2
  11. package/dist/cli-bundle/chunks/{chunk-RB65T4RX.js → chunk-43HQQI6S.js} +2 -2
  12. package/dist/cli-bundle/chunks/{chunk-J4EPW4GT.js → chunk-45G53IU4.js} +2 -2
  13. package/dist/cli-bundle/chunks/{chunk-PQXEB7W4.js → chunk-4VN6GS4U.js} +2 -2
  14. package/dist/cli-bundle/chunks/chunk-4YUBDMQM.js +2 -0
  15. package/dist/cli-bundle/chunks/{chunk-D2MBVMVE.js → chunk-54FNT7U2.js} +2 -2
  16. package/dist/cli-bundle/chunks/{chunk-NRDKVOUE.js → chunk-5ZBOIPGP.js} +2 -2
  17. package/dist/cli-bundle/chunks/{chunk-3XZYTRPC.js → chunk-6MSQJOTG.js} +2 -2
  18. package/dist/cli-bundle/chunks/{chunk-GOICHIX4.js → chunk-7A5OT5J2.js} +2 -2
  19. package/dist/cli-bundle/chunks/{chunk-HTYC76A4.js → chunk-7C4PTJG6.js} +2 -2
  20. package/dist/cli-bundle/chunks/{chunk-BKMZTZYL.js → chunk-A62CYISG.js} +2 -2
  21. package/dist/cli-bundle/chunks/{chunk-5H47J5FG.js → chunk-BPELKUQD.js} +2 -2
  22. package/dist/cli-bundle/chunks/{chunk-HE3DZFN4.js → chunk-BXQLRKWF.js} +2 -2
  23. package/dist/cli-bundle/chunks/{chunk-BLINBTMX.js → chunk-CSI3WS5I.js} +2 -2
  24. package/dist/cli-bundle/chunks/{chunk-KH4GVBMC.js → chunk-DXDREUXT.js} +2 -2
  25. package/dist/cli-bundle/chunks/{chunk-KIKLF2W4.js → chunk-E2RKBKWB.js} +2 -2
  26. package/dist/cli-bundle/chunks/{chunk-377OOXUF.js → chunk-EGJ4JTUG.js} +2 -2
  27. package/dist/cli-bundle/chunks/{chunk-SULWTPQO.js → chunk-FPBQHMFT.js} +2 -2
  28. package/dist/cli-bundle/chunks/{chunk-V5K52PYW.js → chunk-GE4KCSZP.js} +35 -35
  29. package/dist/cli-bundle/chunks/{chunk-NPUJ7OLK.js → chunk-HNFD72UK.js} +2 -2
  30. package/dist/cli-bundle/chunks/{chunk-QMWUL66F.js → chunk-HWRRMBJO.js} +5 -5
  31. package/dist/cli-bundle/chunks/chunk-L3AZOELJ.js +2 -0
  32. package/dist/cli-bundle/chunks/{chunk-CGY5I2GO.js → chunk-LKDGK44W.js} +2 -2
  33. package/dist/cli-bundle/chunks/chunk-LN2WFEU4.js +2 -0
  34. package/dist/cli-bundle/chunks/{chunk-ZSH4GNBH.js → chunk-M72BKL5Q.js} +2 -2
  35. package/dist/cli-bundle/chunks/{chunk-HQ2WU7OY.js → chunk-MHK6LIWE.js} +2 -2
  36. package/dist/cli-bundle/chunks/{chunk-H6FITE7D.js → chunk-NE5VRDAI.js} +2 -2
  37. package/dist/cli-bundle/chunks/chunk-NY4T3JWN.js +2 -0
  38. package/dist/cli-bundle/chunks/{chunk-DCJ6CM6F.js → chunk-OMXVBQ2N.js} +2 -2
  39. package/dist/cli-bundle/chunks/chunk-OPVH7SKD.js +8 -0
  40. package/dist/cli-bundle/chunks/{chunk-CU5ENFNP.js → chunk-OTHLDSFP.js} +2 -2
  41. package/dist/cli-bundle/chunks/{chunk-NH35JNK5.js → chunk-PMXJEU3F.js} +2 -2
  42. package/dist/cli-bundle/chunks/{chunk-SVDH5CHC.js → chunk-Q35VBGOQ.js} +4 -4
  43. package/dist/cli-bundle/chunks/{chunk-5PZGZMPG.js → chunk-R546TPDE.js} +2 -2
  44. package/dist/cli-bundle/chunks/{chunk-Q5F6OI7C.js → chunk-RKAVWO3O.js} +2 -2
  45. package/dist/cli-bundle/chunks/{chunk-JMKVCQSE.js → chunk-SSF4PIUR.js} +2 -2
  46. package/dist/cli-bundle/chunks/{chunk-PA5XRN2A.js → chunk-UN66FZRO.js} +3 -3
  47. package/dist/cli-bundle/chunks/{chunk-FQ4EFFDU.js → chunk-UP7DTVMD.js} +2 -2
  48. package/dist/cli-bundle/chunks/{chunk-NFF3JAQR.js → chunk-UZBWIUYD.js} +2 -2
  49. package/dist/cli-bundle/chunks/{chunk-2POYGY53.js → chunk-V3774P7D.js} +2 -2
  50. package/dist/cli-bundle/chunks/{chunk-B5ZLCD5Z.js → chunk-V3EUXXOF.js} +2 -2
  51. package/dist/cli-bundle/chunks/{chunk-6S7I3UKV.js → chunk-VCKLFEUN.js} +19 -19
  52. package/dist/cli-bundle/chunks/{chunk-PYYPQLHC.js → chunk-VN5VITU3.js} +2 -2
  53. package/dist/cli-bundle/chunks/chunk-WRL4KNDL.js +20 -0
  54. package/dist/cli-bundle/chunks/{chunk-UJHUR3LZ.js → chunk-XCEZYMNI.js} +2 -2
  55. package/dist/cli-bundle/chunks/{chunk-JDPKBV5P.js → chunk-YEWNL576.js} +2 -2
  56. package/dist/cli-bundle/chunks/{chunk-OB7TRZ2G.js → chunk-YSO3YFZ4.js} +2 -2
  57. package/dist/cli-bundle/chunks/{chunk-UVZREFZU.js → chunk-ZYHOB3SN.js} +2 -2
  58. package/dist/cli-bundle/chunks/close-VZ3OQPN5.js +2 -0
  59. package/dist/cli-bundle/chunks/close-many-SB4TI27P.js +2 -0
  60. package/dist/cli-bundle/chunks/comments-BIF3Q4KY.js +2 -0
  61. package/dist/cli-bundle/chunks/copy-6AI5Z57X.js +2 -0
  62. package/dist/cli-bundle/chunks/{create-RLLCBCXM.js → create-XLKTXTUF.js} +2 -2
  63. package/dist/cli-bundle/chunks/delete-ZY2VHQTP.js +2 -0
  64. package/dist/cli-bundle/chunks/{deps-J4ONTF4X.js → deps-ITTY3GIC.js} +2 -2
  65. package/dist/cli-bundle/chunks/{docs-YL2DJ4WD.js → docs-W4OSRTYR.js} +2 -2
  66. package/dist/cli-bundle/chunks/{files-NGNAIYKK.js → files-EOK4AZI4.js} +2 -2
  67. package/dist/cli-bundle/chunks/focus-DLBNWL7L.js +2 -0
  68. package/dist/cli-bundle/chunks/{history-compact-HW62K5XP.js → history-compact-7UGTMLL3.js} +2 -2
  69. package/dist/cli-bundle/chunks/{history-redact-HVBKUJOW.js → history-redact-4DZRMD6Z.js} +2 -2
  70. package/dist/cli-bundle/chunks/{history-repair-OPNBH5JJ.js → history-repair-UPOSZW5R.js} +2 -2
  71. package/dist/cli-bundle/chunks/{learnings-F36PZXT6.js → learnings-GMRNCBS3.js} +2 -2
  72. package/dist/cli-bundle/chunks/{profile-N3XMWBM7.js → profile-2MUUMHRE.js} +2 -2
  73. package/dist/cli-bundle/chunks/{register-list-query-BKGHBI7Y.js → register-list-query-LR3SQ5ZF.js} +2 -2
  74. package/dist/cli-bundle/chunks/register-mutation-SUOHFVWM.js +20 -0
  75. package/dist/cli-bundle/chunks/register-operations-ARRRKOVN.js +2 -0
  76. package/dist/cli-bundle/chunks/{register-setup-KWV6UD77.js → register-setup-O6AYP6NP.js} +2 -2
  77. package/dist/cli-bundle/chunks/restore-ZVCVHTB5.js +2 -0
  78. package/dist/cli-bundle/chunks/{schema-4PJQMGUY.js → schema-FJ4EA3XF.js} +2 -2
  79. package/dist/cli-bundle/chunks/update-YHV52CSS.js +2 -0
  80. package/dist/cli-bundle/chunks/update-many-M6YHVNXM.js +2 -0
  81. package/dist/cli-bundle/focused-chunks/chunk-7J5TUBUJ.js +153 -0
  82. package/dist/cli-bundle/focused-chunks/{chunk-ONIX2KKW.js → chunk-A7BJ5SS6.js} +2 -2
  83. package/dist/cli-bundle/focused-chunks/chunk-B7LJWAZE.js +2 -0
  84. package/dist/cli-bundle/focused-chunks/{chunk-QM2BIVK7.js → chunk-BIMTMOS7.js} +3 -3
  85. package/dist/cli-bundle/focused-chunks/{chunk-BOGRY7M6.js → chunk-FGKY4MBE.js} +10 -10
  86. package/dist/cli-bundle/focused-chunks/chunk-G6ETT4QK.js +2 -0
  87. package/dist/cli-bundle/focused-chunks/{chunk-C2QSL62X.js → chunk-GJ2TG2CW.js} +2 -2
  88. package/dist/cli-bundle/focused-chunks/{chunk-RO5BQFG3.js → chunk-IPWSFADF.js} +2 -2
  89. package/dist/cli-bundle/focused-chunks/{chunk-UFCPSWIL.js → chunk-MJ7HWSFK.js} +2 -2
  90. package/dist/cli-bundle/focused-chunks/{chunk-2VIIXOAD.js → chunk-N5XU5UVK.js} +2 -2
  91. package/dist/cli-bundle/focused-chunks/chunk-PG2RIZBX.js +2 -0
  92. package/dist/cli-bundle/focused-chunks/{chunk-OYTK4VNH.js → chunk-PIMMYG7Q.js} +2 -2
  93. package/dist/cli-bundle/focused-chunks/{chunk-K37BB4JL.js → chunk-QVHKCI4T.js} +2 -2
  94. package/dist/cli-bundle/focused-chunks/{chunk-SQXVGHMH.js → chunk-RUR5I3TK.js} +2 -2
  95. package/dist/cli-bundle/focused-chunks/chunk-SV3O7TSH.js +8 -0
  96. package/dist/cli-bundle/focused-chunks/{chunk-L6A4NVQC.js → chunk-UIL2M2NA.js} +2 -2
  97. package/dist/cli-bundle/focused-chunks/{chunk-WVGJAD7L.js → chunk-VLYOEYML.js} +2 -2
  98. package/dist/cli-bundle/focused-chunks/chunk-W7BJEWHX.js +2 -0
  99. package/dist/cli-bundle/focused-chunks/{chunk-DQ4PLKEE.js → chunk-WEM2E2PE.js} +2 -2
  100. package/dist/cli-bundle/focused-chunks/chunk-WVIVUWVL.js +5 -0
  101. package/dist/cli-bundle/focused-chunks/chunk-Y4LDYLLT.js +2 -0
  102. package/dist/cli-bundle/main.js +4 -4
  103. package/dist/cli-bundle/sdk-authoring.js +1 -1
  104. package/dist/cli-bundle/sdk-contracts.js +1 -1
  105. package/dist/cli-bundle/sdk-core.js +28 -28
  106. package/dist/cli-bundle/sdk-governance.js +1 -1
  107. package/dist/cli-bundle/sdk-graph.js +1 -1
  108. package/dist/cli-bundle/sdk-merge.js +1 -1
  109. package/dist/cli-bundle/sdk-query.js +1 -1
  110. package/dist/cli-bundle/sdk-runtime.js +1 -1
  111. package/dist/cli-bundle/sdk-testing.js +1 -1
  112. package/dist/cli-bundle/sdk.js +1 -1
  113. package/dist/core/extensions/loader.js +5 -2
  114. package/dist/core/item/item-format.js +14 -20
  115. package/dist/core/shared/constants.js +3 -2
  116. package/dist/core/store/item-store.js +2 -2
  117. package/dist/core/store/settings.js +2 -2
  118. package/dist/mcp/server.js +12 -6
  119. package/dist/mcp/tool-definitions.js +14 -7
  120. package/dist/sdk/cli-contracts/agent-output-contracts.d.ts +18 -18
  121. package/dist/sdk/cli-contracts/agent-output-contracts.js +51 -23
  122. package/dist/sdk/cli-contracts/commander-mutation-options.js +26 -2
  123. package/dist/sdk/cli-contracts/flag-contracts.d.ts +2 -0
  124. package/dist/sdk/cli-contracts/flag-contracts.js +28 -2
  125. package/dist/sdk/cli-contracts/registration-helpers.js +4 -2
  126. package/dist/sdk/cli-contracts/runtime-contracts.d.ts +10 -2
  127. package/dist/sdk/cli-contracts/runtime-contracts.js +20 -5
  128. package/dist/sdk/cli-contracts/tool-schema.js +4 -2
  129. package/dist/sdk/cli-contracts.d.ts +2 -2
  130. package/dist/sdk/cli-contracts.js +4 -4
  131. package/dist/sdk/cli-program.js +3 -3
  132. package/dist/sdk/contracts.d.ts +1 -0
  133. package/dist/sdk/contracts.js +3 -2
  134. package/dist/sdk/dependency-provenance.d.ts +2 -0
  135. package/dist/sdk/dependency-provenance.js +7 -3
  136. package/dist/sdk/error-code-catalog.d.ts +23 -0
  137. package/dist/sdk/error-code-catalog.js +25 -5
  138. package/dist/sdk/generated-error-code-catalog.js +499 -3
  139. package/dist/sdk/graph/governance.js +3 -3
  140. package/dist/sdk/graph/remediation.js +3 -3
  141. package/dist/sdk/graph/run.js +4 -8
  142. package/dist/sdk/index.d.ts +2 -1
  143. package/dist/sdk/index.js +4 -3
  144. package/dist/sdk/item-transaction.d.ts +51 -6
  145. package/dist/sdk/item-transaction.js +132 -22
  146. package/dist/sdk/lifecycle/create.d.ts +4 -0
  147. package/dist/sdk/lifecycle/create.js +26 -10
  148. package/dist/sdk/lifecycle-policy.d.ts +9 -0
  149. package/dist/sdk/lifecycle-policy.js +22 -9
  150. package/dist/sdk/merge/driver.js +6 -3
  151. package/dist/sdk/output-contracts.d.ts +67 -0
  152. package/dist/sdk/output-contracts.js +173 -0
  153. package/dist/sdk/package-import-adapters.js +2 -2
  154. package/dist/sdk/structured-mutations.d.ts +23 -0
  155. package/dist/sdk/structured-mutations.js +219 -10
  156. package/dist/sdk/workspace-snapshot.js +58 -12
  157. package/dist/sdk/workspace.js +30 -4
  158. package/docs/COMMANDS.md +40 -10
  159. package/docs/EXTENSIONS.md +1 -1
  160. package/docs/MERGE_SAFETY.md +2 -0
  161. package/docs/PR_REVIEW_LOOP.md +10 -4
  162. package/docs/README.md +22 -22
  163. package/docs/RELEASING.md +3 -3
  164. package/docs/SCRIPTING.md +32 -9
  165. package/docs/SDK.md +91 -11
  166. package/docs/SELF_DESCRIBING_CONTEXT_CONTRACTS.md +13 -0
  167. package/docs/TESTING.md +25 -0
  168. package/docs/examples/sdk-contract-consumer/README.md +11 -1
  169. package/docs/examples/sdk-contract-consumer/package.json +2 -1
  170. package/docs/examples/sdk-contract-consumer/parse-receipt.mjs +22 -0
  171. package/marketplace.json +2 -2
  172. package/package.json +3 -2
  173. package/packages/pm-beads/package.json +1 -1
  174. package/packages/pm-calendar/package.json +1 -1
  175. package/packages/pm-command-kit/package.json +1 -1
  176. package/packages/pm-digital-twin/package.json +1 -1
  177. package/packages/pm-governance-audit/package.json +1 -1
  178. package/packages/pm-guide-shell/package.json +1 -1
  179. package/packages/pm-kanban/package.json +1 -1
  180. package/packages/pm-lifecycle-hooks/package.json +1 -1
  181. package/packages/pm-linked-test-adapters/package.json +1 -1
  182. package/packages/pm-search-advanced/package.json +1 -1
  183. package/packages/pm-templates/package.json +1 -1
  184. package/packages/pm-todos/package.json +1 -1
  185. package/packages/pm-vcs/package.json +1 -1
  186. package/plugins/pm-claude/.claude-plugin/plugin.json +1 -1
  187. package/plugins/pm-codex/.codex-plugin/plugin.json +1 -1
  188. package/sdk/public-surface.json +292 -14
  189. package/dist/cli-bundle/chunks/append-DHBRLHHS.js +0 -2
  190. package/dist/cli-bundle/chunks/chunk-2INN52SU.js +0 -8
  191. package/dist/cli-bundle/chunks/chunk-6RSK4IFN.js +0 -20
  192. package/dist/cli-bundle/chunks/chunk-ASJJKA57.js +0 -2
  193. package/dist/cli-bundle/chunks/chunk-IYAVULRN.js +0 -2
  194. package/dist/cli-bundle/chunks/chunk-RRQBHQOV.js +0 -2
  195. package/dist/cli-bundle/chunks/chunk-XBLOD5TZ.js +0 -2
  196. package/dist/cli-bundle/chunks/close-VLHNN6YB.js +0 -2
  197. package/dist/cli-bundle/chunks/close-many-LSJNZKU6.js +0 -2
  198. package/dist/cli-bundle/chunks/comments-AAIA6A6X.js +0 -2
  199. package/dist/cli-bundle/chunks/copy-Z7YMLEHN.js +0 -2
  200. package/dist/cli-bundle/chunks/delete-KNOHHQJM.js +0 -2
  201. package/dist/cli-bundle/chunks/focus-LFRCGALV.js +0 -2
  202. package/dist/cli-bundle/chunks/register-mutation-GU3DCECN.js +0 -20
  203. package/dist/cli-bundle/chunks/register-operations-PTWH727R.js +0 -2
  204. package/dist/cli-bundle/chunks/restore-4HZSLILR.js +0 -2
  205. package/dist/cli-bundle/chunks/update-E6LPS5IV.js +0 -2
  206. package/dist/cli-bundle/chunks/update-many-OSIC6KRO.js +0 -2
  207. package/dist/cli-bundle/focused-chunks/chunk-5MTKO7TV.js +0 -153
  208. package/dist/cli-bundle/focused-chunks/chunk-6GIZK7VQ.js +0 -2
  209. package/dist/cli-bundle/focused-chunks/chunk-AOP2WIZZ.js +0 -2
  210. package/dist/cli-bundle/focused-chunks/chunk-CL75YW32.js +0 -2
  211. package/dist/cli-bundle/focused-chunks/chunk-E7OFMWGT.js +0 -8
  212. package/dist/cli-bundle/focused-chunks/chunk-I5F5UK3Q.js +0 -2
  213. package/dist/cli-bundle/focused-chunks/chunk-T5TSY36R.js +0 -5
  214. package/dist/cli-bundle/focused-chunks/chunk-VT6BF2IX.js +0 -2
@@ -5,7 +5,7 @@
5
5
  * state while excluding clone-local caches, locks, and recovery journals.
6
6
  */
7
7
 
8
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="343fc918-e300-504c-80be-779c0d01b93e")}catch(e){}}();
8
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="3e32be7c-f8a4-547d-8c19-456b4567982e")}catch(e){}}();
9
9
  import crypto from "node:crypto";
10
10
  import { cp, lstat, mkdir, readFile, readdir, rename, rm, writeFile, } from "node:fs/promises";
11
11
  import path from "node:path";
@@ -13,6 +13,8 @@ import { writeFileAtomic } from "../core/fs/fs-utils.js";
13
13
  import { appendWorkspaceAuditEvent } from "../core/history/workspace-history.js";
14
14
  import { acquireLock } from "../core/lock/lock.js";
15
15
  import { getLockPath } from "../core/store/paths.js";
16
+ import { EXIT_CODE } from "../core/shared/constants.js";
17
+ import { PmCliError } from "../core/shared/errors.js";
16
18
  /** Current content-addressed workspace snapshot manifest schema identifier. */
17
19
  export const SNAPSHOT_SCHEMA = "https://schema.unbrained.dev/pm/workspace-snapshot/v1";
18
20
  const SNAPSHOT_RUNTIME_PATH = path.join("runtime", "workspace-snapshots");
@@ -168,7 +170,21 @@ async function snapshotContents(root, files) {
168
170
  }
169
171
  function validateSnapshotTarget(target) {
170
172
  if (!SNAPSHOT_TARGET_PATTERN.test(target)) {
171
- throw new Error("Snapshot names and fingerprints must use lowercase letters, digits, dots, underscores, or hyphens");
173
+ throw new PmCliError("Snapshot names and fingerprints must use lowercase letters, digits, dots, underscores, or hyphens", EXIT_CODE.USAGE, {
174
+ code: "invalid_workspace_snapshot_target",
175
+ required: "Provide a non-empty lowercase snapshot name or 64-character hexadecimal fingerprint.",
176
+ why: "Snapshot targets are used as portable reference filenames and content identities.",
177
+ examples: [
178
+ "pm workspace snapshot list --json",
179
+ "pm workspace snapshot inspect baseline --json",
180
+ ],
181
+ nextSteps: [
182
+ "List available snapshots, then retry with a returned name or fingerprint.",
183
+ ],
184
+ recovery: {
185
+ suggested_retry: "pm workspace snapshot list --json",
186
+ },
187
+ });
172
188
  }
173
189
  }
174
190
  function isErrno(error, code) {
@@ -180,15 +196,23 @@ function isErrno(error, code) {
180
196
  function snapshotStore(pmRoot) {
181
197
  return path.join(pmRoot, SNAPSHOT_RUNTIME_PATH);
182
198
  }
199
+ function workspaceSnapshotNotFound(target) {
200
+ return new PmCliError(`Unknown workspace snapshot: ${target}`, EXIT_CODE.NOT_FOUND, {
201
+ code: "workspace_snapshot_not_found",
202
+ required: "Use a snapshot name or fingerprint returned by snapshot list.",
203
+ why: "The requested reference or immutable snapshot object does not exist.",
204
+ examples: ["pm workspace snapshot list --json"],
205
+ nextSteps: ["List available snapshots and retry with an exact target."],
206
+ recovery: { suggested_retry: "pm workspace snapshot list --json" },
207
+ });
208
+ }
183
209
  async function readSnapshotJson(file, target) {
184
210
  try {
185
211
  return JSON.parse(await readFile(file, "utf8"));
186
212
  }
187
213
  catch (error) {
188
214
  if (isErrno(error, "ENOENT")) {
189
- throw new Error(`Unknown workspace snapshot: ${target}`, {
190
- cause: error,
191
- });
215
+ throw workspaceSnapshotNotFound(target);
192
216
  }
193
217
  throw error;
194
218
  }
@@ -199,9 +223,7 @@ async function removeSnapshotEntry(entry, target, recursive) {
199
223
  }
200
224
  catch (error) {
201
225
  if (isErrno(error, "ENOENT")) {
202
- throw new Error(`Unknown workspace snapshot: ${target}`, {
203
- cause: error,
204
- });
226
+ throw workspaceSnapshotNotFound(target);
205
227
  }
206
228
  throw error;
207
229
  }
@@ -256,7 +278,13 @@ export async function createWorkspaceSnapshot(pmRoot, options = {}) {
256
278
  if (options.name !== undefined) {
257
279
  validateSnapshotTarget(options.name);
258
280
  if (/^[a-f0-9]{64}$/.test(options.name)) {
259
- throw new Error("Snapshot names must not be 64-character lowercase hexadecimal fingerprints");
281
+ throw new PmCliError("Snapshot names must not be 64-character lowercase hexadecimal fingerprints", EXIT_CODE.USAGE, {
282
+ code: "workspace_snapshot_name_reserved_fingerprint",
283
+ required: "Choose a human-readable reference name that cannot be mistaken for a content fingerprint.",
284
+ why: "Exact 64-character hexadecimal values address immutable objects.",
285
+ examples: ["pm workspace snapshot create baseline --json"],
286
+ nextSteps: ["Retry with a shorter descriptive snapshot name."],
287
+ });
260
288
  }
261
289
  }
262
290
  const { manifest, contents } = await buildManifest(pmRoot);
@@ -307,7 +335,13 @@ export async function inspectWorkspaceSnapshot(pmRoot, target) {
307
335
  const manifest = await readSnapshotJson(path.join(snapshotStore(pmRoot), "objects", fingerprint, "manifest.json"), target);
308
336
  if (manifest.schema !== SNAPSHOT_SCHEMA ||
309
337
  manifest.fingerprint !== fingerprint) {
310
- throw new Error(`Snapshot manifest identity mismatch: ${target}`);
338
+ throw new PmCliError(`Snapshot manifest identity mismatch: ${target}`, EXIT_CODE.CONFLICT, {
339
+ code: "workspace_snapshot_manifest_mismatch",
340
+ required: "Use an intact snapshot whose manifest fingerprint matches its object path.",
341
+ why: "Content identity must be verified before snapshot data is trusted.",
342
+ examples: ["pm workspace snapshot list --json"],
343
+ nextSteps: ["Inspect or recreate the snapshot before restoring it."],
344
+ });
311
345
  }
312
346
  return manifest;
313
347
  }
@@ -399,7 +433,19 @@ export async function planWorkspaceSnapshotRestore(pmRoot, target) {
399
433
  */
400
434
  export async function restoreWorkspaceSnapshotWithRecovery(pmRoot, target, options = {}) {
401
435
  if (options.force !== true) {
402
- throw new Error("Workspace snapshot restore requires explicit force confirmation; inspect the impact with planWorkspaceSnapshotRestore or pm workspace snapshot restore <target> --dry-run, then retry with force");
436
+ throw new PmCliError("Workspace snapshot restore requires explicit force confirmation; inspect the impact with planWorkspaceSnapshotRestore or pm workspace snapshot restore <target> --dry-run, then retry with force", EXIT_CODE.USAGE, {
437
+ code: "workspace_snapshot_force_required",
438
+ required: "Preview the destructive impact, then explicitly confirm the restore.",
439
+ why: "A restore replaces the complete authoritative tracker state.",
440
+ examples: [
441
+ `pm workspace snapshot restore ${target} --dry-run --json`,
442
+ `pm workspace snapshot restore ${target} --force --json`,
443
+ ],
444
+ nextSteps: ["Review the dry-run counts before retrying with --force."],
445
+ recovery: {
446
+ suggested_retry: `pm workspace snapshot restore ${target} --dry-run --json`,
447
+ },
448
+ });
403
449
  }
404
450
  const author = options.author?.trim() || "pm-sdk";
405
451
  const lockTtlSeconds = options.lockTtlSeconds ?? 60;
@@ -518,4 +564,4 @@ export async function deleteWorkspaceSnapshot(pmRoot, target) {
518
564
  return { deleted: "object", target };
519
565
  }
520
566
  //# sourceMappingURL=workspace-snapshot.js.map
521
- //# debugId=343fc918-e300-504c-80be-779c0d01b93e
567
+ //# debugId=3e32be7c-f8a4-547d-8c19-456b4567982e
@@ -4,9 +4,11 @@
4
4
  * Maintains repository-scaffold contracts shared by the public SDK and CLI.
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]="786d5cc6-521d-521e-9e91-95d82551c279")}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]="bbfa5b19-d801-582a-98e8-0c4925dd57c0")}catch(e){}}();
8
8
  import { readFile, writeFile } from "node:fs/promises";
9
9
  import path from "node:path";
10
+ import { EXIT_CODE } from "../core/shared/constants.js";
11
+ import { PmCliError } from "../core/shared/errors.js";
10
12
  /** Opening marker for the init-owned ignore block. */
11
13
  export const PM_GITIGNORE_START = "# pm-cli:runtime-cache:start";
12
14
  /** Closing marker for the init-owned ignore block. */
@@ -31,6 +33,30 @@ export const PM_GITIGNORE_RUNTIME_DIRECTORIES = [
31
33
  ];
32
34
  /** Tracker-relative curated search evidence that remains version controlled. */
33
35
  export const PM_GITIGNORE_TRACKED_FILES = ["search/eval-queries.json"];
36
+ /** Convert expected workspace permission failures into stable, path-safe recovery. */
37
+ async function withGitignorePermissionRecovery(operation) {
38
+ try {
39
+ return await operation();
40
+ }
41
+ catch (error) {
42
+ if (error instanceof Error &&
43
+ "code" in error &&
44
+ typeof error.code === "string" &&
45
+ ["EACCES", "EPERM", "EROFS"].includes(error.code)) {
46
+ throw new PmCliError("The workspace .gitignore is not writable.", EXIT_CODE.GENERIC_FAILURE, {
47
+ code: "init_gitignore_unwritable",
48
+ reason: error.code.toLowerCase(),
49
+ required: "Grant the current user read and write access to the workspace .gitignore before initialization.",
50
+ why: "pm init must publish its managed runtime-cache ignore fence without replacing unrelated entries.",
51
+ nextSteps: [
52
+ "Grant read and write access to the workspace .gitignore and rerun pm init.",
53
+ "If the workspace is intentionally read-only, initialize pm in a writable workspace or clone.",
54
+ ],
55
+ });
56
+ }
57
+ throw error;
58
+ }
59
+ }
34
60
  function normalizeTrackerRelativeRoot(trackerRelativeRoot) {
35
61
  return trackerRelativeRoot
36
62
  .replaceAll("\\", "/")
@@ -78,7 +104,7 @@ export async function ensurePmGitignore(workspaceRoot, options = {}) {
78
104
  }
79
105
  let current = "";
80
106
  try {
81
- current = await readFile(gitignorePath, "utf8");
107
+ current = await withGitignorePermissionRecovery(() => readFile(gitignorePath, "utf8"));
82
108
  }
83
109
  catch (error) {
84
110
  if (!(error instanceof Error && "code" in error && error.code === "ENOENT")) {
@@ -95,8 +121,8 @@ export async function ensurePmGitignore(workspaceRoot, options = {}) {
95
121
  if (next === current) {
96
122
  return { path: gitignorePath, changed: false };
97
123
  }
98
- await writeFile(gitignorePath, next, "utf8");
124
+ await withGitignorePermissionRecovery(() => writeFile(gitignorePath, next, "utf8"));
99
125
  return { path: gitignorePath, changed: true };
100
126
  }
101
127
  //# sourceMappingURL=workspace.js.map
102
- //# debugId=786d5cc6-521d-521e-9e91-95d82551c279
128
+ //# debugId=bbfa5b19-d801-582a-98e8-0c4925dd57c0
package/docs/COMMANDS.md CHANGED
@@ -27,7 +27,7 @@ Tracked documentation work: [pm-u9d0](../.agents/pm/epics/pm-u9d0.toon).
27
27
  | ------------ | ------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
28
28
  | Bootstrap | `init`, `config`, `health`, `telemetry` | create and inspect tracker setup |
29
29
  | Lifecycle | `create`, `copy`, `focus`, `claim`, `update`, `append`, `close`, `release`, `delete`, `start-task`, `pause-task`, `close-task` | mutate item state |
30
- | Bulk | `item mutate`, `update-many`, `close-many` | atomically commit heterogeneous SDK mutation batches, or apply one change across a matched, dry-run-previewed set with a rollback checkpoint |
30
+ | Bulk | `item mutate`, `item complete`, `update-many`, `close-many` | atomically commit heterogeneous SDK mutation batches or evidence-backed completion, or apply one change across a matched, dry-run-previewed set with a rollback checkpoint |
31
31
  | Scheduling | `meet`, `event`, `remind` | low-friction Meeting/Event/Reminder creation |
32
32
  | Planning | `plan create`, `plan add-step`, `plan update-step`, `plan complete-step`, `plan link`, `plan approve`, `plan materialize` | agent-optimized living plans with ordered steps, evidence, decisions, validation, and materialization |
33
33
  | Links | `files`, `docs`, `test`, `deps` | connect items to artifacts, tests, and relationships |
@@ -516,20 +516,30 @@ row summaries. See tracker item [pm-awe3t6](../.agents/pm/issues/pm-awe3t6.toon)
516
516
 
517
517
  ### Atomic heterogeneous mutation batches
518
518
 
519
- `pm item mutate` is the noun-first CLI adapter over the public SDK
520
- `commitItemMutations` primitive. Pipe a non-empty JSON array (or an object with a
521
- `mutations` array), provide one stable transaction id, and mix create/update/
522
- close operations in order:
519
+ Tracked by [pm-o8z748](../.agents/pm/issues/pm-o8z748.toon) and
520
+ [pm-cyn0y6](../.agents/pm/issues/pm-cyn0y6.toon).
521
+
522
+ `pm item mutate` is the noun-first CLI adapter over the public SDK resolver and
523
+ `commitItemMutations` primitive. Pipe either the legacy non-empty JSON array or
524
+ a versioned `{ "schema_version": 1, "mutations": [...] }` document, provide one
525
+ stable transaction id, and mix create/update/close/release operations in order.
526
+ Create rows may declare a unique `ref` and omit `id`; exact `@ref` values work
527
+ in target ids, `parent`, `blockedBy`, and dependency `id` fields. The resolver
528
+ derives replay-stable ids before the writer lock and returns a `references`
529
+ receipt:
523
530
 
524
531
  ```bash
525
532
  pm item mutate \
526
533
  --transaction-id sync-2026-07-20-001 \
527
534
  --stdin-json <<'JSON'
528
- [
529
- {"op":"create","id":"ext-1042","options":{"title":"Imported issue","type":"Issue"}},
530
- {"op":"update","id":"pm-a1b2","options":{"priority":"1","addTags":["synced"]}},
531
- {"op":"close","id":"pm-c3d4","reason":"Resolved upstream"}
532
- ]
535
+ {
536
+ "schema_version": 1,
537
+ "mutations": [
538
+ {"op":"create","ref":"initiative","options":{"title":"Imported initiative","type":"Epic"}},
539
+ {"op":"create","ref":"delivery","options":{"title":"Deliver it","type":"Feature","parent":"@initiative","dep":["id=@initiative,kind=implements"]}},
540
+ {"op":"update","id":"@initiative","options":{"addTags":["synced"]}}
541
+ ]
542
+ }
533
543
  JSON
534
544
  ```
535
545
 
@@ -540,6 +550,26 @@ step. `--create-compensation close|delete`, `--lock-ttl-seconds`, and
540
550
  `--lock-wait-ms` expose the transaction safety controls. The equivalent MCP
541
551
  surface is `pm_mutate`.
542
552
 
553
+ `pm item complete` composes evidence, governed closure, and claim release into
554
+ one compensating SDK transaction. It accepts the normal repeatable evidence
555
+ flags and can preview the exact ordered mutations before writing:
556
+
557
+ ```bash
558
+ pm item complete pm-a1b2 "Implemented and verified" \
559
+ --transaction-id complete-pm-a1b2-v1 \
560
+ --file path=src/index.ts,scope=project,note=implementation \
561
+ --doc path=docs/SDK.md,scope=project,note=contract \
562
+ --test command="pnpm test",scope=project,timeout_seconds=240 \
563
+ --comment "Evidence: full verification passed" \
564
+ --validate-close warn
565
+ ```
566
+
567
+ If any phase fails, the SDK restores the evidence, lifecycle, and prior claim.
568
+ Reusing the exact transaction id and payload returns the committed result;
569
+ changing a replayed payload fails against the journal plan fingerprint.
570
+ `--lock-ttl-seconds` and `--lock-wait-ms` tune the same workspace transaction
571
+ controls exposed by `pm item mutate` for slow or contended trackers.
572
+
543
573
  ## Focus (session default parent)
544
574
 
545
575
  `pm focus` sets a session "focused" item so subsequent `pm create` calls default their `--parent` to it — project management is context management, and focus keeps new work attached to the active parent without restating `--parent` every time.
@@ -270,7 +270,7 @@ Surface tokens include command handlers/overrides, parser/preflight/services/ren
270
270
 
271
271
  ## Registration Collisions
272
272
 
273
- Some extension surfaces are intentionally single-winner: command handlers and overrides, parser overrides, preflight overrides, and format renderers. If multiple packages register the same single-winner surface, the later-loaded registration wins and `pm package doctor` / `pm health` report deterministic `extension_*_collision` warnings. `pm package describe --json` also exposes `command_ownership`: every claimant in activation order, the effective winner, collision state, and the explicit `last_activated_wins` policy. SDK hosts can build the identical table with `buildExtensionDescribeResult` and the exported `ExtensionCommandOwnership` contracts.
273
+ Some extension surfaces are intentionally single-winner: command handlers and overrides, parser overrides, preflight overrides, and format renderers. Activation is deterministic: lower manifest `priority` values load first, omitted priority defaults to `100`, equal priorities sort by package identity/path, and the last registration wins. If multiple packages register the same single-winner surface, `pm package doctor` / `pm health` report deterministic `extension_*_collision` warnings whose suffix names the winning layer/package before the displaced layer/package. `pm package describe --json` also exposes `command_ownership`: every claimant in activation order, the effective winner, collision state, and the explicit `last_activated_wins` policy. SDK hosts can build the identical table with `buildExtensionDescribeResult` and the exported `ExtensionCommandOwnership` contracts. Renderer ownership is evaluated per command: same-format renderers with disjoint `commands` lists safely coexist, while an unscoped or overlapping claim still warns; runtime `resultDiscriminator` predicates alone cannot prove static disjointness. Tracked by [pm-6mjxgq](../.agents/pm/issues/pm-6mjxgq.toon).
274
274
 
275
275
  For definition-based commands, validation is isolated per command: a malformed definition is recorded as `extension_command_quarantined:*` with a registration trace while valid siblings continue to activate. Unknown-command recovery reports that failure without recommending reinstallation.
276
276
  Use the warning details to resolve the overlap:
@@ -63,6 +63,8 @@ pm merge install --dry-run --json
63
63
 
64
64
  When both sides change the same scalar or JSON leaf differently, the driver writes a parseable preferred-side result but exits nonzero. Git keeps the path conflicted so a human or coordinating agent must review the losing value and explicitly `git add` the resolution. Use `--prefer theirs` only when that is the intended resolution policy.
65
65
 
66
+ The driver result's `guidance` always points unresolved conflicts to `pm merge report`. When a clone-local receipt exists, guidance includes its privacy-safe receipt and item ids for exact correlation; discarded values remain confined to the local receipt and never appear in generic logs or tracker history. Tracked by [pm-fbrz7p](../.agents/pm/issues/pm-fbrz7p.toon).
67
+
66
68
  For item conflicts, the driver also writes a clone-local receipt below the Git
67
69
  directory. It contains retained and discarded values so recovery does not
68
70
  depend on a reflog. Raw values never enter public tracker history:
@@ -1,6 +1,6 @@
1
1
  # Pull Request Review Loop
2
2
 
3
- Tracker: [pm-hq28](../.agents/pm/tasks/pm-hq28.toon)
3
+ Trackers: [pm-hq28](../.agents/pm/tasks/pm-hq28.toon), [pm-cp5pbo](../.agents/pm/tasks/pm-cp5pbo.toon)
4
4
 
5
5
  Use `scripts/reviews/pr-review-loop.mjs` to inventory every GitHub pull-request
6
6
  conversation surface before deciding that review is complete. The inventory includes
@@ -11,6 +11,7 @@ reaction state, thread resolution, outdated markers, and the reviewed head SHA.
11
11
  node scripts/reviews/pr-review-loop.mjs inventory --pr 123 > /tmp/pr-123-review-inventory.json
12
12
  node scripts/reviews/pr-review-loop.mjs watch --pr 123 --interval 30 > /tmp/pr-123-review-inventory.json
13
13
  node scripts/reviews/pr-review-loop.mjs react --node-id IC_kw... --reaction THUMBS_UP
14
+ node scripts/reviews/pr-review-loop.mjs acknowledge --pr 123 --node-id PRR_kw... --reaction THUMBS_UP --body "CodeRabbit feedback implemented: https://github.com/owner/repo/pull/123#pullrequestreview-456. The suggested edge case is covered by test X."
14
15
  node scripts/reviews/pr-review-loop.mjs reply-inline --pr 123 --comment-id 456 --body "Addressed in abc123."
15
16
  node scripts/reviews/pr-review-loop.mjs acknowledge-inline --pr 123 --comment-id 456 --node-id PRRC_kw... --reaction THUMBS_UP --body "Addressed in abc123."
16
17
  ```
@@ -18,9 +19,14 @@ node scripts/reviews/pr-review-loop.mjs acknowledge-inline --pr 123 --comment-id
18
19
  Choose `THUMBS_UP` when feedback is useful or correct and `THUMBS_DOWN` when a
19
20
  finding is materially incorrect. Use `acknowledge-inline` so the reaction and
20
21
  explanation land on the actual review comment and its thread. GitHub does not expose
21
- a reply thread for top-level PR conversation comments or submitted review summaries;
22
- react to those surfaces, but do not create a generic PR comment that pretends to be
23
- a direct reply. The complete inventory keeps those non-threadable surfaces visible.
22
+ a reply thread for top-level PR conversation comments or submitted review summaries.
23
+ Use `acknowledge` for those surfaces: its PR comment must identify the bot, link the
24
+ exact GitHub artifact, and explain whether the feedback was implemented or declined.
25
+ That keeps the response auditable without pretending GitHub created a direct thread.
26
+ The command adds a hidden artifact marker and reuses an existing marked comment on
27
+ retry, so a lost response cannot create duplicate acknowledgements. It reports a
28
+ partial result and exits unsuccessfully when either the comment or reaction write
29
+ fails, allowing the missing write to be retried safely.
24
30
 
25
31
  After every push or reviewer retrigger, run `watch`. It delegates waiting to
26
32
  `gh pr checks --watch`, because reviewer agents report completion through GitHub
package/docs/README.md CHANGED
@@ -17,17 +17,17 @@ pm guide release --json
17
17
 
18
18
  ## Read Path
19
19
 
20
- | Reader | First page | Then read |
21
- |--------|------------|-----------|
22
- | New user | [Quickstart](QUICKSTART.md) | [Command Reference](COMMANDS.md) |
23
- | New maintainer | [Onboarding](ONBOARDING.md) | [Agent Guide](AGENT_GUIDE.md), [Testing](TESTING.md), [Releasing](RELEASING.md) |
24
- | Coding agent | [Agent Guide](AGENT_GUIDE.md) | [Configuration](CONFIGURATION.md), then command help |
25
- | Maintainer | [Contributing](../CONTRIBUTING.md) | [Testing](TESTING.md), [Releasing](RELEASING.md), [Architecture](ARCHITECTURE.md) |
26
- | Package author | [Packages and Extensions](EXTENSIONS.md) | [SDK](SDK.md), [starter extension](examples/starter-extension/README.md) |
27
- | Codex or ChatGPT plugin implementer | [Codex Plugin](CODEX_PLUGIN.md) | [Native ChatGPT and Codex Plugin Implementation Plan](CHATGPT_CODEX_PLUGIN_IMPLEMENTATION.md) |
28
- | Codex user | [Codex Plugin](CODEX_PLUGIN.md) | [Agent Guide](AGENT_GUIDE.md), then [Command Reference](COMMANDS.md) |
29
- | Claude Code user | [Claude Code Plugin](CLAUDE_CODE_PLUGIN.md) | [Agent Guide](AGENT_GUIDE.md), then [Command Reference](COMMANDS.md) |
30
- | Machine client | `pm contracts --json` | [CLI Scripting Contract](SCRIPTING.md), [Command Reference](COMMANDS.md#machine-contracts), optionally `pm install guide-shell --project && pm guide commands` |
20
+ | Reader | First page | Then read |
21
+ | ----------------------------------- | ------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
22
+ | New user | [Quickstart](QUICKSTART.md) | [Command Reference](COMMANDS.md) |
23
+ | New maintainer | [Onboarding](ONBOARDING.md) | [Agent Guide](AGENT_GUIDE.md), [Testing](TESTING.md), [Releasing](RELEASING.md) |
24
+ | Coding agent | [Agent Guide](AGENT_GUIDE.md) | [Configuration](CONFIGURATION.md), then command help |
25
+ | Maintainer | [Contributing](../CONTRIBUTING.md) | [Testing](TESTING.md), [Releasing](RELEASING.md), [Architecture](ARCHITECTURE.md) |
26
+ | Package author | [Packages and Extensions](EXTENSIONS.md) | [SDK](SDK.md), [starter extension](examples/starter-extension/README.md) |
27
+ | Codex or ChatGPT plugin implementer | [Codex Plugin](CODEX_PLUGIN.md) | [Native ChatGPT and Codex Plugin Implementation Plan](CHATGPT_CODEX_PLUGIN_IMPLEMENTATION.md) |
28
+ | Codex user | [Codex Plugin](CODEX_PLUGIN.md) | [Agent Guide](AGENT_GUIDE.md), then [Command Reference](COMMANDS.md) |
29
+ | Claude Code user | [Claude Code Plugin](CLAUDE_CODE_PLUGIN.md) | [Agent Guide](AGENT_GUIDE.md), then [Command Reference](COMMANDS.md) |
30
+ | Machine client | `pm contracts --json` | [CLI Scripting Contract](SCRIPTING.md), [Command Reference](COMMANDS.md#machine-contracts), optionally `pm install guide-shell --project && pm guide commands` |
31
31
 
32
32
  ## Documentation Map
33
33
 
@@ -35,7 +35,7 @@ pm guide release --json
35
35
  - [Onboarding](ONBOARDING.md) - first-two-hours maintainer and contributor setup.
36
36
  - [Agent Guide](AGENT_GUIDE.md) - canonical agent loop, tracker linking, and token-minimal command choices.
37
37
  - [Command Reference](COMMANDS.md) - command families with examples and when to use each family.
38
- - [CLI Scripting Contract](SCRIPTING.md) - exit codes, stdout/stderr boundaries, stable JSON fields, uniform OR filters, and shell composition recipes.
38
+ - [CLI Scripting Contract](SCRIPTING.md) - exit codes, flat mutation receipts versus read envelopes, stdout/stderr boundaries, stable JSON fields, uniform OR filters, and shell composition recipes.
39
39
  - [Configuration](CONFIGURATION.md) - settings, storage formats, output, search, validation, and environment variables.
40
40
  - [Testing](TESTING.md) - sandbox-safe local tests and linked-test orchestration.
41
41
  - [Security Governance](SECURITY_GOVERNANCE.md) - vulnerability reporting, review discipline, property fuzzing, and OpenSSF limitations.
@@ -72,16 +72,16 @@ pm guide release --json
72
72
 
73
73
  ## Guide Topic Map
74
74
 
75
- | Optional `pm guide` topic | Primary docs |
76
- |-----------------------------|--------------|
77
- | `quickstart` | [Quickstart](QUICKSTART.md), [Command Reference](COMMANDS.md) |
78
- | `commands` | [Command Reference](COMMANDS.md), [Configuration](CONFIGURATION.md) |
79
- | `workflows` | [Agent Guide](AGENT_GUIDE.md), [Testing](TESTING.md) |
80
- | `sdk` | [SDK](SDK.md), [Architecture](ARCHITECTURE.md) |
81
- | `extensions`, `packages` | [Packages and Extensions](EXTENSIONS.md), [starter extension](examples/starter-extension/README.md) |
82
- | `skills` | [Agent Guide](AGENT_GUIDE.md) plus `.agents/skills/*` |
83
- | `harnesses` | [Agent Guide](AGENT_GUIDE.md) plus `.agents/skills/HARNESS_COMPATIBILITY.md` |
84
- | `release` | [Releasing](RELEASING.md), [CHANGELOG](../CHANGELOG.md) |
75
+ | Optional `pm guide` topic | Primary docs |
76
+ | ------------------------- | --------------------------------------------------------------------------------------------------- |
77
+ | `quickstart` | [Quickstart](QUICKSTART.md), [Command Reference](COMMANDS.md) |
78
+ | `commands` | [Command Reference](COMMANDS.md), [Configuration](CONFIGURATION.md) |
79
+ | `workflows` | [Agent Guide](AGENT_GUIDE.md), [Testing](TESTING.md) |
80
+ | `sdk` | [SDK](SDK.md), [Architecture](ARCHITECTURE.md) |
81
+ | `extensions`, `packages` | [Packages and Extensions](EXTENSIONS.md), [starter extension](examples/starter-extension/README.md) |
82
+ | `skills` | [Agent Guide](AGENT_GUIDE.md) plus `.agents/skills/*` |
83
+ | `harnesses` | [Agent Guide](AGENT_GUIDE.md) plus `.agents/skills/HARNESS_COMPATIBILITY.md` |
84
+ | `release` | [Releasing](RELEASING.md), [CHANGELOG](../CHANGELOG.md) |
85
85
 
86
86
  Community files:
87
87
 
package/docs/RELEASING.md CHANGED
@@ -66,7 +66,7 @@ pnpm version:check
66
66
  Policy:
67
67
 
68
68
  - release only when commits exist after the latest release tag
69
- - ignore `.agents/pm`-only tracker commits for publish eligibility so post-release evidence and closure updates do not create a package release by themselves
69
+ - ignore tracker-governance-only commits for publish eligibility: `.agents/pm/**` and the mechanically generated `CHANGELOG.md` projection do not create a package release by themselves, while any product, test, documentation, workflow, or other changed path remains release-relevant
70
70
  - create at most one production tag and npm version per UTC day; if no tag was
71
71
  created, a non-`github-actions[bot]` closure of the exact bot-created
72
72
  `Auto Release blocked` issue on the same UTC day triggers one preparation
@@ -103,7 +103,7 @@ The pipeline performs:
103
103
  2. a single `YYYY.M.D` version bump; ordinal targets and the removed
104
104
  `--allow-same-day-release` override fail closed
105
105
  3. latest `pm-changelog` install and main changelog refresh through package-owned full-history generation; the release pipeline passes `--release-version` with `--all-release-tags` so the pending release section matches post-tag CI checks
106
- 4. strict gates (build, typecheck, docs/skills freshness, coverage, static quality, compatibility, security, smoke checks, reliability gate)
106
+ 4. build, clone-local merge-driver installation, then the remaining strict gates (typecheck, docs/skills freshness, coverage, static quality, compatibility, security, smoke checks, reliability gate); this ordering makes the checkout-owned CLI available before bootstrap, matches CI, and prevents fresh-clone tracker measurements from observing undeclared merge-driver repairs
107
107
  5. release note generation from changelog + pm evidence
108
108
  6. commit and tag creation (plus optional push)
109
109
 
@@ -337,7 +337,7 @@ Use the npm registry package for maintainer global updates. Do not use `npm inst
337
337
 
338
338
  When auto-release exits green but does not cut a version, inspect the pipeline's JSON skip `reason` from `scripts/release/run-release-pipeline.mjs` (or rerun locally with `pnpm release:pipeline:dry-run -- --json`):
339
339
 
340
- - tracker-only skip family: `tracker_only_changes_since_last_tag` (all changed paths are `.agents/pm` only)
340
+ - tracker-only skip family: `tracker_only_changes_since_last_tag` (all changed paths are `.agents/pm/**` and/or the generated `CHANGELOG.md` projection; a product-visible path is the required negative control)
341
341
  - changelog-empty skip family: `empty_generated_changelog_section_for_target_version` (generated release section exists but has no non-empty entries)
342
342
 
343
343
  `pm-changelog` is maintained in a separate repository/package. Classifier or release-window bugs must be fixed and released there first, then consumed here via the latest npm package (`pm install npm:pm-changelog --project`) before rerunning release generation.
package/docs/SCRIPTING.md CHANGED
@@ -1,19 +1,19 @@
1
1
  # CLI Scripting Contract
2
2
 
3
- Tracked by [pm-psy1](../.agents/pm/tasks/pm-psy1.toon), [pm-gknu](../.agents/pm/issues/pm-gknu.toon), and [pm-999jh7](../.agents/pm/issues/pm-999jh7.toon).
3
+ Tracked by [pm-psy1](../.agents/pm/tasks/pm-psy1.toon), [pm-gknu](../.agents/pm/issues/pm-gknu.toon), [pm-999jh7](../.agents/pm/issues/pm-999jh7.toon), and [pm-srns](../.agents/pm/issues/pm-srns.toon).
4
4
 
5
5
  Use this contract when composing `pm` with shells, CI runners, `jq`, or another process. Exact flags remain discoverable from `pm <command> --help --json` and `pm contracts --command <command> --flags-only --json`.
6
6
 
7
7
  ## Process Contract
8
8
 
9
- | Exit | Meaning | Script response |
10
- |------|---------|-----------------|
11
- | `0` | The requested operation completed. A successful read may still return zero rows. | Parse stdout. |
12
- | `1` | Runtime or unexpected failure. | Preserve stderr and stop. |
13
- | `2` | Invalid flags, values, or command composition. | Correct the invocation; do not retry unchanged. |
14
- | `3` | Requested tracker or resource was not found. | Correct the path or ID. |
15
- | `4` | State or concurrency conflict. | Refresh live state before deciding whether to retry. |
16
- | `5` | A required dependency operation failed. | Inspect the dependency evidence before retrying. |
9
+ | Exit | Meaning | Script response |
10
+ | ---- | -------------------------------------------------------------------------------- | ---------------------------------------------------- |
11
+ | `0` | The requested operation completed. A successful read may still return zero rows. | Parse stdout. |
12
+ | `1` | Runtime or unexpected failure. | Preserve stderr and stop. |
13
+ | `2` | Invalid flags, values, or command composition. | Correct the invocation; do not retry unchanged. |
14
+ | `3` | Requested tracker or resource was not found. | Correct the path or ID. |
15
+ | `4` | State or concurrency conflict. | Refresh live state before deciding whether to retry. |
16
+ | `5` | A required dependency operation failed. | Inspect the dependency evidence before retrying. |
17
17
 
18
18
  Successful structured results are written to stdout. Diagnostics, warnings, profiles, and errors are written to stderr so `--json`, `--format ndjson`, CSV, and table stdout remain pipe-safe. Never merge stderr into stdout before parsing structured output.
19
19
 
@@ -29,6 +29,29 @@ fi
29
29
 
30
30
  ## Stable Structured Fields
31
31
 
32
+ Mutation and read envelopes are intentionally different. Single-item mutation
33
+ commands emit a flat receipt whose `id`, `status`, and `changed_field_count`
34
+ are top-level fields. Reads wrap their primary entity or rows under documented
35
+ keys such as `item` or `items`. Bulk mutations such as `close-many` and
36
+ `update-many` use collection envelopes under `rows`; consult
37
+ `command_output_contracts` for the exact command path. Never infer one shape
38
+ from another.
39
+
40
+ TypeScript package consumers should parse mutation stdout with the SDK boundary
41
+ helper so a wrapped or malformed result fails loudly:
42
+
43
+ ```ts
44
+ import { parseMutationReceipt } from "@unbrained/pm-cli/sdk/contracts";
45
+
46
+ const { id, status, changedFieldCount } = parseMutationReceipt(stdout);
47
+ ```
48
+
49
+ `pm contracts --summary --json` keeps bootstrap discovery compact while
50
+ declaring every command's default token ceiling. Use `pm contracts --full
51
+ --json` for `command_output_contracts`, which pairs the envelope declaration
52
+ with TOON- and JSON-specific token ceilings for every active core or package
53
+ command.
54
+
32
55
  JSON object field order is not an API. Consume fields by name. Read envelopes keep the stable pagination vocabulary `items`, `count`, `total`, `has_more`, and, when another page exists, `next_cursor`. The `filters` object echoes the effective query scope. Plain `pm list` and `pm search` are all-status reads and disclose `filters.status: "all"`; lifecycle-specific commands such as `pm list-open` remain explicit shortcuts.
33
56
 
34
57
  Projection flags intentionally change row shape. Use `--fields` when a script requires an exact subset, `--brief` or `--compact` only when the documented sparse shape is sufficient, and `--full` when linked metadata is required. Check `row_contract` on generic read surfaces that expose one; do not infer omitted fields as empty values.