@unbrained/pm-cli 2026.8.21 → 2026.8.22
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 +16 -0
- package/dist/cli/error-guidance.d.ts +9 -4
- package/dist/cli/error-guidance.js +16 -15
- package/dist/cli/main.d.ts +3 -0
- package/dist/cli/main.js +40 -7
- package/dist/cli-bundle/bundle-manifest.json +153 -153
- package/dist/cli-bundle/chunks/{chunk-BKYB45NQ.js → chunk-BWX4SK46.js} +48 -48
- package/dist/cli-bundle/chunks/chunk-EMWDM5FI.js +13 -0
- package/dist/cli-bundle/chunks/chunk-HYG6LRL4.js +200 -0
- package/dist/cli-bundle/chunks/{chunk-LARJJ3RK.js → chunk-MYYI3ZOA.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-BUNIEJNE.js → chunk-MZTZQTMS.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-LOVTQ52Z.js → chunk-QI2CT3IX.js} +2 -2
- package/dist/cli-bundle/chunks/chunk-SMWXHMVB.js +35 -0
- package/dist/cli-bundle/chunks/{chunk-N3DSV4CH.js → chunk-U6GQ4VMV.js} +6 -6
- package/dist/cli-bundle/chunks/{chunk-3AFAUHUE.js → chunk-VMMIL3SI.js} +2 -2
- package/dist/cli-bundle/chunks/chunk-WG4STC36.js +5 -0
- package/dist/cli-bundle/chunks/{chunk-JSLOFXGA.js → chunk-YBPJAOQQ.js} +2 -2
- package/dist/cli-bundle/chunks/{register-list-query-F57EWDEF.js → register-list-query-HZKBQNWW.js} +2 -2
- package/dist/cli-bundle/chunks/{register-mutation-7IY2D5KO.js → register-mutation-HTKEEGRD.js} +2 -2
- package/dist/cli-bundle/chunks/{register-operations-FALL3YTU.js → register-operations-6EMRWJJY.js} +2 -2
- package/dist/cli-bundle/chunks/{register-setup-HXU7IZZD.js → register-setup-QK4OTOXN.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-FJ22HNRP.js → chunk-2ARQGDDW.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-CKKQSJNN.js → chunk-2AZT5WXZ.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-F4YEW5I2.js → chunk-2POVTNLY.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-3LKU6PTJ.js +4 -0
- package/dist/cli-bundle/focused-chunks/chunk-5SHSBMX2.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-FH6DYED3.js → chunk-6S2MO3Q3.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-UZE7XUZK.js → chunk-A2BC5PQL.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-C4S4A4JJ.js +5 -0
- package/dist/cli-bundle/focused-chunks/{chunk-KDNG7TKQ.js → chunk-D6RBZEJJ.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-E2EWYPY6.js +16 -0
- package/dist/cli-bundle/focused-chunks/{chunk-4ERLO7QD.js → chunk-GMYPD4FX.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-L5LDSRO2.js +155 -0
- package/dist/cli-bundle/focused-chunks/{chunk-ZOSEELYJ.js → chunk-MB37AYN6.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-MCOR37QK.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-2NIY5NKG.js → chunk-PH2OXXVZ.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-YKBKIEAJ.js → chunk-PMGJUFNQ.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-R6SR45XU.js +50 -0
- package/dist/cli-bundle/focused-chunks/chunk-WZE4LIPW.js +8 -0
- package/dist/cli-bundle/main.js +13 -13
- package/dist/cli-bundle/sdk-authoring.js +1 -1
- package/dist/cli-bundle/sdk-contracts.js +2 -2
- package/dist/cli-bundle/sdk-core.js +40 -40
- 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 +32 -32
- 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 +5 -5
- package/dist/core/extensions/extension-hook-runtime.js +22 -20
- package/dist/core/extensions/extension-types.d.ts +8 -1
- package/dist/core/extensions/extension-types.js +2 -2
- package/dist/core/extensions/loader.js +7 -3
- package/dist/core/extensions/service-ownership.d.ts +8 -0
- package/dist/core/extensions/service-ownership.js +20 -0
- package/dist/core/item/id.js +20 -5
- package/dist/core/item/item-format.js +27 -2
- package/dist/core/shared/errors.d.ts +4 -0
- package/dist/core/shared/errors.js +2 -2
- package/dist/sdk/agent/refusal-reachability.d.ts +1 -1
- package/dist/sdk/authoring.d.ts +1 -1
- package/dist/sdk/authoring.js +2 -2
- package/dist/sdk/cli-contracts/agent-output-contracts.d.ts +77 -0
- package/dist/sdk/cli-contracts/agent-output-contracts.js +324 -2
- package/dist/sdk/cli-contracts/commander-mutation-options.js +3 -3
- package/dist/sdk/cli-contracts/runtime-contracts.d.ts +3 -1
- package/dist/sdk/cli-contracts/runtime-contracts.js +4 -3
- package/dist/sdk/cli-contracts.d.ts +1 -1
- package/dist/sdk/cli-contracts.js +3 -3
- package/dist/sdk/extension/install-sources.d.ts +1 -1
- package/dist/sdk/extension/install-sources.js +6 -3
- package/dist/sdk/extension/output-ownership.d.ts +1 -0
- package/dist/sdk/extension/output-ownership.js +3 -2
- package/dist/sdk/generated/generated-error-code-catalog-part-1.js +38 -14
- package/dist/sdk/generated/generated-error-code-catalog-part-2.js +14 -2
- package/dist/sdk/governance/health.d.ts +3 -0
- package/dist/sdk/governance/health.js +39 -7
- package/dist/sdk/governance/hierarchy-validation.d.ts +29 -0
- package/dist/sdk/governance/hierarchy-validation.js +109 -0
- package/dist/sdk/governance/validate.d.ts +1 -7
- package/dist/sdk/governance/validate.js +47 -99
- package/dist/sdk/graph/assembly.d.ts +6 -1
- package/dist/sdk/graph/assembly.js +16 -22
- package/dist/sdk/graph/governance-contracts.d.ts +1 -1
- package/dist/sdk/graph/governance-contracts.js +8 -2
- package/dist/sdk/graph/governance.js +46 -2
- package/dist/sdk/graph/hierarchy-integrity.d.ts +94 -0
- package/dist/sdk/graph/hierarchy-integrity.js +311 -0
- package/dist/sdk/graph/index.d.ts +2 -1
- package/dist/sdk/graph/index.js +3 -2
- package/dist/sdk/graph/remediation.js +32 -2
- package/dist/sdk/graph/run.d.ts +31 -2
- package/dist/sdk/graph/run.js +80 -31
- package/dist/sdk/graph/workspace-relationship-kind-registry.d.ts +8 -0
- package/dist/sdk/graph/workspace-relationship-kind-registry.js +28 -0
- package/dist/sdk/index.d.ts +2 -2
- package/dist/sdk/index.js +3 -3
- package/dist/sdk/item-children.js +21 -8
- package/dist/sdk/lifecycle/create.js +125 -96
- package/dist/sdk/lifecycle/hierarchy-mutation-lock.d.ts +15 -0
- package/dist/sdk/lifecycle/hierarchy-mutation-lock.js +25 -0
- package/dist/sdk/lifecycle/update.d.ts +2 -0
- package/dist/sdk/lifecycle/update.js +171 -83
- package/dist/sdk/query/complete-list.d.ts +3 -3
- package/dist/sdk/query/complete-list.js +46 -3
- package/dist/sdk/query/list.d.ts +4 -3
- package/dist/sdk/query/list.js +89 -49
- package/dist/sdk/read-output-contracts.d.ts +5 -1
- package/dist/sdk/read-output-contracts.js +87 -22
- package/dist/sdk/relationship-context.js +3 -4
- package/dist/sdk/relationships.js +17 -10
- package/dist/sdk/runtime.d.ts +3 -2
- package/dist/sdk/runtime.js +3 -2
- package/dist/sdk/test/batch.js +13 -5
- package/dist/sdk/test/execution.js +10 -2
- package/dist/types.d.ts +11 -0
- package/dist/types.js +2 -2
- package/docs/AGENT_UX_CONTRACTS.md +20 -4
- package/docs/COMMANDS.md +29 -14
- package/docs/DEPENDENCY_KIND_CONTRACT.md +31 -3
- package/docs/DIAGNOSTIC_OUTPUT_CONTRACTS.md +98 -0
- package/docs/EXTENSIONS.md +2 -1
- package/docs/README.md +1 -0
- package/docs/READ_OUTPUT_CONTRACTS.md +9 -2
- package/docs/RELATIONSHIP_GRAPH.md +6 -3
- package/docs/TESTING.md +15 -0
- package/marketplace.json +2 -2
- package/package.json +1 -1
- 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 +593 -35
- package/dist/cli-bundle/chunks/chunk-2MA6ZQVZ.js +0 -197
- package/dist/cli-bundle/chunks/chunk-7VHZS727.js +0 -5
- package/dist/cli-bundle/chunks/chunk-OCLPLFAY.js +0 -35
- package/dist/cli-bundle/chunks/chunk-S4IRYKBU.js +0 -13
- package/dist/cli-bundle/focused-chunks/chunk-7WZRLCYF.js +0 -50
- package/dist/cli-bundle/focused-chunks/chunk-EEFKYMDR.js +0 -16
- package/dist/cli-bundle/focused-chunks/chunk-F2A56DHV.js +0 -8
- package/dist/cli-bundle/focused-chunks/chunk-FV5ACOK7.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-JEAVFOWM.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-NJ63LOP6.js +0 -155
- package/dist/cli-bundle/focused-chunks/chunk-NXRTQ7HI.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-TJ7EMJ46.js +0 -4
package/dist/sdk/test/batch.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Implements the pm test all 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]="bb2758a5-a5c1-5f6e-be42-0e173fe16fe3")}catch(e){}}();
|
|
8
8
|
import { assertInitializedTracker } from "../environment/tracker-preflight.js";
|
|
9
9
|
import { getActiveExtensionRegistrations } from "../../core/extensions/index.js";
|
|
10
10
|
import { resolveItemTypeRegistry } from "../../core/item/type-registry.js";
|
|
@@ -15,7 +15,7 @@ import { EXIT_CODE } from "../../core/shared/constants.js";
|
|
|
15
15
|
import { PmCliError } from "../../core/shared/errors.js";
|
|
16
16
|
import { nowIso } from "../../core/shared/time.js";
|
|
17
17
|
import { listAllItemMetadataLight } from "../../core/store/item-store.js";
|
|
18
|
-
import { resolveGlobalPmRoot, resolvePmRoot
|
|
18
|
+
import { resolveGlobalPmRoot, resolvePmRoot } from "../../core/store/paths.js";
|
|
19
19
|
import { readSettings } from "../../core/store/settings.js";
|
|
20
20
|
import { appendTrackedTestRunSummary } from "../../core/test/item-test-run-tracking.js";
|
|
21
21
|
import { resolveAuthor } from "../../core/shared/author.js";
|
|
@@ -245,7 +245,7 @@ const runTestAllItem = async (entry, context) => {
|
|
|
245
245
|
});
|
|
246
246
|
const summary = countStatuses(runResults);
|
|
247
247
|
const failureCategories = countFailureCategories(runResults);
|
|
248
|
-
const trackingWarnings = await appendTestAllItemTracking(entry, summary, context);
|
|
248
|
+
const trackingWarnings = await appendTestAllItemTracking(entry, summary, runResults, context);
|
|
249
249
|
return {
|
|
250
250
|
passed: summary.passed,
|
|
251
251
|
failed: summary.failed,
|
|
@@ -273,7 +273,7 @@ const trackedRunFailed = (summary, options) => [
|
|
|
273
273
|
].includes(true);
|
|
274
274
|
/** Projects true flags while keeping false values absent from persisted rows. */
|
|
275
275
|
const optionalTrue = (value) => value ? true : undefined;
|
|
276
|
-
const appendTestAllItemTracking = async (entry, summary, context) => {
|
|
276
|
+
const appendTestAllItemTracking = async (entry, summary, runResults, context) => {
|
|
277
277
|
if (!context.trackingEnabled) {
|
|
278
278
|
return [];
|
|
279
279
|
}
|
|
@@ -300,6 +300,14 @@ const appendTestAllItemTracking = async (entry, summary, context) => {
|
|
|
300
300
|
items: 1,
|
|
301
301
|
linked_tests: entry.tests.length,
|
|
302
302
|
fail_on_skipped_triggered: optionalTrue(context.options.failOnSkipped === true && summary.skipped > 0),
|
|
303
|
+
executions: runResults
|
|
304
|
+
.filter((result) => result.command?.trim())
|
|
305
|
+
.slice(0, 32)
|
|
306
|
+
.map((result) => ({
|
|
307
|
+
command: result.command.trim(),
|
|
308
|
+
requested_pm_context_mode: result.execution_context?.requested_pm_context_mode,
|
|
309
|
+
pm_context_mode: result.execution_context?.pm_context_mode,
|
|
310
|
+
})),
|
|
303
311
|
},
|
|
304
312
|
});
|
|
305
313
|
}
|
|
@@ -487,4 +495,4 @@ export const _testOnlyTestAll = {
|
|
|
487
495
|
formatTrackingError,
|
|
488
496
|
};
|
|
489
497
|
//# sourceMappingURL=batch.js.map
|
|
490
|
-
//# debugId=
|
|
498
|
+
//# debugId=bb2758a5-a5c1-5f6e-be42-0e173fe16fe3
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Implements the pm test 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]="5fe0ee3e-9590-56fc-b238-e56ff1970e52")}catch(e){}}();
|
|
8
8
|
import { assertInitializedTracker } from "../environment/tracker-preflight.js";
|
|
9
9
|
import { spawn } from "node:child_process";
|
|
10
10
|
import { cp, mkdir, mkdtemp, open, readdir, rm } from "node:fs/promises";
|
|
@@ -1791,6 +1791,14 @@ function buildTrackedTestRunSummary(params) {
|
|
|
1791
1791
|
skipped: summary.skipped,
|
|
1792
1792
|
fail_on_skipped_triggered: params.failOnSkippedTriggered ? true : undefined,
|
|
1793
1793
|
measurements: measurements.length > 0 ? measurements : undefined,
|
|
1794
|
+
executions: params.runResults
|
|
1795
|
+
.filter((result) => result.command?.trim())
|
|
1796
|
+
.slice(0, 32)
|
|
1797
|
+
.map((result) => ({
|
|
1798
|
+
command: result.command.trim(),
|
|
1799
|
+
requested_pm_context_mode: result.execution_context?.requested_pm_context_mode,
|
|
1800
|
+
pm_context_mode: result.execution_context?.pm_context_mode,
|
|
1801
|
+
})),
|
|
1794
1802
|
};
|
|
1795
1803
|
}
|
|
1796
1804
|
async function recordTestRunSummary(params) {
|
|
@@ -1964,4 +1972,4 @@ export const _testOnlyTestCommand = {
|
|
|
1964
1972
|
summarizeRunResultStatuses,
|
|
1965
1973
|
};
|
|
1966
1974
|
//# sourceMappingURL=execution.js.map
|
|
1967
|
-
//# debugId=
|
|
1975
|
+
//# debugId=5fe0ee3e-9590-56fc-b238-e56ff1970e52
|
package/dist/types.d.ts
CHANGED
|
@@ -558,6 +558,15 @@ export interface TestRunMeasurement {
|
|
|
558
558
|
/** ISO 8601 timestamp binding the measurement to its producing run. */
|
|
559
559
|
recorded_at: string;
|
|
560
560
|
}
|
|
561
|
+
/** Bounded command and tracker-context provenance for one linked-test execution. */
|
|
562
|
+
export interface ItemTestRunExecution {
|
|
563
|
+
/** Exact linked command selected for execution. */
|
|
564
|
+
command: string;
|
|
565
|
+
/** Context mode requested before linked-test overrides or auto-remediation. */
|
|
566
|
+
requested_pm_context_mode?: "schema" | "tracker" | "auto";
|
|
567
|
+
/** Effective context mode used by the linked command. */
|
|
568
|
+
pm_context_mode?: "schema" | "tracker" | "auto";
|
|
569
|
+
}
|
|
561
570
|
/** Documents the item test run summary payload exchanged by command, SDK, and package integrations. */
|
|
562
571
|
export interface ItemTestRunSummary {
|
|
563
572
|
/** Executes the id operation through the package runtime. */
|
|
@@ -590,6 +599,8 @@ export interface ItemTestRunSummary {
|
|
|
590
599
|
fail_on_skipped_triggered?: boolean;
|
|
591
600
|
/** Bounded, deterministic quantitative evidence produced by this run. */
|
|
592
601
|
measurements?: TestRunMeasurement[];
|
|
602
|
+
/** Commands and effective tracker contexts bound to this recorded run. */
|
|
603
|
+
executions?: ItemTestRunExecution[];
|
|
593
604
|
}
|
|
594
605
|
/** Documents the item metadata payload exchanged by command, SDK, and package integrations. */
|
|
595
606
|
export interface ItemMetadata {
|
package/dist/types.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
/** Supported values accepted by the builtin item type contract. */
|
|
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]="13c65470-8f5f-59ca-acb5-50c926c68870")}catch(e){}}();
|
|
9
9
|
export const BUILTIN_ITEM_TYPE_VALUES = [
|
|
10
10
|
"Epic",
|
|
11
11
|
"Feature",
|
|
@@ -243,4 +243,4 @@ export const CONTEXT_SECTION_VALUES = [
|
|
|
243
243
|
"tests",
|
|
244
244
|
];
|
|
245
245
|
//# sourceMappingURL=types.js.map
|
|
246
|
-
//# debugId=
|
|
246
|
+
//# debugId=13c65470-8f5f-59ca-acb5-50c926c68870
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Agent UX Contracts
|
|
2
2
|
|
|
3
|
-
Tracker references: [pm-v1yo](../.agents/pm/issues/pm-v1yo.toon), [pm-i6pi](../.agents/pm/issues/pm-i6pi.toon), [pm-um4g](../.agents/pm/issues/pm-um4g.toon), [pm-tmhs](../.agents/pm/issues/pm-tmhs.toon), [pm-6m1i](../.agents/pm/issues/pm-6m1i.toon), [pm-cj9v](../.agents/pm/issues/pm-cj9v.toon), [pm-yp56](../.agents/pm/issues/pm-yp56.toon), [pm-gos426](../.agents/pm/issues/pm-gos426.toon),
|
|
3
|
+
Tracker references: [pm-v1yo](../.agents/pm/issues/pm-v1yo.toon), [pm-i6pi](../.agents/pm/issues/pm-i6pi.toon), [pm-um4g](../.agents/pm/issues/pm-um4g.toon), [pm-tmhs](../.agents/pm/issues/pm-tmhs.toon), [pm-6m1i](../.agents/pm/issues/pm-6m1i.toon), [pm-cj9v](../.agents/pm/issues/pm-cj9v.toon), [pm-yp56](../.agents/pm/issues/pm-yp56.toon), [pm-gos426](../.agents/pm/issues/pm-gos426.toon), [pm-flnefm](../.agents/pm/issues/pm-flnefm.toon), [pm-rggtvd](../.agents/pm/issues/pm-rggtvd.toon), and [pm-vk7zek](../.agents/pm/issues/pm-vk7zek.toon).
|
|
4
4
|
|
|
5
5
|
These contracts keep common agent loops deterministic, token-efficient, and recoverable. Runtime contracts and `--help --json` remain the exact source for available flags.
|
|
6
6
|
|
|
@@ -13,9 +13,25 @@ The public SDK exports `collectNewOrderingCycleWarnings(beforeItems, afterItems,
|
|
|
13
13
|
Dependency removal is lossless. `--dep-remove` rejects the same malformed
|
|
14
14
|
shorthand as `--dep`, and a selector that matches nothing returns the typed
|
|
15
15
|
`dependency_remove_no_match` refusal instead of a successful no-op. Exact
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
rows can be retired by selecting `id`, `kind` (or its input-only `type` alias),
|
|
17
|
+
`source_kind`, `author`, and `created_at`; omitted coordinates intentionally broaden the match. Exact
|
|
18
|
+
duplicate rows can still be normalized without delete-then-add risk by
|
|
19
|
+
re-adding the same identity; the mutation keeps one canonical row and never
|
|
20
|
+
removes the logical edge. Identity comparison includes normalized `id`, `kind`,
|
|
21
|
+
`source_kind`, `author`, and creation instant, preserving provenance-distinct
|
|
22
|
+
siblings.
|
|
23
|
+
|
|
24
|
+
Hierarchy mutations are stricter than ordering advisories. `pm create` and
|
|
25
|
+
`pm update` refuse a new cycle, registry cardinality breach, or contradictory
|
|
26
|
+
scalar/dependency parent before writing. The structured refusal names the
|
|
27
|
+
changed holder plus the cycle members or competing parents. Existing legacy
|
|
28
|
+
debt remains mutable only toward a cleaner state, so repair does not require a
|
|
29
|
+
global bypass. Read paths canonicalize every registry-declared hierarchy kind;
|
|
30
|
+
an item cannot disappear from `pm list --parent` or `pm get --tree` merely
|
|
31
|
+
because an integration used a dependency row instead of the scalar field.
|
|
32
|
+
`pm update-many` applies the same hierarchy guard independently to each matched
|
|
33
|
+
item: one refused row is reported as failed while other rows may still commit,
|
|
34
|
+
so a bulk hierarchy mutation is not atomic across the complete match set.
|
|
19
35
|
|
|
20
36
|
`pm graph audit` uses two explicit units:
|
|
21
37
|
|
package/docs/COMMANDS.md
CHANGED
|
@@ -6,6 +6,8 @@ Tracked implementation updates: [pm-52eh](../.agents/pm/features/pm-52eh.toon),
|
|
|
6
6
|
|
|
7
7
|
Workspace-integrity contracts are tracked by [pm-22rzjp](../.agents/pm/issues/pm-22rzjp.toon), [pm-76fkpp](../.agents/pm/issues/pm-76fkpp.toon), [pm-igdvfq](../.agents/pm/issues/pm-igdvfq.toon), [pm-643e0k](../.agents/pm/issues/pm-643e0k.toon), and [pm-larv4r](../.agents/pm/issues/pm-larv4r.toon).
|
|
8
8
|
|
|
9
|
+
Create-safe init prefix normalization is tracked by [pm-gh1073](../.agents/pm/issues/pm-gh1073.toon).
|
|
10
|
+
|
|
9
11
|
```bash
|
|
10
12
|
pm <command> --help
|
|
11
13
|
pm <command> --help --json
|
|
@@ -49,21 +51,21 @@ JSON ceiling; TOON uses the smaller default agent ceiling.
|
|
|
49
51
|
|
|
50
52
|
## Command Families
|
|
51
53
|
|
|
52
|
-
| Family | Commands
|
|
53
|
-
| ------------ |
|
|
54
|
-
| Bootstrap | `init`, `config`, `health`, `telemetry`
|
|
54
|
+
| Family | Commands | Purpose |
|
|
55
|
+
| ------------ | --------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
56
|
+
| Bootstrap | `init`, `config`, `health`, `telemetry` | create and inspect tracker setup |
|
|
55
57
|
| Lifecycle | `create`, `copy`, `focus`, `claim`, `update`, `item reopen`, `append`, `close`, `release`, `delete`, `start-task`, `pause-task`, `close-task` | mutate item state, including terminal-work recurrence without duplicate creation |
|
|
56
|
-
| Bulk | `item mutate`, `item complete`, `update-many`, `close-many`
|
|
57
|
-
| Scheduling | `meet`, `event`, `remind`
|
|
58
|
-
| Planning | `plan create`, `plan add-step`, `plan update-step`, `plan complete-step`, `plan link`, `plan approve`, `plan materialize`
|
|
59
|
-
| Links | `files`, `docs`, `test`, `deps`
|
|
60
|
-
| Verification | `test`, `test-all`, `test-runs`†, `validate`, `gc`
|
|
61
|
-
| History | `history`, `history-compact`, `history-redact`, `history-repair`, `activity`, `restore`, `stats`
|
|
62
|
-
| Schema | `schema add/remove-*` / `rename-type` / `rename-field` / `remap-status` / `apply-preset`
|
|
63
|
-
| Profiles | `profile list` / `show` / `apply` / `lint`
|
|
64
|
-
| Calendar | `calendar`, `cal`
|
|
65
|
-
| Packages | `install`, `upgrade`, `package`, `packages`, `extension`, package/extension command groups
|
|
66
|
-
| Machines | `contracts`, `help`, optional `guide`/`completion`
|
|
58
|
+
| 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 |
|
|
59
|
+
| Scheduling | `meet`, `event`, `remind` | low-friction Meeting/Event/Reminder creation |
|
|
60
|
+
| 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 |
|
|
61
|
+
| Links | `files`, `docs`, `test`, `deps` | connect items to artifacts, tests, and relationships |
|
|
62
|
+
| Verification | `test`, `test-all`, `test-runs`†, `validate`, `gc` | run linked tests and repository checks |
|
|
63
|
+
| History | `history`, `history-compact`, `history-redact`, `history-repair`, `activity`, `restore`, `stats` | inspect, compact, redact, re-anchor, and recover item state |
|
|
64
|
+
| Schema | `schema add/remove-*` / `rename-type` / `rename-field` / `remap-status` / `apply-preset` | manage config-driven types, statuses, and fields; losslessly migrate existing items when definitions evolve; adopt presets or infer types |
|
|
65
|
+
| Profiles | `profile list` / `show` / `apply` / `lint` | compose item types, statuses, fields, workflows, config, templates, and recommended packages into archetype bundles (agile/ops/research); `apply` stages every dimension idempotently; `lint` reports author-time consistency findings without writing |
|
|
66
|
+
| Calendar | `calendar`, `cal` | project deadlines, reminders, and events |
|
|
67
|
+
| Packages | `install`, `upgrade`, `package`, `packages`, `extension`, package/extension command groups | install, upgrade, manage, and run package-backed extension commands |
|
|
68
|
+
| Machines | `contracts`, `help`, optional `guide`/`completion` | command contracts plus optional guide-shell docs routing and shell helpers |
|
|
67
69
|
|
|
68
70
|
`†` `test-runs` subcommands are provided by the optional `linked-test-adapters` package (`pm install linked-test-adapters --project`).
|
|
69
71
|
|
|
@@ -89,6 +91,15 @@ ID prefix without relying on the legacy positional form. `pm init ops` remains
|
|
|
89
91
|
compatible, and supplying both forms is accepted only when they normalize to the
|
|
90
92
|
same prefix; conflicting values fail with `init_id_prefix_conflict` instead of
|
|
91
93
|
silently choosing one.
|
|
94
|
+
Prefixes normalize through the same primitive used by item creation: letters
|
|
95
|
+
become lowercase, each run of whitespace or punctuation becomes one `-`, edge
|
|
96
|
+
separators are removed, and exactly one trailing `-` is stored. For example,
|
|
97
|
+
`"Release Candidate"` persists as `release-candidate-`; an input with no ASCII
|
|
98
|
+
letters or digits falls back to `pm-`. Path-like values remain invalid tracker
|
|
99
|
+
prefixes when passed through `--id-prefix`; a path-like positional value remains
|
|
100
|
+
the advanced tracker-root target described below. To repair an older unsafe
|
|
101
|
+
value, rerun init with a safe prefix and explicit replacement intent, for example
|
|
102
|
+
`pm init --id-prefix "release candidate" --force --defaults`.
|
|
92
103
|
Use `pm init --workspace <dir>` when `<dir>` is a project root; it creates `<dir>/.agents/pm`. A path-like positional remains the advanced tracker-root form and writes tracker files directly at that path. Both explicit target forms return `target.mode`, `target.tracker_root`, and tracker-scoped executable `next_steps` so agents can run the suggestions from any working directory.
|
|
93
104
|
Implicit init discovery also reports whether the selected tracker is local or was found in an ancestor. If `pm init <name>` would change an ancestor tracker, the refusal names both directories and gives the safe current-directory retry: `pm init <name> --pm-path "$PWD/.agents/pm" --defaults`.
|
|
94
105
|
`pm init --agent-guidance ask` is the default behavior: prompt in TTY only when AGENTS/CLAUDE guidance is missing and no decline is recorded.
|
|
@@ -163,6 +174,10 @@ Use `duplicates --status all` for a true whole-history duplicate check. The
|
|
|
163
174
|
result echoes `filters.statuses: null` for the unrestricted corpus; named or
|
|
164
175
|
custom statuses are normalized through the runtime status registry and an
|
|
165
176
|
unknown status fails instead of returning a false-clean result.
|
|
177
|
+
As a read-only structured surface, `duplicates` accepts the universal output
|
|
178
|
+
controls, including `--output-format json`, `--lean`, projection/amount
|
|
179
|
+
controls, and token accounting, while its default TOON output remains bounded.
|
|
180
|
+
Tracked by [pm-gh1076](../.agents/pm/issues/pm-gh1076.toon).
|
|
166
181
|
Use `pm get <id>` to read a single item by ID — the single-item read primitive used throughout the agent loop. It accepts `--fields <list>` and `--depth brief|standard|deep|full` for token-minimal projections, and `--tree`/`--tree-depth <n>` to include descendants. Standard/deep reads expose a normalized `schedule` facet (`deadline`, `start_at`, `end_at`, `location`, reminders, and events) when scheduling metadata exists. Container-oriented built-ins (Epic, Feature, Milestone, and Plan) plus custom types automatically expose type-agnostic child counts and continuation metadata. Standard depth keeps that rollup counts-only; `--depth deep|full` or an explicit `--fields id,children` request adds the deterministic bounded child sample. Built-in leaf reads avoid a workspace scan unless children are explicitly requested. `pm get <id> --json` returns the `body` inside the `item` object (`.item.body`); see [Full results, totals, and bodies](#full-results-totals-and-bodies). To duplicate an existing item as a starting point, `pm copy <id> --title "New title"` clones it into a fresh id with lifecycle fields reset.
|
|
167
182
|
|
|
168
183
|
When the strongest duplicate match is terminal because the same work recurred,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Dependency-kind contract
|
|
2
2
|
|
|
3
|
-
Tracker: [pm-4020c5](../.agents/pm/issues/pm-4020c5.toon), [pm-jkbqt8](../.agents/pm/issues/pm-jkbqt8.toon), [pm-q6n8sj](../.agents/pm/issues/pm-q6n8sj.toon), [pm-ouyq3n](../.agents/pm/issues/pm-ouyq3n.toon), [pm-gos426](../.agents/pm/issues/pm-gos426.toon),
|
|
3
|
+
Tracker: [pm-4020c5](../.agents/pm/issues/pm-4020c5.toon), [pm-jkbqt8](../.agents/pm/issues/pm-jkbqt8.toon), [pm-q6n8sj](../.agents/pm/issues/pm-q6n8sj.toon), [pm-ouyq3n](../.agents/pm/issues/pm-ouyq3n.toon), [pm-gos426](../.agents/pm/issues/pm-gos426.toon), [pm-flnefm](../.agents/pm/issues/pm-flnefm.toon), [pm-rggtvd](../.agents/pm/issues/pm-rggtvd.toon), and [pm-vk7zek](../.agents/pm/issues/pm-vk7zek.toon).
|
|
4
4
|
|
|
5
5
|
Dependency rows have one canonical stored spelling per relationship meaning. Command inputs remain compatibility-friendly: hyphens normalize to underscores and the aliases below are accepted, but `pm create` and `pm update` persist the canonical kind. Existing historical rows are never rewritten implicitly.
|
|
6
6
|
|
|
@@ -15,9 +15,17 @@ Dependency rows have one canonical stored spelling per relationship meaning. Com
|
|
|
15
15
|
|
|
16
16
|
The SDK relationship registry is authoritative. `canonicalizeRelationshipKind()` rejects unknown spellings, while `resolveCanonicalRelationshipKind()` supports validation flows that need an undefined result. `pm contracts` publishes `relationship_kind_contracts` with canonical names, aliases, inverses, and ordering/hierarchy semantics.
|
|
17
17
|
|
|
18
|
+
Extension kinds may opt into both ordering and hierarchy semantics. Unless they
|
|
19
|
+
declare an explicit `traversal`, ordering is the primary traversal and context
|
|
20
|
+
role family; hierarchy direction and cardinality remain enforceable integrity
|
|
21
|
+
constraints. This ordering-first precedence is shared by registry snapshots and
|
|
22
|
+
direct-edge context explanations.
|
|
23
|
+
|
|
18
24
|
Dependency additions and removals share the same lossless input grammar. A
|
|
19
|
-
bare value is an item id; structured input uses `id=<id>` plus
|
|
20
|
-
canonical `kind
|
|
25
|
+
bare value is an item id; structured removal input uses `id=<id>` plus optional
|
|
26
|
+
canonical `kind` (with `type` accepted only as an input alias), `source_kind`, `author`, and ISO `created_at`
|
|
27
|
+
selectors. Supplying all stored coordinates retires exactly one dependency row
|
|
28
|
+
without deleting siblings that share an id and kind. Punctuation-shaped shorthand such as
|
|
21
29
|
`OTHER,related` is rejected with `dependency_flag_value_invalid` on both
|
|
22
30
|
`--dep` and `--dep-remove`, before prefix normalization can turn it into a
|
|
23
31
|
dangling id. A removal selector that matches no stored row fails with
|
|
@@ -25,6 +33,26 @@ dangling id. A removal selector that matches no stored row fails with
|
|
|
25
33
|
available identities. Re-adding a stored dependency identity is idempotent; if
|
|
26
34
|
legacy storage contains that exact identity more than once, the same mutation
|
|
27
35
|
collapses the touched copies to one without creating an edge-absence window.
|
|
36
|
+
The stored identity includes normalized `id`, `kind`, `source_kind`, `author`,
|
|
37
|
+
and creation instant, so provenance-distinct sibling rows remain independent.
|
|
38
|
+
|
|
39
|
+
## Hierarchy integrity
|
|
40
|
+
|
|
41
|
+
The registry's `hierarchy`, `hierarchyDirection`, `outgoing`, and `incoming`
|
|
42
|
+
fields are executable contracts. Scalar `parent` metadata and every registered
|
|
43
|
+
hierarchy dependency spelling normalize into the same parent-to-child relation.
|
|
44
|
+
That normalized relation powers `pm list --parent`, list/get tree projections,
|
|
45
|
+
child rollups, graph traversal, graph analysis, graph audit, validate, and
|
|
46
|
+
health. Extensions therefore gain hierarchy behavior by registering semantics;
|
|
47
|
+
consumers do not hard-code kind names.
|
|
48
|
+
|
|
49
|
+
Create and update transactions reject a newly introduced hierarchy cycle,
|
|
50
|
+
registry cardinality violation, or scalar/dependency direction contradiction
|
|
51
|
+
before persistence. Existing debt remains readable and repairable. Active debt
|
|
52
|
+
is gate-failing in graph governance and health; defects confined to terminal
|
|
53
|
+
items are labeled legacy and are never mutated automatically. `pm validate`
|
|
54
|
+
reports cycle, cardinality, and parent-divergence counts and exact bounded rows,
|
|
55
|
+
while `pm graph analyze` exposes a compact `hierarchy` summary.
|
|
28
56
|
|
|
29
57
|
`recurs_from` has no alias: a later occurrence points to an earlier occurrence.
|
|
30
58
|
It is persistent after both items become terminal and carries temporal identity,
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# Diagnostic Output Contracts
|
|
2
|
+
|
|
3
|
+
Tracker references: [pm-cha95z](../.agents/pm/tasks/pm-cha95z.toon), [pm-5t33or](../.agents/pm/features/pm-5t33or.toon), [pm-f05lsg](../.agents/pm/features/pm-f05lsg.toon), and [pm-h8tpeh](../.agents/pm/features/pm-h8tpeh.toon).
|
|
4
|
+
|
|
5
|
+
## Agent Quick Context
|
|
6
|
+
|
|
7
|
+
Failures are context-management surfaces. Every diagnostic family now declares
|
|
8
|
+
a format-aware token ceiling and one degradation ladder in the public SDK:
|
|
9
|
+
|
|
10
|
+
| Class | Text | JSON | Corrective action that survives degradation |
|
|
11
|
+
| -------------------- | ---: | ---: | ------------------------------------------- |
|
|
12
|
+
| `error` | 768 | 2000 | required action, retry/domain, or next step |
|
|
13
|
+
| `warning` | 768 | 2000 | required action, retry/domain, or next step |
|
|
14
|
+
| `validation_summary` | 1500 | 3000 | required action, retry/domain, or next step |
|
|
15
|
+
| `recovery_bundle` | 768 | 2000 | required action, retry/domain, or next step |
|
|
16
|
+
|
|
17
|
+
The smallest explicit ceiling is 192 estimated tokens. At that floor, the
|
|
18
|
+
projector may reduce the diagnostic to its code, required action, compact
|
|
19
|
+
recovery, and exit status. It never removes the first corrective action.
|
|
20
|
+
|
|
21
|
+
## SDK Contract
|
|
22
|
+
|
|
23
|
+
Use the public contract surface rather than maintaining a package-local error
|
|
24
|
+
budget:
|
|
25
|
+
|
|
26
|
+
```ts
|
|
27
|
+
import {
|
|
28
|
+
PM_DIAGNOSTIC_OUTPUT_BUDGET_CONTRACTS,
|
|
29
|
+
projectPmDiagnosticOutput,
|
|
30
|
+
projectPmDiagnosticText,
|
|
31
|
+
resolvePmDiagnosticOutputBudget,
|
|
32
|
+
} from "@unbrained/pm-cli/sdk/contracts";
|
|
33
|
+
|
|
34
|
+
const contract = resolvePmDiagnosticOutputBudget("error");
|
|
35
|
+
const projected = projectPmDiagnosticOutput(
|
|
36
|
+
{
|
|
37
|
+
code: "invalid_argument_value",
|
|
38
|
+
required: "Use --status open and retry.",
|
|
39
|
+
recovery: { suggested_retry: "pm list --status open" },
|
|
40
|
+
detail: "The supplied status is not declared.",
|
|
41
|
+
exit_code: 2,
|
|
42
|
+
},
|
|
43
|
+
{ maxEstimatedTokens: contract.minimum_max_estimated_tokens },
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
const text = projectPmDiagnosticText(
|
|
47
|
+
"A long rendered diagnostic",
|
|
48
|
+
"Use --status open and retry.",
|
|
49
|
+
).output;
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
The JSON projector orders `code`, `required`, recovery, and next steps before
|
|
53
|
+
explanation. Untruncated diagnostics add no per-call receipt overhead; their
|
|
54
|
+
binding declaration is discoverable from `pm contracts --full --json` under
|
|
55
|
+
`diagnostic_output_contracts`. When degradation occurs, the returned
|
|
56
|
+
`diagnostic_output` receipt records the effective budget, original and emitted
|
|
57
|
+
estimates, applied stages, and omitted top-level fields. Minimal fallbacks bound
|
|
58
|
+
the named omission list and disclose any additional count through
|
|
59
|
+
`omitted_fields_overflow_count`.
|
|
60
|
+
|
|
61
|
+
The deterministic ladder is:
|
|
62
|
+
|
|
63
|
+
1. full diagnostic;
|
|
64
|
+
2. omit explanation;
|
|
65
|
+
3. limit diagnostic collections;
|
|
66
|
+
4. compact recovery to actionable keys;
|
|
67
|
+
5. retain the action-only envelope.
|
|
68
|
+
|
|
69
|
+
Human diagnostics lead with `What is required` and next steps before explaining
|
|
70
|
+
what happened. If their declared ceiling binds, the compact text still begins
|
|
71
|
+
with the required action and points to structured JSON for the bounded recovery
|
|
72
|
+
envelope.
|
|
73
|
+
|
|
74
|
+
## Executable Assurance
|
|
75
|
+
|
|
76
|
+
`pnpm quality:recovery-closure` builds the current CLI and replays 22 refusal
|
|
77
|
+
contracts in isolated trackers. Ten representative, high-frequency failure
|
|
78
|
+
paths are also ratcheted by
|
|
79
|
+
`scripts/release/diagnostic-output-baseline.json`. The gate requires every row
|
|
80
|
+
to remain within the SDK-declared JSON ceiling and retain a mechanically
|
|
81
|
+
actionable correction. It reports the aggregate original and emitted token
|
|
82
|
+
estimates without claiming a reduction when no degradation was required.
|
|
83
|
+
|
|
84
|
+
The baseline is a coverage ratchet, not permission to weaken a ceiling. Its
|
|
85
|
+
negative control requires a missing baseline probe to fail. The existing
|
|
86
|
+
refusal-closure negative controls independently prove that incomplete domains,
|
|
87
|
+
broken retries, and malformed recovery envelopes remain blocking findings.
|
|
88
|
+
|
|
89
|
+
Run the focused proof with:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
pnpm build
|
|
93
|
+
node scripts/release/refusal-closure-gate.mjs
|
|
94
|
+
node scripts/run-tests.mjs test -- \
|
|
95
|
+
tests/unit/sdk/agent-output-contracts.spec.ts \
|
|
96
|
+
tests/unit/cli/error-guidance.spec.ts \
|
|
97
|
+
tests/unit/scripts/refusal-closure-gate.spec.ts
|
|
98
|
+
```
|
package/docs/EXTENSIONS.md
CHANGED
|
@@ -45,6 +45,7 @@ pm install kanban --project
|
|
|
45
45
|
External registry packages are installed by exact package name. If `npm:<name>` returns a registry 404, JSON error output includes `fallback_candidates` and `next_best_command`; unpublished first-party packages fall back to `pm install --project github.com/unbraind/<name>`. Install results include package-owned `command_paths`, `action_paths`, `contributions`, `command_discovery`, and a light `verification` block covering the target tracker, activation status, registered commands/actions/item types, and health verdict. Agents should consume those fields instead of guessing from the package name or immediately spending another invocation on doctor. A successful activation persists the versioned contribution inventory in `.managed-extensions.json`; subsequent discovery can enumerate command handlers, hooks, parser/renderer targets, schema names, and the other registered surfaces without importing the package module. A failed runtime activation returns `ok: false`, `activated: false`, a non-zero CLI exit, and actionable diagnostics; missing SDK resolution adds an explicit dependency recovery step. Local installs are containment-safe when the extension destination is nested inside the source checkout: pm stages the package outside the source and prunes the destination, `.agents`, `node_modules`, and install-backup directories before copying, so reinstalling cannot recursively copy tracker history, host dependencies, or prior backups.
|
|
46
46
|
Local `.tgz` and `.tar.gz` npm archives are inspected and extracted in an isolated temporary directory without invoking a shell. Archives must contain one `package/package.json` root, regular files/directories only, and bounded entry and expanded-byte totals. Absolute paths, traversal, alternate roots, links, device entries, oversized entries, and decompression-ratio abuse fail before installation. The managed source remains the original archive path, so reload and upgrade provenance do not point at a temporary extraction directory.
|
|
47
47
|
Registry dependency names and versions are parsed as npm package specs before the install subprocess starts. Leading-option names and shell control syntax are rejected. npm reads those validated dependencies from an isolated runtime-only manifest; no caller-controlled spec is forwarded through the Windows command shell, and the fixed invocation still ends option parsing with `--`. Runtime verification then activates a temporary snapshot of the complete installed extension directory, so an upgrade cannot silently reuse stale transitive ESM dependencies from the current process. Successful install details expose `module_graph_verification: "fresh_snapshot"` for this check.
|
|
48
|
+
pm-owned npm subprocesses clear any inherited, case-insensitive `npm_config_allow_scripts` value while retaining registry, auth, proxy, and executable-path environment; `--ignore-scripts` remains authoritative. Tracked by [pm-gh1072](../.agents/pm/issues/pm-gh1072.toon).
|
|
48
49
|
An explicit `--pm-path` scopes project installs to that tracker root, including extension files, managed state, settings, type-folder scaffolding, and verification output. This is the safe form for temporary package testing from inside another repository checkout.
|
|
49
50
|
|
|
50
51
|
```bash
|
|
@@ -308,7 +309,7 @@ Common APIs:
|
|
|
308
309
|
- `api.registerMigration(definition)` adds schema migrations.
|
|
309
310
|
- `api.registerProfile(profile)` contributes a project profile — a declarative archetype bundling item types, statuses, fields, per-type workflows, config, templates, and package recommendations. Once active it resolves by name through `pm profile list/show/apply` alongside the core `agile`/`ops`/`research` archetypes (built-in names are reserved; a colliding registration is ignored with a warning). Requires the `schema` capability.
|
|
310
311
|
- `api.registerAssuranceMeasurementProvider(provider)` contributes typed measurements to assurance. It requires `services`; network providers also require manifest `permissions.network: true`. Gates allow providers and cost/network limits per trigger. See [Project Assurance Primitives](ASSURANCE.md#extension-measurement-providers) for examples.
|
|
311
|
-
- `api.registerService("output_format", handler)` customizes output formatting through the service override API. Use `handleServiceOverride(result)` to claim a payload and return the scaffold-compatible literal `{ handled: false }` (or `declineServiceOverride()`) for commands the extension does not own. Legacy `null`/`undefined` declines remain supported; returning the original payload is now an unambiguous handled result.
|
|
312
|
+
- `api.registerService("output_format", handler, ownership?)` customizes output formatting through the service override API. Use `handleServiceOverride(result)` to claim a payload and return the scaffold-compatible literal `{ handled: false }` (or `declineServiceOverride()`) for commands the extension does not own. An override that is unconditionally inert can declare `{ passThrough: true }`; the host then ignores and diagnoses any handled result, and package doctor treats the registration as statically safe. Legacy `null`/`undefined` declines remain supported; returning the original payload is now an unambiguous handled result. Tracked by [pm-gh1074](../.agents/pm/issues/pm-gh1074.toon).
|
|
312
313
|
- `api.registerRenderer("toon" | "json", renderer, ownership?)` adds format-specific renderers. Scope ownership with `commands` and/or a `resultDiscriminator`; the host checks both before invoking the renderer and falls back to native rendering for unrelated output. The legacy unscoped callback remains supported, but doctor warns because package ownership cannot be proven statically.
|
|
313
314
|
- `suppressHostOutput(result?)` from `@unbrained/pm-cli/sdk` marks commands that already wrote output, preventing a second CLI payload while retaining the optional result for hooks, telemetry, and embedded hosts.
|
|
314
315
|
- `api.hooks.beforeCommand(handler)`, `api.hooks.beforeMutation(handler)`, `api.hooks.afterCommand(handler)`, `api.hooks.onWrite(handler)`, `api.hooks.onRead(handler)`, and `api.hooks.onIndex(handler)` add lifecycle hooks.
|
package/docs/README.md
CHANGED
|
@@ -51,6 +51,7 @@ pm guide release --json
|
|
|
51
51
|
- [SDK Context Platform](SDK_CONTEXT.md) - task-oriented entry point for authoritative reads, ranking, package workflows, diagnostics, recovery, and verification.
|
|
52
52
|
- [Self-Describing Context Contracts](SELF_DESCRIBING_CONTEXT_CONTRACTS.md) - intent-scoped reads, semantic flag invocation metadata, visibility parity, and generated error vocabulary.
|
|
53
53
|
- [Universal Read Output Contracts](READ_OUTPUT_CONTRACTS.md) - cross-command include, amount, cost, and encoding controls for CLI, SDK, MCP, and packages.
|
|
54
|
+
- [Diagnostic Output Contracts](DIAGNOSTIC_OUTPUT_CONTRACTS.md) - action-first error budgets, deterministic degradation, SDK projection, and executable refusal assurance.
|
|
54
55
|
- [Mutation Integrity](MUTATION_INTEGRITY.md) - shared CLI/SDK/MCP author, secret, append-only disposition, and stale-work guardrails.
|
|
55
56
|
- [Agent Provenance ADR Amendment](AGENT_PROVENANCE_ADR.md) - extensible model, effort, role, and host provenance with privacy and compatibility boundaries.
|
|
56
57
|
- [SDK Agent Session and Episode Context](SDK_AGENT_SESSION_CONTEXT.md) - inherited role/topic context, cross-process episode identity, and deterministic history grouping.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Universal Read Output Contracts
|
|
2
2
|
|
|
3
|
-
Tracker references: [pm-hb7ug8](../.agents/pm/features/pm-hb7ug8.toon), [pm-cxr0jb](../.agents/pm/features/pm-cxr0jb.toon), [pm-hid9g1](../.agents/pm/features/pm-hid9g1.toon), [pm-h8tpeh](../.agents/pm/features/pm-h8tpeh.toon), [pm-5t33or](../.agents/pm/features/pm-5t33or.toon), [pm-sb0tns](../.agents/pm/issues/pm-sb0tns.toon), [pm-gjjurs](../.agents/pm/issues/pm-gjjurs.toon), [pm-eugaqy](../.agents/pm/issues/pm-eugaqy.toon), [pm-jt8aa2](../.agents/pm/issues/pm-jt8aa2.toon), [pm-kyjdne](../.agents/pm/issues/pm-kyjdne.toon), [pm-8nev0o](../.agents/pm/issues/pm-8nev0o.toon), [pm-e5gl05](../.agents/pm/issues/pm-e5gl05.toon), [pm-cha95z](../.agents/pm/tasks/pm-cha95z.toon), and [pm-2qvq7a](../.agents/pm/issues/pm-2qvq7a.toon).
|
|
3
|
+
Tracker references: [pm-hb7ug8](../.agents/pm/features/pm-hb7ug8.toon), [pm-cxr0jb](../.agents/pm/features/pm-cxr0jb.toon), [pm-hid9g1](../.agents/pm/features/pm-hid9g1.toon), [pm-h8tpeh](../.agents/pm/features/pm-h8tpeh.toon), [pm-5t33or](../.agents/pm/features/pm-5t33or.toon), [pm-srns](../.agents/pm/issues/pm-srns.toon), [pm-sb0tns](../.agents/pm/issues/pm-sb0tns.toon), [pm-gjjurs](../.agents/pm/issues/pm-gjjurs.toon), [pm-eugaqy](../.agents/pm/issues/pm-eugaqy.toon), [pm-jt8aa2](../.agents/pm/issues/pm-jt8aa2.toon), [pm-kyjdne](../.agents/pm/issues/pm-kyjdne.toon), [pm-8nev0o](../.agents/pm/issues/pm-8nev0o.toon), [pm-e5gl05](../.agents/pm/issues/pm-e5gl05.toon), [pm-cha95z](../.agents/pm/tasks/pm-cha95z.toon), and [pm-2qvq7a](../.agents/pm/issues/pm-2qvq7a.toon).
|
|
4
4
|
|
|
5
5
|
## Agent Quick Context
|
|
6
6
|
|
|
@@ -140,7 +140,7 @@ pm stats --output-row-contract
|
|
|
140
140
|
pm contracts --full --json
|
|
141
141
|
```
|
|
142
142
|
|
|
143
|
-
Every projected result carries a `read_output` receipt with the requested dimensions, precedence, observed
|
|
143
|
+
Every projected result carries a `read_output` receipt with the requested dimensions, precedence, observed option provenance, deterministic estimated token count, string/row compaction signals, and budget outcome. When canonical controls are present, `canonical_options_used` records spellings such as `--output-include`; the optional field is omitted when no canonical control was supplied so minimum-budget session receipts remain compact. `legacy_aliases_used` and `migration_hints` record only compatibility flags the caller actually supplied. A command-local flag synthesized internally to execute a canonical projection mode is therefore never misreported as deprecated syntax. When both spellings are supplied, both provenance arrays report that mixed invocation. Budget degradation discovers nested arrays as well as declared result rows, so validation diagnostics and other governance payloads compact their inner findings before the useful result is omitted. `compacted_row_paths` names every reduced collection without redefining those nested arrays as ordinary pagination rows.
|
|
144
144
|
|
|
145
145
|
When rows are dropped to satisfy a ceiling, the result also carries `output_budget_truncation`, naming the binding budget and its source, any explicitly requested dimension the budget overrode, every compacted collection path, and executable CLI/SDK/MCP recovery options — a default ceiling can override an explicit `--output-limit unbounded`, and that override is reported rather than silent. If a producer supplied an opaque item-page cursor, compaction rebases it to the last row actually returned and reports `continuation_cursor_rebased: true`; following the cursor therefore cannot skip rows removed from the middle of a producer page. If no useful content can fit, `PmReadOutputBudgetExceeded` provides a discriminated omission result, a compact `{ outputBudget: "unbounded" }` recovery object, and `omitted_result_estimated_tokens`, the last useful-result estimate before omission; use `isReadOutputBudgetExceeded` before accessing result-specific fields. Universal controls are rejected on mutation commands and on the mutation mode of hybrid commands such as `comments`, `notes`, `files`, and `docs`.
|
|
146
146
|
|
|
@@ -179,6 +179,13 @@ key. Health retains at most 100 warning rows and reports `warning_count`,
|
|
|
179
179
|
projection unless `--full` is explicit, keeping the failing check identities
|
|
180
180
|
and warning codes inside the ordinary budget.
|
|
181
181
|
|
|
182
|
+
Failure transports use the companion
|
|
183
|
+
[Diagnostic Output Contracts](DIAGNOSTIC_OUTPUT_CONTRACTS.md). Those contracts
|
|
184
|
+
bind errors, warnings, validation summaries, and recovery bundles independently
|
|
185
|
+
from successful command results. Corrective actions precede explanation and
|
|
186
|
+
survive every degradation stage, while untruncated JSON avoids a per-call
|
|
187
|
+
receipt tax.
|
|
188
|
+
|
|
182
189
|
## SDK and Package Usage
|
|
183
190
|
|
|
184
191
|
Typed `PmClient` read methods accept `PmReadOutputOptions` directly:
|
|
@@ -314,9 +314,12 @@ outcome milestones are roots, not work subjects, and are excluded from those
|
|
|
314
314
|
populations. Rate or
|
|
315
315
|
all-status floors are lifecycle-stable; an absolute active-population floor is
|
|
316
316
|
invalid because completing reachable work legitimately moves it into the
|
|
317
|
-
terminal population.
|
|
318
|
-
|
|
319
|
-
clean class with a
|
|
317
|
+
terminal population. Detailed output's nested SDK profile census,
|
|
318
|
+
`finding_subjects_by_code`, includes every known finding code even when its
|
|
319
|
+
population is zero, so assurance selectors never confuse a clean class with a
|
|
320
|
+
missing contract field. The top-level audit and persisted-baseline census is
|
|
321
|
+
`affected_subjects_by_code`; both fields count affected subjects, but their
|
|
322
|
+
locations and consumers differ and neither is an alias for the other.
|
|
320
323
|
|
|
321
324
|
```ts
|
|
322
325
|
import {
|
package/docs/TESTING.md
CHANGED
|
@@ -366,6 +366,18 @@ The manifest records baseline bytes and estimated tokens for visible review
|
|
|
366
366
|
deltas. Updating it cannot raise answer ceilings, which remain owned by
|
|
367
367
|
`PM_COMMAND_OUTPUT_BUDGET_CONTRACTS`.
|
|
368
368
|
|
|
369
|
+
Diagnostic ceilings share the executable refusal gate:
|
|
370
|
+
|
|
371
|
+
```bash
|
|
372
|
+
pnpm quality:recovery-closure
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
The gate replays 22 refusal contracts and ratchets ten representative failure
|
|
376
|
+
paths against `PM_DIAGNOSTIC_OUTPUT_BUDGET_CONTRACTS`. Every diagnostic must fit
|
|
377
|
+
its declared JSON ceiling and preserve a mechanically actionable correction;
|
|
378
|
+
the missing-probe negative control proves that the diagnostic corpus cannot
|
|
379
|
+
silently shrink.
|
|
380
|
+
|
|
369
381
|
The gate derives every supported harness, model, session, and provenance
|
|
370
382
|
environment key from the SDK-owned harness descriptor registry. It deletes
|
|
371
383
|
those host inputs before each fixture invocation, then supplies only the
|
|
@@ -480,6 +492,9 @@ pm test <item-id> --metric-below coverage=100 --metric-diff p95_latency
|
|
|
480
492
|
|
|
481
493
|
Measurements are stored on the producing `test_runs` row, retained with the
|
|
482
494
|
bounded run history, and exposed consistently by CLI, SDK, MCP, and contracts.
|
|
495
|
+
Each recorded row also keeps a bounded `executions` list with the exact linked
|
|
496
|
+
command plus its requested and effective `pm_context_mode`, so tracker-backed
|
|
497
|
+
verification remains attributable after the transient process logs are gone.
|
|
483
498
|
|
|
484
499
|
## Linked-Test Assertions
|
|
485
500
|
|
package/marketplace.json
CHANGED
|
@@ -6,14 +6,14 @@
|
|
|
6
6
|
},
|
|
7
7
|
"metadata": {
|
|
8
8
|
"description": "Official marketplace for pm CLI — native git-based project management for Claude Code and AI coding agents.",
|
|
9
|
-
"version": "2026.8.
|
|
9
|
+
"version": "2026.8.22"
|
|
10
10
|
},
|
|
11
11
|
"plugins": [
|
|
12
12
|
{
|
|
13
13
|
"name": "pm-claude",
|
|
14
14
|
"source": "./plugins/pm-claude",
|
|
15
15
|
"description": "Native pm CLI integration for Claude Code — 28 MCP tools, 5 workflow skills, 14 slash commands, 4 subagents, hybrid TUI task tracking, session context injection, and coordination subagents for git-based project management without leaving Claude Code.",
|
|
16
|
-
"version": "2026.8.
|
|
16
|
+
"version": "2026.8.22",
|
|
17
17
|
"author": {
|
|
18
18
|
"name": "unbrained",
|
|
19
19
|
"url": "https://github.com/unbraind/pm-cli"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@unbrained/pm-digital-twin",
|
|
3
|
-
"version": "2026.8.
|
|
3
|
+
"version": "2026.8.22",
|
|
4
4
|
"private": true,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Beyond-PM exemplar: a temporal production-facility digital twin built entirely on public pm SDK and extension primitives.",
|