@unbrained/pm-cli 2026.8.18 → 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/CHANGELOG.md +16 -2
- package/dist/cli/error-guidance.js +3 -2
- 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 +8 -5
- package/dist/cli/register-mutation.js +8 -8
- package/dist/cli/register-operations.js +6 -6
- package/dist/cli-bundle/bundle-manifest.json +139 -139
- package/dist/cli-bundle/chunks/chunk-4NRRH7AM.js +2 -0
- package/dist/cli-bundle/chunks/{chunk-UYCLQVL2.js → chunk-4THEB6PD.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-BSK2IN3C.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-YRGOLZA7.js → chunk-OIOKV6NO.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-5UZZAJKR.js → chunk-QXSH7BLM.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-RZQTVMRQ.js → chunk-TOXJM4WA.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-GNFAFIJI.js → chunk-YBMRWW4E.js} +44 -44
- package/dist/cli-bundle/chunks/{register-list-query-I23LALEE.js → register-list-query-Y56KINDU.js} +11 -11
- 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-PPPEF3SN.js → register-setup-I4LUHGVW.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-5AF3ZBNB.js → chunk-34QBIYZI.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-V5XTGLK7.js → chunk-BJRYFVSH.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-DKPLYW3L.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-ODOVCP45.js → chunk-EF6ZS5GH.js} +44 -44
- package/dist/cli-bundle/focused-chunks/{chunk-EX6MKP2X.js → chunk-ESISGDAY.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-EUEGXZ2A.js → chunk-EXBCLIBU.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-UI6AJ5TD.js → chunk-JDOMQ7VQ.js} +2 -2
- 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-3TKWMNKF.js → chunk-PRHY2IMX.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-RZU5U6Q7.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-M62NO7EI.js → chunk-US7VEYZG.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-TN4AE665.js → chunk-VXDSU5MC.js} +2 -2
- 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-K43KKAFS.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 +31 -31
- package/dist/cli-bundle/sdk-governance.js +1 -1
- package/dist/cli-bundle/sdk-graph.js +1 -1
- package/dist/cli-bundle/sdk-merge.js +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/shared/errors.d.ts +2 -0
- package/dist/core/shared/errors.js +2 -2
- 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-capability-contracts.d.ts +13 -0
- package/dist/sdk/agent-capability-contracts.js +104 -7
- package/dist/sdk/cli-contracts/command-aliases.js +18 -2
- 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/flag-contracts.d.ts +5 -0
- package/dist/sdk/cli-contracts/flag-contracts.js +75 -8
- 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 +81 -0
- package/dist/sdk/cli-contracts/grammar-contracts.js +615 -2
- package/dist/sdk/cli-contracts/runtime-contracts.d.ts +15 -4
- package/dist/sdk/cli-contracts/runtime-contracts.js +42 -12
- 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.d.ts +3 -2
- package/dist/sdk/cli-contracts.js +5 -4
- 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 +2 -0
- package/dist/sdk/contracts.js +4 -2
- 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 +134 -2
- package/dist/sdk/generated/generated-error-code-catalog-part-2.js +154 -22
- package/dist/sdk/index.d.ts +7 -5
- package/dist/sdk/index.js +7 -5
- package/dist/sdk/output-projection.d.ts +2 -0
- package/dist/sdk/output-projection.js +11 -5
- package/dist/sdk/query/get.js +25 -6
- package/dist/sdk/query/list.js +16 -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/read-output/continuation.d.ts +1 -1
- package/dist/sdk/read-output/continuation.js +7 -24
- package/dist/sdk/read-output-contracts.js +55 -6
- package/dist/sdk/read-output-rows.d.ts +4 -0
- package/dist/sdk/read-output-rows.js +47 -18
- package/dist/sdk/runtime.js +9 -5
- package/dist/sdk/workspace-snapshot.d.ts +2 -0
- package/dist/sdk/workspace-snapshot.js +10 -2
- package/docs/COMMANDS.md +16 -4
- package/docs/OUTPUT_PROJECTION_CONTRACTS.md +11 -2
- package/docs/READ_OUTPUT_CONTRACTS.md +10 -6
- package/docs/SDK.md +6 -0
- package/docs/TESTING.md +14 -1
- 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 -3
- 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 +576 -12
- package/dist/cli-bundle/chunks/chunk-ALDJGKAK.js +0 -2
- package/dist/cli-bundle/chunks/chunk-DY4DMUMC.js +0 -197
- package/dist/cli-bundle/chunks/chunk-L5Q2CLPE.js +0 -35
- package/dist/cli-bundle/chunks/chunk-PVRUN5ZS.js +0 -5
- package/dist/cli-bundle/chunks/register-mutation-6YGU3GPH.js +0 -20
- package/dist/cli-bundle/chunks/register-operations-4HTFC6J7.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-2PN4TJXH.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-C5IW2NDA.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-RNDNMARJ.js +0 -16
- package/dist/cli-bundle/focused-chunks/chunk-TVV2DONO.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-WGHQVU6P.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-XYNBXTDQ.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-Z56ECT7I.js +0 -2
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { type PmCommandCapabilityFamily } from "../agent-capability-contracts.js";
|
|
2
|
+
/** Stable value kinds used by the public flag lexicon. */
|
|
3
|
+
export type PmFlagValueKind = "boolean" | "string" | "number" | "list";
|
|
4
|
+
/** One canonical command-flag concept and every accepted compatibility alias. */
|
|
5
|
+
export interface PmFlagLexiconEntry {
|
|
6
|
+
/** Canonical command path. */
|
|
7
|
+
command: string;
|
|
8
|
+
/** Command capability family. */
|
|
9
|
+
family: PmCommandCapabilityFamily;
|
|
10
|
+
/** Stable semantic concept identifier. */
|
|
11
|
+
concept: string;
|
|
12
|
+
/** Canonical long spelling emitted by generated surfaces. */
|
|
13
|
+
flag: string;
|
|
14
|
+
/** Accepted compatibility spellings that must never become canonical rows. */
|
|
15
|
+
aliases: readonly string[];
|
|
16
|
+
/** Parsed value shape. */
|
|
17
|
+
value_kind: PmFlagValueKind;
|
|
18
|
+
}
|
|
19
|
+
/** Ratcheted canonical flag budget for one command. */
|
|
20
|
+
export interface PmCommandFlagBudget {
|
|
21
|
+
/** Canonical command path. */
|
|
22
|
+
command: string;
|
|
23
|
+
/** Current canonical flag count. */
|
|
24
|
+
current: number;
|
|
25
|
+
/** Maximum count accepted by the repository gate. */
|
|
26
|
+
maximum: number;
|
|
27
|
+
}
|
|
28
|
+
/** One fail-closed lexicon or budget violation. */
|
|
29
|
+
export interface PmFlagLexiconFinding {
|
|
30
|
+
/** Stable finding code. */
|
|
31
|
+
code: "alias_collision" | "budget_exceeded" | "duplicate_canonical_flag" | "inconsistent_concept_kind" | "missing_budget" | "stale_budget";
|
|
32
|
+
/** Canonical command path. */
|
|
33
|
+
command: string;
|
|
34
|
+
/** Human-readable finding detail. */
|
|
35
|
+
detail: string;
|
|
36
|
+
}
|
|
37
|
+
/** Complete verification receipt for a flag lexicon corpus. */
|
|
38
|
+
export interface PmFlagLexiconReport {
|
|
39
|
+
/** Whether every invariant and ratchet passed. */
|
|
40
|
+
ok: boolean;
|
|
41
|
+
/** Number of canonical command-flag rows checked. */
|
|
42
|
+
entry_count: number;
|
|
43
|
+
/** Number of command budgets checked. */
|
|
44
|
+
budget_count: number;
|
|
45
|
+
/** Stable ordered findings. */
|
|
46
|
+
findings: readonly PmFlagLexiconFinding[];
|
|
47
|
+
}
|
|
48
|
+
/** Build the canonical lexicon lazily from the same contracts as CLI and MCP. */
|
|
49
|
+
export declare function listPmFlagLexicon(): readonly PmFlagLexiconEntry[];
|
|
50
|
+
/** Return persisted no-growth ratchets with current counts derived from the canonical vocabulary. */
|
|
51
|
+
export declare function listPmCommandFlagBudgets(): readonly PmCommandFlagBudget[];
|
|
52
|
+
/** Verify uniqueness, concept kind stability, alias safety, and flag budgets. */
|
|
53
|
+
export declare function verifyPmFlagLexicon(entries?: readonly PmFlagLexiconEntry[], budgets?: readonly PmCommandFlagBudget[]): PmFlagLexiconReport;
|
|
54
|
+
/** Render a compact, generated family and command budget reference. Persisted budget rows are initialized to an explicit fallback so stale rows remain renderable. */
|
|
55
|
+
export declare function renderPmFlagLexiconMarkdown(): string;
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module sdk/flag-lexicon-contracts
|
|
3
|
+
*
|
|
4
|
+
* Compiles command flags into a canonical concept lexicon with enforceable
|
|
5
|
+
* per-command growth budgets.
|
|
6
|
+
*/
|
|
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]="19215662-5a8c-5b91-bc97-8dbdc1daff02")}catch(e){}}();
|
|
9
|
+
import { hasSubcommandFlagContractsForCommand, resolveSubcommandFlagContractsForCommand, } from "./flag-contracts.js";
|
|
10
|
+
import { PM_COMMAND_CAPABILITY_CONTRACTS, } from "../agent-capability-contracts.js";
|
|
11
|
+
import { enrichCliFlagInvocationContracts } from "../flag-invocation-contracts.js";
|
|
12
|
+
/** Memoized immutable canonical lexicon for this module instance. */
|
|
13
|
+
let cachedPmFlagLexicon;
|
|
14
|
+
/** Build the canonical lexicon lazily from the same contracts as CLI and MCP. */
|
|
15
|
+
export function listPmFlagLexicon() {
|
|
16
|
+
if (cachedPmFlagLexicon !== undefined)
|
|
17
|
+
return cachedPmFlagLexicon;
|
|
18
|
+
const commandContracts = PM_COMMAND_CAPABILITY_CONTRACTS.filter(({ command }) => hasSubcommandFlagContractsForCommand(command));
|
|
19
|
+
const provisionalEntries = commandContracts.flatMap(({ command, family }) => enrichCliFlagInvocationContracts(command, resolveSubcommandFlagContractsForCommand(command)).map((contract) => ({
|
|
20
|
+
command,
|
|
21
|
+
family,
|
|
22
|
+
concept: contract.flag.slice(2),
|
|
23
|
+
flag: contract.flag,
|
|
24
|
+
aliases: Object.freeze([...(contract.aliases ?? [])]),
|
|
25
|
+
value_kind: (contract.repeatable
|
|
26
|
+
? "list"
|
|
27
|
+
: contract.value_type),
|
|
28
|
+
})));
|
|
29
|
+
const compatibilityAliasFlags = new Set(provisionalEntries.flatMap((entry) => entry.aliases.map((alias) => `${entry.command}:${alias}`)));
|
|
30
|
+
const canonicalEntries = provisionalEntries.filter((entry) => !compatibilityAliasFlags.has(`${entry.command}:${entry.flag}`));
|
|
31
|
+
const kindsByConcept = new Map();
|
|
32
|
+
for (const entry of canonicalEntries) {
|
|
33
|
+
const kinds = kindsByConcept.get(entry.concept) ?? new Set();
|
|
34
|
+
kinds.add(entry.value_kind);
|
|
35
|
+
kindsByConcept.set(entry.concept, kinds);
|
|
36
|
+
}
|
|
37
|
+
cachedPmFlagLexicon = Object.freeze(canonicalEntries.map((entry) => Object.freeze({
|
|
38
|
+
...entry,
|
|
39
|
+
concept: kindsByConcept.get(entry.concept)?.size === 1
|
|
40
|
+
? entry.concept
|
|
41
|
+
: `${entry.concept}@${entry.command}`,
|
|
42
|
+
})));
|
|
43
|
+
return cachedPmFlagLexicon;
|
|
44
|
+
}
|
|
45
|
+
const PM_COMMAND_FLAG_BUDGET_MAXIMUMS = Object.freeze({
|
|
46
|
+
init: 30,
|
|
47
|
+
config: 35,
|
|
48
|
+
extension: 53,
|
|
49
|
+
package: 54,
|
|
50
|
+
packages: 54,
|
|
51
|
+
install: 26,
|
|
52
|
+
upgrade: 29,
|
|
53
|
+
create: 100,
|
|
54
|
+
copy: 24,
|
|
55
|
+
focus: 22,
|
|
56
|
+
list: 86,
|
|
57
|
+
"list-all": 85,
|
|
58
|
+
"list-draft": 84,
|
|
59
|
+
"list-open": 84,
|
|
60
|
+
"list-in-progress": 84,
|
|
61
|
+
"list-blocked": 84,
|
|
62
|
+
"list-closed": 84,
|
|
63
|
+
"list-canceled": 84,
|
|
64
|
+
aggregate: 37,
|
|
65
|
+
context: 45,
|
|
66
|
+
ctx: 45,
|
|
67
|
+
get: 30,
|
|
68
|
+
graph: 34,
|
|
69
|
+
search: 78,
|
|
70
|
+
duplicates: 24,
|
|
71
|
+
eval: 25,
|
|
72
|
+
next: 35,
|
|
73
|
+
history: 35,
|
|
74
|
+
events: 33,
|
|
75
|
+
"history-redact": 27,
|
|
76
|
+
"history-repair": 26,
|
|
77
|
+
"history-compact": 30,
|
|
78
|
+
"history-author-acknowledge": 28,
|
|
79
|
+
merge: 24,
|
|
80
|
+
schema: 40,
|
|
81
|
+
profile: 22,
|
|
82
|
+
activity: 35,
|
|
83
|
+
restore: 23,
|
|
84
|
+
update: 105,
|
|
85
|
+
"update-many": 140,
|
|
86
|
+
close: 31,
|
|
87
|
+
"close-many": 72,
|
|
88
|
+
delete: 24,
|
|
89
|
+
append: 24,
|
|
90
|
+
comments: 30,
|
|
91
|
+
notes: 34,
|
|
92
|
+
learnings: 26,
|
|
93
|
+
files: 39,
|
|
94
|
+
docs: 30,
|
|
95
|
+
deps: 32,
|
|
96
|
+
plan: 109,
|
|
97
|
+
test: 48,
|
|
98
|
+
"test-all": 37,
|
|
99
|
+
telemetry: 21,
|
|
100
|
+
stats: 29,
|
|
101
|
+
health: 36,
|
|
102
|
+
validate: 45,
|
|
103
|
+
assurance: 30,
|
|
104
|
+
gc: 22,
|
|
105
|
+
workspace: 23,
|
|
106
|
+
contracts: 29,
|
|
107
|
+
claim: 36,
|
|
108
|
+
release: 23,
|
|
109
|
+
"start-task": 23,
|
|
110
|
+
"pause-task": 23,
|
|
111
|
+
"close-task": 24,
|
|
112
|
+
meet: 33,
|
|
113
|
+
event: 33,
|
|
114
|
+
remind: 29,
|
|
115
|
+
"test-runs-worker": 25,
|
|
116
|
+
});
|
|
117
|
+
/** Return persisted no-growth ratchets with current counts derived from the canonical vocabulary. */
|
|
118
|
+
export function listPmCommandFlagBudgets() {
|
|
119
|
+
const currentByCommand = new Map(Object.keys(PM_COMMAND_FLAG_BUDGET_MAXIMUMS).map((command) => [command, 0]));
|
|
120
|
+
for (const { command } of listPmFlagLexicon()) {
|
|
121
|
+
currentByCommand.set(command, Number(currentByCommand.get(command)) + 1);
|
|
122
|
+
}
|
|
123
|
+
return Object.freeze(Object.entries(PM_COMMAND_FLAG_BUDGET_MAXIMUMS).map(([command, maximum]) => Object.freeze({
|
|
124
|
+
command,
|
|
125
|
+
current: Number(currentByCommand.get(command)),
|
|
126
|
+
maximum,
|
|
127
|
+
})));
|
|
128
|
+
}
|
|
129
|
+
/** Append collisions between compatibility aliases and canonical spellings. */
|
|
130
|
+
function appendAliasCollisionFindings(entries, canonicalOwners, findings) {
|
|
131
|
+
for (const entry of entries) {
|
|
132
|
+
for (const alias of entry.aliases) {
|
|
133
|
+
const owner = canonicalOwners.get(`${entry.command}:${alias}`);
|
|
134
|
+
if (owner === undefined || owner.flag === entry.flag)
|
|
135
|
+
continue;
|
|
136
|
+
findings.push({
|
|
137
|
+
code: "alias_collision",
|
|
138
|
+
command: entry.command,
|
|
139
|
+
detail: `${alias} aliases ${entry.flag} but is canonical for ${owner.flag}.`,
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
/** Append missing, stale, and exceeded command-budget findings. */
|
|
145
|
+
function appendBudgetFindings(counts, budgets, findings) {
|
|
146
|
+
const budgetedCommands = new Set(budgets.map(({ command }) => command));
|
|
147
|
+
for (const command of counts.keys()) {
|
|
148
|
+
if (budgetedCommands.has(command))
|
|
149
|
+
continue;
|
|
150
|
+
findings.push({
|
|
151
|
+
code: "missing_budget",
|
|
152
|
+
command,
|
|
153
|
+
detail: `${command} has canonical flags but no persisted budget.`,
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
for (const budget of budgets) {
|
|
157
|
+
const actual = counts.get(budget.command) ?? 0;
|
|
158
|
+
if (actual === 0) {
|
|
159
|
+
findings.push({
|
|
160
|
+
code: "stale_budget",
|
|
161
|
+
command: budget.command,
|
|
162
|
+
detail: `${budget.command} has a persisted budget but no canonical flags.`,
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
if (actual <= budget.maximum)
|
|
166
|
+
continue;
|
|
167
|
+
findings.push({
|
|
168
|
+
code: "budget_exceeded",
|
|
169
|
+
command: budget.command,
|
|
170
|
+
detail: `${actual} canonical flags exceed the ratcheted maximum ${budget.maximum}.`,
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
/** Verify uniqueness, concept kind stability, alias safety, and flag budgets. */
|
|
175
|
+
export function verifyPmFlagLexicon(entries = listPmFlagLexicon(), budgets = listPmCommandFlagBudgets()) {
|
|
176
|
+
const findings = [];
|
|
177
|
+
const canonicalOwners = new Map();
|
|
178
|
+
const conceptKinds = new Map();
|
|
179
|
+
const counts = new Map();
|
|
180
|
+
for (const entry of entries) {
|
|
181
|
+
const commandFlag = `${entry.command}:${entry.flag}`;
|
|
182
|
+
if (canonicalOwners.has(commandFlag)) {
|
|
183
|
+
findings.push({
|
|
184
|
+
code: "duplicate_canonical_flag",
|
|
185
|
+
command: entry.command,
|
|
186
|
+
detail: `${entry.flag} has more than one canonical row.`,
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
canonicalOwners.set(commandFlag, entry);
|
|
191
|
+
}
|
|
192
|
+
counts.set(entry.command, (counts.get(entry.command) ?? 0) + 1);
|
|
193
|
+
const priorKind = conceptKinds.get(entry.concept);
|
|
194
|
+
if (priorKind !== undefined && priorKind !== entry.value_kind) {
|
|
195
|
+
findings.push({
|
|
196
|
+
code: "inconsistent_concept_kind",
|
|
197
|
+
command: entry.command,
|
|
198
|
+
detail: `${entry.concept} uses both ${priorKind} and ${entry.value_kind}.`,
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
else {
|
|
202
|
+
conceptKinds.set(entry.concept, entry.value_kind);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
appendAliasCollisionFindings(entries, canonicalOwners, findings);
|
|
206
|
+
appendBudgetFindings(counts, budgets, findings);
|
|
207
|
+
findings.sort((left, right) => left.command.localeCompare(right.command) ||
|
|
208
|
+
left.code.localeCompare(right.code) ||
|
|
209
|
+
left.detail.localeCompare(right.detail));
|
|
210
|
+
return {
|
|
211
|
+
ok: findings.length === 0,
|
|
212
|
+
entry_count: entries.length,
|
|
213
|
+
budget_count: budgets.length,
|
|
214
|
+
findings,
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
/** Render a compact, generated family and command budget reference. Persisted budget rows are initialized to an explicit fallback so stale rows remain renderable. */
|
|
218
|
+
export function renderPmFlagLexiconMarkdown() {
|
|
219
|
+
const lexicon = listPmFlagLexicon();
|
|
220
|
+
const budgets = listPmCommandFlagBudgets();
|
|
221
|
+
const familyByCommand = new Map(budgets.map(({ command }) => [command, "unknown"]));
|
|
222
|
+
for (const { command, family } of lexicon)
|
|
223
|
+
familyByCommand.set(command, family);
|
|
224
|
+
const rows = budgets.map(({ command, current, maximum }) => {
|
|
225
|
+
const family = familyByCommand.get(command);
|
|
226
|
+
return `| \`${command}\` | ${family} | ${current} | ${maximum} |`;
|
|
227
|
+
});
|
|
228
|
+
return [
|
|
229
|
+
"# Generated flag lexicon budgets",
|
|
230
|
+
"",
|
|
231
|
+
"This file is generated by `listPmFlagLexicon()`. Compatibility aliases do not consume canonical budget.",
|
|
232
|
+
"",
|
|
233
|
+
"| Command | Capability family | Canonical flags | Maximum |",
|
|
234
|
+
"| --- | --- | ---: | ---: |",
|
|
235
|
+
...rows,
|
|
236
|
+
"",
|
|
237
|
+
].join("\n");
|
|
238
|
+
}
|
|
239
|
+
//# sourceMappingURL=flag-lexicon-contracts.js.map
|
|
240
|
+
//# debugId=19215662-5a8c-5b91-bc97-8dbdc1daff02
|
|
@@ -28,8 +28,53 @@ export interface PmCommandDestinationContract {
|
|
|
28
28
|
/** Reason required only for a deliberate keep-as-is exception. */
|
|
29
29
|
reason?: string;
|
|
30
30
|
}
|
|
31
|
+
/** Semantic value class for one positional slot, independent of its display label. */
|
|
32
|
+
export type PmCommandPositionalValueKind = "action" | "integer" | "item_id" | "string";
|
|
33
|
+
/** One ordered positional slot accepted by a command path. */
|
|
34
|
+
export interface PmCommandPositionalSlotContract {
|
|
35
|
+
/** Stable agent-facing slot name. */
|
|
36
|
+
name: string;
|
|
37
|
+
/** Whether Commander and the SDK action both require the slot. */
|
|
38
|
+
required: boolean;
|
|
39
|
+
/** Whether the final slot consumes every remaining positional token. */
|
|
40
|
+
variadic: boolean;
|
|
41
|
+
/** Semantic value class used to compare shapes across commands. */
|
|
42
|
+
value_kind: PmCommandPositionalValueKind;
|
|
43
|
+
/** Whether the slot accepts more than one concept for compatibility. */
|
|
44
|
+
polymorphic: boolean;
|
|
45
|
+
}
|
|
46
|
+
/** Complete positional signature for one executable or virtual action path. */
|
|
47
|
+
export interface PmCommandPositionalContract {
|
|
48
|
+
/** Normalized command path. */
|
|
49
|
+
command: string;
|
|
50
|
+
/** Ordered positional slots after the command path. */
|
|
51
|
+
slots: readonly PmCommandPositionalSlotContract[];
|
|
52
|
+
}
|
|
53
|
+
/** Discoverable positional action projected through help, contracts, and completion. */
|
|
54
|
+
export interface PmPositionalActionContract extends PmCommandPositionalContract {
|
|
55
|
+
/** Commander command that dispatches the action positionally. */
|
|
56
|
+
parent: "assurance" | "plan" | "workspace snapshot";
|
|
57
|
+
/** Literal action token accepted in the parent's first positional slot. */
|
|
58
|
+
action: string;
|
|
59
|
+
/** Canonical flags applicable to this action-specific view. */
|
|
60
|
+
accepted_flags: readonly string[];
|
|
61
|
+
/** Concise action-specific intent. */
|
|
62
|
+
description: string;
|
|
63
|
+
/** Executable example suitable for recovery and help output. */
|
|
64
|
+
example: string;
|
|
65
|
+
}
|
|
66
|
+
/** Virtual action paths dispatched by positional parent commands. */
|
|
67
|
+
export declare const PM_POSITIONAL_ACTION_CONTRACTS: readonly PmPositionalActionContract[];
|
|
68
|
+
/** Resolve one declared signature without treating arbitrary object keys as commands. */
|
|
69
|
+
export declare function resolvePmCommandPositionalContract(command: string): PmCommandPositionalContract | undefined;
|
|
70
|
+
/** Resolve one action-specific help/contract view. */
|
|
71
|
+
export declare function resolvePmPositionalActionContract(command: string): PmPositionalActionContract | undefined;
|
|
72
|
+
/** Format the shared action-flag tip rendered by text and structured help. */
|
|
73
|
+
export declare function formatPmPositionalActionFlagTip(acceptedFlags: readonly string[]): string;
|
|
31
74
|
/** Checked-in exhaustive destination census for core and known package commands. */
|
|
32
75
|
export declare const PM_COMMAND_DESTINATION_CONTRACTS: readonly PmCommandDestinationContract[];
|
|
76
|
+
/** Exhaustive current command and positional-action signature table. */
|
|
77
|
+
export declare const PM_COMMAND_POSITIONAL_CONTRACTS: readonly PmCommandPositionalContract[];
|
|
33
78
|
/** Immutable grammar policy used by contracts and the CI gate. */
|
|
34
79
|
export declare const PM_CLI_GRAMMAR_CONTRACT: {
|
|
35
80
|
readonly nouns: readonly ["item", "list", "context", "search", "graph", "history", "workspace", "package", "ops", "plan", "contracts", "help"];
|
|
@@ -37,7 +82,43 @@ export declare const PM_CLI_GRAMMAR_CONTRACT: {
|
|
|
37
82
|
readonly scope_before_verb: true;
|
|
38
83
|
readonly visible_top_level_ceiling: 69;
|
|
39
84
|
readonly ceiling_raise_requires_pm_item: true;
|
|
85
|
+
readonly positional_shape_budget: 21;
|
|
40
86
|
};
|
|
87
|
+
/** One positional-signature drift finding. */
|
|
88
|
+
export interface PmCommandPositionalFinding {
|
|
89
|
+
/** Stable remediation category. */
|
|
90
|
+
code: "missing_observed_signature" | "positional_shape_budget_exceeded" | "positional_signature_mismatch" | "stale_observed_signature";
|
|
91
|
+
/** Command path whose positional contract drifted. */
|
|
92
|
+
command: string;
|
|
93
|
+
/** Actionable mismatch detail. */
|
|
94
|
+
detail: string;
|
|
95
|
+
}
|
|
96
|
+
/** Complete positional grammar conformance receipt. */
|
|
97
|
+
export interface PmCommandPositionalReport {
|
|
98
|
+
/** Whether the observed signatures exactly match the declaration. */
|
|
99
|
+
ok: boolean;
|
|
100
|
+
/** Declared command/action paths. */
|
|
101
|
+
declared_command_count: number;
|
|
102
|
+
/** Independently observed command/action paths. */
|
|
103
|
+
observed_command_count: number;
|
|
104
|
+
/** Number of distinct semantic positional shapes. */
|
|
105
|
+
positional_shape_count: number;
|
|
106
|
+
/** Maximum distinct shapes allowed without a tracked grammar decision. */
|
|
107
|
+
positional_shape_budget: number;
|
|
108
|
+
/** Stable positional conformance failures. */
|
|
109
|
+
findings: PmCommandPositionalFinding[];
|
|
110
|
+
}
|
|
111
|
+
/** Report explicit positional entries that no destination command declares. */
|
|
112
|
+
export declare function verifyExplicitPositionalSlotCensus(explicitCommands: Iterable<string>, destinationCommands: Iterable<string>): PmCommandPositionalFinding[];
|
|
113
|
+
/** Return the semantic shape identity used by the positional-shape budget. */
|
|
114
|
+
export declare function positionalShapeKey(slots: readonly PmCommandPositionalSlotContract[]): string;
|
|
115
|
+
/** Return the exact canonical identity of an ordered positional signature. */
|
|
116
|
+
export declare function positionalSignatureKey(slots: readonly PmCommandPositionalSlotContract[]): string;
|
|
117
|
+
/** Compare independently observed Commander signatures with the SDK declaration. */
|
|
118
|
+
export declare function verifyPmCommandPositionalContracts(observed: readonly PmCommandPositionalContract[], options?: {
|
|
119
|
+
declared?: readonly PmCommandPositionalContract[];
|
|
120
|
+
positionalShapeBudget?: number;
|
|
121
|
+
}): PmCommandPositionalReport;
|
|
41
122
|
/** One self-correcting grammar-gate finding. */
|
|
42
123
|
export interface PmCliGrammarFinding {
|
|
43
124
|
/** Stable diagnostic category suitable for automated remediation. */
|