@unbrained/pm-cli 2026.9.3 → 2026.9.4
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 +27 -0
- package/dist/cli-bundle/bundle-manifest.json +146 -146
- package/dist/cli-bundle/chunks/{chunk-E5RBBCXO.js → chunk-6XSKPNCF.js} +75 -75
- package/dist/cli-bundle/chunks/chunk-A24WAVE6.js +8 -0
- package/dist/cli-bundle/chunks/{chunk-DKGP3QLE.js → chunk-HI6BHPCU.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-Y4PJ6HPK.js → chunk-I2AS367G.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-IEHHE6GA.js → chunk-OGBVU67G.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-EDPIS7EB.js → chunk-RI4XNOYS.js} +2 -2
- package/dist/cli-bundle/chunks/chunk-TXW6VL33.js +38 -0
- package/dist/cli-bundle/chunks/{chunk-LENC656S.js → chunk-V72UV7QS.js} +76 -79
- package/dist/cli-bundle/chunks/chunk-VGLHECAP.js +9 -0
- package/dist/cli-bundle/chunks/{chunk-34HASX3S.js → chunk-X6CMGV6L.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-UPPM2FOZ.js → chunk-YW4QK2G7.js} +2 -2
- package/dist/cli-bundle/chunks/{register-list-query-W2ZTOMKP.js → register-list-query-Z5YYSJJG.js} +2 -2
- package/dist/cli-bundle/chunks/{register-mutation-RVND5NCG.js → register-mutation-ELSP6I4I.js} +2 -2
- package/dist/cli-bundle/chunks/{register-operations-TTROIVC4.js → register-operations-OH7R3ZT4.js} +2 -2
- package/dist/cli-bundle/chunks/{register-setup-D3ZFHY3L.js → register-setup-E2AE72QG.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-Q45NHPF2.js → chunk-25UJBH4M.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-4HJFY4MB.js → chunk-3646BZ4W.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-TXE4TSHM.js → chunk-4YRAVI43.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-M5M6SVHS.js → chunk-53IHPICX.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-5P4HVOWG.js +176 -0
- package/dist/cli-bundle/focused-chunks/chunk-636VVQ7F.js +54 -0
- package/dist/cli-bundle/focused-chunks/{chunk-D7KXFBXV.js → chunk-6PWPQKDN.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-S27XMBIN.js → chunk-7N2TV7WZ.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-5RFXUPN5.js → chunk-AJR3OP2E.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-KZ2NB3ET.js → chunk-B3A6MJYE.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-BWKHEIVF.js → chunk-BFDDJ2T2.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-4WR46RMG.js → chunk-BHUIRZWQ.js} +8 -8
- package/dist/cli-bundle/focused-chunks/{chunk-4RRHC3S4.js → chunk-JADHHPY6.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-GT7MXDLW.js → chunk-MHKUIPJW.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-NBMJD6MK.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-NSKBLHVI.js +20 -0
- package/dist/cli-bundle/focused-chunks/{chunk-OL5EH6I3.js → chunk-P2GOAOQN.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-UCLO3XDU.js → chunk-YARWJM2B.js} +2 -2
- package/dist/cli-bundle/main.js +2 -2
- 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 -31
- 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 +42 -37
- package/dist/cli-bundle/sdk-query.js +1 -1
- package/dist/cli-bundle/sdk-runtime.js +1 -1
- package/dist/cli-bundle/sdk-testing.js +1 -1
- package/dist/cli-bundle/sdk.js +10 -10
- package/dist/core/diagnostics/remediation.js +4 -4
- package/dist/core/history/history.d.ts +37 -1
- package/dist/core/history/history.js +278 -58
- package/dist/core/history/replay.js +68 -34
- package/dist/core/lock/lock.d.ts +10 -0
- package/dist/core/lock/lock.js +42 -3
- package/dist/core/shared/author.d.ts +3 -1
- package/dist/core/shared/author.js +111 -23
- package/dist/sdk/environment/agent-environment.d.ts +296 -0
- package/dist/sdk/environment/agent-environment.js +467 -0
- package/dist/sdk/environment/project-runtime-compatibility.d.ts +19 -1
- package/dist/sdk/environment/project-runtime-compatibility.js +118 -21
- package/dist/sdk/generated/generated-error-code-catalog-part-1.js +14 -2
- package/dist/sdk/generated/generated-error-code-catalog-part-2.js +14 -14
- package/dist/sdk/governance/health.js +13 -44
- package/dist/sdk/governance/merge-receipt-history.d.ts +62 -0
- package/dist/sdk/governance/merge-receipt-history.js +207 -0
- package/dist/sdk/governance/provenance-health.js +9 -3
- package/dist/sdk/history-compact.js +14 -5
- package/dist/sdk/history-redact.js +58 -23
- package/dist/sdk/history-repair.js +16 -6
- package/dist/sdk/index.d.ts +2 -0
- package/dist/sdk/index.js +4 -2
- package/dist/sdk/merge/driver.d.ts +3 -1
- package/dist/sdk/merge/driver.js +9 -9
- package/dist/sdk/merge/index.d.ts +1 -1
- package/dist/sdk/merge/index.js +3 -3
- package/dist/sdk/merge/receipts.d.ts +17 -6
- package/dist/sdk/merge/receipts.js +246 -75
- package/dist/sdk/merge/reconcile.d.ts +9 -7
- package/dist/sdk/merge/reconcile.js +175 -12
- package/dist/sdk/merge/three-way.d.ts +22 -2
- package/dist/sdk/merge/three-way.js +92 -25
- package/dist/sdk/runtime-primitives.d.ts +2 -2
- package/dist/sdk/runtime-primitives.js +4 -4
- package/dist/types.d.ts +25 -0
- package/dist/types.js +2 -2
- package/docs/AGENT_ENVIRONMENTS.md +47 -0
- package/docs/AGENT_PROVENANCE_ADR.md +17 -2
- package/docs/CONTEXT_INTEGRITY_CONTRACTS.md +38 -1
- package/docs/MERGE_SAFETY.md +119 -23
- package/docs/README.md +1 -0
- package/docs/SDK_CONTEXT_EVIDENCE_CONTRACTS.md +24 -2
- package/docs/SDK_RUNTIME_BOUNDARIES.md +17 -1
- package/docs/examples/sdk-agent-environment/README.md +14 -0
- package/docs/examples/sdk-agent-environment/package.json +8 -0
- package/docs/examples/sdk-agent-environment/run-agent-environment.mjs +154 -0
- package/docs/generated/REFUSAL_CLOSURE_CENSUS.md +4 -3
- package/marketplace.json +2 -2
- package/package.json +2 -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 +534 -24
- package/dist/cli-bundle/chunks/chunk-AY324UJ5.js +0 -9
- package/dist/cli-bundle/chunks/chunk-L7B7343B.js +0 -8
- package/dist/cli-bundle/chunks/chunk-LISESA7W.js +0 -35
- package/dist/cli-bundle/focused-chunks/chunk-3ZBI35HU.js +0 -176
- package/dist/cli-bundle/focused-chunks/chunk-GHCZ3YFR.js +0 -20
- package/dist/cli-bundle/focused-chunks/chunk-KBLZRU62.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-QKHCSUGJ.js +0 -51
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* leaving diagnosis reads available.
|
|
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]="f9737b75-b285-5fe9-a9ce-63e7c07626cb")}catch(e){}}();
|
|
9
9
|
import fs from "node:fs";
|
|
10
10
|
import path from "node:path";
|
|
11
11
|
import { EXIT_CODE } from "../../core/shared/constants.js";
|
|
@@ -80,6 +80,8 @@ const GLOBAL_VALUE_FLAGS = new Set([
|
|
|
80
80
|
"--pm-path",
|
|
81
81
|
]);
|
|
82
82
|
const VERSION_PATTERN = /\b(\d{4})\.(\d{1,2})\.(\d{1,2})(?:-(\d+))?\b/u;
|
|
83
|
+
/** First pm release whose history writer and reader support item-hash epoch 3. */
|
|
84
|
+
export const HISTORY_ITEM_HASH_VERSION_3_INTRODUCED_IN = "2026.8.31";
|
|
83
85
|
/** Return whether an invocation includes one of the exact mutation switches. */
|
|
84
86
|
function hasAnyToken(argv, tokens) {
|
|
85
87
|
return argv.some((token) => tokens.includes(token.split("=", 1)[0]));
|
|
@@ -194,6 +196,21 @@ export function comparePmDateVersions(left, right) {
|
|
|
194
196
|
}
|
|
195
197
|
return 0;
|
|
196
198
|
}
|
|
199
|
+
/** Resolve the item-hash epoch written by a known pm runtime release. */
|
|
200
|
+
export function historyItemHashVersionForRuntime(version) {
|
|
201
|
+
return comparePmDateVersions(version, HISTORY_ITEM_HASH_VERSION_3_INTRODUCED_IN) !== -1
|
|
202
|
+
? 3
|
|
203
|
+
: 2;
|
|
204
|
+
}
|
|
205
|
+
/** Find the oldest declaration that cannot select a reader for the executing writer epoch. */
|
|
206
|
+
function findIncompatibleHistoryEpochPin(pins, writerItemHashVersion) {
|
|
207
|
+
if (writerItemHashVersion !== 3)
|
|
208
|
+
return undefined;
|
|
209
|
+
return pins
|
|
210
|
+
.filter((pin) => pin.history_epoch_compatible === false)
|
|
211
|
+
.map((pin) => ({ ...pin, declaration: pin.declaration ?? pin.version }))
|
|
212
|
+
.sort((left, right) => comparePmDateVersions(left.version, right.version))[0];
|
|
213
|
+
}
|
|
197
214
|
/** Read one optional JSON object without turning absence or corruption into startup failure. */
|
|
198
215
|
function readJsonRecord(filePath) {
|
|
199
216
|
try {
|
|
@@ -208,27 +225,61 @@ function readJsonRecord(filePath) {
|
|
|
208
225
|
return null;
|
|
209
226
|
}
|
|
210
227
|
}
|
|
211
|
-
/** Extract
|
|
212
|
-
function
|
|
213
|
-
const
|
|
214
|
-
|
|
228
|
+
/** Extract explicit comparator and hyphen upper bounds from one range branch. */
|
|
229
|
+
function rangeUpperBounds(alternative) {
|
|
230
|
+
const comparators = [
|
|
231
|
+
...alternative.matchAll(/(<=|<)\s*v?(\d{4}\.\d{1,2}\.\d{1,2}(?:-\d+)?)/gu),
|
|
232
|
+
].map((match) => ({ inclusive: match[1] === "<=", version: match[2] }));
|
|
233
|
+
const hyphen = alternative.match(/\b\d{4}\.\d{1,2}\.\d{1,2}(?:-\d+)?\s+-\s+v?(\d{4}\.\d{1,2}\.\d{1,2}(?:-\d+)?)/u);
|
|
234
|
+
return hyphen
|
|
235
|
+
? [...comparators, { inclusive: true, version: hyphen[1] }]
|
|
236
|
+
: comparators;
|
|
237
|
+
}
|
|
238
|
+
/** Classify whether a range is bounded and can select an epoch-3 reader. */
|
|
239
|
+
function analyzeHistoryEpochRange(specification) {
|
|
240
|
+
const alternativeBounds = specification
|
|
241
|
+
.split("||")
|
|
242
|
+
.map((alternative) => rangeUpperBounds(alternative));
|
|
243
|
+
return {
|
|
244
|
+
bounded: alternativeBounds.some((bounds) => bounds.length > 0),
|
|
245
|
+
compatible: alternativeBounds.some((bounds) => bounds.every((bound) => {
|
|
246
|
+
const comparison = comparePmDateVersions(HISTORY_ITEM_HASH_VERSION_3_INTRODUCED_IN, bound.version);
|
|
247
|
+
return (comparison !== null &&
|
|
248
|
+
(bound.inclusive ? comparison !== 1 : comparison === -1));
|
|
249
|
+
})),
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
/** Extract every supported pm declaration without letting one section hide another. */
|
|
253
|
+
function dependencyPins(packageJson) {
|
|
254
|
+
return [
|
|
215
255
|
"dependencies",
|
|
216
256
|
"devDependencies",
|
|
217
257
|
"optionalDependencies",
|
|
218
258
|
"peerDependencies",
|
|
219
|
-
]) {
|
|
259
|
+
].flatMap((field) => {
|
|
220
260
|
const dependencies = packageJson[field];
|
|
221
261
|
if (typeof dependencies !== "object" || dependencies === null)
|
|
222
|
-
|
|
262
|
+
return [];
|
|
223
263
|
const value = dependencies[PACKAGE_NAME];
|
|
224
264
|
const specification = typeof value === "string" ? value.trim() : "";
|
|
225
265
|
const version = /^[<!]/u.test(specification)
|
|
226
266
|
? undefined
|
|
227
267
|
: specification.match(VERSION_PATTERN)?.[0];
|
|
228
|
-
if (version)
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
268
|
+
if (!version)
|
|
269
|
+
return [];
|
|
270
|
+
const exact = /^(?:=|v)?\d{4}\.\d{1,2}\.\d{1,2}(?:-\d+)?$/u.test(specification);
|
|
271
|
+
const range = analyzeHistoryEpochRange(specification);
|
|
272
|
+
return [
|
|
273
|
+
{
|
|
274
|
+
version,
|
|
275
|
+
constraint: exact ? "exact" : range.bounded ? "range" : "minimum",
|
|
276
|
+
...(exact ? {} : { declaration: specification }),
|
|
277
|
+
history_epoch_compatible: exact
|
|
278
|
+
? comparePmDateVersions(version, HISTORY_ITEM_HASH_VERSION_3_INTRODUCED_IN) !== -1
|
|
279
|
+
: range.compatible,
|
|
280
|
+
},
|
|
281
|
+
];
|
|
282
|
+
});
|
|
232
283
|
}
|
|
233
284
|
/** Read npm's exact installed package coordinate from package-lock.json. */
|
|
234
285
|
function packageLockPin(projectRoot) {
|
|
@@ -273,23 +324,42 @@ function textLockPin(projectRoot, file) {
|
|
|
273
324
|
export function discoverProjectRuntimeVersionPins(projectRoot) {
|
|
274
325
|
const pins = [];
|
|
275
326
|
const projectPackage = readJsonRecord(path.join(projectRoot, "package.json"));
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
327
|
+
if (projectPackage) {
|
|
328
|
+
pins.push(...dependencyPins(projectPackage).map((pin) => ({
|
|
329
|
+
...pin,
|
|
330
|
+
source: "package.json",
|
|
331
|
+
})));
|
|
332
|
+
}
|
|
279
333
|
const installedPackage = readJsonRecord(path.join(projectRoot, "node_modules", "@unbrained", "pm-cli", "package.json"));
|
|
280
334
|
const installedVersion = installedPackage?.version;
|
|
281
335
|
if (typeof installedVersion === "string" &&
|
|
282
336
|
parseDateVersion(installedVersion)) {
|
|
283
|
-
pins.push({
|
|
337
|
+
pins.push({
|
|
338
|
+
version: installedVersion,
|
|
339
|
+
source: "installed-package",
|
|
340
|
+
constraint: "exact",
|
|
341
|
+
history_epoch_compatible: historyItemHashVersionForRuntime(installedVersion) === 3,
|
|
342
|
+
});
|
|
284
343
|
}
|
|
285
344
|
const packageLockVersion = packageLockPin(projectRoot);
|
|
286
345
|
if (packageLockVersion && parseDateVersion(packageLockVersion)) {
|
|
287
|
-
pins.push({
|
|
346
|
+
pins.push({
|
|
347
|
+
version: packageLockVersion,
|
|
348
|
+
source: "package-lock.json",
|
|
349
|
+
constraint: "exact",
|
|
350
|
+
history_epoch_compatible: historyItemHashVersionForRuntime(packageLockVersion) === 3,
|
|
351
|
+
});
|
|
288
352
|
}
|
|
289
353
|
for (const file of ["pnpm-lock.yaml", "yarn.lock"]) {
|
|
290
354
|
const version = textLockPin(projectRoot, file);
|
|
291
|
-
if (version)
|
|
292
|
-
pins.push({
|
|
355
|
+
if (version) {
|
|
356
|
+
pins.push({
|
|
357
|
+
version,
|
|
358
|
+
source: file,
|
|
359
|
+
constraint: "exact",
|
|
360
|
+
history_epoch_compatible: historyItemHashVersionForRuntime(version) === 3,
|
|
361
|
+
});
|
|
362
|
+
}
|
|
293
363
|
}
|
|
294
364
|
return pins;
|
|
295
365
|
}
|
|
@@ -339,6 +409,9 @@ export function inspectProjectRuntimeCompatibility(options) {
|
|
|
339
409
|
const newest = pins[0];
|
|
340
410
|
const stale = newest !== undefined &&
|
|
341
411
|
comparePmDateVersions(options.executingVersion, newest.version) === -1;
|
|
412
|
+
const writerItemHashVersion = historyItemHashVersionForRuntime(options.executingVersion);
|
|
413
|
+
const incompatibleEpochPin = findIncompatibleHistoryEpochPin(pins, writerItemHashVersion);
|
|
414
|
+
const historyEpochIncompatible = mutating && incompatibleEpochPin !== undefined;
|
|
342
415
|
const warning = stale && !mutating
|
|
343
416
|
? {
|
|
344
417
|
code: "project_runtime_stale_read",
|
|
@@ -353,7 +426,9 @@ export function inspectProjectRuntimeCompatibility(options) {
|
|
|
353
426
|
}
|
|
354
427
|
: undefined;
|
|
355
428
|
return {
|
|
356
|
-
compatible: !mutating ||
|
|
429
|
+
compatible: !mutating ||
|
|
430
|
+
(!stale && !historyEpochIncompatible) ||
|
|
431
|
+
options.allowStale === true,
|
|
357
432
|
executing_version: options.executingVersion,
|
|
358
433
|
...(newest
|
|
359
434
|
? { project_version: newest.version, source: newest.source }
|
|
@@ -361,8 +436,18 @@ export function inspectProjectRuntimeCompatibility(options) {
|
|
|
361
436
|
...(command ? { command } : {}),
|
|
362
437
|
mutating,
|
|
363
438
|
stale,
|
|
439
|
+
history_epoch_incompatible: historyEpochIncompatible,
|
|
440
|
+
writer_item_hash_version: writerItemHashVersion,
|
|
441
|
+
...(incompatibleEpochPin
|
|
442
|
+
? {
|
|
443
|
+
incompatible_project_version: incompatibleEpochPin.declaration,
|
|
444
|
+
incompatible_source: incompatibleEpochPin.source,
|
|
445
|
+
}
|
|
446
|
+
: {}),
|
|
364
447
|
...(warning ? { warning } : {}),
|
|
365
|
-
override_applied:
|
|
448
|
+
override_applied: mutating &&
|
|
449
|
+
(stale || historyEpochIncompatible) &&
|
|
450
|
+
options.allowStale === true,
|
|
366
451
|
};
|
|
367
452
|
}
|
|
368
453
|
/** Refuse stale mutations with a stable SDK error and package-neutral recovery. */
|
|
@@ -370,6 +455,18 @@ export function assertProjectRuntimeCompatibility(options) {
|
|
|
370
455
|
const result = inspectProjectRuntimeCompatibility(options);
|
|
371
456
|
if (result.compatible)
|
|
372
457
|
return result;
|
|
458
|
+
if (result.history_epoch_incompatible) {
|
|
459
|
+
throw new PmCliError(`pm ${result.executing_version} cannot write item-hash epoch ${result.writer_item_hash_version} into a project pinned to pm ${result.incompatible_project_version}.`, EXIT_CODE.CONFLICT, {
|
|
460
|
+
code: "project_runtime_history_epoch_incompatible",
|
|
461
|
+
reason: result.incompatible_source,
|
|
462
|
+
why: `The pinned runtime cannot read item_hash_version ${result.writer_item_hash_version}; allowing the write would break its health and validation gates.`,
|
|
463
|
+
nextSteps: [
|
|
464
|
+
`Upgrade the project's ${PACKAGE_NAME} pin to ${HISTORY_ITEM_HASH_VERSION_3_INTRODUCED_IN} or newer before mutating tracker history.`,
|
|
465
|
+
"For an intentional coordinated migration only, set PM_ALLOW_STALE_CLI=1 for this invocation and record why.",
|
|
466
|
+
"Read-only commands remain available without an override.",
|
|
467
|
+
],
|
|
468
|
+
});
|
|
469
|
+
}
|
|
373
470
|
throw new PmCliError(`pm ${result.executing_version} cannot mutate a project pinned to newer pm ${result.project_version}.`, EXIT_CODE.CONFLICT, {
|
|
374
471
|
code: "project_runtime_stale_mutation",
|
|
375
472
|
reason: result.source,
|
|
@@ -382,4 +479,4 @@ export function assertProjectRuntimeCompatibility(options) {
|
|
|
382
479
|
});
|
|
383
480
|
}
|
|
384
481
|
//# sourceMappingURL=project-runtime-compatibility.js.map
|
|
385
|
-
//# debugId=
|
|
482
|
+
//# debugId=f9737b75-b285-5fe9-a9ce-63e7c07626cb
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/** Generated partition 1 of the exhaustive error-code catalog. */
|
|
2
2
|
|
|
3
|
-
!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]="
|
|
3
|
+
!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]="f9059953-1d3c-5c1c-b739-4ad6cc8815a3")}catch(e){}}();
|
|
4
4
|
export const PM_ERROR_CODE_CATALOG_PART_1 = [
|
|
5
5
|
{
|
|
6
6
|
code: "acceptance_criteria_mutation_conflict",
|
|
@@ -2160,6 +2160,18 @@ export const PM_ERROR_CODE_CATALOG_PART_1 = [
|
|
|
2160
2160
|
canonical_code: "missing_budget",
|
|
2161
2161
|
aliases: [],
|
|
2162
2162
|
},
|
|
2163
|
+
{
|
|
2164
|
+
code: "missing_cli_flag",
|
|
2165
|
+
meaning: "Missing cli flag condition.",
|
|
2166
|
+
stability: "provisional",
|
|
2167
|
+
exit_code: 1,
|
|
2168
|
+
class: "generic_failure",
|
|
2169
|
+
recovery: "Inspect the structured error guidance and retry the suggested command.",
|
|
2170
|
+
sources: ["sdk/cli-contracts/tool-option-contracts.ts"],
|
|
2171
|
+
emitting_commands: ["*"],
|
|
2172
|
+
canonical_code: "missing_cli_flag",
|
|
2173
|
+
aliases: [],
|
|
2174
|
+
},
|
|
2163
2175
|
];
|
|
2164
2176
|
//# sourceMappingURL=generated-error-code-catalog-part-1.js.map
|
|
2165
|
-
//# debugId=
|
|
2177
|
+
//# debugId=f9059953-1d3c-5c1c-b739-4ad6cc8815a3
|
|
@@ -1,19 +1,7 @@
|
|
|
1
1
|
/** Generated partition 2 of the exhaustive error-code catalog. */
|
|
2
2
|
|
|
3
|
-
!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]="
|
|
3
|
+
!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]="f1a77960-6191-5e11-9622-4250be7b0e89")}catch(e){}}();
|
|
4
4
|
export const PM_ERROR_CODE_CATALOG_PART_2 = [
|
|
5
|
-
{
|
|
6
|
-
code: "missing_cli_flag",
|
|
7
|
-
meaning: "Missing cli flag condition.",
|
|
8
|
-
stability: "provisional",
|
|
9
|
-
exit_code: 1,
|
|
10
|
-
class: "generic_failure",
|
|
11
|
-
recovery: "Inspect the structured error guidance and retry the suggested command.",
|
|
12
|
-
sources: ["sdk/cli-contracts/tool-option-contracts.ts"],
|
|
13
|
-
emitting_commands: ["*"],
|
|
14
|
-
canonical_code: "missing_cli_flag",
|
|
15
|
-
aliases: [],
|
|
16
|
-
},
|
|
17
5
|
{
|
|
18
6
|
code: "missing_destination",
|
|
19
7
|
meaning: "Missing destination condition.",
|
|
@@ -499,6 +487,18 @@ export const PM_ERROR_CODE_CATALOG_PART_2 = [
|
|
|
499
487
|
canonical_code: "profile_title_empty",
|
|
500
488
|
aliases: [],
|
|
501
489
|
},
|
|
490
|
+
{
|
|
491
|
+
code: "project_runtime_history_epoch_incompatible",
|
|
492
|
+
meaning: "Project runtime history epoch incompatible condition.",
|
|
493
|
+
stability: "provisional",
|
|
494
|
+
exit_code: 4,
|
|
495
|
+
class: "conflict",
|
|
496
|
+
recovery: "Inspect the structured error guidance and retry the suggested command.",
|
|
497
|
+
sources: ["sdk/environment/project-runtime-compatibility.ts"],
|
|
498
|
+
emitting_commands: ["*"],
|
|
499
|
+
canonical_code: "project_runtime_history_epoch_incompatible",
|
|
500
|
+
aliases: [],
|
|
501
|
+
},
|
|
502
502
|
{
|
|
503
503
|
code: "project_runtime_stale_mutation",
|
|
504
504
|
meaning: "Project runtime stale mutation condition.",
|
|
@@ -2186,4 +2186,4 @@ export const PM_ERROR_CODE_CATALOG_PART_2 = [
|
|
|
2186
2186
|
},
|
|
2187
2187
|
];
|
|
2188
2188
|
//# sourceMappingURL=generated-error-code-catalog-part-2.js.map
|
|
2189
|
-
//# debugId=
|
|
2189
|
+
//# debugId=f1a77960-6191-5e11-9622-4250be7b0e89
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Implements the pm health command surface and its agent-facing runtime behavior.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
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]="9f0077a4-4f0a-540f-9951-2e8a640629c9")}catch(e){}}();
|
|
8
8
|
import fs from "node:fs/promises";
|
|
9
9
|
import path from "node:path";
|
|
10
10
|
import { assertInitializedTracker } from "../environment/tracker-preflight.js";
|
|
@@ -28,7 +28,6 @@ import { EXIT_CODE, PM_CORE_REQUIRED_SUBDIRS, TYPE_TO_FOLDER, } from "../../core
|
|
|
28
28
|
import { findFirstMergeConflictMarker } from "../../core/shared/conflict-markers.js";
|
|
29
29
|
import { PmCliError } from "../../core/shared/errors.js";
|
|
30
30
|
import { toNonEmptyStringOrUndefined } from "../../core/shared/primitives.js";
|
|
31
|
-
import { sha256Hex } from "../../core/shared/serialization.js";
|
|
32
31
|
import { nowIso } from "../../core/shared/time.js";
|
|
33
32
|
import { parseItemDocument } from "../../core/item/item-format.js";
|
|
34
33
|
import { effectiveItemFormatVersion, scanItemFormatVersions, } from "../../core/item/item-format-version.js";
|
|
@@ -47,7 +46,8 @@ import { buildCapabilityContractMetadata, buildRegistrationCollisionRemediation,
|
|
|
47
46
|
import { scanStaleInProgressItems, } from "./stale-work.js";
|
|
48
47
|
import { scanTrackedRuntimeCache } from "./tracked-runtime-cache.js";
|
|
49
48
|
import { auditMergeDriverConfiguration, findGitWorkspaceRoot, } from "../merge/install.js";
|
|
50
|
-
import { inspectMergeReceiptEvidence,
|
|
49
|
+
import { inspectMergeReceiptEvidence, partitionMergeReceipts, } from "../merge/receipts.js";
|
|
50
|
+
import { classifyHistoryMergeReceiptReferences, extractHistoryMergeReceiptDispositions, extractHistoryMergeReceiptReferences, } from "./merge-receipt-history.js";
|
|
51
51
|
import { runHistoryRepair } from "../history-repair.js";
|
|
52
52
|
import { resolveWorkspaceRelationshipKindRegistry } from "../graph/assembly.js";
|
|
53
53
|
import { analyzeHierarchyIntegrity, } from "../graph/hierarchy-integrity.js";
|
|
@@ -279,41 +279,13 @@ async function scanItemIntegrity(pmRoot, typeToFolder, schema) {
|
|
|
279
279
|
}
|
|
280
280
|
return { paths, unreadable, conflictMarkers, parseFailures, formatVersions };
|
|
281
281
|
}
|
|
282
|
-
function mergeReceiptIdsFromHistoryEntry(value) {
|
|
283
|
-
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
284
|
-
return [];
|
|
285
|
-
}
|
|
286
|
-
const context = value.context;
|
|
287
|
-
if (typeof context !== "object" ||
|
|
288
|
-
context === null ||
|
|
289
|
-
Array.isArray(context)) {
|
|
290
|
-
return [];
|
|
291
|
-
}
|
|
292
|
-
const merge = context.merge;
|
|
293
|
-
if (typeof merge !== "object" || merge === null || Array.isArray(merge)) {
|
|
294
|
-
return [];
|
|
295
|
-
}
|
|
296
|
-
const receipts = merge.receipts;
|
|
297
|
-
if (!Array.isArray(receipts))
|
|
298
|
-
return [];
|
|
299
|
-
return receipts.flatMap((receipt) => {
|
|
300
|
-
if (typeof receipt !== "object" ||
|
|
301
|
-
receipt === null ||
|
|
302
|
-
Array.isArray(receipt)) {
|
|
303
|
-
return [];
|
|
304
|
-
}
|
|
305
|
-
const receiptId = receipt.receipt_id;
|
|
306
|
-
return typeof receiptId === "string" && receiptId.length > 0
|
|
307
|
-
? [receiptId]
|
|
308
|
-
: [];
|
|
309
|
-
});
|
|
310
|
-
}
|
|
311
282
|
async function scanHistoryIntegrity(pmRoot) {
|
|
312
283
|
const historyDir = path.join(pmRoot, "history");
|
|
313
284
|
const unreadable = [];
|
|
314
285
|
const conflictMarkers = [];
|
|
315
286
|
const invalidJson = [];
|
|
316
287
|
const mergeReceiptReferences = [];
|
|
288
|
+
const mergeReceiptDispositions = [];
|
|
317
289
|
let files = [];
|
|
318
290
|
try {
|
|
319
291
|
files = (await fs.readdir(historyDir))
|
|
@@ -346,11 +318,12 @@ async function scanHistoryIntegrity(pmRoot) {
|
|
|
346
318
|
return;
|
|
347
319
|
try {
|
|
348
320
|
const parsed = JSON.parse(line);
|
|
349
|
-
mergeReceiptReferences.push(...
|
|
321
|
+
mergeReceiptReferences.push(...extractHistoryMergeReceiptReferences(parsed, itemId).map((reference) => ({
|
|
350
322
|
itemId,
|
|
351
323
|
line: index + 1,
|
|
352
|
-
|
|
324
|
+
...reference,
|
|
353
325
|
})));
|
|
326
|
+
mergeReceiptDispositions.push(...extractHistoryMergeReceiptDispositions(parsed, itemId, index + 1));
|
|
354
327
|
}
|
|
355
328
|
catch {
|
|
356
329
|
invalidJson.push({ id: itemId, line: index + 1 });
|
|
@@ -363,6 +336,7 @@ async function scanHistoryIntegrity(pmRoot) {
|
|
|
363
336
|
conflictMarkers,
|
|
364
337
|
invalidJson,
|
|
365
338
|
mergeReceiptReferences,
|
|
339
|
+
mergeReceiptDispositions,
|
|
366
340
|
};
|
|
367
341
|
}
|
|
368
342
|
function buildHierarchyIntegrityWarnings(analysis) {
|
|
@@ -405,15 +379,8 @@ async function buildIntegrityCheck(pmRoot, typeToFolder, schema, requireMergeDri
|
|
|
405
379
|
pmRoot,
|
|
406
380
|
});
|
|
407
381
|
const availableMergeReceiptIds = new Set(mergeReceiptEvidence.receipts.map((receipt) => receipt.id));
|
|
408
|
-
const
|
|
409
|
-
|
|
410
|
-
.map((reference) => ({
|
|
411
|
-
item_id: reference.itemId,
|
|
412
|
-
history_line: reference.line,
|
|
413
|
-
...(isSafeReceiptId(reference.receiptId)
|
|
414
|
-
? { receipt_id: reference.receiptId }
|
|
415
|
-
: { receipt_reference_hash: sha256Hex(reference.receiptId) }),
|
|
416
|
-
}));
|
|
382
|
+
const historyReceiptClassification = classifyHistoryMergeReceiptReferences(historyScan.mergeReceiptReferences, availableMergeReceiptIds, historyScan.mergeReceiptDispositions);
|
|
383
|
+
const missingMergeReceiptReferences = historyReceiptClassification.missing;
|
|
417
384
|
const pendingMergeReceipts = mergeReceiptEvidence.receipts.filter((receipt) => receipt.state === "pending");
|
|
418
385
|
const { pendingDecisions: pendingMergeDecisions, lossless: losslessMergeReceipts, } = partitionMergeReceipts(pendingMergeReceipts);
|
|
419
386
|
const mergeDriverInstallationMissing = mergeDriverAudit?.status === "missing" &&
|
|
@@ -483,6 +450,8 @@ async function buildIntegrityCheck(pmRoot, typeToFolder, schema, requireMergeDri
|
|
|
483
450
|
lossless_merge_receipts: losslessMergeReceipts.length,
|
|
484
451
|
invalid_merge_receipt_evidence: mergeReceiptEvidence.invalid_evidence_count,
|
|
485
452
|
missing_merge_receipt_history_references: missingMergeReceiptReferences.length,
|
|
453
|
+
accepted_legacy_merge_receipt_references: historyReceiptClassification.acceptedLegacyCount,
|
|
454
|
+
accepted_missing_merge_receipt_dispositions: historyReceiptClassification.acceptedDispositionCount,
|
|
486
455
|
},
|
|
487
456
|
item_unreadable: itemScan.unreadable,
|
|
488
457
|
item_conflict_markers: itemScan.conflictMarkers,
|
|
@@ -2375,4 +2344,4 @@ export const _testOnlyHealthCommand = {
|
|
|
2375
2344
|
warningCode,
|
|
2376
2345
|
};
|
|
2377
2346
|
//# sourceMappingURL=health.js.map
|
|
2378
|
-
//# debugId=
|
|
2347
|
+
//# debugId=9f0077a4-4f0a-540f-9951-2e8a640629c9
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/** First commit timestamp at which merge receipts gained a tracked durable copy. */
|
|
2
|
+
export declare const DURABLE_MERGE_RECEIPT_INTRODUCED_AT = "2026-08-09T16:15:18.000Z";
|
|
3
|
+
/** One receipt reference discovered at an immutable history coordinate. */
|
|
4
|
+
export interface HistoryMergeReceiptReference {
|
|
5
|
+
/** Item whose history contains the summary. */
|
|
6
|
+
itemId: string;
|
|
7
|
+
/** One-based history line containing the summary. */
|
|
8
|
+
line: number;
|
|
9
|
+
/** Privacy-safe receipt identifier. */
|
|
10
|
+
receiptId: string;
|
|
11
|
+
/** Whether the summary is a complete supported preferred-era record. */
|
|
12
|
+
legacySummaryAccepted: boolean;
|
|
13
|
+
/** Timestamp of the history event that introduced the reference, when valid. */
|
|
14
|
+
eventTimestamp?: string;
|
|
15
|
+
}
|
|
16
|
+
/** Audited disposition for one receipt that a pre-durable writer could never publish. */
|
|
17
|
+
export interface HistoryMergeReceiptDisposition {
|
|
18
|
+
/** Item whose history contains both the original reference and disposition. */
|
|
19
|
+
itemId: string;
|
|
20
|
+
/** Receipt identity explicitly accepted as unrecoverable. */
|
|
21
|
+
receiptId: string;
|
|
22
|
+
/** One-based coordinate of the original merge event. */
|
|
23
|
+
originalHistoryLine: number;
|
|
24
|
+
/** Timestamp copied from the original merge event for exact matching. */
|
|
25
|
+
originalEventTimestamp: string;
|
|
26
|
+
/** One-based coordinate of the later audit event that records this disposition. */
|
|
27
|
+
auditHistoryLine: number;
|
|
28
|
+
/** Closed reason vocabulary for this exceptional compatibility path. */
|
|
29
|
+
reason: "legacy_clone_local_only";
|
|
30
|
+
}
|
|
31
|
+
/** Missing-reference coordinate returned to bounded integrity diagnostics. */
|
|
32
|
+
export interface MissingHistoryMergeReceiptReference {
|
|
33
|
+
/** Item whose history contains the unresolved reference. */
|
|
34
|
+
item_id: string;
|
|
35
|
+
/** One-based history line containing the unresolved reference. */
|
|
36
|
+
history_line: number;
|
|
37
|
+
/** Safe identifier when the source value is suitable for diagnostics. */
|
|
38
|
+
receipt_id?: string;
|
|
39
|
+
/** Digest used instead of an unsafe identifier. */
|
|
40
|
+
receipt_reference_hash?: string;
|
|
41
|
+
}
|
|
42
|
+
/** Partitioned compatibility outcome for all scanned history references. */
|
|
43
|
+
export interface HistoryMergeReceiptReferenceClassification {
|
|
44
|
+
/** References requiring authoritative external evidence. */
|
|
45
|
+
missing: MissingHistoryMergeReceiptReference[];
|
|
46
|
+
/** Complete preferred-era summaries accepted without impossible migration. */
|
|
47
|
+
acceptedLegacyCount: number;
|
|
48
|
+
/** Pre-durable references accepted by a later explicit audited disposition. */
|
|
49
|
+
acceptedDispositionCount: number;
|
|
50
|
+
}
|
|
51
|
+
/** Return whether one summary is a complete, self-contained preferred-era receipt. */
|
|
52
|
+
export declare function isLegacyMergeReceiptSummary(value: Record<string, unknown>, historyItemId: string): boolean;
|
|
53
|
+
/** Return whether a summary matches the final clone-local-only schema before durable receipts. */
|
|
54
|
+
export declare function isPreDurableCloneLocalReceiptSummary(value: Record<string, unknown>, historyItemId: string): boolean;
|
|
55
|
+
/** Return whether an extracted reference carried a validated pre-durable summary. */
|
|
56
|
+
export declare function isPreDurableDispositionEligibleReference(reference: Omit<HistoryMergeReceiptReference, "itemId" | "line">): boolean;
|
|
57
|
+
/** Extract receipt ids and legacy compatibility disposition from one history entry. */
|
|
58
|
+
export declare function extractHistoryMergeReceiptReferences(value: unknown, historyItemId: string): Array<Omit<HistoryMergeReceiptReference, "itemId" | "line">>;
|
|
59
|
+
/** Extract validated explicit missing-receipt dispositions from one merge audit event. */
|
|
60
|
+
export declare function extractHistoryMergeReceiptDispositions(value: unknown, historyItemId: string, historyLine: number): HistoryMergeReceiptDisposition[];
|
|
61
|
+
/** Classify scanned references without treating complete legacy summaries as absent. */
|
|
62
|
+
export declare function classifyHistoryMergeReceiptReferences(references: readonly HistoryMergeReceiptReference[], availableReceiptIds: ReadonlySet<string>, dispositions?: readonly HistoryMergeReceiptDisposition[]): HistoryMergeReceiptReferenceClassification;
|