@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
|
@@ -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
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module sdk/cli-contracts/grammar-contracts
|
|
3
|
+
*
|
|
4
|
+
* Declares and verifies the agent-facing noun–verb grammar. The destination
|
|
5
|
+
* census is intentionally exact: live command contracts are compared with
|
|
6
|
+
* this checked-in table in both directions so adding or removing a command
|
|
7
|
+
* cannot silently bypass the architecture decision.
|
|
8
|
+
*/
|
|
9
|
+
import type { PmCommandAliasContract } from "./command-aliases.js";
|
|
10
|
+
/** Canonical top-level domains an agent must retain to route pm operations. */
|
|
11
|
+
export declare const PM_CLI_GRAMMAR_NOUNS: readonly ["item", "list", "context", "search", "graph", "history", "workspace", "package", "ops", "plan", "contracts", "help"];
|
|
12
|
+
/** Shared verbs whose meaning transfers across domain nouns. */
|
|
13
|
+
export declare const PM_CLI_SHARED_VERBS: readonly ["activate", "add", "adopt", "adopt-all", "catalog", "compact", "complete", "create", "deactivate", "delete", "describe", "doctor", "edit", "explore", "import", "init", "inspect", "install", "list", "manage", "migrate", "mutate", "read", "redact", "reload", "remove", "repair", "restore", "run", "show", "uninstall", "verify"];
|
|
14
|
+
/** Why a current command is permitted while the grammar migration proceeds. */
|
|
15
|
+
export type PmCommandDestinationDisposition = "target_noun" | "consolidation" | "package_owned" | "keep_as_is";
|
|
16
|
+
/** Exact destination decision for one command emitted by runtime contracts. */
|
|
17
|
+
export interface PmCommandDestinationContract {
|
|
18
|
+
/** Current executable command path. */
|
|
19
|
+
command: string;
|
|
20
|
+
/** Canonical noun that owns the capability. */
|
|
21
|
+
noun: (typeof PM_CLI_GRAMMAR_NOUNS)[number];
|
|
22
|
+
/** Canonical noun-first invocation or family destination. */
|
|
23
|
+
target: string;
|
|
24
|
+
/** Why the current spelling remains in the executable surface. */
|
|
25
|
+
disposition: PmCommandDestinationDisposition;
|
|
26
|
+
/** PM item or package identifier owning the disposition. */
|
|
27
|
+
owner: string;
|
|
28
|
+
/** Reason required only for a deliberate keep-as-is exception. */
|
|
29
|
+
reason?: string;
|
|
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;
|
|
74
|
+
/** Checked-in exhaustive destination census for core and known package commands. */
|
|
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[];
|
|
78
|
+
/** Immutable grammar policy used by contracts and the CI gate. */
|
|
79
|
+
export declare const PM_CLI_GRAMMAR_CONTRACT: {
|
|
80
|
+
readonly nouns: readonly ["item", "list", "context", "search", "graph", "history", "workspace", "package", "ops", "plan", "contracts", "help"];
|
|
81
|
+
readonly shared_verbs: readonly ["activate", "add", "adopt", "adopt-all", "catalog", "compact", "complete", "create", "deactivate", "delete", "describe", "doctor", "edit", "explore", "import", "init", "inspect", "install", "list", "manage", "migrate", "mutate", "read", "redact", "reload", "remove", "repair", "restore", "run", "show", "uninstall", "verify"];
|
|
82
|
+
readonly scope_before_verb: true;
|
|
83
|
+
readonly visible_top_level_ceiling: 69;
|
|
84
|
+
readonly ceiling_raise_requires_pm_item: true;
|
|
85
|
+
readonly positional_shape_budget: 21;
|
|
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;
|
|
122
|
+
/** One self-correcting grammar-gate finding. */
|
|
123
|
+
export interface PmCliGrammarFinding {
|
|
124
|
+
/** Stable diagnostic category suitable for automated remediation. */
|
|
125
|
+
code: "alias_target_missing" | "duplicate_destination" | "missing_destination" | "stale_destination" | "unknown_noun" | "visible_surface_ceiling_exceeded";
|
|
126
|
+
/** Exact command or alias spelling that violated the contract. */
|
|
127
|
+
spelling: string;
|
|
128
|
+
/** Human-readable explanation of the violated invariant. */
|
|
129
|
+
message: string;
|
|
130
|
+
/** Closest canonical invocation or corrective policy action. */
|
|
131
|
+
nearest_target: string;
|
|
132
|
+
}
|
|
133
|
+
/** Deterministic conformance report for the live command and alias surfaces. */
|
|
134
|
+
export interface PmCliGrammarReport {
|
|
135
|
+
/** Whether every checked grammar invariant passed. */
|
|
136
|
+
ok: boolean;
|
|
137
|
+
/** Number of normalized live command paths evaluated. */
|
|
138
|
+
command_count: number;
|
|
139
|
+
/** Number of checked-in destination-census rows. */
|
|
140
|
+
destination_count: number;
|
|
141
|
+
/** Number of declared aliases omitted from default discovery. */
|
|
142
|
+
hidden_alias_count: number;
|
|
143
|
+
/** Number of distinct visible non-package single-token command paths. */
|
|
144
|
+
visible_top_level_count: number;
|
|
145
|
+
/** Maximum visible single-token command paths permitted by the ADR. */
|
|
146
|
+
visible_top_level_ceiling: number;
|
|
147
|
+
/** Self-correcting conformance diagnostics, empty when `ok` is true. */
|
|
148
|
+
findings: PmCliGrammarFinding[];
|
|
149
|
+
}
|
|
150
|
+
/** Verify exhaustive census parity, noun ownership, alias targets, and growth. */
|
|
151
|
+
export declare function verifyPmCliGrammar(commands: readonly string[], aliases?: readonly PmCommandAliasContract[]): PmCliGrammarReport;
|