@unbrained/pm-cli 2026.8.17 → 2026.8.19
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/AGENTS.md +4 -3
- package/CHANGELOG.md +51 -5
- package/README.md +3 -3
- package/dist/cli/error-guidance.js +8 -4
- package/dist/cli/help-content.js +32 -13
- package/dist/cli/help-json-payload.d.ts +15 -0
- package/dist/cli/help-json-payload.js +101 -23
- package/dist/cli/main.js +6 -2
- package/dist/cli/register-list-query.js +138 -54
- package/dist/cli/register-mutation.js +8 -8
- package/dist/cli/register-operations.js +6 -6
- package/dist/cli-bundle/bundle-manifest.json +149 -149
- package/dist/cli-bundle/chunks/chunk-4NRRH7AM.js +2 -0
- package/dist/cli-bundle/chunks/chunk-4THEB6PD.js +13 -0
- package/dist/cli-bundle/chunks/{chunk-HBJAS566.js → chunk-BHYMXLAE.js} +2 -2
- package/dist/cli-bundle/chunks/chunk-GWMXAQOD.js +197 -0
- package/dist/cli-bundle/chunks/chunk-HVFQTLYM.js +35 -0
- package/dist/cli-bundle/chunks/chunk-OI4XI562.js +5 -0
- package/dist/cli-bundle/chunks/{chunk-3UEGXBMR.js → chunk-OIOKV6NO.js} +58 -54
- package/dist/cli-bundle/chunks/chunk-QXSH7BLM.js +3 -0
- package/dist/cli-bundle/chunks/chunk-SARFF5H5.js +3 -0
- package/dist/cli-bundle/chunks/{chunk-7IBRGCHX.js → chunk-TOXJM4WA.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-JOKATURE.js → chunk-YBMRWW4E.js} +44 -44
- package/dist/cli-bundle/chunks/register-list-query-Y56KINDU.js +11 -0
- package/dist/cli-bundle/chunks/register-mutation-AUWVCW4M.js +20 -0
- package/dist/cli-bundle/chunks/register-operations-PZQPHXW5.js +2 -0
- package/dist/cli-bundle/chunks/{register-setup-DOSFBGKE.js → register-setup-I4LUHGVW.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-34QBIYZI.js +155 -0
- package/dist/cli-bundle/focused-chunks/{chunk-MHPIL773.js → chunk-BJRYFVSH.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-DKPLYW3L.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-SALH6B6K.js → chunk-EF6ZS5GH.js} +44 -44
- package/dist/cli-bundle/focused-chunks/{chunk-XKAMP5OU.js → chunk-ESISGDAY.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-SYZENPIT.js → chunk-EXBCLIBU.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-JDOMQ7VQ.js +4 -0
- package/dist/cli-bundle/focused-chunks/chunk-L623ZPNK.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-MCZXYZAF.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-ODHQEECS.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-ZQPGZZWQ.js → chunk-PRHY2IMX.js} +3 -3
- package/dist/cli-bundle/focused-chunks/chunk-RZU5U6Q7.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-ATEY76SX.js → chunk-US7VEYZG.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-VXDSU5MC.js +26 -0
- package/dist/cli-bundle/focused-chunks/chunk-YBMGXBFV.js +16 -0
- package/dist/cli-bundle/focused-chunks/chunk-YLVBJ6GF.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-CYFK5UPB.js → chunk-ZBIQQYMI.js} +2 -2
- 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 -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 +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 -4
- package/dist/core/config/nested-settings.js +8 -2
- package/dist/core/extensions/exporter-output-contract.d.ts +12 -0
- package/dist/core/extensions/exporter-output-contract.js +67 -0
- package/dist/core/extensions/extension-types.d.ts +36 -1
- package/dist/core/extensions/extension-types.js +2 -2
- package/dist/core/extensions/loader.js +35 -44
- package/dist/core/history/event-index.d.ts +5 -0
- package/dist/core/history/event-index.js +133 -27
- package/dist/core/sentry/helpers.js +3 -3
- package/dist/core/shared/constants.js +5 -2
- package/dist/core/shared/errors.d.ts +2 -0
- package/dist/core/shared/errors.js +2 -2
- package/dist/core/store/settings-validator.d.ts +4 -0
- package/dist/core/store/settings-validator.js +3 -2
- package/dist/core/store/settings.js +8 -2
- package/dist/mcp/tool-definitions.js +12 -7
- package/dist/sdk/agent/refusal-closure.d.ts +41 -0
- package/dist/sdk/agent/refusal-closure.js +92 -0
- package/dist/sdk/agent/refusal-reachability.d.ts +1 -1
- package/dist/sdk/agent/refusal-reachability.js +4 -4
- package/dist/sdk/agent-capability-contracts.d.ts +13 -0
- package/dist/sdk/agent-capability-contracts.js +104 -7
- package/dist/sdk/authoring.d.ts +1 -1
- package/dist/sdk/authoring.js +2 -2
- package/dist/sdk/cli-bootstrap.d.ts +2 -2
- package/dist/sdk/cli-bootstrap.js +4 -4
- package/dist/sdk/cli-contracts/command-aliases.d.ts +34 -2
- package/dist/sdk/cli-contracts/command-aliases.js +80 -13
- package/dist/sdk/cli-contracts/commander-mutation-options.js +30 -6
- package/dist/sdk/cli-contracts/commander-types.js +5 -4
- package/dist/sdk/cli-contracts/enum-contracts.d.ts +4 -0
- package/dist/sdk/cli-contracts/enum-contracts.js +9 -2
- package/dist/sdk/cli-contracts/flag-contracts.d.ts +5 -0
- package/dist/sdk/cli-contracts/flag-contracts.js +84 -13
- package/dist/sdk/cli-contracts/flag-lexicon-contracts.d.ts +55 -0
- package/dist/sdk/cli-contracts/flag-lexicon-contracts.js +240 -0
- package/dist/sdk/cli-contracts/grammar-contracts.d.ts +151 -0
- package/dist/sdk/cli-contracts/grammar-contracts.js +958 -0
- package/dist/sdk/cli-contracts/runtime-contracts.d.ts +33 -5
- package/dist/sdk/cli-contracts/runtime-contracts.js +100 -23
- package/dist/sdk/cli-contracts/tool-option-contracts.d.ts +28 -1
- package/dist/sdk/cli-contracts/tool-option-contracts.js +38 -3
- package/dist/sdk/cli-contracts/tool-parameter-tables.js +7 -2
- package/dist/sdk/cli-contracts/tool-schema.d.ts +2 -2
- package/dist/sdk/cli-contracts/tool-schema.js +20 -11
- package/dist/sdk/cli-contracts.d.ts +5 -4
- package/dist/sdk/cli-contracts.js +7 -6
- package/dist/sdk/completion.js +13 -15
- package/dist/sdk/compose.d.ts +3 -3
- package/dist/sdk/compose.js +2 -2
- package/dist/sdk/context-intent-contracts.d.ts +2 -2
- package/dist/sdk/context-intent-contracts.js +22 -7
- package/dist/sdk/contracts.d.ts +3 -0
- package/dist/sdk/contracts.js +5 -2
- package/dist/sdk/core.d.ts +1 -1
- package/dist/sdk/core.js +3 -3
- package/dist/sdk/environment/host-environment-errors.js +3 -3
- package/dist/sdk/flag-invocation-contracts.d.ts +37 -0
- package/dist/sdk/flag-invocation-contracts.js +218 -9
- package/dist/sdk/generated/generated-error-code-catalog-part-1.js +186 -14
- package/dist/sdk/generated/generated-error-code-catalog-part-2.js +194 -26
- package/dist/sdk/guide-topics.js +5 -5
- package/dist/sdk/index.d.ts +10 -7
- package/dist/sdk/index.js +10 -7
- package/dist/sdk/init-agent-guidance.js +3 -3
- package/dist/sdk/mutation-events.d.ts +18 -2
- package/dist/sdk/mutation-events.js +59 -16
- package/dist/sdk/output-projection.d.ts +2 -0
- package/dist/sdk/output-projection.js +11 -5
- package/dist/sdk/output.d.ts +44 -0
- package/dist/sdk/output.js +28 -2
- package/dist/sdk/query/complete-list.d.ts +94 -0
- package/dist/sdk/query/complete-list.js +173 -0
- package/dist/sdk/query/get.js +25 -6
- package/dist/sdk/query/list.js +19 -2
- package/dist/sdk/query/search-contracts.d.ts +1 -1
- package/dist/sdk/query/search-contracts.js +23 -9
- package/dist/sdk/query/search.js +3 -3
- package/dist/sdk/query.d.ts +1 -0
- package/dist/sdk/query.js +3 -2
- package/dist/sdk/read-output/continuation.d.ts +1 -1
- package/dist/sdk/read-output/continuation.js +7 -24
- package/dist/sdk/read-output-contracts.d.ts +2 -2
- package/dist/sdk/read-output-contracts.js +89 -13
- package/dist/sdk/read-output-rows.d.ts +4 -0
- package/dist/sdk/read-output-rows.js +47 -18
- package/dist/sdk/runtime-extended-actions.js +10 -2
- package/dist/sdk/runtime.d.ts +8 -2
- package/dist/sdk/runtime.js +18 -11
- package/dist/sdk/workspace-snapshot.d.ts +2 -0
- package/dist/sdk/workspace-snapshot.js +10 -2
- package/dist/types.d.ts +5 -0
- package/dist/types.js +2 -2
- package/docs/AGENT_GUIDE.md +25 -9
- package/docs/CLI_GRAMMAR.md +106 -0
- package/docs/COMMANDS.md +39 -27
- package/docs/ONBOARDING.md +4 -4
- package/docs/OUTPUT_PROJECTION_CONTRACTS.md +11 -2
- package/docs/QUICKSTART.md +1 -1
- package/docs/README.md +2 -0
- package/docs/READ_OUTPUT_CONTRACTS.md +10 -6
- package/docs/RELEASING.md +30 -6
- package/docs/SDK.md +42 -2
- package/docs/SDK_ARTIFACT_OUTPUT.md +72 -0
- package/docs/SDK_CONTEXT_COORDINATION.md +46 -12
- package/docs/TESTING.md +14 -1
- package/docs/agent-task-token-baseline.json +5 -5
- package/docs/generated/AGENT_COMMAND_SURFACE.md +78 -78
- package/docs/generated/FLAG_LEXICON_BUDGETS.md +76 -0
- package/marketplace.json +2 -2
- package/package.json +5 -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/scripts/generate-agent-capability-surfaces.mjs +20 -14
- package/sdk/public-surface.json +1245 -60
- package/dist/cli-bundle/chunks/chunk-2QLOXC3V.js +0 -3
- package/dist/cli-bundle/chunks/chunk-4JPYF536.js +0 -35
- package/dist/cli-bundle/chunks/chunk-6VDLG2FC.js +0 -13
- package/dist/cli-bundle/chunks/chunk-ION3E43Q.js +0 -197
- package/dist/cli-bundle/chunks/chunk-OAC5NIV4.js +0 -3
- package/dist/cli-bundle/chunks/chunk-TPXZIBIV.js +0 -5
- package/dist/cli-bundle/chunks/chunk-YM2YAMF7.js +0 -2
- package/dist/cli-bundle/chunks/register-list-query-Q7KII4G5.js +0 -10
- package/dist/cli-bundle/chunks/register-mutation-4WBRPXLV.js +0 -20
- package/dist/cli-bundle/chunks/register-operations-SSENDH5B.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-267MUUS6.js +0 -16
- package/dist/cli-bundle/focused-chunks/chunk-2NNFLLNG.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-2QSAKMIH.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-BUCG4ZI2.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-EHXIKD6K.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-KGEXTMPG.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-KP2VQQVQ.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-POEEAD2V.js +0 -4
- package/dist/cli-bundle/focused-chunks/chunk-XPIC53VA.js +0 -26
- package/dist/cli-bundle/focused-chunks/chunk-ZT2DJS27.js +0 -155
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* envelopes, including dot-delimited nested paths used by graph projections.
|
|
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]="810d42b5-98f4-57a7-bdd9-2dfa1b2b1c03")}catch(e){}}();
|
|
9
9
|
const BUDGET_METADATA_ROOT_KEYS = new Set([
|
|
10
10
|
"applied_bound",
|
|
11
11
|
"completeness",
|
|
@@ -29,31 +29,43 @@ function isRecord(value) {
|
|
|
29
29
|
function valueAtPath(result, rowPath) {
|
|
30
30
|
let value = result;
|
|
31
31
|
for (const segment of rowPath.split(".")) {
|
|
32
|
-
if (
|
|
33
|
-
|
|
34
|
-
|
|
32
|
+
if (Array.isArray(value)) {
|
|
33
|
+
if (!/^\d+$/u.test(segment))
|
|
34
|
+
return undefined;
|
|
35
|
+
value = value[Number(segment)];
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
if (!isRecord(value))
|
|
39
|
+
return undefined;
|
|
40
|
+
value = value[segment];
|
|
41
|
+
}
|
|
35
42
|
}
|
|
36
43
|
return value;
|
|
37
44
|
}
|
|
38
45
|
/** Clone the owners along one row path and replace only its terminal value. */
|
|
39
46
|
function replaceValueAtPath(result, rowPath, replacement) {
|
|
40
47
|
const segments = rowPath.split(".");
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
48
|
+
const replace = (value, offset) => {
|
|
49
|
+
if (offset === segments.length)
|
|
50
|
+
return replacement;
|
|
51
|
+
const segment = segments[offset];
|
|
52
|
+
if (Array.isArray(value)) {
|
|
53
|
+
const index = Number(segment);
|
|
54
|
+
const cloned = [...value];
|
|
55
|
+
cloned[index] = replace(value[index], offset + 1);
|
|
56
|
+
return cloned;
|
|
57
|
+
}
|
|
58
|
+
const record = value;
|
|
59
|
+
return {
|
|
60
|
+
...record,
|
|
61
|
+
[segment]: replace(record[segment], offset + 1),
|
|
62
|
+
};
|
|
63
|
+
};
|
|
64
|
+
return replace(result, 0);
|
|
53
65
|
}
|
|
54
66
|
/** Replace one declared row collection with a suffix beginning at an offset. */
|
|
55
67
|
export function sliceReadOutputRowCollection(result, rowPath, offset) {
|
|
56
|
-
const collection =
|
|
68
|
+
const collection = readOutputContinuationRowCollections(result).find((entry) => entry.path === rowPath);
|
|
57
69
|
if (!collection)
|
|
58
70
|
return result;
|
|
59
71
|
const replacement = Array.isArray(collection.value)
|
|
@@ -71,6 +83,14 @@ export function readOutputRowPaths(result) {
|
|
|
71
83
|
.filter(([, value]) => Array.isArray(value))
|
|
72
84
|
.map(([key]) => key);
|
|
73
85
|
}
|
|
86
|
+
/** Resolve collections that may be resumed independently from primary result rows. */
|
|
87
|
+
export function readOutputContinuationRowPaths(result) {
|
|
88
|
+
const contract = result.row_contract;
|
|
89
|
+
if (isRecord(contract) && Array.isArray(contract.continuation_row_keys)) {
|
|
90
|
+
return contract.continuation_row_keys.filter((entry) => typeof entry === "string" && entry.trim().length > 0);
|
|
91
|
+
}
|
|
92
|
+
return readOutputRowPaths(result);
|
|
93
|
+
}
|
|
74
94
|
/** Resolve every declared row path that currently contains iterable rows. */
|
|
75
95
|
export function readOutputRowCollections(result) {
|
|
76
96
|
return readOutputRowPaths(result).flatMap((rowPath) => {
|
|
@@ -80,6 +100,15 @@ export function readOutputRowCollections(result) {
|
|
|
80
100
|
: [];
|
|
81
101
|
});
|
|
82
102
|
}
|
|
103
|
+
/** Resolve every declared continuation path that currently contains iterable rows. */
|
|
104
|
+
export function readOutputContinuationRowCollections(result) {
|
|
105
|
+
return readOutputContinuationRowPaths(result).flatMap((rowPath) => {
|
|
106
|
+
const value = valueAtPath(result, rowPath);
|
|
107
|
+
return Array.isArray(value) || isRecord(value)
|
|
108
|
+
? [{ path: rowPath, value }]
|
|
109
|
+
: [];
|
|
110
|
+
});
|
|
111
|
+
}
|
|
83
112
|
/**
|
|
84
113
|
* Discover every collection the token-budget degradation ladder may reduce.
|
|
85
114
|
*
|
|
@@ -155,4 +184,4 @@ export function boundReadOutputRows(result, amount) {
|
|
|
155
184
|
return { result: projected, truncated };
|
|
156
185
|
}
|
|
157
186
|
//# sourceMappingURL=read-output-rows.js.map
|
|
158
|
-
//# debugId=
|
|
187
|
+
//# debugId=810d42b5-98f4-57a7-bdd9-2dfa1b2b1c03
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
!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]="
|
|
2
|
+
!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]="0492d773-2af2-5072-8164-9f8aab536191")}catch(e){}}();
|
|
3
3
|
import { EXIT_CODE } from "../core/shared/constants.js";
|
|
4
4
|
import { PmCliError } from "../core/shared/errors.js";
|
|
5
5
|
import { createUnknownSubcommandError } from "./agent/subcommand-recovery.js";
|
|
@@ -32,6 +32,13 @@ export function runRuntimeEvalAction(context) {
|
|
|
32
32
|
/** Dispatch one bounded mutation-event page through the public SDK runner. */
|
|
33
33
|
export function runRuntimeEventsAction(context) {
|
|
34
34
|
const input = mergedInput(context);
|
|
35
|
+
const rawCursorMode = input.cursorMode;
|
|
36
|
+
if (rawCursorMode !== undefined &&
|
|
37
|
+
rawCursorMode !== "batch" &&
|
|
38
|
+
rawCursorMode !== "row") {
|
|
39
|
+
throw new PmCliError("Mutation event cursor mode must be batch or row.", EXIT_CODE.USAGE, { code: "invalid_event_cursor_mode" });
|
|
40
|
+
}
|
|
41
|
+
const cursorMode = rawCursorMode;
|
|
35
42
|
return listMutationEvents({
|
|
36
43
|
cwd: readRuntimeString(input, "cwd"),
|
|
37
44
|
pmRoot: readRuntimeString(input, "path"),
|
|
@@ -43,6 +50,7 @@ export function runRuntimeEventsAction(context) {
|
|
|
43
50
|
? undefined
|
|
44
51
|
: parseRuntimeInteger(input.limit, "limit"),
|
|
45
52
|
full: input.full === true,
|
|
53
|
+
cursorMode,
|
|
46
54
|
...(input.provenance === undefined
|
|
47
55
|
? {}
|
|
48
56
|
: { provenance: input.provenance === true }),
|
|
@@ -161,4 +169,4 @@ export function runRuntimeSchedulingAction(context) {
|
|
|
161
169
|
return runRemind(title, input, context.global);
|
|
162
170
|
}
|
|
163
171
|
//# sourceMappingURL=runtime-extended-actions.js.map
|
|
164
|
-
//# debugId=
|
|
172
|
+
//# debugId=0492d773-2af2-5072-8164-9f8aab536191
|
package/dist/sdk/runtime.d.ts
CHANGED
|
@@ -8,6 +8,8 @@ export { SEARCH_EXTENSION_FLAG_DEFINITIONS } from "./extension-contracts.js";
|
|
|
8
8
|
export type { FlagDefinition } from "../core/extensions/loader.js";
|
|
9
9
|
import { EXIT_CODE } from "../core/shared/constants.js";
|
|
10
10
|
import type { ItemMetadata } from "../types/index.js";
|
|
11
|
+
import { type PmCompleteListOptions, type PmCompleteListResult } from "./query/complete-list.js";
|
|
12
|
+
export { PmCompleteListValidationError, assertCompleteListResult, certifyCompleteListResult, createCompleteListOptions, inspectCompleteListResult, type PmCompleteListCertificate, type PmCompleteListFailureReceipt, type PmCompleteListFinding, type PmCompleteListFindingCode, type PmCompleteListInspection, type PmCompleteListOptions, type PmCompleteListResult } from "./query/complete-list.js";
|
|
11
13
|
export type { WorkspaceExtensionCommandContract, WorkspaceFieldContract, } from "./workspace-contracts.js";
|
|
12
14
|
import { type PmReadOutputOptions, type PmReadOutputResultFor } from "./read-output-contracts.js";
|
|
13
15
|
export type { PmReadOutputBudgetExceeded, PmReadOutputOptions, PmReadOutputResult, PmReadOutputResultFor, PmReadOutputSurfaceContract, } from "./read-output-contracts.js";
|
|
@@ -138,6 +140,8 @@ export declare class PmClient {
|
|
|
138
140
|
listAllItemMetadataLight(): Promise<ItemMetadata[]>;
|
|
139
141
|
/** List items with the MCP/agent compact defaults. */
|
|
140
142
|
list<Options extends ReadOptions<ListOptions> = ListOptions>(options?: Options): ReadPromise<ListResult, Options>;
|
|
143
|
+
/** Return every status and full item row only after fail-closed corpus certification. */
|
|
144
|
+
listAllComplete(options?: PmCompleteListOptions): Promise<PmCompleteListResult>;
|
|
141
145
|
/** Search items with the MCP/agent compact defaults. */
|
|
142
146
|
search<Options extends ReadOptions<SearchOptions> = SearchOptions>(query: string, options?: Options): ReadPromise<SearchResult, Options>;
|
|
143
147
|
/** Read one item by id. */
|
|
@@ -336,7 +340,7 @@ export declare class PmClient {
|
|
|
336
340
|
/** Reload installed package extensions using the same action as `pm package reload`. */
|
|
337
341
|
packageReload(options?: PackageCommandOptions): Promise<PackageCommandResult>;
|
|
338
342
|
/** Read bundled package catalog metadata using the same action as `pm package catalog`. */
|
|
339
|
-
packageCatalog(options?:
|
|
343
|
+
packageCatalog<Options extends ReadOptions<PackageCommandOptions> = PackageCommandOptions>(options?: Options): ReadPromise<PackageCommandResult, Options>;
|
|
340
344
|
/** Enable an installed package using the same action as `pm package activate`. */
|
|
341
345
|
packageActivate(target: string, options?: PackageCommandOptions): Promise<PackageCommandResult>;
|
|
342
346
|
/** Disable an installed package using the same action as `pm package deactivate`. */
|
|
@@ -350,6 +354,8 @@ export declare class PmClient {
|
|
|
350
354
|
export declare function context<Options extends ReadOptions<ContextOptions> = ContextOptions>(options?: Options, clientOptions?: PmClientOptions): ReadPromise<ContextResult, Options>;
|
|
351
355
|
/** List items with the MCP/agent compact defaults without constructing a reusable client. */
|
|
352
356
|
export declare function list<Options extends ReadOptions<ListOptions> = ListOptions>(options?: Options, clientOptions?: PmClientOptions): ReadPromise<ListResult, Options>;
|
|
357
|
+
/** Return every status and full item row with fail-closed corpus proof. */
|
|
358
|
+
export declare function listAllComplete(options?: PmCompleteListOptions, clientOptions?: PmClientOptions): Promise<PmCompleteListResult>;
|
|
353
359
|
/** Search items with the MCP/agent compact defaults without constructing a reusable client. */
|
|
354
360
|
export declare function search<Options extends ReadOptions<SearchOptions> = SearchOptions>(query: string, options?: Options, clientOptions?: PmClientOptions): ReadPromise<SearchResult, Options>;
|
|
355
361
|
/** Read one item by id without constructing a reusable client. */
|
|
@@ -510,7 +516,7 @@ export declare function packageDescribe(target?: string, options?: PackageComman
|
|
|
510
516
|
/** Reload package extensions without constructing a reusable client. */
|
|
511
517
|
export declare function packageReload(options?: PackageCommandOptions, clientOptions?: PmClientOptions): Promise<PackageCommandResult>;
|
|
512
518
|
/** Read bundled package catalog metadata without constructing a reusable client. */
|
|
513
|
-
export declare function packageCatalog(options?:
|
|
519
|
+
export declare function packageCatalog<Options extends ReadOptions<PackageCommandOptions> = PackageCommandOptions>(options?: Options, clientOptions?: PmClientOptions): ReadPromise<PackageCommandResult, Options>;
|
|
514
520
|
/** Enable a package without constructing a reusable client. */
|
|
515
521
|
export declare function packageActivate(target: string, options?: PackageCommandOptions, clientOptions?: PmClientOptions): Promise<PackageCommandResult>;
|
|
516
522
|
/** Disable a package without constructing a reusable client. */
|
package/dist/sdk/runtime.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Defines public SDK APIs and package-author helpers for Runtime.
|
|
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]="95764dd9-1b0d-5732-9f10-b13b334ce27d")}catch(e){}}();
|
|
8
8
|
export { PM_GITIGNORE_END, PM_GITIGNORE_START, ensurePmGitignore, getPmGitignoreBlock, } from "./workspace.js";
|
|
9
9
|
export { SEARCH_EXTENSION_FLAG_DEFINITIONS } from "./extension-contracts.js";
|
|
10
10
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
@@ -23,6 +23,8 @@ import { resolveRuntimeFieldRegistry, resolveRuntimeStatusRegistry, } from "../c
|
|
|
23
23
|
import { getSettingsPath, resolvePmRoot } from "../core/store/paths.js";
|
|
24
24
|
import { readSettings } from "../core/store/settings.js";
|
|
25
25
|
import { listClientItemMetadataLight } from "./query/light-metadata.js";
|
|
26
|
+
import { certifyCompleteListResult, createCompleteListOptions } from "./query/complete-list.js";
|
|
27
|
+
export { PmCompleteListValidationError, assertCompleteListResult, certifyCompleteListResult, createCompleteListOptions, inspectCompleteListResult } from "./query/complete-list.js";
|
|
26
28
|
import { buildWorkspaceExtensionCommandContracts, buildWorkspaceFieldContracts, } from "./workspace-contracts.js";
|
|
27
29
|
import { PM_TOOL_ACTIONS } from "./cli-contracts/enum-contracts.js";
|
|
28
30
|
import { clearWorkspaceContractsCache, memoizeWorkspaceExtensionRegistrations, } from "./workspace-contracts-cache.js";
|
|
@@ -181,6 +183,8 @@ export class PmClient {
|
|
|
181
183
|
list(options = {}) {
|
|
182
184
|
return this.runTyped("list", { options });
|
|
183
185
|
}
|
|
186
|
+
/** Return every status and full item row only after fail-closed corpus certification. */
|
|
187
|
+
async listAllComplete(options = {}) { return certifyCompleteListResult(await this.list(createCompleteListOptions(options))); }
|
|
184
188
|
/** Search items with the MCP/agent compact defaults. */
|
|
185
189
|
search(query, options = {}) {
|
|
186
190
|
return this.runTyped("search", { query, options });
|
|
@@ -673,9 +677,7 @@ export class PmClient {
|
|
|
673
677
|
return this.runTyped("package-reload", { options });
|
|
674
678
|
}
|
|
675
679
|
/** Read bundled package catalog metadata using the same action as `pm package catalog`. */
|
|
676
|
-
packageCatalog(options = {}) {
|
|
677
|
-
return this.runTyped("package-catalog", { options });
|
|
678
|
-
}
|
|
680
|
+
packageCatalog(options = {}) { return this.runTyped("package-catalog", { options }); }
|
|
679
681
|
/** Enable an installed package using the same action as `pm package activate`. */
|
|
680
682
|
packageActivate(target, options = {}) {
|
|
681
683
|
return this.runTyped("package-activate", { target, options });
|
|
@@ -704,6 +706,8 @@ export function context(options = {}, clientOptions = {}) {
|
|
|
704
706
|
export function list(options = {}, clientOptions = {}) {
|
|
705
707
|
return new PmClient(clientOptions).list(options);
|
|
706
708
|
}
|
|
709
|
+
/** Return every status and full item row with fail-closed corpus proof. */
|
|
710
|
+
export function listAllComplete(options = {}, clientOptions = {}) { return new PmClient(clientOptions).listAllComplete(options); }
|
|
707
711
|
/** Search items with the MCP/agent compact defaults without constructing a reusable client. */
|
|
708
712
|
export function search(query, options = {}, clientOptions = {}) {
|
|
709
713
|
return new PmClient(clientOptions).search(query, options);
|
|
@@ -997,9 +1001,7 @@ export function packageReload(options = {}, clientOptions = {}) {
|
|
|
997
1001
|
return new PmClient(clientOptions).packageReload(options);
|
|
998
1002
|
}
|
|
999
1003
|
/** Read bundled package catalog metadata without constructing a reusable client. */
|
|
1000
|
-
export function packageCatalog(options = {}, clientOptions = {}) {
|
|
1001
|
-
return new PmClient(clientOptions).packageCatalog(options);
|
|
1002
|
-
}
|
|
1004
|
+
export function packageCatalog(options = {}, clientOptions = {}) { return new PmClient(clientOptions).packageCatalog(options); }
|
|
1003
1005
|
/** Enable a package without constructing a reusable client. */
|
|
1004
1006
|
export function packageActivate(target, options = {}, clientOptions = {}) {
|
|
1005
1007
|
return new PmClient(clientOptions).packageActivate(target, options);
|
|
@@ -1338,6 +1340,7 @@ async function runMcpListAction(ctx) {
|
|
|
1338
1340
|
const listOptions = applyContextIntentProjection("list", ctx.options);
|
|
1339
1341
|
if (listOptions.compact === undefined &&
|
|
1340
1342
|
listOptions.brief === undefined &&
|
|
1343
|
+
listOptions.full === undefined &&
|
|
1341
1344
|
listOptions.fields === undefined &&
|
|
1342
1345
|
listOptions.includeBody === undefined) {
|
|
1343
1346
|
listOptions.compact = true;
|
|
@@ -1346,13 +1349,14 @@ async function runMcpListAction(ctx) {
|
|
|
1346
1349
|
return withQuerySummary((await runList(readString(ctx.args, "status") ?? readString(listOptions, "status"), listOptions, ctx.global)), listOptions);
|
|
1347
1350
|
}
|
|
1348
1351
|
async function runMcpSearchAction(ctx) {
|
|
1349
|
-
const
|
|
1352
|
+
const query = readRequiredString(ctx.args, "query");
|
|
1353
|
+
const searchOptions = applyContextIntentProjection("search", ctx.options, [query]);
|
|
1350
1354
|
if (searchOptions.compact === undefined &&
|
|
1351
1355
|
searchOptions.full === undefined &&
|
|
1352
1356
|
searchOptions.fields === undefined) {
|
|
1353
1357
|
searchOptions.compact = true;
|
|
1354
1358
|
}
|
|
1355
|
-
return withQuerySummary((await runSearch(
|
|
1359
|
+
return withQuerySummary((await runSearch(query, searchOptions, ctx.global)), searchOptions);
|
|
1356
1360
|
}
|
|
1357
1361
|
async function runMcpCreateAction(ctx) {
|
|
1358
1362
|
const { changedFields, idOnly, runnerOptions } = withMutationCompaction(ctx.args, ctx.options);
|
|
@@ -1780,7 +1784,10 @@ const SDK_ACTION_HANDLERS = {
|
|
|
1780
1784
|
event: runRuntimeSchedulingAction,
|
|
1781
1785
|
remind: runRuntimeSchedulingAction,
|
|
1782
1786
|
list: runMcpListAction,
|
|
1783
|
-
get: (ctx) =>
|
|
1787
|
+
get: (ctx) => {
|
|
1788
|
+
const id = requireMcpItemId(ctx);
|
|
1789
|
+
return runGet(id, ctx.global, applyContextIntentProjection("get", ctx.options, [id]));
|
|
1790
|
+
},
|
|
1784
1791
|
search: runMcpSearchAction,
|
|
1785
1792
|
duplicates: (ctx) => {
|
|
1786
1793
|
const status = typeof ctx.options.status === "string"
|
|
@@ -1933,4 +1940,4 @@ async function loadWorkspaceExtensionRegistrations(pmRoot, settings, cwd) {
|
|
|
1933
1940
|
}
|
|
1934
1941
|
}
|
|
1935
1942
|
//# sourceMappingURL=runtime.js.map
|
|
1936
|
-
//# debugId=
|
|
1943
|
+
//# debugId=95764dd9-1b0d-5732-9f10-b13b334ce27d
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
/** Current content-addressed workspace snapshot manifest schema identifier. */
|
|
2
2
|
export declare const SNAPSHOT_SCHEMA = "https://schema.unbrained.dev/pm/workspace-snapshot/v1";
|
|
3
|
+
/** Workspace snapshot action tokens accepted by the SDK and CLI dispatcher. */
|
|
4
|
+
export declare const WORKSPACE_SNAPSHOT_ACTIONS: readonly ["create", "list", "inspect", "restore", "delete"];
|
|
3
5
|
/** Filesystem operations required by atomic snapshot publish and restore swaps. */
|
|
4
6
|
export interface WorkspaceSnapshotAtomicOperations {
|
|
5
7
|
/** Rename one filesystem entry atomically. */
|
|
@@ -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]="2580e043-8675-5070-b57e-30cae333228c")}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";
|
|
@@ -18,6 +18,14 @@ import { PmCliError } from "../core/shared/errors.js";
|
|
|
18
18
|
import { withHostEnvironmentBoundary } from "./environment/host-environment-errors.js";
|
|
19
19
|
/** Current content-addressed workspace snapshot manifest schema identifier. */
|
|
20
20
|
export const SNAPSHOT_SCHEMA = "https://schema.unbrained.dev/pm/workspace-snapshot/v1";
|
|
21
|
+
/** Workspace snapshot action tokens accepted by the SDK and CLI dispatcher. */
|
|
22
|
+
export const WORKSPACE_SNAPSHOT_ACTIONS = [
|
|
23
|
+
"create",
|
|
24
|
+
"list",
|
|
25
|
+
"inspect",
|
|
26
|
+
"restore",
|
|
27
|
+
"delete",
|
|
28
|
+
];
|
|
21
29
|
const SNAPSHOT_RUNTIME_PATH = path.join("runtime", "workspace-snapshots");
|
|
22
30
|
const EXCLUDED_ROOT_NAMES = new Set([
|
|
23
31
|
"checkpoints",
|
|
@@ -603,4 +611,4 @@ export async function deleteWorkspaceSnapshot(pmRoot, target) {
|
|
|
603
611
|
return { deleted: "object", target };
|
|
604
612
|
}
|
|
605
613
|
//# sourceMappingURL=workspace-snapshot.js.map
|
|
606
|
-
//# debugId=
|
|
614
|
+
//# debugId=2580e043-8675-5070-b57e-30cae333228c
|
package/dist/types.d.ts
CHANGED
|
@@ -1078,6 +1078,11 @@ export interface PmSettings {
|
|
|
1078
1078
|
output: {
|
|
1079
1079
|
default_format: "toon" | "json";
|
|
1080
1080
|
};
|
|
1081
|
+
/** Agent and human interaction preferences that do not change command semantics. */
|
|
1082
|
+
ux?: {
|
|
1083
|
+
/** Emit one stderr migration hint when a deprecated command alias is invoked. */
|
|
1084
|
+
deprecation_hints?: boolean;
|
|
1085
|
+
};
|
|
1081
1086
|
/** Value that configures or reports history for this contract. */
|
|
1082
1087
|
history: {
|
|
1083
1088
|
missing_stream: "auto_create" | "strict_error";
|
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]="f6ab5bae-53b3-5feb-b89f-46e64afe7058")}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=f6ab5bae-53b3-5feb-b89f-46e64afe7058
|
package/docs/AGENT_GUIDE.md
CHANGED
|
@@ -9,8 +9,8 @@ Run this before heavy work:
|
|
|
9
9
|
```bash
|
|
10
10
|
pm context --limit 10
|
|
11
11
|
pm search "<request keywords>" --limit 10
|
|
12
|
-
pm list
|
|
13
|
-
pm list
|
|
12
|
+
pm list --status open --limit 20
|
|
13
|
+
pm list --status in_progress --limit 20
|
|
14
14
|
pm init --agent-guidance status
|
|
15
15
|
pm install guide-shell --project
|
|
16
16
|
pm guide workflows
|
|
@@ -28,8 +28,8 @@ Tracked documentation work: [pm-u9d0](../.agents/pm/epics/pm-u9d0.toon).
|
|
|
28
28
|
```bash
|
|
29
29
|
pm context --limit 10
|
|
30
30
|
pm search "<keywords>" --limit 10
|
|
31
|
-
pm list
|
|
32
|
-
pm list
|
|
31
|
+
pm list --status open --limit 20
|
|
32
|
+
pm list --status in_progress --limit 20
|
|
33
33
|
```
|
|
34
34
|
|
|
35
35
|
2. **Create only when necessary**
|
|
@@ -115,13 +115,13 @@ pm release <item-id>
|
|
|
115
115
|
| Require every query token | `pm search "<keywords>" --match-mode and` (hard-filter; `exact` = contiguous phrase; default `or` adds an all-terms ranking bonus) |
|
|
116
116
|
| Just the match count | `pm search "<keywords>" --count` (no hit rows; `count`/`total` carry the matched total) |
|
|
117
117
|
| Per-query score threshold | `pm search "<keywords>" --min-score 5` (overrides settings `search.score_threshold` for this query) |
|
|
118
|
-
| Every matched row (no cap) | `pm list
|
|
119
|
-
| Item bodies in bulk (one call) | `pm list
|
|
118
|
+
| Every matched row (no cap) | `pm list --all --no-truncate --brief` (`result.total` reports the full count when a `--limit`/`--offset` truncates) |
|
|
119
|
+
| Item bodies in bulk (one call) | `pm list --status open --json --include-body` (avoids one `pm get` per item) |
|
|
120
120
|
| Open work only | `pm search "<keywords>" --status open` (drops closed-history noise; did-you-mean on typos) |
|
|
121
121
|
| Scope search like list | `pm search "<keywords>" --type Task --assignee <name> --parent <id>` (full `pm list` filter parity) |
|
|
122
|
-
| Items changed since last window | `pm list
|
|
123
|
-
| Open items changed today | `pm list
|
|
124
|
-
| Items changed recently | `pm list
|
|
122
|
+
| Items changed since last window | `pm list --all --updated-after <prev-run-ISO> --brief` (relative `-2h`/`-7d` also work) |
|
|
123
|
+
| Open items changed today | `pm list --status open --today --brief` (local-midnight shorthand; mutually exclusive with `--updated-after`) |
|
|
124
|
+
| Items changed recently | `pm list --all --recent --brief` (last seven days; mutually exclusive with `--updated-after`) |
|
|
125
125
|
| Single item | `pm get <id>` |
|
|
126
126
|
| Full machine payload | `pm get <id> --full --json` |
|
|
127
127
|
| Command flags | `pm <command> --help --json` |
|
|
@@ -171,6 +171,22 @@ Use the canonical [guide topic map](README.md#guide-topic-map) when local in-CLI
|
|
|
171
171
|
- Use `--force` only for explicit override paths.
|
|
172
172
|
- Release when pausing, handing off, or after close.
|
|
173
173
|
|
|
174
|
+
## Reviewed Delivery Closeout
|
|
175
|
+
|
|
176
|
+
Treat PM evidence, item closure, and the generated changelog as part of the
|
|
177
|
+
reviewed change. Add all evidence known before merge to the active branch,
|
|
178
|
+
close and release the item there, regenerate `CHANGELOG.md`, and include those
|
|
179
|
+
artifacts in the same pull request.
|
|
180
|
+
|
|
181
|
+
If evidence depends on the merge commit SHA or a post-merge hosted result, use
|
|
182
|
+
a normal `main`-based follow-up pull request for the repository mutation. Never
|
|
183
|
+
push tracker-only or changelog-only closeout directly to `main`: that direct
|
|
184
|
+
commit becomes the release candidate but has no reviewed analyzer provenance,
|
|
185
|
+
so `Release analyzer readiness (main)` must refuse it. Record external
|
|
186
|
+
post-merge observations on GitHub without changing repository state when no
|
|
187
|
+
tracked closeout update is required. See [Releasing](RELEASING.md#reviewed-delivery-closeout)
|
|
188
|
+
for the release contract.
|
|
189
|
+
|
|
174
190
|
## Documentation Rules for Agents
|
|
175
191
|
|
|
176
192
|
- Keep [README](../README.md) short.
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# Noun–Verb CLI Grammar and Compatibility Policy
|
|
2
|
+
|
|
3
|
+
Tracked by [pm-pbyu](../.agents/pm/decisions/pm-pbyu.toon), implemented through [pm-0z7n](../.agents/pm/features/pm-0z7n.toon), [pm-pfqi](../.agents/pm/tasks/pm-pfqi.toon), [pm-yy8rmx](../.agents/pm/tasks/pm-yy8rmx.toon), and [pm-wt43zj](../.agents/pm/tasks/pm-wt43zj.toon).
|
|
4
|
+
|
|
5
|
+
## Agent Quick Context
|
|
6
|
+
|
|
7
|
+
Use the canonical noun-first form when generating commands. Existing spellings remain executable, but deprecated compatibility aliases are absent from default help and completion discovery and emit one migration hint on stderr. Machine clients can read alias lifecycle and replacement tokens from `pm contracts --full --json`.
|
|
8
|
+
|
|
9
|
+
The first completed consolidation is the list family:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
pm list # active lifecycle rows
|
|
13
|
+
pm list --status open # one lifecycle class
|
|
14
|
+
pm list --status open,blocked # several classes
|
|
15
|
+
pm list --status blocked # status- or dependency-blocked semantics
|
|
16
|
+
pm list --all # every lifecycle status
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
`list-all`, `list-draft`, `list-open`, `list-in-progress`, `list-blocked`, `list-closed`, and `list-canceled` preserve command results and stdout behavior. Their documented migration hint may add one stderr line.
|
|
20
|
+
|
|
21
|
+
## Status
|
|
22
|
+
|
|
23
|
+
Accepted. The grammar contract, destination census, and compatibility policy are executable SDK data and mandatory static gates.
|
|
24
|
+
|
|
25
|
+
## Context
|
|
26
|
+
|
|
27
|
+
pm grew by adding one top-level spelling per feature. That made help, completions, contracts, documentation, and agent routing grow linearly even when several commands represented the same concept. The list family alone repeated almost the same help surface eight times. A universal project-management tool needs extensible behavior without requiring every agent to memorize an ever-growing flat vocabulary.
|
|
28
|
+
|
|
29
|
+
The governing product principle is `project management = context management`: command discovery must route an agent to the smallest authoritative context, while compatibility must preserve scripts and historical instructions.
|
|
30
|
+
|
|
31
|
+
## Decision Drivers
|
|
32
|
+
|
|
33
|
+
- Preserve every published invocation and its stdout behavior.
|
|
34
|
+
- Keep frequent operations concise without making aliases the discovery model.
|
|
35
|
+
- Make domain ownership explicit enough to generate routing, help, completions, SDK contracts, MCP projections, and documentation.
|
|
36
|
+
- Prevent surface regrowth with a fail-closed, bidirectional contract gate.
|
|
37
|
+
- Let packages add domain behavior without consuming the core noun budget.
|
|
38
|
+
- Make migration guidance suppressible for automation while keeping canonical replacements machine-readable.
|
|
39
|
+
|
|
40
|
+
## Alternatives Considered
|
|
41
|
+
|
|
42
|
+
### Flat surface status quo
|
|
43
|
+
|
|
44
|
+
Rejected. Each feature adds another root spelling and duplicates contract/help context. A byte-count snapshot records growth but does not decide whether the new command belongs in the architecture.
|
|
45
|
+
|
|
46
|
+
### Pure git-style subcommands
|
|
47
|
+
|
|
48
|
+
Rejected as an exclusive rule. Noun-first paths are canonical, but forcing high-frequency operations such as `create`, `get`, `update`, `claim`, and `close` to pay an extra token on every invocation would regress the agent hot path. Named permanent aliases may remain visible and are distinguished from deprecated compatibility shims in contract data.
|
|
49
|
+
|
|
50
|
+
### BusyBox-style multi-binary surface
|
|
51
|
+
|
|
52
|
+
Rejected. Separate binaries multiply distribution, signing, package resolution, documentation, and shell-discovery surfaces without improving domain routing.
|
|
53
|
+
|
|
54
|
+
## Decision
|
|
55
|
+
|
|
56
|
+
1. The core routing vocabulary has twelve nouns: `item`, `list`, `context`, `search`, `graph`, `history`, `workspace`, `package`, `ops`, `plan`, `contracts`, and `help`.
|
|
57
|
+
2. Canonical forms are noun-first. Verbs and facets are subcommands; projections and predicates are flags.
|
|
58
|
+
3. Shared semantics use a shared verb vocabulary. Noun-specific verbs require an explicit checked-in disposition.
|
|
59
|
+
4. Scope precedes its operation: for example, `workspace snapshot create`, not `workspace create snapshot`.
|
|
60
|
+
5. Package-owned commands are declared as such and do not silently expand the core noun set.
|
|
61
|
+
6. Published spellings are not removed. Deprecated spellings are hidden aliases with a canonical token sequence, PM owner, lifecycle, and one stderr migration hint.
|
|
62
|
+
7. Permanent hot-path aliases and deprecated aliases are different contract states. Permanent aliases are ergonomic API; deprecated aliases are compatibility state.
|
|
63
|
+
8. Every live command has exactly one destination row. A row may name its target noun, a tracked consolidation owner, a package owner, or a reasoned keep-as-is exception.
|
|
64
|
+
9. The census is bidirectional: missing live rows and stale checked-in rows both fail CI.
|
|
65
|
+
10. Default-visible top-level growth is ceilinged. Lowering the ceiling is always valid; raising it requires a tracked noun-placement decision rather than regenerating a baseline.
|
|
66
|
+
|
|
67
|
+
## SDK Contract
|
|
68
|
+
|
|
69
|
+
Package authors and embedded clients use the public exports:
|
|
70
|
+
|
|
71
|
+
```ts
|
|
72
|
+
import {
|
|
73
|
+
PM_CLI_GRAMMAR_CONTRACT,
|
|
74
|
+
PM_COMMAND_ALIAS_CONTRACTS,
|
|
75
|
+
PM_COMMAND_DESTINATION_CONTRACTS,
|
|
76
|
+
resolvePmCommandAlias,
|
|
77
|
+
verifyPmCliGrammar,
|
|
78
|
+
} from "@unbrained/pm-cli/sdk";
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
`PM_COMMAND_ALIAS_CONTRACTS` carries `alias`, `canonical`, `canonical_argv`, `lifecycle`, `hidden`, `registration`, and `owner`. `verifyPmCliGrammar` returns deterministic findings with an offending spelling and nearest conforming target.
|
|
82
|
+
|
|
83
|
+
Runtime contracts expose the compact noun/verb policy in summary output and include the exhaustive destination census in full output. Deprecated aliases remain queryable but are excluded from the default command-summary denominator.
|
|
84
|
+
|
|
85
|
+
## Compatibility and Migration Hints
|
|
86
|
+
|
|
87
|
+
Hints go to stderr exactly once per deprecated-alias invocation and never alter stdout. Disable them for a project when an automation intentionally retains old spellings:
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
pm config project set ux_deprecation_hints false
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
This setting changes presentation only. It does not disable aliases or change command results. The uniform machine result-envelope receipt is intentionally deferred to its separately tracked cross-command contract so this implementation does not create a list-only shape.
|
|
94
|
+
|
|
95
|
+
## Enforcement
|
|
96
|
+
|
|
97
|
+
`pnpm quality:command-grammar` builds the SDK, reads the live runtime command contracts, and compares them with the checked-in destination and alias tables. Package-owned destination rows are conditional because installed packages vary by workspace; every activated package command still requires a declared row, while an inactive package does not make its row stale. The gate also proves parity between discoverable SDK actions, the MCP `pm_run` action enum, and narrow MCP tools. The same gate runs inside `quality:static`, alongside contract drift checks. Its negative controls prove that unknown commands, stale core rows, broken alias targets, MCP drift, and surface-ceiling growth fail upward.
|
|
98
|
+
|
|
99
|
+
## Consequences
|
|
100
|
+
|
|
101
|
+
- Agents discover one list command instead of eight repeated help pages.
|
|
102
|
+
- Existing scripts keep working and receive an actionable replacement.
|
|
103
|
+
- CLI, SDK, completion, and contract consumers share one alias table.
|
|
104
|
+
- New commands require an explicit architectural home and PM owner.
|
|
105
|
+
- The compatibility table is long-lived public API and must be reviewed like any other SDK contract.
|
|
106
|
+
- Consolidation proceeds incrementally: current legacy commands may remain only with a named disposition until their owning PM item lands.
|