@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.
- package/.claude-plugin/marketplace.json +2 -2
- package/CHANGELOG.md +39 -13
- package/dist/cli/error-guidance.js +4 -4
- package/dist/cli/register-structured-mutation.d.ts +2 -0
- package/dist/cli/register-structured-mutation.js +124 -12
- package/dist/cli-bundle/bundle-manifest.json +407 -407
- package/dist/cli-bundle/chunks/append-VXXGOXSG.js +2 -0
- package/dist/cli-bundle/chunks/{chunk-QVO3VTA4.js → chunk-2WFXWAYX.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-NM5G7RLU.js → chunk-3FTILRJ2.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-VH2EAGUG.js → chunk-42E7YPLG.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-RB65T4RX.js → chunk-43HQQI6S.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-J4EPW4GT.js → chunk-45G53IU4.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-PQXEB7W4.js → chunk-4VN6GS4U.js} +2 -2
- package/dist/cli-bundle/chunks/chunk-4YUBDMQM.js +2 -0
- package/dist/cli-bundle/chunks/{chunk-D2MBVMVE.js → chunk-54FNT7U2.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-NRDKVOUE.js → chunk-5ZBOIPGP.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-3XZYTRPC.js → chunk-6MSQJOTG.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-GOICHIX4.js → chunk-7A5OT5J2.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-HTYC76A4.js → chunk-7C4PTJG6.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-BKMZTZYL.js → chunk-A62CYISG.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-5H47J5FG.js → chunk-BPELKUQD.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-HE3DZFN4.js → chunk-BXQLRKWF.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-BLINBTMX.js → chunk-CSI3WS5I.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-KH4GVBMC.js → chunk-DXDREUXT.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-KIKLF2W4.js → chunk-E2RKBKWB.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-377OOXUF.js → chunk-EGJ4JTUG.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-SULWTPQO.js → chunk-FPBQHMFT.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-V5K52PYW.js → chunk-GE4KCSZP.js} +35 -35
- package/dist/cli-bundle/chunks/{chunk-NPUJ7OLK.js → chunk-HNFD72UK.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-QMWUL66F.js → chunk-HWRRMBJO.js} +5 -5
- package/dist/cli-bundle/chunks/chunk-L3AZOELJ.js +2 -0
- package/dist/cli-bundle/chunks/{chunk-CGY5I2GO.js → chunk-LKDGK44W.js} +2 -2
- package/dist/cli-bundle/chunks/chunk-LN2WFEU4.js +2 -0
- package/dist/cli-bundle/chunks/{chunk-ZSH4GNBH.js → chunk-M72BKL5Q.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-HQ2WU7OY.js → chunk-MHK6LIWE.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-H6FITE7D.js → chunk-NE5VRDAI.js} +2 -2
- package/dist/cli-bundle/chunks/chunk-NY4T3JWN.js +2 -0
- package/dist/cli-bundle/chunks/{chunk-DCJ6CM6F.js → chunk-OMXVBQ2N.js} +2 -2
- package/dist/cli-bundle/chunks/chunk-OPVH7SKD.js +8 -0
- package/dist/cli-bundle/chunks/{chunk-CU5ENFNP.js → chunk-OTHLDSFP.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-NH35JNK5.js → chunk-PMXJEU3F.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-SVDH5CHC.js → chunk-Q35VBGOQ.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-5PZGZMPG.js → chunk-R546TPDE.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-Q5F6OI7C.js → chunk-RKAVWO3O.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-JMKVCQSE.js → chunk-SSF4PIUR.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-PA5XRN2A.js → chunk-UN66FZRO.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-FQ4EFFDU.js → chunk-UP7DTVMD.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-NFF3JAQR.js → chunk-UZBWIUYD.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-2POYGY53.js → chunk-V3774P7D.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-B5ZLCD5Z.js → chunk-V3EUXXOF.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-6S7I3UKV.js → chunk-VCKLFEUN.js} +19 -19
- package/dist/cli-bundle/chunks/{chunk-PYYPQLHC.js → chunk-VN5VITU3.js} +2 -2
- package/dist/cli-bundle/chunks/chunk-WRL4KNDL.js +20 -0
- package/dist/cli-bundle/chunks/{chunk-UJHUR3LZ.js → chunk-XCEZYMNI.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-JDPKBV5P.js → chunk-YEWNL576.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-OB7TRZ2G.js → chunk-YSO3YFZ4.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-UVZREFZU.js → chunk-ZYHOB3SN.js} +2 -2
- package/dist/cli-bundle/chunks/close-VZ3OQPN5.js +2 -0
- package/dist/cli-bundle/chunks/close-many-SB4TI27P.js +2 -0
- package/dist/cli-bundle/chunks/comments-BIF3Q4KY.js +2 -0
- package/dist/cli-bundle/chunks/copy-6AI5Z57X.js +2 -0
- package/dist/cli-bundle/chunks/{create-RLLCBCXM.js → create-XLKTXTUF.js} +2 -2
- package/dist/cli-bundle/chunks/delete-ZY2VHQTP.js +2 -0
- package/dist/cli-bundle/chunks/{deps-J4ONTF4X.js → deps-ITTY3GIC.js} +2 -2
- package/dist/cli-bundle/chunks/{docs-YL2DJ4WD.js → docs-W4OSRTYR.js} +2 -2
- package/dist/cli-bundle/chunks/{files-NGNAIYKK.js → files-EOK4AZI4.js} +2 -2
- package/dist/cli-bundle/chunks/focus-DLBNWL7L.js +2 -0
- package/dist/cli-bundle/chunks/{history-compact-HW62K5XP.js → history-compact-7UGTMLL3.js} +2 -2
- package/dist/cli-bundle/chunks/{history-redact-HVBKUJOW.js → history-redact-4DZRMD6Z.js} +2 -2
- package/dist/cli-bundle/chunks/{history-repair-OPNBH5JJ.js → history-repair-UPOSZW5R.js} +2 -2
- package/dist/cli-bundle/chunks/{learnings-F36PZXT6.js → learnings-GMRNCBS3.js} +2 -2
- package/dist/cli-bundle/chunks/{profile-N3XMWBM7.js → profile-2MUUMHRE.js} +2 -2
- package/dist/cli-bundle/chunks/{register-list-query-BKGHBI7Y.js → register-list-query-LR3SQ5ZF.js} +2 -2
- package/dist/cli-bundle/chunks/register-mutation-SUOHFVWM.js +20 -0
- package/dist/cli-bundle/chunks/register-operations-ARRRKOVN.js +2 -0
- package/dist/cli-bundle/chunks/{register-setup-KWV6UD77.js → register-setup-O6AYP6NP.js} +2 -2
- package/dist/cli-bundle/chunks/restore-ZVCVHTB5.js +2 -0
- package/dist/cli-bundle/chunks/{schema-4PJQMGUY.js → schema-FJ4EA3XF.js} +2 -2
- package/dist/cli-bundle/chunks/update-YHV52CSS.js +2 -0
- package/dist/cli-bundle/chunks/update-many-M6YHVNXM.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-7J5TUBUJ.js +153 -0
- package/dist/cli-bundle/focused-chunks/{chunk-ONIX2KKW.js → chunk-A7BJ5SS6.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-B7LJWAZE.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-QM2BIVK7.js → chunk-BIMTMOS7.js} +3 -3
- package/dist/cli-bundle/focused-chunks/{chunk-BOGRY7M6.js → chunk-FGKY4MBE.js} +10 -10
- package/dist/cli-bundle/focused-chunks/chunk-G6ETT4QK.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-C2QSL62X.js → chunk-GJ2TG2CW.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-RO5BQFG3.js → chunk-IPWSFADF.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-UFCPSWIL.js → chunk-MJ7HWSFK.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-2VIIXOAD.js → chunk-N5XU5UVK.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-PG2RIZBX.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-OYTK4VNH.js → chunk-PIMMYG7Q.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-K37BB4JL.js → chunk-QVHKCI4T.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-SQXVGHMH.js → chunk-RUR5I3TK.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-SV3O7TSH.js +8 -0
- package/dist/cli-bundle/focused-chunks/{chunk-L6A4NVQC.js → chunk-UIL2M2NA.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-WVGJAD7L.js → chunk-VLYOEYML.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-W7BJEWHX.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-DQ4PLKEE.js → chunk-WEM2E2PE.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-WVIVUWVL.js +5 -0
- package/dist/cli-bundle/focused-chunks/chunk-Y4LDYLLT.js +2 -0
- package/dist/cli-bundle/main.js +4 -4
- package/dist/cli-bundle/sdk-authoring.js +1 -1
- package/dist/cli-bundle/sdk-contracts.js +1 -1
- package/dist/cli-bundle/sdk-core.js +28 -28
- package/dist/cli-bundle/sdk-governance.js +1 -1
- package/dist/cli-bundle/sdk-graph.js +1 -1
- package/dist/cli-bundle/sdk-merge.js +1 -1
- package/dist/cli-bundle/sdk-query.js +1 -1
- package/dist/cli-bundle/sdk-runtime.js +1 -1
- package/dist/cli-bundle/sdk-testing.js +1 -1
- package/dist/cli-bundle/sdk.js +1 -1
- package/dist/core/extensions/loader.js +5 -2
- package/dist/core/item/item-format.js +14 -20
- package/dist/core/shared/constants.js +3 -2
- package/dist/core/store/item-store.js +2 -2
- package/dist/core/store/settings.js +2 -2
- package/dist/mcp/server.js +12 -6
- package/dist/mcp/tool-definitions.js +14 -7
- package/dist/sdk/cli-contracts/agent-output-contracts.d.ts +18 -18
- package/dist/sdk/cli-contracts/agent-output-contracts.js +51 -23
- package/dist/sdk/cli-contracts/commander-mutation-options.js +26 -2
- package/dist/sdk/cli-contracts/flag-contracts.d.ts +2 -0
- package/dist/sdk/cli-contracts/flag-contracts.js +28 -2
- package/dist/sdk/cli-contracts/registration-helpers.js +4 -2
- package/dist/sdk/cli-contracts/runtime-contracts.d.ts +10 -2
- package/dist/sdk/cli-contracts/runtime-contracts.js +20 -5
- package/dist/sdk/cli-contracts/tool-schema.js +4 -2
- package/dist/sdk/cli-contracts.d.ts +2 -2
- package/dist/sdk/cli-contracts.js +4 -4
- package/dist/sdk/cli-program.js +3 -3
- package/dist/sdk/contracts.d.ts +1 -0
- package/dist/sdk/contracts.js +3 -2
- package/dist/sdk/dependency-provenance.d.ts +2 -0
- package/dist/sdk/dependency-provenance.js +7 -3
- package/dist/sdk/error-code-catalog.d.ts +23 -0
- package/dist/sdk/error-code-catalog.js +25 -5
- package/dist/sdk/generated-error-code-catalog.js +499 -3
- package/dist/sdk/graph/governance.js +3 -3
- package/dist/sdk/graph/remediation.js +3 -3
- package/dist/sdk/graph/run.js +4 -8
- package/dist/sdk/index.d.ts +2 -1
- package/dist/sdk/index.js +4 -3
- package/dist/sdk/item-transaction.d.ts +51 -6
- package/dist/sdk/item-transaction.js +132 -22
- package/dist/sdk/lifecycle/create.d.ts +4 -0
- package/dist/sdk/lifecycle/create.js +26 -10
- package/dist/sdk/lifecycle-policy.d.ts +9 -0
- package/dist/sdk/lifecycle-policy.js +22 -9
- package/dist/sdk/merge/driver.js +6 -3
- package/dist/sdk/output-contracts.d.ts +67 -0
- package/dist/sdk/output-contracts.js +173 -0
- package/dist/sdk/package-import-adapters.js +2 -2
- package/dist/sdk/structured-mutations.d.ts +23 -0
- package/dist/sdk/structured-mutations.js +219 -10
- package/dist/sdk/workspace-snapshot.js +58 -12
- package/dist/sdk/workspace.js +30 -4
- package/docs/COMMANDS.md +40 -10
- package/docs/EXTENSIONS.md +1 -1
- package/docs/MERGE_SAFETY.md +2 -0
- package/docs/PR_REVIEW_LOOP.md +10 -4
- package/docs/README.md +22 -22
- package/docs/RELEASING.md +3 -3
- package/docs/SCRIPTING.md +32 -9
- package/docs/SDK.md +91 -11
- package/docs/SELF_DESCRIBING_CONTEXT_CONTRACTS.md +13 -0
- package/docs/TESTING.md +25 -0
- package/docs/examples/sdk-contract-consumer/README.md +11 -1
- package/docs/examples/sdk-contract-consumer/package.json +2 -1
- package/docs/examples/sdk-contract-consumer/parse-receipt.mjs +22 -0
- package/marketplace.json +2 -2
- package/package.json +3 -2
- package/packages/pm-beads/package.json +1 -1
- package/packages/pm-calendar/package.json +1 -1
- package/packages/pm-command-kit/package.json +1 -1
- package/packages/pm-digital-twin/package.json +1 -1
- package/packages/pm-governance-audit/package.json +1 -1
- package/packages/pm-guide-shell/package.json +1 -1
- package/packages/pm-kanban/package.json +1 -1
- package/packages/pm-lifecycle-hooks/package.json +1 -1
- package/packages/pm-linked-test-adapters/package.json +1 -1
- package/packages/pm-search-advanced/package.json +1 -1
- package/packages/pm-templates/package.json +1 -1
- package/packages/pm-todos/package.json +1 -1
- package/packages/pm-vcs/package.json +1 -1
- package/plugins/pm-claude/.claude-plugin/plugin.json +1 -1
- package/plugins/pm-codex/.codex-plugin/plugin.json +1 -1
- package/sdk/public-surface.json +292 -14
- package/dist/cli-bundle/chunks/append-DHBRLHHS.js +0 -2
- package/dist/cli-bundle/chunks/chunk-2INN52SU.js +0 -8
- package/dist/cli-bundle/chunks/chunk-6RSK4IFN.js +0 -20
- package/dist/cli-bundle/chunks/chunk-ASJJKA57.js +0 -2
- package/dist/cli-bundle/chunks/chunk-IYAVULRN.js +0 -2
- package/dist/cli-bundle/chunks/chunk-RRQBHQOV.js +0 -2
- package/dist/cli-bundle/chunks/chunk-XBLOD5TZ.js +0 -2
- package/dist/cli-bundle/chunks/close-VLHNN6YB.js +0 -2
- package/dist/cli-bundle/chunks/close-many-LSJNZKU6.js +0 -2
- package/dist/cli-bundle/chunks/comments-AAIA6A6X.js +0 -2
- package/dist/cli-bundle/chunks/copy-Z7YMLEHN.js +0 -2
- package/dist/cli-bundle/chunks/delete-KNOHHQJM.js +0 -2
- package/dist/cli-bundle/chunks/focus-LFRCGALV.js +0 -2
- package/dist/cli-bundle/chunks/register-mutation-GU3DCECN.js +0 -20
- package/dist/cli-bundle/chunks/register-operations-PTWH727R.js +0 -2
- package/dist/cli-bundle/chunks/restore-4HZSLILR.js +0 -2
- package/dist/cli-bundle/chunks/update-E6LPS5IV.js +0 -2
- package/dist/cli-bundle/chunks/update-many-OSIC6KRO.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-5MTKO7TV.js +0 -153
- package/dist/cli-bundle/focused-chunks/chunk-6GIZK7VQ.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-AOP2WIZZ.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-CL75YW32.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-E7OFMWGT.js +0 -8
- package/dist/cli-bundle/focused-chunks/chunk-I5F5UK3Q.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-T5TSY36R.js +0 -5
- 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]="
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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=
|
|
567
|
+
//# debugId=3e32be7c-f8a4-547d-8c19-456b4567982e
|
package/dist/sdk/workspace.js
CHANGED
|
@@ -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]="
|
|
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=
|
|
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`
|
|
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
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
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
|
-
|
|
530
|
-
|
|
531
|
-
|
|
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.
|
package/docs/EXTENSIONS.md
CHANGED
|
@@ -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,
|
|
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:
|
package/docs/MERGE_SAFETY.md
CHANGED
|
@@ -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:
|
package/docs/PR_REVIEW_LOOP.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Pull Request Review Loop
|
|
2
2
|
|
|
3
|
-
|
|
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
|
-
|
|
23
|
-
|
|
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
|
|
21
|
-
|
|
22
|
-
| New user
|
|
23
|
-
| New maintainer
|
|
24
|
-
| Coding agent
|
|
25
|
-
| Maintainer
|
|
26
|
-
| Package author
|
|
27
|
-
| Codex or ChatGPT plugin implementer | [Codex Plugin](CODEX_PLUGIN.md)
|
|
28
|
-
| Codex user
|
|
29
|
-
| Claude Code user
|
|
30
|
-
| Machine client
|
|
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`
|
|
78
|
-
| `commands`
|
|
79
|
-
| `workflows`
|
|
80
|
-
| `sdk`
|
|
81
|
-
| `extensions`, `packages`
|
|
82
|
-
| `skills`
|
|
83
|
-
| `harnesses`
|
|
84
|
-
| `release`
|
|
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
|
|
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 (
|
|
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`
|
|
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),
|
|
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
|
|
10
|
-
|
|
11
|
-
| `0`
|
|
12
|
-
| `1`
|
|
13
|
-
| `2`
|
|
14
|
-
| `3`
|
|
15
|
-
| `4`
|
|
16
|
-
| `5`
|
|
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.
|