@unbrained/pm-cli 2026.8.18 → 2026.8.20
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 +35 -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 +18 -13
- package/dist/cli/register-mutation.js +8 -8
- package/dist/cli/register-operations.js +6 -6
- package/dist/cli/register-structured-mutation.d.ts +2 -0
- package/dist/cli/register-structured-mutation.js +29 -6
- package/dist/cli-bundle/bundle-manifest.json +151 -143
- package/dist/cli-bundle/chunks/{chunk-UYCLQVL2.js → chunk-2RDVGYWE.js} +12 -12
- package/dist/cli-bundle/chunks/{chunk-BSK2IN3C.js → chunk-4GB2LTOQ.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-RZQTVMRQ.js → chunk-7BRF2BX2.js} +2 -2
- package/dist/cli-bundle/chunks/chunk-BLVQHFSY.js +35 -0
- package/dist/cli-bundle/chunks/chunk-CU25EQVV.js +5 -0
- package/dist/cli-bundle/chunks/chunk-K3EN3LK2.js +2 -0
- package/dist/cli-bundle/chunks/{chunk-YRGOLZA7.js → chunk-L4LGPBJU.js} +49 -49
- package/dist/cli-bundle/chunks/chunk-RS3IV2R6.js +197 -0
- package/dist/cli-bundle/chunks/chunk-TSMWLCHS.js +3 -0
- package/dist/cli-bundle/chunks/chunk-US2ZQW2M.js +77 -0
- package/dist/cli-bundle/chunks/{chunk-5UZZAJKR.js → chunk-XYDDWBZN.js} +2 -2
- package/dist/cli-bundle/chunks/register-list-query-JSAQCVOC.js +11 -0
- package/dist/cli-bundle/chunks/register-mutation-XJPAW63D.js +20 -0
- package/dist/cli-bundle/chunks/register-operations-DSOSB2XQ.js +2 -0
- package/dist/cli-bundle/chunks/{register-setup-PPPEF3SN.js → register-setup-QUR6QL2C.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-325UXIO7.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-5L7M4AI7.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-ODOVCP45.js → chunk-6AHG2YW7.js} +44 -44
- package/dist/cli-bundle/focused-chunks/chunk-AZBACT5T.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-TN4AE665.js → chunk-BLJCGGID.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-FUREQLQN.js +18 -0
- package/dist/cli-bundle/focused-chunks/{chunk-M62NO7EI.js → chunk-G3C5ERXG.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-K43KKAFS.js → chunk-GXWQBE3T.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-UI6AJ5TD.js → chunk-JWKEDZJI.js} +3 -3
- package/dist/cli-bundle/focused-chunks/chunk-KYZ6JGPL.js +155 -0
- package/dist/cli-bundle/focused-chunks/{chunk-EX6MKP2X.js → chunk-M32HFIQB.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-EUEGXZ2A.js → chunk-OM65KHGF.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-Q47EX4DI.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-V5XTGLK7.js → chunk-RIHDMCUM.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-T4ZFY7ZJ.js +16 -0
- package/dist/cli-bundle/focused-chunks/chunk-TDR5OGG3.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-UGSS4F5X.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-Z3PLWSGM.js +2 -0
- package/dist/cli-bundle/main.js +13 -13
- package/dist/cli-bundle/sdk-authoring.js +1 -1
- package/dist/cli-bundle/sdk-contracts.js +2 -1
- package/dist/cli-bundle/sdk-core.js +41 -41
- 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/output/mutation-projection.js +26 -2
- package/dist/core/shared/constants.d.ts +1 -5
- package/dist/core/shared/constants.js +3 -81
- package/dist/core/shared/errors.d.ts +2 -0
- package/dist/core/shared/errors.js +2 -2
- package/dist/core/shared/item-metadata-contract.d.ts +14 -0
- package/dist/core/shared/item-metadata-contract.js +90 -0
- package/dist/core/store/item-store.d.ts +60 -0
- package/dist/core/store/item-store.js +22 -5
- package/dist/sdk/agent/closed-domain-contracts.d.ts +25 -0
- package/dist/sdk/agent/closed-domain-contracts.js +140 -0
- package/dist/sdk/agent/refusal-closure.d.ts +53 -0
- package/dist/sdk/agent/refusal-closure.js +134 -0
- package/dist/sdk/agent/refusal-reachability.d.ts +27 -1
- package/dist/sdk/agent/refusal-reachability.js +26 -2
- package/dist/sdk/agent-capability-contracts.d.ts +13 -0
- package/dist/sdk/agent-capability-contracts.js +101 -9
- 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/completeness.js +8 -2
- package/dist/sdk/cli-contracts/enum-contracts.d.ts +4 -2
- package/dist/sdk/cli-contracts/enum-contracts.js +16 -6
- package/dist/sdk/cli-contracts/flag-contracts.d.ts +7 -0
- package/dist/sdk/cli-contracts/flag-contracts.js +84 -8
- package/dist/sdk/cli-contracts/flag-lexicon-contracts.d.ts +72 -0
- package/dist/sdk/cli-contracts/flag-lexicon-contracts.js +340 -0
- package/dist/sdk/cli-contracts/grammar-contracts.d.ts +83 -2
- package/dist/sdk/cli-contracts/grammar-contracts.js +618 -2
- package/dist/sdk/cli-contracts/runtime-contracts.d.ts +15 -4
- package/dist/sdk/cli-contracts/runtime-contracts.js +47 -13
- 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-schema.js +7 -2
- package/dist/sdk/cli-contracts.d.ts +4 -3
- package/dist/sdk/cli-contracts.js +6 -5
- 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/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 +206 -2
- package/dist/sdk/generated/generated-error-code-catalog-part-2.js +244 -40
- package/dist/sdk/index.d.ts +11 -7
- package/dist/sdk/index.js +10 -6
- package/dist/sdk/init-agent-guidance.d.ts +5 -3
- package/dist/sdk/init-agent-guidance.js +69 -9
- package/dist/sdk/lifecycle/mcp-actions.d.ts +18 -0
- package/dist/sdk/lifecycle/mcp-actions.js +52 -0
- package/dist/sdk/lifecycle/reopen.d.ts +44 -0
- package/dist/sdk/lifecycle/reopen.js +69 -0
- package/dist/sdk/lifecycle/update.d.ts +31 -0
- package/dist/sdk/lifecycle/update.js +95 -13
- package/dist/sdk/output-projection.d.ts +2 -0
- package/dist/sdk/output-projection.js +11 -5
- package/dist/sdk/query/get.d.ts +1 -1
- package/dist/sdk/query/get.js +34 -49
- package/dist/sdk/query/list.d.ts +7 -21
- package/dist/sdk/query/list.js +44 -44
- package/dist/sdk/query/projection-contracts.d.ts +33 -0
- package/dist/sdk/query/projection-contracts.js +185 -0
- package/dist/sdk/query/search-contracts.d.ts +3 -2
- package/dist/sdk/query/search-contracts.js +30 -85
- package/dist/sdk/query/search.d.ts +15 -0
- package/dist/sdk/query/search.js +32 -6
- 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-primitives.d.ts +1 -1
- package/dist/sdk/runtime-primitives.js +3 -3
- package/dist/sdk/runtime.d.ts +6 -0
- package/dist/sdk/runtime.js +25 -17
- package/dist/sdk/similarity.d.ts +13 -0
- package/dist/sdk/similarity.js +32 -6
- package/dist/sdk/workspace-snapshot.d.ts +2 -0
- package/dist/sdk/workspace-snapshot.js +10 -2
- package/docs/COMMANDS.md +29 -5
- package/docs/OUTPUT_PROJECTION_CONTRACTS.md +11 -2
- package/docs/README.md +1 -0
- package/docs/READ_OUTPUT_CONTRACTS.md +10 -6
- package/docs/RECURRENCE_RECOVERY_CONTRACTS.md +114 -0
- package/docs/SDK.md +16 -2
- package/docs/SDK_CONTEXT_INTEGRITY.md +45 -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/docs/performance/sdk-entrypoint-import-costs.md +14 -21
- package/marketplace.json +2 -2
- package/package.json +9 -7
- 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 +950 -24
- 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-GNFAFIJI.js +0 -77
- 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/chunk-SARFF5H5.js +0 -3
- package/dist/cli-bundle/chunks/register-list-query-I23LALEE.js +0 -11
- 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-3TKWMNKF.js +0 -18
- package/dist/cli-bundle/focused-chunks/chunk-5AF3ZBNB.js +0 -155
- 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
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Defines SDK command-contract metadata for Enum Contracts.
|
|
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]="8b8b6b8e-5061-5da4-a369-eca379c0090b")}catch(e){}}();
|
|
8
8
|
import { KNOWN_EXTENSION_CAPABILITIES, KNOWN_EXTENSION_POLICY_MODES, KNOWN_EXTENSION_POLICY_SURFACES, KNOWN_EXTENSION_SANDBOX_PROFILES, KNOWN_EXTENSION_SERVICE_NAMES, KNOWN_EXTENSION_TRUST_MODES, } from "../../core/extensions/extension-types.js";
|
|
9
9
|
import { PM_COMMAND_ALIAS_CONTRACTS } from "./command-aliases.js";
|
|
10
10
|
/** Public contract for pm extension capability contracts, shared by SDK and presentation-layer consumers. */
|
|
@@ -140,10 +140,11 @@ export const PM_EXTENSION_PACKAGE_ACTION_SUBCOMMANDS = [
|
|
|
140
140
|
"activate",
|
|
141
141
|
"deactivate",
|
|
142
142
|
];
|
|
143
|
+
/** Noun-first item lifecycle verbs flattened for SDK and MCP dispatch. */
|
|
144
|
+
export const PM_ITEM_ACTION_SUBCOMMANDS = ["reopen"];
|
|
143
145
|
/** CLI-only presentation commands intentionally omitted from programmatic actions. */
|
|
144
146
|
export const PM_CLI_ONLY_TOOL_ACTION_WAIVERS = {
|
|
145
147
|
help: "Commander help rendering has no SDK operation result.",
|
|
146
|
-
item: "The item namespace only groups lifecycle subcommands already exposed as actions.",
|
|
147
148
|
packages: "The plural package alias only renders package-oriented help.",
|
|
148
149
|
};
|
|
149
150
|
/**
|
|
@@ -159,6 +160,9 @@ export const PM_TOOL_ACTIONS = Object.freeze(PM_CORE_COMMAND_NAMES.flatMap((comm
|
|
|
159
160
|
command,
|
|
160
161
|
];
|
|
161
162
|
}
|
|
163
|
+
if (command === "item") {
|
|
164
|
+
return PM_ITEM_ACTION_SUBCOMMANDS.map((subcommand) => `item-${subcommand}`);
|
|
165
|
+
}
|
|
162
166
|
return [command];
|
|
163
167
|
}));
|
|
164
168
|
/** Deprecated compatibility actions accepted by the SDK but omitted from canonical MCP discovery. */
|
|
@@ -172,9 +176,15 @@ export function analyzePmToolActionParity(cliCommands = PM_CORE_COMMAND_NAMES, t
|
|
|
172
176
|
const toolActionSet = new Set(toolActions);
|
|
173
177
|
const cliCommandSet = new Set(cliCommands);
|
|
174
178
|
return {
|
|
175
|
-
missing_cli_actions: cliCommands.filter((command) => !toolActionSet.has(command) &&
|
|
176
|
-
|
|
177
|
-
|
|
179
|
+
missing_cli_actions: cliCommands.filter((command) => !toolActionSet.has(command) &&
|
|
180
|
+
!toolActions.some((action) => action.startsWith(`${command}-`)) &&
|
|
181
|
+
waivers[command] === undefined),
|
|
182
|
+
waived_cli_actions: cliCommands.filter((command) => !toolActionSet.has(command) &&
|
|
183
|
+
!toolActions.some((action) => action.startsWith(`${command}-`)) &&
|
|
184
|
+
waivers[command] !== undefined),
|
|
185
|
+
stale_waivers: Object.keys(waivers).filter((command) => !cliCommandSet.has(command) ||
|
|
186
|
+
toolActionSet.has(command) ||
|
|
187
|
+
toolActions.some((action) => action.startsWith(`${command}-`))),
|
|
178
188
|
};
|
|
179
189
|
}
|
|
180
190
|
/** Implements check whether pm tool action for the public runtime surface of this module. */
|
|
@@ -198,4 +208,4 @@ export function isPmExtensionPolicySurfaceContract(value) {
|
|
|
198
208
|
return PM_EXTENSION_POLICY_SURFACE_CONTRACTS.includes(value);
|
|
199
209
|
}
|
|
200
210
|
//# sourceMappingURL=enum-contracts.js.map
|
|
201
|
-
//# debugId=
|
|
211
|
+
//# debugId=8b8b6b8e-5061-5da4-a369-eca379c0090b
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type PmPositionalActionContract } from "./grammar-contracts.js";
|
|
1
2
|
/** A single CLI flag's contract: its canonical `--flag`, optional short form, aliases, value metadata, and repeat/list semantics. One source of truth shared by Commander registration, argv normalization, shell completion, and the `pm contracts` command so every surface agrees on the flag vocabulary. */
|
|
2
3
|
export interface CliFlagContract {
|
|
3
4
|
/** Value that configures or reports flag for this contract. */
|
|
@@ -176,6 +177,8 @@ export declare const CREATE_FLAG_CONTRACTS: CliFlagContract[];
|
|
|
176
177
|
export declare const ITEM_MUTATE_FLAG_CONTRACTS: CliFlagContract[];
|
|
177
178
|
/** Atomic item-completion flags shared by contracts, help, and completions. */
|
|
178
179
|
export declare const ITEM_COMPLETE_FLAG_CONTRACTS: CliFlagContract[];
|
|
180
|
+
/** Recurrence transition flags shared by CLI, SDK, MCP, help, and completion. */
|
|
181
|
+
export declare const ITEM_REOPEN_FLAG_CONTRACTS: CliFlagContract[];
|
|
179
182
|
/** Public contract for copy flag contracts, shared by SDK and presentation-layer consumers. */
|
|
180
183
|
export declare const COPY_FLAG_CONTRACTS: CliFlagContract[];
|
|
181
184
|
/** Public contract for focus flag contracts, shared by SDK and presentation-layer consumers. */
|
|
@@ -214,6 +217,10 @@ export declare const CONTRACTS_FLAG_CONTRACTS: CliFlagContract[];
|
|
|
214
217
|
export declare const COMPLETION_FLAG_CONTRACTS: CliFlagContract[];
|
|
215
218
|
/** Deduplicates flag contracts by their `flag`/`short`/`aliases` identity, preserving first-seen order. Used when merging the shared subcommand-global flags into a command's own contracts so a flag declared by both surfaces is registered only once. */
|
|
216
219
|
export declare function toUniqueFlagContracts(contracts: CliFlagContract[]): CliFlagContract[];
|
|
220
|
+
/** Resolve every positional action's accepted flags against one parent contract. */
|
|
221
|
+
export declare function resolvePmPositionalActionFlagContracts(actions?: readonly PmPositionalActionContract[]): Array<readonly [string, CliFlagContract[]]>;
|
|
222
|
+
/** Validated positional action flag entries shared by registration and contracts. */
|
|
223
|
+
export declare const PM_POSITIONAL_ACTION_FLAG_CONTRACTS: (readonly [string, CliFlagContract[]])[];
|
|
217
224
|
/** Returns whether a normalized command path owns a concrete core flag-contract row. Surface-less commands such as `help` intentionally return false, while positional virtual paths such as `workspace snapshot create` return true. */
|
|
218
225
|
export declare function hasSubcommandFlagContractsForCommand(commandName: string | undefined): boolean;
|
|
219
226
|
/** Resolves the flag contracts a given command (or list/extension subcommand) accepts, merged with the shared subcommand-global flags. Returns the global set for unknown or surface-less commands so completion and validation degrade gracefully. */
|
|
@@ -7,9 +7,10 @@
|
|
|
7
7
|
* flag surface stays single-sourced across the CLI, SDK, and MCP boundaries.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
!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]="
|
|
10
|
+
!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]="e302f519-aa51-503b-bd1a-f3155338f133")}catch(e){}}();
|
|
11
11
|
import { normalizeUniqueStringList } from "./string-lists.js";
|
|
12
12
|
import { RESERVED_EXTENSION_HOST_FLAGS } from "../../core/extensions/reserved-host-flags.js";
|
|
13
|
+
import { PM_POSITIONAL_ACTION_CONTRACTS, } from "./grammar-contracts.js";
|
|
13
14
|
function normalizeFlagAliasKey(flag) {
|
|
14
15
|
if (!flag.startsWith("--")) {
|
|
15
16
|
return flag;
|
|
@@ -1139,8 +1140,8 @@ export const CREATE_FLAG_CONTRACTS = [
|
|
|
1139
1140
|
{ flag: "--comment" },
|
|
1140
1141
|
{ flag: "--note" },
|
|
1141
1142
|
{ flag: "--learning" },
|
|
1142
|
-
{ flag: "--file" },
|
|
1143
|
-
{ flag: "--test" },
|
|
1143
|
+
{ flag: "--file", aliases: ["--linked-file"] },
|
|
1144
|
+
{ flag: "--test", aliases: ["--linked-test"] },
|
|
1144
1145
|
{ flag: "--doc" },
|
|
1145
1146
|
{ flag: "--unset" },
|
|
1146
1147
|
{ flag: "--clear-deps" },
|
|
@@ -1187,6 +1188,14 @@ export const ITEM_COMPLETE_FLAG_CONTRACTS = [
|
|
|
1187
1188
|
{ flag: "--force" },
|
|
1188
1189
|
{ flag: "--author", value_name: "value" },
|
|
1189
1190
|
];
|
|
1191
|
+
/** Recurrence transition flags shared by CLI, SDK, MCP, help, and completion. */
|
|
1192
|
+
export const ITEM_REOPEN_FLAG_CONTRACTS = [
|
|
1193
|
+
{ flag: "--id", value_name: "item-id" },
|
|
1194
|
+
{ flag: "--status", value_name: "open|in_progress" },
|
|
1195
|
+
{ flag: "--message", value_name: "value" },
|
|
1196
|
+
{ flag: "--force" },
|
|
1197
|
+
{ flag: "--author", value_name: "value" },
|
|
1198
|
+
];
|
|
1190
1199
|
/** Public contract for copy flag contracts, shared by SDK and presentation-layer consumers. */
|
|
1191
1200
|
export const COPY_FLAG_CONTRACTS = [
|
|
1192
1201
|
{ flag: "--id", value_name: "item-id" },
|
|
@@ -1240,8 +1249,8 @@ export const UPDATE_FLAG_CONTRACTS = [
|
|
|
1240
1249
|
{ flag: "--comment" },
|
|
1241
1250
|
{ flag: "--note" },
|
|
1242
1251
|
{ flag: "--learning" },
|
|
1243
|
-
{ flag: "--file" },
|
|
1244
|
-
{ flag: "--test" },
|
|
1252
|
+
{ flag: "--file", aliases: ["--linked-file"] },
|
|
1253
|
+
{ flag: "--test", aliases: ["--linked-test"] },
|
|
1245
1254
|
{ flag: "--doc" },
|
|
1246
1255
|
{ flag: "--reminder" },
|
|
1247
1256
|
{ flag: "--event" },
|
|
@@ -1636,7 +1645,33 @@ export function toUniqueFlagContracts(contracts) {
|
|
|
1636
1645
|
return unique;
|
|
1637
1646
|
}
|
|
1638
1647
|
function withSubcommandGlobalFlags(contracts) {
|
|
1639
|
-
|
|
1648
|
+
const byCanonicalFlag = new Map();
|
|
1649
|
+
for (const contract of [...SUBCOMMAND_GLOBAL_FLAG_CONTRACTS, ...contracts]) {
|
|
1650
|
+
const canonicalFlag = normalizeFlagAliasKey(contract.flag);
|
|
1651
|
+
const prior = byCanonicalFlag.get(canonicalFlag);
|
|
1652
|
+
const { aliases: declaredAliases, ...contractWithoutAliases } = contract;
|
|
1653
|
+
const aliases = normalizeUniqueStringList([
|
|
1654
|
+
...(declaredAliases ?? []),
|
|
1655
|
+
...(contract.flag === canonicalFlag ? [] : [contract.flag]),
|
|
1656
|
+
]).filter((alias) => alias !== canonicalFlag);
|
|
1657
|
+
const normalizedContract = {
|
|
1658
|
+
...contractWithoutAliases,
|
|
1659
|
+
flag: canonicalFlag,
|
|
1660
|
+
...(aliases.length > 0 ? { aliases } : {}),
|
|
1661
|
+
};
|
|
1662
|
+
const mergedAliases = normalizeUniqueStringList([
|
|
1663
|
+
...(prior?.aliases ?? []),
|
|
1664
|
+
...(normalizedContract.aliases ?? []),
|
|
1665
|
+
]);
|
|
1666
|
+
byCanonicalFlag.set(canonicalFlag, prior === undefined
|
|
1667
|
+
? normalizedContract
|
|
1668
|
+
: {
|
|
1669
|
+
...prior,
|
|
1670
|
+
...normalizedContract,
|
|
1671
|
+
...(mergedAliases.length > 0 ? { aliases: mergedAliases } : {}),
|
|
1672
|
+
});
|
|
1673
|
+
}
|
|
1674
|
+
return withFlagAliasMetadata([...byCanonicalFlag.values()]);
|
|
1640
1675
|
}
|
|
1641
1676
|
const FIXED_STATUS_LIST_COMMAND_ALIASES = [
|
|
1642
1677
|
"list-draft",
|
|
@@ -1648,6 +1683,43 @@ const FIXED_STATUS_LIST_COMMAND_ALIASES = [
|
|
|
1648
1683
|
];
|
|
1649
1684
|
const FIXED_STATUS_LIST_FLAG_CONTRACTS = LIST_FILTER_FLAG_CONTRACTS.filter((contract) => contract.flag !== "--status" && contract.flag !== "--all");
|
|
1650
1685
|
const ALL_STATUS_LIST_FLAG_CONTRACTS = LIST_FILTER_FLAG_CONTRACTS.filter((contract) => contract.flag !== "--status");
|
|
1686
|
+
function indexCliFlagContracts(contracts) {
|
|
1687
|
+
const index = new Map();
|
|
1688
|
+
for (const contract of contracts) {
|
|
1689
|
+
for (const spelling of [contract.flag, ...(contract.aliases ?? [])]) {
|
|
1690
|
+
const matches = index.get(spelling) ?? [];
|
|
1691
|
+
matches.push(contract);
|
|
1692
|
+
index.set(spelling, matches);
|
|
1693
|
+
}
|
|
1694
|
+
}
|
|
1695
|
+
return index;
|
|
1696
|
+
}
|
|
1697
|
+
const PLAN_FLAG_CONTRACT_INDEX = indexCliFlagContracts(PLAN_FLAG_CONTRACTS);
|
|
1698
|
+
const ASSURANCE_FLAG_CONTRACT_INDEX = indexCliFlagContracts(ASSURANCE_FLAG_CONTRACTS);
|
|
1699
|
+
const POSITIONAL_ACTION_FLAG_INDEX_BY_PARENT = new Map([
|
|
1700
|
+
["assurance", ASSURANCE_FLAG_CONTRACT_INDEX],
|
|
1701
|
+
["plan", PLAN_FLAG_CONTRACT_INDEX],
|
|
1702
|
+
["workspace snapshot", indexCliFlagContracts(WORKSPACE_FLAG_CONTRACTS)],
|
|
1703
|
+
]);
|
|
1704
|
+
/** Resolve every positional action's accepted flags against one parent contract. */
|
|
1705
|
+
export function resolvePmPositionalActionFlagContracts(actions = PM_POSITIONAL_ACTION_CONTRACTS) {
|
|
1706
|
+
return actions.map(({ command, parent, accepted_flags: acceptedFlags }) => {
|
|
1707
|
+
const parentFlagIndex = POSITIONAL_ACTION_FLAG_INDEX_BY_PARENT.get(parent);
|
|
1708
|
+
if (!parentFlagIndex) {
|
|
1709
|
+
throw new Error(`Positional action ${command} has no flag-contract index for ${parent}.`);
|
|
1710
|
+
}
|
|
1711
|
+
const selected = acceptedFlags.map((acceptedFlag) => {
|
|
1712
|
+
const matches = parentFlagIndex.get(acceptedFlag) ?? [];
|
|
1713
|
+
if (matches.length !== 1) {
|
|
1714
|
+
throw new Error(`Positional action ${command} accepted flag ${acceptedFlag} does not resolve to exactly one ${parent} flag contract.`);
|
|
1715
|
+
}
|
|
1716
|
+
return matches[0];
|
|
1717
|
+
});
|
|
1718
|
+
return [command, selected];
|
|
1719
|
+
});
|
|
1720
|
+
}
|
|
1721
|
+
/** Validated positional action flag entries shared by registration and contracts. */
|
|
1722
|
+
export const PM_POSITIONAL_ACTION_FLAG_CONTRACTS = resolvePmPositionalActionFlagContracts();
|
|
1651
1723
|
// Single-token command (plus the `list`/`cal`/`ctx`/`templates` aliases) → its
|
|
1652
1724
|
// dedicated flag-contract table. Lookups fall back to the subcommand-global set,
|
|
1653
1725
|
// so tokens absent here (`reindex`, `help`, or any unknown command) degrade to
|
|
@@ -1676,6 +1748,7 @@ const SUBCOMMAND_FLAG_CONTRACTS_BY_COMMAND = new Map([
|
|
|
1676
1748
|
["create", CREATE_FLAG_CONTRACTS],
|
|
1677
1749
|
["item mutate", ITEM_MUTATE_FLAG_CONTRACTS],
|
|
1678
1750
|
["item complete", ITEM_COMPLETE_FLAG_CONTRACTS],
|
|
1751
|
+
["item reopen", ITEM_REOPEN_FLAG_CONTRACTS],
|
|
1679
1752
|
["copy", COPY_FLAG_CONTRACTS],
|
|
1680
1753
|
["focus", FOCUS_FLAG_CONTRACTS],
|
|
1681
1754
|
["aggregate", AGGREGATE_FLAG_CONTRACTS],
|
|
@@ -1723,6 +1796,7 @@ const SUBCOMMAND_FLAG_CONTRACTS_BY_COMMAND = new Map([
|
|
|
1723
1796
|
["telemetry", TELEMETRY_FLAG_CONTRACTS],
|
|
1724
1797
|
["health", HEALTH_FLAG_CONTRACTS],
|
|
1725
1798
|
["assurance", ASSURANCE_FLAG_CONTRACTS],
|
|
1799
|
+
...PM_POSITIONAL_ACTION_FLAG_CONTRACTS,
|
|
1726
1800
|
["validate", VALIDATE_FLAG_CONTRACTS],
|
|
1727
1801
|
["gc", GC_FLAG_CONTRACTS],
|
|
1728
1802
|
["stats", STATS_FLAG_CONTRACTS],
|
|
@@ -1751,6 +1825,7 @@ const EXTENSION_LIFECYCLE_FLAG_CONTRACTS_BY_SUBCOMMAND = new Map([
|
|
|
1751
1825
|
["reload", EXTENSION_RELOAD_FLAG_CONTRACTS],
|
|
1752
1826
|
["doctor", EXTENSION_DOCTOR_FLAG_CONTRACTS],
|
|
1753
1827
|
["catalog", EXTENSION_CATALOG_FLAG_CONTRACTS],
|
|
1828
|
+
["list", EXTENSION_CATALOG_FLAG_CONTRACTS],
|
|
1754
1829
|
["adopt", EXTENSION_ADOPT_FLAG_CONTRACTS],
|
|
1755
1830
|
["adopt-all", EXTENSION_ADOPT_ALL_FLAG_CONTRACTS],
|
|
1756
1831
|
["activate", EXTENSION_ACTIVATE_FLAG_CONTRACTS],
|
|
@@ -1776,11 +1851,12 @@ export function hasSubcommandFlagContractsForCommand(commandName) {
|
|
|
1776
1851
|
lifecycleSubcommand !== undefined &&
|
|
1777
1852
|
extraParts.length === 0 &&
|
|
1778
1853
|
(lifecycleSubcommand === "init" ||
|
|
1854
|
+
lifecycleSubcommand === "scaffold" ||
|
|
1779
1855
|
EXTENSION_LIFECYCLE_FLAG_CONTRACTS_BY_SUBCOMMAND.has(lifecycleSubcommand)));
|
|
1780
1856
|
}
|
|
1781
1857
|
/** Resolves the flag contracts an `extension`/`package <subcommand>` lifecycle invocation accepts. `init` carries the package-only `--declarative` flag, so `package`/`packages init` resolve to the package init table while `extension init` resolves to the extension init table; every other lifecycle subcommand shares one table, and an unknown subcommand falls back to globals-only. */
|
|
1782
1858
|
function resolveExtensionLifecycleFlagContracts(rootCommand, lifecycleSubcommand) {
|
|
1783
|
-
if (lifecycleSubcommand === "init") {
|
|
1859
|
+
if (lifecycleSubcommand === "init" || lifecycleSubcommand === "scaffold") {
|
|
1784
1860
|
// `--declarative` is package-only, so `package init` / `packages init` carry it.
|
|
1785
1861
|
return rootCommand === "extension"
|
|
1786
1862
|
? EXTENSION_INIT_FLAG_CONTRACTS
|
|
@@ -1825,4 +1901,4 @@ export function toCompletionFlagString(flagContracts, includeGlobal = true) {
|
|
|
1825
1901
|
return normalizeUniqueStringList(all).join(" ");
|
|
1826
1902
|
}
|
|
1827
1903
|
//# sourceMappingURL=flag-contracts.js.map
|
|
1828
|
-
//# debugId=
|
|
1904
|
+
//# debugId=e302f519-aa51-503b-bd1a-f3155338f133
|
|
@@ -0,0 +1,72 @@
|
|
|
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
|
+
/** Persistable compatibility inventory for one canonical command flag. */
|
|
20
|
+
export interface PmFlagSpellingInventoryEntry {
|
|
21
|
+
/** Canonical command path. */
|
|
22
|
+
command: string;
|
|
23
|
+
/** Canonical long spelling generated for new callers. */
|
|
24
|
+
canonical_flag: string;
|
|
25
|
+
/** Every executable long spelling, including compatibility aliases. */
|
|
26
|
+
accepted_spellings: readonly string[];
|
|
27
|
+
}
|
|
28
|
+
/** Ratcheted canonical flag budget for one command. */
|
|
29
|
+
export interface PmCommandFlagBudget {
|
|
30
|
+
/** Canonical command path. */
|
|
31
|
+
command: string;
|
|
32
|
+
/** Current canonical flag count. */
|
|
33
|
+
current: number;
|
|
34
|
+
/** Maximum count accepted by the repository gate. */
|
|
35
|
+
maximum: number;
|
|
36
|
+
}
|
|
37
|
+
/** One fail-closed lexicon or budget violation. */
|
|
38
|
+
export interface PmFlagLexiconFinding {
|
|
39
|
+
/** Stable finding code. */
|
|
40
|
+
code: "alias_collision" | "budget_exceeded" | "duplicate_canonical_flag" | "inconsistent_concept_kind" | "missing_budget" | "removed_canonical_spelling" | "removed_compatibility_spelling" | "semantic_spelling_collision" | "stale_budget";
|
|
41
|
+
/** Canonical command path. */
|
|
42
|
+
command: string;
|
|
43
|
+
/** Human-readable finding detail. */
|
|
44
|
+
detail: string;
|
|
45
|
+
}
|
|
46
|
+
/** Complete verification receipt for a flag lexicon corpus. */
|
|
47
|
+
export interface PmFlagLexiconReport {
|
|
48
|
+
/** Whether every invariant and ratchet passed. */
|
|
49
|
+
ok: boolean;
|
|
50
|
+
/** Number of canonical command-flag rows checked. */
|
|
51
|
+
entry_count: number;
|
|
52
|
+
/** Number of command budgets checked. */
|
|
53
|
+
budget_count: number;
|
|
54
|
+
/** Number of stable semantic concepts represented. */
|
|
55
|
+
concept_count: number;
|
|
56
|
+
/** Number of historical spelling rows checked. */
|
|
57
|
+
baseline_entry_count: number;
|
|
58
|
+
/** Stable ordered findings. */
|
|
59
|
+
findings: readonly PmFlagLexiconFinding[];
|
|
60
|
+
}
|
|
61
|
+
/** Resolve one executable command flag to its stable cross-command semantic concept. */
|
|
62
|
+
export declare function resolvePmFlagSemanticConcept(command: string, flag: string): string;
|
|
63
|
+
/** Build the canonical lexicon lazily from the same contracts as CLI and MCP. */
|
|
64
|
+
export declare function listPmFlagLexicon(): readonly PmFlagLexiconEntry[];
|
|
65
|
+
/** Return the complete canonical and compatibility spelling inventory. */
|
|
66
|
+
export declare function listPmFlagSpellingInventory(): readonly PmFlagSpellingInventoryEntry[];
|
|
67
|
+
/** Return persisted no-growth ratchets with current counts derived from the canonical vocabulary. */
|
|
68
|
+
export declare function listPmCommandFlagBudgets(): readonly PmCommandFlagBudget[];
|
|
69
|
+
/** Verify uniqueness, concept kind stability, alias safety, and flag budgets. */
|
|
70
|
+
export declare function verifyPmFlagLexicon(entries?: readonly PmFlagLexiconEntry[], budgets?: readonly PmCommandFlagBudget[], baseline?: readonly PmFlagSpellingInventoryEntry[]): PmFlagLexiconReport;
|
|
71
|
+
/** Render a compact, generated family and command budget reference. Persisted budget rows are initialized to an explicit fallback so stale rows remain renderable. */
|
|
72
|
+
export declare function renderPmFlagLexiconMarkdown(): string;
|
|
@@ -0,0 +1,340 @@
|
|
|
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]="6ba3d756-dcd6-59b7-92fe-ec33d294d72b")}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
|
+
const FULL_PROJECTION_CONCEPT_BY_COMMAND = Object.freeze({
|
|
15
|
+
list: "list-item-projection",
|
|
16
|
+
"list-all": "list-item-projection",
|
|
17
|
+
"list-draft": "list-item-projection",
|
|
18
|
+
"list-open": "list-item-projection",
|
|
19
|
+
"list-in-progress": "list-item-projection",
|
|
20
|
+
"list-blocked": "list-item-projection",
|
|
21
|
+
"list-closed": "list-item-projection",
|
|
22
|
+
"list-canceled": "list-item-projection",
|
|
23
|
+
get: "get-item-projection",
|
|
24
|
+
graph: "graph-detail-projection",
|
|
25
|
+
search: "search-result-projection",
|
|
26
|
+
history: "history-entry-projection",
|
|
27
|
+
events: "mutation-event-projection",
|
|
28
|
+
activity: "activity-entry-projection",
|
|
29
|
+
deps: "dependency-graph-projection",
|
|
30
|
+
health: "health-diagnostic-projection",
|
|
31
|
+
validate: "validation-diagnostic-projection",
|
|
32
|
+
contracts: "contract-catalog-projection",
|
|
33
|
+
});
|
|
34
|
+
/** Resolve one executable command flag to its stable cross-command semantic concept. */
|
|
35
|
+
export function resolvePmFlagSemanticConcept(command, flag) {
|
|
36
|
+
if (flag === "--limit")
|
|
37
|
+
return "result-row-limit";
|
|
38
|
+
if (flag === "--node-limit")
|
|
39
|
+
return "graph-node-limit";
|
|
40
|
+
if (flag === "--edge-limit")
|
|
41
|
+
return "graph-edge-limit";
|
|
42
|
+
if (flag === "--output-limit")
|
|
43
|
+
return "rendered-output-row-limit";
|
|
44
|
+
if (flag === "--output-budget")
|
|
45
|
+
return "rendered-output-byte-budget";
|
|
46
|
+
if (flag === "--token-budget")
|
|
47
|
+
return "context-intent-token-budget";
|
|
48
|
+
if (flag === "--full") {
|
|
49
|
+
const concept = FULL_PROJECTION_CONCEPT_BY_COMMAND[command];
|
|
50
|
+
if (concept === undefined) {
|
|
51
|
+
throw new Error(`Command ${command} exposes --full without a registered projection concept.`);
|
|
52
|
+
}
|
|
53
|
+
return concept;
|
|
54
|
+
}
|
|
55
|
+
if (flag !== "--file")
|
|
56
|
+
return flag.slice(2);
|
|
57
|
+
if (["create", "update", "update-many"].includes(command))
|
|
58
|
+
return "linked-file-path";
|
|
59
|
+
if (["comments", "notes", "learnings"].includes(command))
|
|
60
|
+
return "entry-file-input";
|
|
61
|
+
return "plan-definition-file";
|
|
62
|
+
}
|
|
63
|
+
/** Build the canonical lexicon lazily from the same contracts as CLI and MCP. */
|
|
64
|
+
export function listPmFlagLexicon() {
|
|
65
|
+
if (cachedPmFlagLexicon !== undefined)
|
|
66
|
+
return cachedPmFlagLexicon;
|
|
67
|
+
const commandContracts = PM_COMMAND_CAPABILITY_CONTRACTS.filter(({ command }) => hasSubcommandFlagContractsForCommand(command));
|
|
68
|
+
const provisionalEntries = commandContracts.flatMap(({ command, family }) => enrichCliFlagInvocationContracts(command, resolveSubcommandFlagContractsForCommand(command)).map((contract) => ({
|
|
69
|
+
command,
|
|
70
|
+
family,
|
|
71
|
+
concept: resolvePmFlagSemanticConcept(command, contract.flag),
|
|
72
|
+
flag: contract.flag,
|
|
73
|
+
aliases: Object.freeze([...(contract.aliases ?? [])]),
|
|
74
|
+
value_kind: (contract.repeatable
|
|
75
|
+
? "list"
|
|
76
|
+
: contract.flag === "--limit"
|
|
77
|
+
? "number"
|
|
78
|
+
: contract.value_type),
|
|
79
|
+
})));
|
|
80
|
+
const compatibilityAliasFlags = new Set(provisionalEntries.flatMap((entry) => entry.aliases.map((alias) => `${entry.command}:${alias}`)));
|
|
81
|
+
const canonicalEntries = provisionalEntries.filter((entry) => !compatibilityAliasFlags.has(`${entry.command}:${entry.flag}`));
|
|
82
|
+
const kindsByConcept = new Map();
|
|
83
|
+
for (const entry of canonicalEntries) {
|
|
84
|
+
const kinds = kindsByConcept.get(entry.concept) ?? new Set();
|
|
85
|
+
kinds.add(entry.value_kind);
|
|
86
|
+
kindsByConcept.set(entry.concept, kinds);
|
|
87
|
+
}
|
|
88
|
+
cachedPmFlagLexicon = Object.freeze(canonicalEntries.map((entry) => Object.freeze({
|
|
89
|
+
...entry,
|
|
90
|
+
concept: kindsByConcept.get(entry.concept)?.size === 1
|
|
91
|
+
? entry.concept
|
|
92
|
+
: `${entry.concept}@${entry.command}`,
|
|
93
|
+
})));
|
|
94
|
+
return cachedPmFlagLexicon;
|
|
95
|
+
}
|
|
96
|
+
/** Return the complete canonical and compatibility spelling inventory. */
|
|
97
|
+
export function listPmFlagSpellingInventory() {
|
|
98
|
+
return Object.freeze(listPmFlagLexicon().map((entry) => Object.freeze({
|
|
99
|
+
command: entry.command,
|
|
100
|
+
canonical_flag: entry.flag,
|
|
101
|
+
accepted_spellings: Object.freeze([...new Set([entry.flag, ...entry.aliases])].sort()),
|
|
102
|
+
})));
|
|
103
|
+
}
|
|
104
|
+
const PM_COMMAND_FLAG_BUDGET_MAXIMUMS = Object.freeze({
|
|
105
|
+
init: 30,
|
|
106
|
+
config: 35,
|
|
107
|
+
extension: 53,
|
|
108
|
+
package: 54,
|
|
109
|
+
packages: 54,
|
|
110
|
+
install: 26,
|
|
111
|
+
upgrade: 29,
|
|
112
|
+
create: 100,
|
|
113
|
+
copy: 24,
|
|
114
|
+
focus: 22,
|
|
115
|
+
list: 86,
|
|
116
|
+
"list-all": 85,
|
|
117
|
+
"list-draft": 84,
|
|
118
|
+
"list-open": 84,
|
|
119
|
+
"list-in-progress": 84,
|
|
120
|
+
"list-blocked": 84,
|
|
121
|
+
"list-closed": 84,
|
|
122
|
+
"list-canceled": 84,
|
|
123
|
+
aggregate: 37,
|
|
124
|
+
context: 45,
|
|
125
|
+
ctx: 45,
|
|
126
|
+
get: 30,
|
|
127
|
+
graph: 34,
|
|
128
|
+
search: 78,
|
|
129
|
+
duplicates: 24,
|
|
130
|
+
eval: 25,
|
|
131
|
+
next: 35,
|
|
132
|
+
history: 35,
|
|
133
|
+
events: 33,
|
|
134
|
+
"history-redact": 27,
|
|
135
|
+
"history-repair": 26,
|
|
136
|
+
"history-compact": 30,
|
|
137
|
+
"history-author-acknowledge": 28,
|
|
138
|
+
merge: 24,
|
|
139
|
+
schema: 40,
|
|
140
|
+
profile: 22,
|
|
141
|
+
activity: 35,
|
|
142
|
+
restore: 23,
|
|
143
|
+
update: 105,
|
|
144
|
+
"update-many": 140,
|
|
145
|
+
close: 31,
|
|
146
|
+
"close-many": 72,
|
|
147
|
+
delete: 24,
|
|
148
|
+
append: 24,
|
|
149
|
+
comments: 30,
|
|
150
|
+
notes: 34,
|
|
151
|
+
learnings: 26,
|
|
152
|
+
files: 39,
|
|
153
|
+
docs: 30,
|
|
154
|
+
deps: 32,
|
|
155
|
+
plan: 109,
|
|
156
|
+
test: 48,
|
|
157
|
+
"test-all": 37,
|
|
158
|
+
telemetry: 21,
|
|
159
|
+
stats: 29,
|
|
160
|
+
health: 36,
|
|
161
|
+
validate: 45,
|
|
162
|
+
assurance: 30,
|
|
163
|
+
gc: 22,
|
|
164
|
+
workspace: 23,
|
|
165
|
+
contracts: 29,
|
|
166
|
+
claim: 36,
|
|
167
|
+
release: 23,
|
|
168
|
+
"start-task": 23,
|
|
169
|
+
"pause-task": 23,
|
|
170
|
+
"close-task": 24,
|
|
171
|
+
meet: 33,
|
|
172
|
+
event: 33,
|
|
173
|
+
remind: 29,
|
|
174
|
+
"test-runs-worker": 25,
|
|
175
|
+
});
|
|
176
|
+
/** Return persisted no-growth ratchets with current counts derived from the canonical vocabulary. */
|
|
177
|
+
export function listPmCommandFlagBudgets() {
|
|
178
|
+
const currentByCommand = new Map(Object.keys(PM_COMMAND_FLAG_BUDGET_MAXIMUMS).map((command) => [command, 0]));
|
|
179
|
+
for (const { command } of listPmFlagLexicon()) {
|
|
180
|
+
currentByCommand.set(command, Number(currentByCommand.get(command)) + 1);
|
|
181
|
+
}
|
|
182
|
+
return Object.freeze(Object.entries(PM_COMMAND_FLAG_BUDGET_MAXIMUMS).map(([command, maximum]) => Object.freeze({
|
|
183
|
+
command,
|
|
184
|
+
current: Number(currentByCommand.get(command)),
|
|
185
|
+
maximum,
|
|
186
|
+
})));
|
|
187
|
+
}
|
|
188
|
+
/** Append collisions between compatibility aliases and canonical spellings. */
|
|
189
|
+
function appendAliasCollisionFindings(entries, canonicalOwners, findings) {
|
|
190
|
+
for (const entry of entries) {
|
|
191
|
+
for (const alias of entry.aliases) {
|
|
192
|
+
const owner = canonicalOwners.get(`${entry.command}:${alias}`);
|
|
193
|
+
if (owner === undefined || owner.flag === entry.flag)
|
|
194
|
+
continue;
|
|
195
|
+
findings.push({
|
|
196
|
+
code: "alias_collision",
|
|
197
|
+
command: entry.command,
|
|
198
|
+
detail: `${alias} aliases ${entry.flag} but is canonical for ${owner.flag}.`,
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
/** Append missing, stale, and exceeded command-budget findings. */
|
|
204
|
+
function appendBudgetFindings(counts, budgets, findings) {
|
|
205
|
+
const budgetedCommands = new Set(budgets.map(({ command }) => command));
|
|
206
|
+
for (const command of counts.keys()) {
|
|
207
|
+
if (budgetedCommands.has(command))
|
|
208
|
+
continue;
|
|
209
|
+
findings.push({
|
|
210
|
+
code: "missing_budget",
|
|
211
|
+
command,
|
|
212
|
+
detail: `${command} has canonical flags but no persisted budget.`,
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
for (const budget of budgets) {
|
|
216
|
+
const actual = counts.get(budget.command) ?? 0;
|
|
217
|
+
if (actual === 0) {
|
|
218
|
+
findings.push({
|
|
219
|
+
code: "stale_budget",
|
|
220
|
+
command: budget.command,
|
|
221
|
+
detail: `${budget.command} has a persisted budget but no canonical flags.`,
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
if (actual <= budget.maximum)
|
|
225
|
+
continue;
|
|
226
|
+
findings.push({
|
|
227
|
+
code: "budget_exceeded",
|
|
228
|
+
command: budget.command,
|
|
229
|
+
detail: `${actual} canonical flags exceed the ratcheted maximum ${budget.maximum}.`,
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
/** Append regressions against the persisted pre-change spelling inventory. */
|
|
234
|
+
function appendSpellingCompatibilityFindings(entries, baseline, findings) {
|
|
235
|
+
const current = new Map(entries.map((entry) => [`${entry.command}:${entry.flag}`, entry]));
|
|
236
|
+
for (const historical of baseline) {
|
|
237
|
+
const key = `${historical.command}:${historical.canonical_flag}`;
|
|
238
|
+
const entry = current.get(key);
|
|
239
|
+
if (!entry) {
|
|
240
|
+
findings.push({
|
|
241
|
+
code: "removed_canonical_spelling",
|
|
242
|
+
command: historical.command,
|
|
243
|
+
detail: `${historical.canonical_flag} disappeared from the executable spelling inventory.`,
|
|
244
|
+
});
|
|
245
|
+
continue;
|
|
246
|
+
}
|
|
247
|
+
const accepted = new Set([entry.flag, ...entry.aliases]);
|
|
248
|
+
for (const spelling of historical.accepted_spellings) {
|
|
249
|
+
if (accepted.has(spelling))
|
|
250
|
+
continue;
|
|
251
|
+
findings.push({
|
|
252
|
+
code: "removed_compatibility_spelling",
|
|
253
|
+
command: historical.command,
|
|
254
|
+
detail: `${spelling} no longer resolves to ${historical.canonical_flag}.`,
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
/** Verify uniqueness, concept kind stability, alias safety, and flag budgets. */
|
|
260
|
+
export function verifyPmFlagLexicon(entries = listPmFlagLexicon(), budgets = listPmCommandFlagBudgets(), baseline = []) {
|
|
261
|
+
const findings = [];
|
|
262
|
+
const canonicalOwners = new Map();
|
|
263
|
+
const conceptKinds = new Map();
|
|
264
|
+
const conceptSpellings = new Map();
|
|
265
|
+
const counts = new Map();
|
|
266
|
+
for (const entry of entries) {
|
|
267
|
+
const commandFlag = `${entry.command}:${entry.flag}`;
|
|
268
|
+
if (canonicalOwners.has(commandFlag)) {
|
|
269
|
+
findings.push({
|
|
270
|
+
code: "duplicate_canonical_flag",
|
|
271
|
+
command: entry.command,
|
|
272
|
+
detail: `${entry.flag} has more than one canonical row.`,
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
else {
|
|
276
|
+
canonicalOwners.set(commandFlag, entry);
|
|
277
|
+
}
|
|
278
|
+
counts.set(entry.command, (counts.get(entry.command) ?? 0) + 1);
|
|
279
|
+
const priorKind = conceptKinds.get(entry.concept);
|
|
280
|
+
if (priorKind !== undefined && priorKind !== entry.value_kind) {
|
|
281
|
+
findings.push({
|
|
282
|
+
code: "inconsistent_concept_kind",
|
|
283
|
+
command: entry.command,
|
|
284
|
+
detail: `${entry.concept} uses both ${priorKind} and ${entry.value_kind}.`,
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
else {
|
|
288
|
+
conceptKinds.set(entry.concept, entry.value_kind);
|
|
289
|
+
}
|
|
290
|
+
const priorSpelling = conceptSpellings.get(entry.concept);
|
|
291
|
+
if (priorSpelling !== undefined && priorSpelling !== entry.flag) {
|
|
292
|
+
findings.push({
|
|
293
|
+
code: "semantic_spelling_collision",
|
|
294
|
+
command: entry.command,
|
|
295
|
+
detail: `${entry.concept} is canonicalized by both ${priorSpelling} and ${entry.flag}.`,
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
else {
|
|
299
|
+
conceptSpellings.set(entry.concept, entry.flag);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
appendAliasCollisionFindings(entries, canonicalOwners, findings);
|
|
303
|
+
appendBudgetFindings(counts, budgets, findings);
|
|
304
|
+
appendSpellingCompatibilityFindings(entries, baseline, findings);
|
|
305
|
+
findings.sort((left, right) => left.command.localeCompare(right.command) ||
|
|
306
|
+
left.code.localeCompare(right.code) ||
|
|
307
|
+
left.detail.localeCompare(right.detail));
|
|
308
|
+
return {
|
|
309
|
+
ok: findings.length === 0,
|
|
310
|
+
entry_count: entries.length,
|
|
311
|
+
budget_count: budgets.length,
|
|
312
|
+
concept_count: new Set(entries.map(({ concept }) => concept)).size,
|
|
313
|
+
baseline_entry_count: baseline.length,
|
|
314
|
+
findings,
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
/** Render a compact, generated family and command budget reference. Persisted budget rows are initialized to an explicit fallback so stale rows remain renderable. */
|
|
318
|
+
export function renderPmFlagLexiconMarkdown() {
|
|
319
|
+
const lexicon = listPmFlagLexicon();
|
|
320
|
+
const budgets = listPmCommandFlagBudgets();
|
|
321
|
+
const familyByCommand = new Map(budgets.map(({ command }) => [command, "unknown"]));
|
|
322
|
+
for (const { command, family } of lexicon)
|
|
323
|
+
familyByCommand.set(command, family);
|
|
324
|
+
const rows = budgets.map(({ command, current, maximum }) => {
|
|
325
|
+
const family = familyByCommand.get(command);
|
|
326
|
+
return `| \`${command}\` | ${family} | ${current} | ${maximum} |`;
|
|
327
|
+
});
|
|
328
|
+
return [
|
|
329
|
+
"# Generated flag lexicon budgets",
|
|
330
|
+
"",
|
|
331
|
+
"This file is generated by `listPmFlagLexicon()`. Compatibility aliases do not consume canonical budget.",
|
|
332
|
+
"",
|
|
333
|
+
"| Command | Capability family | Canonical flags | Maximum |",
|
|
334
|
+
"| --- | --- | ---: | ---: |",
|
|
335
|
+
...rows,
|
|
336
|
+
"",
|
|
337
|
+
].join("\n");
|
|
338
|
+
}
|
|
339
|
+
//# sourceMappingURL=flag-lexicon-contracts.js.map
|
|
340
|
+
//# debugId=6ba3d756-dcd6-59b7-92fe-ec33d294d72b
|