@unbrained/pm-cli 2026.8.23 → 2026.8.25
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 +27 -1
- package/dist/cli/description-stdin.js +5 -4
- package/dist/cli/extension-command-help.d.ts +5 -0
- package/dist/cli/extension-command-help.js +6 -2
- package/dist/cli/help-content.d.ts +5 -0
- package/dist/cli/help-content.js +56 -3
- package/dist/cli/help-json-payload.d.ts +5 -2
- package/dist/cli/help-json-payload.js +57 -17
- package/dist/cli/main.d.ts +3 -0
- package/dist/cli/main.js +28 -3
- package/dist/cli/register-annotations.js +5 -5
- package/dist/cli/register-mutation.js +73 -27
- package/dist/cli-bundle/bundle-manifest.json +152 -152
- package/dist/cli-bundle/chunks/{chunk-HWZ6CELB.js → chunk-244MI4GS.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-QDVHNHAQ.js → chunk-2F3LUFMW.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-EG6CLDZT.js → chunk-5I5RWIJC.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-KPH73XXJ.js → chunk-65MHLHAA.js} +2 -2
- package/dist/cli-bundle/chunks/chunk-6C7GIMIL.js +13 -0
- package/dist/cli-bundle/chunks/chunk-OWHNAR2B.js +2 -0
- package/dist/cli-bundle/chunks/chunk-QKGMHGEI.js +202 -0
- package/dist/cli-bundle/chunks/chunk-QLUORNIB.js +2092 -0
- package/dist/cli-bundle/chunks/{chunk-JB4KZWBF.js → chunk-T2ENPRXF.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-F3AI2JFL.js → chunk-TPQIBSL2.js} +2 -2
- package/dist/cli-bundle/chunks/chunk-YQMYF3YD.js +35 -0
- package/dist/cli-bundle/chunks/{register-list-query-UJB5FMV2.js → register-list-query-XVN2ZLI7.js} +2 -2
- package/dist/cli-bundle/chunks/register-mutation-QCKAEGIJ.js +20 -0
- package/dist/cli-bundle/chunks/{register-operations-RXIJIYXC.js → register-operations-SDEAXE7E.js} +2 -2
- package/dist/cli-bundle/chunks/{register-setup-GFUZEKRE.js → register-setup-LXVBRCJ3.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-QGFNI65N.js → chunk-2UIWOP3O.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-42S3GGZ7.js +50 -0
- package/dist/cli-bundle/focused-chunks/{chunk-OGLQBL46.js → chunk-7I23XGWO.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-7YCDTCBC.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-OFVUGTLJ.js → chunk-A644DUFQ.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-AUFH5H35.js → chunk-GQR3WH3F.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-3UPTYG44.js → chunk-H5JZEIQV.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-IBZZZGK3.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-LMKG3DFE.js +5 -0
- package/dist/cli-bundle/focused-chunks/{chunk-LYVSW5VM.js → chunk-N7W67YIG.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-37Z4OEAP.js → chunk-NOOZGIXP.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-FZS4H32O.js → chunk-OHIHZ7HS.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-ONYQCALA.js +19 -0
- package/dist/cli-bundle/focused-chunks/chunk-OVJL6NZE.js +4 -0
- package/dist/cli-bundle/focused-chunks/chunk-RAFKLNZX.js +16 -0
- package/dist/cli-bundle/focused-chunks/{chunk-IFLWKY2R.js → chunk-VXWATRFL.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-R27IDGHD.js → chunk-XUQPEKRN.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-JOWDB2MH.js → chunk-YO3ZF3FI.js} +2 -2
- package/dist/cli-bundle/main.js +18 -17
- package/dist/cli-bundle/sdk-authoring.js +1 -1
- package/dist/cli-bundle/sdk-contracts.js +2 -2
- package/dist/cli-bundle/sdk-core.js +32 -32
- 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 -33
- 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 +6 -5
- package/dist/core/diagnostics/remediation.js +17 -2
- package/dist/core/extensions/command-metadata-contract.d.ts +10 -0
- package/dist/core/extensions/command-metadata-contract.js +23 -0
- package/dist/core/extensions/command-visibility-tier.js +12 -2
- package/dist/core/extensions/extension-types.d.ts +6 -0
- package/dist/core/extensions/extension-types.js +2 -2
- package/dist/core/extensions/loader.js +4 -3
- package/dist/core/io/body-file.js +7 -2
- package/dist/core/io/bulk-ids-input.d.ts +24 -0
- package/dist/core/io/bulk-ids-input.js +113 -0
- package/dist/core/item/parse.d.ts +22 -2
- package/dist/core/item/parse.js +97 -4
- package/dist/mcp/server.d.ts +3 -2
- package/dist/mcp/server.js +16 -9
- package/dist/sdk/agent/refusal-closure-census.d.ts +66 -0
- package/dist/sdk/agent/refusal-closure-census.js +144 -0
- package/dist/sdk/agent-capability-contracts.d.ts +34 -1
- package/dist/sdk/agent-capability-contracts.js +104 -6
- package/dist/sdk/annotations.d.ts +2 -0
- package/dist/sdk/annotations.js +25 -7
- package/dist/sdk/cli-contracts/runtime-contracts.d.ts +10 -0
- package/dist/sdk/cli-contracts/runtime-contracts.js +20 -3
- package/dist/sdk/cli-contracts/tool-parameter-tables.js +38 -2
- package/dist/sdk/cli-contracts/typed-action-inputs.d.ts +4 -1
- package/dist/sdk/cli-contracts/typed-action-inputs.js +2 -2
- package/dist/sdk/comments.js +15 -7
- package/dist/sdk/flag-invocation-contracts.d.ts +2 -0
- package/dist/sdk/flag-invocation-contracts.js +28 -3
- package/dist/sdk/generated/generated-error-code-catalog-part-1.js +109 -52
- package/dist/sdk/generated/generated-error-code-catalog-part-2.js +62 -2
- package/dist/sdk/governance/health.js +98 -11
- package/dist/sdk/governance/validate.js +15 -9
- package/dist/sdk/guide-topics.d.ts +0 -5
- package/dist/sdk/guide-topics.js +28 -2
- package/dist/sdk/history-compact.d.ts +2 -1
- package/dist/sdk/history-compact.js +24 -5
- package/dist/sdk/history-mcp.js +11 -10
- package/dist/sdk/history-repair.d.ts +24 -0
- package/dist/sdk/history-repair.js +145 -4
- package/dist/sdk/index.d.ts +1 -0
- package/dist/sdk/index.js +3 -2
- package/dist/sdk/item-transaction.js +19 -12
- package/dist/sdk/lifecycle/append.js +4 -4
- package/dist/sdk/lifecycle/close-many.js +16 -7
- package/dist/sdk/lifecycle/create.js +29 -21
- package/dist/sdk/lifecycle/plan.js +24 -6
- package/dist/sdk/lifecycle/update-many.js +15 -8
- package/dist/sdk/lifecycle/update.d.ts +2 -0
- package/dist/sdk/lifecycle/update.js +34 -24
- package/dist/sdk/merge/driver.js +25 -4
- package/dist/sdk/merge/receipt-file-boundary.d.ts +21 -0
- package/dist/sdk/merge/receipt-file-boundary.js +47 -0
- package/dist/sdk/merge/receipts.d.ts +24 -1
- package/dist/sdk/merge/receipts.js +342 -36
- package/dist/sdk/merge/reconcile.js +117 -47
- package/dist/sdk/read-output/continuation.d.ts +15 -2
- package/dist/sdk/read-output/continuation.js +86 -6
- package/dist/sdk/read-output-contracts.d.ts +4 -1
- package/dist/sdk/read-output-contracts.js +9 -6
- package/dist/sdk/runtime-extended-actions.js +5 -3
- package/dist/sdk/runtime-input.d.ts +4 -0
- package/dist/sdk/runtime-input.js +98 -23
- package/dist/sdk/runtime-primitives.d.ts +2 -1
- package/dist/sdk/runtime-primitives.js +4 -3
- package/dist/sdk/runtime.js +7 -20
- package/dist/sdk/scheduling-shortcuts.js +5 -3
- package/dist/sdk/structured-mutations.js +10 -3
- package/dist/sdk/workspace-contracts.d.ts +3 -0
- package/dist/sdk/workspace-contracts.js +3 -2
- package/docs/MERGE_SAFETY.md +34 -5
- package/docs/OUTPUT_PROJECTION_CONTRACTS.md +13 -1
- package/docs/README.md +2 -0
- package/docs/READ_OUTPUT_CONTRACTS.md +25 -2
- package/docs/RELEASING.md +40 -21
- package/docs/SCRIPTING.md +62 -3
- package/docs/SDK.md +8 -0
- package/docs/generated/AGENT_CAPABILITY_ROUTING.md +17 -0
- package/docs/generated/AGENT_COMMAND_SURFACE.md +1 -1
- package/docs/generated/REFUSAL_CLOSURE_CENSUS.md +359 -0
- package/marketplace.json +2 -2
- package/package.json +1 -1
- package/packages/pm-beads/package.json +1 -1
- package/packages/pm-calendar/package.json +1 -1
- package/packages/pm-command-kit/README.md +9 -11
- package/packages/pm-command-kit/extensions/command-kit/index.ts +3 -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/extensions/guide-shell/index.ts +10 -0
- 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 +27 -1
- package/sdk/public-surface.json +351 -26
- package/dist/cli-bundle/chunks/chunk-3ENVHX6C.js +0 -36
- package/dist/cli-bundle/chunks/chunk-DW2CGEMU.js +0 -2
- package/dist/cli-bundle/chunks/chunk-HZBMLSZI.js +0 -201
- package/dist/cli-bundle/chunks/chunk-KXPMB2YL.js +0 -2092
- package/dist/cli-bundle/chunks/chunk-TFI5V5N2.js +0 -13
- package/dist/cli-bundle/chunks/register-mutation-NX5XE4VX.js +0 -20
- package/dist/cli-bundle/focused-chunks/chunk-5S7E72FY.js +0 -16
- package/dist/cli-bundle/focused-chunks/chunk-E7X25GC3.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-FQCSTBWE.js +0 -4
- package/dist/cli-bundle/focused-chunks/chunk-MRCNF3U6.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-OY7QAV4Y.js +0 -51
- package/dist/cli-bundle/focused-chunks/chunk-UYRFYCDQ.js +0 -5
- package/dist/cli-bundle/focused-chunks/chunk-ZHVA42R5.js +0 -18
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
*/
|
|
20
20
|
/** Registry of every non-extension `pm health` / `pm validate` warning code and its remediation. Extension findings keep their richer, contextual `details.triage.remediation` produced by the extension health triage and are intentionally excluded here (see pm-0hnu: "all non-extension checks"). */
|
|
21
21
|
|
|
22
|
-
!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]="
|
|
22
|
+
!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]="c088607b-1be3-54c8-a38b-79c188924102")}catch(e){}}();
|
|
23
23
|
export const REMEDIATION_REGISTRY = Object.freeze([
|
|
24
24
|
// --- pm health: directories ---
|
|
25
25
|
{
|
|
@@ -193,6 +193,16 @@ export const REMEDIATION_REGISTRY = Object.freeze([
|
|
|
193
193
|
command: "pm merge reconcile --dry-run",
|
|
194
194
|
summary: "Review the pending merge receipts, re-apply any intended discarded values, then run pm merge reconcile; lossy receipts require explicit --force acceptance.",
|
|
195
195
|
},
|
|
196
|
+
{
|
|
197
|
+
code: "merge_receipts_pending",
|
|
198
|
+
command: "pm merge reconcile --dry-run",
|
|
199
|
+
summary: "A lossless merge receipt is still pending; preview and run pm merge reconcile so a green health gate certifies receipt settlement, not only intact data.",
|
|
200
|
+
},
|
|
201
|
+
{
|
|
202
|
+
code: "merge_receipt_evidence_invalid",
|
|
203
|
+
command: "pm health --check-only --full",
|
|
204
|
+
summary: "One or more receipt files failed bounded-file, schema, or identity validation; use the full health count to inspect the clone-local and durable receipt directories, then repair or remove only confirmed invalid evidence.",
|
|
205
|
+
},
|
|
196
206
|
{
|
|
197
207
|
code: "validate_merge_decisions_unreviewed",
|
|
198
208
|
command: "pm merge reconcile --dry-run",
|
|
@@ -221,6 +231,11 @@ export const REMEDIATION_REGISTRY = Object.freeze([
|
|
|
221
231
|
command: "pm history-repair <id>",
|
|
222
232
|
summary: "The item's history chain is broken; re-anchor the chain (pm history-repair --all repairs every drifted stream in one pass).",
|
|
223
233
|
},
|
|
234
|
+
{
|
|
235
|
+
code: "history_drift_merge_receipt",
|
|
236
|
+
command: "pm merge reconcile --dry-run",
|
|
237
|
+
summary: "Canonical path, changed-field, and merged-value hash evidence attributes this drift to a pending receipt; preview reconciliation instead of repairing history directly.",
|
|
238
|
+
},
|
|
224
239
|
// --- pm health: storage (history compaction policy) ---
|
|
225
240
|
{
|
|
226
241
|
code: "history_stream_over_compact_threshold",
|
|
@@ -474,4 +489,4 @@ export function buildRemediationCommands(warnings) {
|
|
|
474
489
|
return Object.values(buildRemediationMap(warnings));
|
|
475
490
|
}
|
|
476
491
|
//# sourceMappingURL=remediation.js.map
|
|
477
|
-
//# debugId=
|
|
492
|
+
//# debugId=c088607b-1be3-54c8-a38b-79c188924102
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module core/extensions/command-metadata-contract
|
|
3
|
+
*
|
|
4
|
+
* Owns the closed metadata domains shared by extension registration, runtime
|
|
5
|
+
* validation, SDK contracts, and workspace projections.
|
|
6
|
+
*/
|
|
7
|
+
/** Canonical capability-family values accepted for every command surface. */
|
|
8
|
+
export declare const EXTENSION_COMMAND_CAPABILITY_FAMILIES: readonly ["workspace", "intake", "context", "lifecycle", "evidence", "graph", "quality", "automation", "extensions", "internal"];
|
|
9
|
+
/** Capability family an extension command contributes to agent routing. */
|
|
10
|
+
export type ExtensionCommandCapabilityFamily = (typeof EXTENSION_COMMAND_CAPABILITY_FAMILIES)[number];
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module core/extensions/command-metadata-contract
|
|
3
|
+
*
|
|
4
|
+
* Owns the closed metadata domains shared by extension registration, runtime
|
|
5
|
+
* validation, SDK contracts, and workspace projections.
|
|
6
|
+
*/
|
|
7
|
+
/** Canonical capability-family values accepted for every command surface. */
|
|
8
|
+
|
|
9
|
+
!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]="b799a368-2a8a-5031-8d14-f6b9dc4a3978")}catch(e){}}();
|
|
10
|
+
export const EXTENSION_COMMAND_CAPABILITY_FAMILIES = Object.freeze([
|
|
11
|
+
"workspace",
|
|
12
|
+
"intake",
|
|
13
|
+
"context",
|
|
14
|
+
"lifecycle",
|
|
15
|
+
"evidence",
|
|
16
|
+
"graph",
|
|
17
|
+
"quality",
|
|
18
|
+
"automation",
|
|
19
|
+
"extensions",
|
|
20
|
+
"internal",
|
|
21
|
+
]);
|
|
22
|
+
//# sourceMappingURL=command-metadata-contract.js.map
|
|
23
|
+
//# debugId=b799a368-2a8a-5031-8d14-f6b9dc4a3978
|
|
@@ -1,9 +1,18 @@
|
|
|
1
1
|
|
|
2
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
2
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="764d9a7d-90a2-578f-ab5d-bd0c039596df")}catch(e){}}();
|
|
3
3
|
import { assertOptionalStringField } from "./registration-validation.js";
|
|
4
|
+
import { EXTENSION_COMMAND_CAPABILITY_FAMILIES } from "./command-metadata-contract.js";
|
|
5
|
+
const COMMAND_CAPABILITY_FAMILIES = new Set(EXTENSION_COMMAND_CAPABILITY_FAMILIES);
|
|
6
|
+
function assertCommandCapabilityFamily(family) {
|
|
7
|
+
if (family !== undefined &&
|
|
8
|
+
!COMMAND_CAPABILITY_FAMILIES.has(String(family))) {
|
|
9
|
+
throw new Error(`registerCommand definition.family must be one of: ${EXTENSION_COMMAND_CAPABILITY_FAMILIES.join(", ")}`);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
4
12
|
/** Validate optional command metadata strings and the closed visibility tier. */
|
|
5
13
|
export function assertCommandDefinitionMetadataStrings(definition) {
|
|
6
14
|
assertOptionalStringField("registerCommand definition.action", definition.action);
|
|
15
|
+
assertOptionalStringField("registerCommand definition.family", definition.family);
|
|
7
16
|
assertOptionalStringField("registerCommand definition.description", definition.description);
|
|
8
17
|
assertOptionalStringField("registerCommand definition.intent", definition.intent);
|
|
9
18
|
assertOptionalStringField("registerCommand definition.tier", definition.tier);
|
|
@@ -15,6 +24,7 @@ export function assertCommandDefinitionMetadataStrings(definition) {
|
|
|
15
24
|
tier !== "internal") {
|
|
16
25
|
throw new Error("registerCommand definition.tier must be core, standard, full, or internal");
|
|
17
26
|
}
|
|
27
|
+
assertCommandCapabilityFamily(definition.family);
|
|
18
28
|
}
|
|
19
29
|
//# sourceMappingURL=command-visibility-tier.js.map
|
|
20
|
-
//# debugId=
|
|
30
|
+
//# debugId=764d9a7d-90a2-578f-ab5d-bd0c039596df
|
|
@@ -13,6 +13,8 @@ import type { GetItemAtResult } from "../../sdk/history-read.js";
|
|
|
13
13
|
import type { RelationshipEvent, RelationshipEventInput, RelationshipEventStore } from "../../sdk/relationship-history.js";
|
|
14
14
|
import type { CommitWorkspaceTransactionOptions, WorkspaceTransactionCommitResult } from "../../sdk/workspace-transaction.js";
|
|
15
15
|
import type { KnownItemFieldType } from "./item-field-types.js";
|
|
16
|
+
import type { ExtensionCommandCapabilityFamily } from "./command-metadata-contract.js";
|
|
17
|
+
export type { ExtensionCommandCapabilityFamily } from "./command-metadata-contract.js";
|
|
16
18
|
/** Public contract for known extension capabilities, shared by SDK and presentation-layer consumers. */
|
|
17
19
|
export declare const KNOWN_EXTENSION_CAPABILITIES: readonly ["commands", "renderers", "hooks", "schema", "importers", "search", "parser", "preflight", "services"];
|
|
18
20
|
/** Restricts extension capability values accepted by command, SDK, and storage contracts. */
|
|
@@ -691,6 +693,8 @@ export interface CommandDefinition {
|
|
|
691
693
|
flags?: FlagDefinition[];
|
|
692
694
|
/** Minimum agent surface tier that should advertise this command. */
|
|
693
695
|
tier?: "core" | "standard" | "full" | "internal";
|
|
696
|
+
/** Capability family used by generated agent routing surfaces. */
|
|
697
|
+
family?: ExtensionCommandCapabilityFamily;
|
|
694
698
|
}
|
|
695
699
|
/**
|
|
696
700
|
* Optional command-definition metadata for first-class importer/exporter
|
|
@@ -1272,6 +1276,8 @@ export interface RegisteredExtensionCommandDefinition {
|
|
|
1272
1276
|
arguments: ExtensionCommandArgumentDefinition[];
|
|
1273
1277
|
/** Minimum agent surface tier that should advertise this command. */
|
|
1274
1278
|
tier?: "core" | "standard" | "full" | "internal";
|
|
1279
|
+
/** Capability family used by generated agent routing surfaces. */
|
|
1280
|
+
family?: ExtensionCommandCapabilityFamily;
|
|
1275
1281
|
}
|
|
1276
1282
|
/** Documents the registered extension schema field definitions payload exchanged by command, SDK, and package integrations. */
|
|
1277
1283
|
export interface RegisteredExtensionSchemaFieldDefinitions {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/** Public contract for known extension capabilities, shared by SDK and presentation-layer consumers. */
|
|
2
2
|
|
|
3
|
-
!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]="
|
|
3
|
+
!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]="ef5c8553-c206-5bb5-913a-85afb936f6d7")}catch(e){}}();
|
|
4
4
|
export const KNOWN_EXTENSION_CAPABILITIES = [
|
|
5
5
|
"commands",
|
|
6
6
|
"renderers",
|
|
@@ -100,4 +100,4 @@ export function createDefaultExtensionGovernancePolicy() {
|
|
|
100
100
|
};
|
|
101
101
|
}
|
|
102
102
|
//# sourceMappingURL=extension-types.js.map
|
|
103
|
-
//# debugId=
|
|
103
|
+
//# debugId=ef5c8553-c206-5bb5-913a-85afb936f6d7
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Implements extension runtime contracts and governance for Loader.
|
|
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]="e4e1b7c2-6551-5e56-b26a-30062aed5b97")}catch(e){}}();
|
|
8
8
|
import fs from "node:fs/promises";
|
|
9
9
|
import path from "node:path";
|
|
10
10
|
import { pathToFileURL } from "node:url";
|
|
@@ -1505,7 +1505,8 @@ class ExtensionApiRegistrar {
|
|
|
1505
1505
|
examples,
|
|
1506
1506
|
failure_hints: failureHints,
|
|
1507
1507
|
arguments: argumentsDefinition,
|
|
1508
|
-
tier: definition.tier,
|
|
1508
|
+
tier: definition.tier ?? "standard",
|
|
1509
|
+
family: definition.family ?? "extensions",
|
|
1509
1510
|
};
|
|
1510
1511
|
if (description) {
|
|
1511
1512
|
registration.description = description;
|
|
@@ -2220,4 +2221,4 @@ export const _testOnlyLoader = {
|
|
|
2220
2221
|
},
|
|
2221
2222
|
};
|
|
2222
2223
|
//# sourceMappingURL=loader.js.map
|
|
2223
|
-
//# debugId=
|
|
2224
|
+
//# debugId=e4e1b7c2-6551-5e56-b26a-30062aed5b97
|
|
@@ -4,10 +4,11 @@
|
|
|
4
4
|
* Reads command body content from files, stdin, and inline arguments.
|
|
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]="a97ee152-4d20-54f1-add9-fdb991ab6b33")}catch(e){}}();
|
|
8
8
|
import { readFile } from "node:fs/promises";
|
|
9
9
|
import { EXIT_CODE } from "../shared/constants.js";
|
|
10
10
|
import { PmCliError } from "../shared/errors.js";
|
|
11
|
+
import { createStdinTokenResolver } from "../item/parse.js";
|
|
11
12
|
const defaultBodyFileReader = (path) => readFile(path, "utf8");
|
|
12
13
|
/** Implements resolve body file content for the public runtime surface of this module. */
|
|
13
14
|
export async function resolveBodyFileContent(bodyFile, inlineBody, readFileImpl = defaultBodyFileReader) {
|
|
@@ -31,6 +32,9 @@ export async function resolveBodyFileContent(bodyFile, inlineBody, readFileImpl
|
|
|
31
32
|
why: "An empty --body-file value has no file to read the body from.",
|
|
32
33
|
});
|
|
33
34
|
}
|
|
35
|
+
if (path === "-") {
|
|
36
|
+
return (await createStdinTokenResolver().resolveValue("-", "--body-file"));
|
|
37
|
+
}
|
|
34
38
|
try {
|
|
35
39
|
return await readFileImpl(path);
|
|
36
40
|
}
|
|
@@ -49,10 +53,11 @@ export async function resolveBodyFileContent(bodyFile, inlineBody, readFileImpl
|
|
|
49
53
|
why: `The body content is loaded from the file at the supplied path, so an unreadable path cannot produce a body${errno ? ` (underlying error: ${errno})` : ""}.`,
|
|
50
54
|
nextSteps: [
|
|
51
55
|
`Verify the path: ls -l "${path}"`,
|
|
56
|
+
"Or pipe the body with --body-file -.",
|
|
52
57
|
"Or pass the body inline with --body <text>.",
|
|
53
58
|
],
|
|
54
59
|
});
|
|
55
60
|
}
|
|
56
61
|
}
|
|
57
62
|
//# sourceMappingURL=body-file.js.map
|
|
58
|
-
//# debugId=
|
|
63
|
+
//# debugId=a97ee152-4d20-54f1-add9-fdb991ab6b33
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/** File reader injected by tests or host runtimes that virtualize argv files. */
|
|
2
|
+
export type BulkIdsFileReader = (path: string) => Promise<string>;
|
|
3
|
+
/** Stdin reader injected by tests or hosts that do not use process stdin. */
|
|
4
|
+
export type BulkIdsStdinReader = (optionName: string) => Promise<string>;
|
|
5
|
+
/** Dependencies used to resolve CLI-only external ID sources. */
|
|
6
|
+
export interface BulkIdsInputReaders {
|
|
7
|
+
/** Read a UTF-8 `@path` payload. */
|
|
8
|
+
readFile?: BulkIdsFileReader;
|
|
9
|
+
/** Read the complete stdin payload for `-`. */
|
|
10
|
+
readStdin?: BulkIdsStdinReader;
|
|
11
|
+
}
|
|
12
|
+
/** Transport-native bulk ID shapes accepted by SDK and MCP adapters. */
|
|
13
|
+
export type BulkIdsValue = string | number | readonly (string | number)[] | undefined;
|
|
14
|
+
/** Parse comma- or line-delimited item IDs with stable first-seen deduplication. */
|
|
15
|
+
export declare function parseBulkIdsText(raw: string): string[];
|
|
16
|
+
/** Normalize SDK/MCP scalar-or-array ID input into the list query's CSV form. */
|
|
17
|
+
export declare function normalizeBulkIdsValue(value: BulkIdsValue): string | undefined;
|
|
18
|
+
/**
|
|
19
|
+
* Resolve one CLI `--ids` value. `-` reads newline/comma-delimited stdin and
|
|
20
|
+
* `@path` reads the same grammar from a UTF-8 file; ordinary argv text accepts
|
|
21
|
+
* the grammar inline. The return value is canonical CSV for existing list
|
|
22
|
+
* filtering and unmatched-id accounting.
|
|
23
|
+
*/
|
|
24
|
+
export declare function resolveCliBulkIdsInput(value: string | undefined, optionName?: string, readers?: BulkIdsInputReaders): Promise<string | undefined>;
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module core/io/bulk-ids-input
|
|
3
|
+
*
|
|
4
|
+
* Normalizes bulk item-id selectors supplied inline, through stdin, or from an
|
|
5
|
+
* argv-referenced file. Presentation layers can share the parser while MCP and
|
|
6
|
+
* embedded SDK callers keep passing transport-native arrays.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
!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]="411f4336-eb02-5167-9dce-ea99822a8a14")}catch(e){}}();
|
|
10
|
+
import { readFile } from "node:fs/promises";
|
|
11
|
+
import { createStdinTokenResolver } from "../item/parse.js";
|
|
12
|
+
import { EXIT_CODE } from "../shared/constants.js";
|
|
13
|
+
import { PmCliError } from "../shared/errors.js";
|
|
14
|
+
const defaultFileReader = (path) => readFile(path, "utf8");
|
|
15
|
+
const defaultStdinReader = async (optionName) => (await createStdinTokenResolver().resolveValue("-", optionName));
|
|
16
|
+
/** Parse comma- or line-delimited item IDs with stable first-seen deduplication. */
|
|
17
|
+
export function parseBulkIdsText(raw) {
|
|
18
|
+
return [
|
|
19
|
+
...new Set(raw
|
|
20
|
+
.split(/[,\r\n]+/)
|
|
21
|
+
.map((entry) => entry.trim())
|
|
22
|
+
.filter((entry) => entry.length > 0)),
|
|
23
|
+
];
|
|
24
|
+
}
|
|
25
|
+
function normalizeBulkIdsArray(value) {
|
|
26
|
+
const entries = [];
|
|
27
|
+
for (const entry of value) {
|
|
28
|
+
if (typeof entry === "string") {
|
|
29
|
+
entries.push(entry);
|
|
30
|
+
}
|
|
31
|
+
else if (typeof entry === "number" && Number.isFinite(entry)) {
|
|
32
|
+
entries.push(String(entry));
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
return "";
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
const ids = parseBulkIdsText(entries.join("\n"));
|
|
39
|
+
return ids.length > 0 ? ids.join(",") : "";
|
|
40
|
+
}
|
|
41
|
+
/** Normalize SDK/MCP scalar-or-array ID input into the list query's CSV form. */
|
|
42
|
+
export function normalizeBulkIdsValue(value) {
|
|
43
|
+
if (value === undefined) {
|
|
44
|
+
return undefined;
|
|
45
|
+
}
|
|
46
|
+
if (typeof value === "number") {
|
|
47
|
+
// Preserve an explicitly supplied but invalid numeric selector as blank so
|
|
48
|
+
// the bulk lifecycle's fail-closed empty-ID guard rejects it. Returning
|
|
49
|
+
// undefined here would erase the allowlist and could broaden a mutation to
|
|
50
|
+
// every item matched by the remaining filters.
|
|
51
|
+
return Number.isFinite(value) ? String(value) : "";
|
|
52
|
+
}
|
|
53
|
+
if (Array.isArray(value)) {
|
|
54
|
+
return normalizeBulkIdsArray(value);
|
|
55
|
+
}
|
|
56
|
+
if (typeof value !== "string") {
|
|
57
|
+
return "";
|
|
58
|
+
}
|
|
59
|
+
const ids = parseBulkIdsText(value);
|
|
60
|
+
return ids.length > 0 ? ids.join(",") : "";
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Resolve one CLI `--ids` value. `-` reads newline/comma-delimited stdin and
|
|
64
|
+
* `@path` reads the same grammar from a UTF-8 file; ordinary argv text accepts
|
|
65
|
+
* the grammar inline. The return value is canonical CSV for existing list
|
|
66
|
+
* filtering and unmatched-id accounting.
|
|
67
|
+
*/
|
|
68
|
+
export async function resolveCliBulkIdsInput(value, optionName = "--ids", readers = {}) {
|
|
69
|
+
if (value === undefined) {
|
|
70
|
+
return undefined;
|
|
71
|
+
}
|
|
72
|
+
const trimmed = value.trim();
|
|
73
|
+
let raw = value;
|
|
74
|
+
try {
|
|
75
|
+
if (trimmed === "-") {
|
|
76
|
+
raw = await (readers.readStdin ?? defaultStdinReader)(optionName);
|
|
77
|
+
}
|
|
78
|
+
else if (trimmed.startsWith("@")) {
|
|
79
|
+
const path = trimmed.slice(1).trim();
|
|
80
|
+
if (path.length === 0) {
|
|
81
|
+
throw new PmCliError(`${optionName} @path requires a non-empty file path.`, EXIT_CODE.USAGE, {
|
|
82
|
+
code: "bulk_ids_input_missing_path",
|
|
83
|
+
required: `Pass ${optionName} @<path>, ${optionName} -, or inline IDs.`,
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
raw = await (readers.readFile ?? defaultFileReader)(path);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
catch (error) {
|
|
90
|
+
if (error instanceof PmCliError) {
|
|
91
|
+
throw error;
|
|
92
|
+
}
|
|
93
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
94
|
+
throw new PmCliError(`${optionName} could not read ${trimmed === "-" ? "stdin" : `"${trimmed.slice(1).trim()}"`}: ${detail}`, EXIT_CODE.NOT_FOUND, {
|
|
95
|
+
code: "bulk_ids_input_unreadable",
|
|
96
|
+
required: `Provide readable newline/comma-delimited IDs via ${optionName} -, ${optionName} @<path>, or inline argv text.`,
|
|
97
|
+
nextSteps: [
|
|
98
|
+
`Retry with inline IDs: ${optionName} pm-a1b2,pm-c3d4`,
|
|
99
|
+
`Or pipe IDs: pm list --id-only | pm update-many ${optionName} - --dry-run`,
|
|
100
|
+
],
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
const normalized = normalizeBulkIdsValue(raw);
|
|
104
|
+
if (normalized !== "") {
|
|
105
|
+
return normalized;
|
|
106
|
+
}
|
|
107
|
+
throw new PmCliError(`${optionName} requires at least one non-empty item ID.`, EXIT_CODE.USAGE, {
|
|
108
|
+
code: "bulk_ids_input_empty",
|
|
109
|
+
required: `Provide one or more comma- or newline-delimited IDs through argv, stdin, or @path.`,
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=bulk-ids-input.js.map
|
|
113
|
+
//# debugId=411f4336-eb02-5167-9dce-ea99822a8a14
|
|
@@ -53,10 +53,30 @@ export declare function assertNoUnknownCsvKeys(kv: Record<string, string>, optio
|
|
|
53
53
|
/** Documents the stdin token resolver payload exchanged by command, SDK, and package integrations. */
|
|
54
54
|
export interface StdinTokenResolver {
|
|
55
55
|
/** Value that configures or reports resolve value for this contract. */
|
|
56
|
-
resolveValue(value: string | undefined, optionName: string): Promise<string | undefined>;
|
|
56
|
+
resolveValue(value: string | undefined, optionName: string, resolveToken?: boolean): Promise<string | undefined>;
|
|
57
57
|
/** Value that configures or reports resolve list for this contract. */
|
|
58
|
-
resolveList(values: string[] | undefined, optionName: string): Promise<string[] | undefined>;
|
|
58
|
+
resolveList(values: string[] | undefined, optionName: string, resolveToken?: boolean): Promise<string[] | undefined>;
|
|
59
59
|
}
|
|
60
|
+
/** Mark transport-decoded options whose dash values are data, not stdin tokens. */
|
|
61
|
+
export declare function preserveMutationStdinTokenLiterals<T extends object>(options: T): T;
|
|
62
|
+
/** Mark selected mutation fields whose dash values are literal transport data. */
|
|
63
|
+
export declare function preserveMutationStdinTokenFields<T extends object>(options: T, fields: readonly PropertyKey[]): T;
|
|
64
|
+
/** Copy the complete mutation stdin-token policy across an option clone. */
|
|
65
|
+
export declare function transferMutationStdinTokenPolicy<T extends object>(source: object, target: T): T;
|
|
66
|
+
/** Add a source mutation stdin-token policy without weakening the target. */
|
|
67
|
+
export declare function overlayMutationStdinTokenPolicy<T extends object>(source: object, target: T): T;
|
|
68
|
+
/** Report whether lifecycle input should interpret dash values as stdin tokens. */
|
|
69
|
+
export declare function shouldResolveMutationStdinTokens(options: object): boolean;
|
|
70
|
+
/** Report whether one mutation field should interpret dash as a stdin token. */
|
|
71
|
+
export declare function shouldResolveMutationStdinTokenField(options: object, field: PropertyKey): boolean;
|
|
72
|
+
/** Refuse competing stdin-token fields before any resolver starts reading. */
|
|
73
|
+
export declare function assertSingleStdinTokenConsumer(candidates: readonly {
|
|
74
|
+
value: string | readonly string[] | undefined;
|
|
75
|
+
optionName: string;
|
|
76
|
+
resolveToken?: boolean;
|
|
77
|
+
}[]): void;
|
|
78
|
+
/** Resolve a typed mutation option bag only after its complete stdin plan is conflict-free. */
|
|
79
|
+
export declare function resolveMutationStdinTokenFields<T extends object>(options: T, scalarFields: readonly (readonly [keyof T & string, string])[], listFields: readonly (readonly [keyof T & string, string])[]): Promise<T>;
|
|
60
80
|
/** Implements create stdin token resolver for the public runtime surface of this module. */
|
|
61
81
|
export declare function createStdinTokenResolver(): StdinTokenResolver;
|
|
62
82
|
/** Implements parse optional number for the public runtime surface of this module. */
|
package/dist/core/item/parse.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Defines item parsing, formatting, and lifecycle helpers for Parse.
|
|
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]="2252cfb9-37ea-57f1-b7ea-2b0c0f87ecb2")}catch(e){}}();
|
|
8
8
|
import { PmCliError } from "../shared/errors.js";
|
|
9
9
|
import { EXIT_CODE } from "../shared/constants.js";
|
|
10
10
|
const STDIN_TOKEN = "-";
|
|
@@ -416,6 +416,95 @@ async function readStdinText(optionName) {
|
|
|
416
416
|
});
|
|
417
417
|
});
|
|
418
418
|
}
|
|
419
|
+
const ALL_MUTATION_STDIN_FIELDS = Symbol("all-mutation-stdin-fields");
|
|
420
|
+
const literalStdinTokenFields = new WeakMap();
|
|
421
|
+
/** Mark transport-decoded options whose dash values are data, not stdin tokens. */
|
|
422
|
+
export function preserveMutationStdinTokenLiterals(options) {
|
|
423
|
+
literalStdinTokenFields.set(options, ALL_MUTATION_STDIN_FIELDS);
|
|
424
|
+
return options;
|
|
425
|
+
}
|
|
426
|
+
/** Mark selected mutation fields whose dash values are literal transport data. */
|
|
427
|
+
export function preserveMutationStdinTokenFields(options, fields) {
|
|
428
|
+
const current = literalStdinTokenFields.get(options);
|
|
429
|
+
if (current === ALL_MUTATION_STDIN_FIELDS)
|
|
430
|
+
return options;
|
|
431
|
+
literalStdinTokenFields.set(options, new Set([...(current ?? []), ...fields]));
|
|
432
|
+
return options;
|
|
433
|
+
}
|
|
434
|
+
/** Copy the complete mutation stdin-token policy across an option clone. */
|
|
435
|
+
export function transferMutationStdinTokenPolicy(source, target) {
|
|
436
|
+
const policy = literalStdinTokenFields.get(source);
|
|
437
|
+
if (policy === undefined)
|
|
438
|
+
return target;
|
|
439
|
+
literalStdinTokenFields.set(target, policy === ALL_MUTATION_STDIN_FIELDS ? policy : new Set(policy));
|
|
440
|
+
return target;
|
|
441
|
+
}
|
|
442
|
+
/** Add a source mutation stdin-token policy without weakening the target. */
|
|
443
|
+
export function overlayMutationStdinTokenPolicy(source, target) {
|
|
444
|
+
const sourcePolicy = literalStdinTokenFields.get(source);
|
|
445
|
+
const targetPolicy = literalStdinTokenFields.get(target);
|
|
446
|
+
if (sourcePolicy === undefined ||
|
|
447
|
+
targetPolicy === ALL_MUTATION_STDIN_FIELDS) {
|
|
448
|
+
return target;
|
|
449
|
+
}
|
|
450
|
+
if (sourcePolicy === ALL_MUTATION_STDIN_FIELDS) {
|
|
451
|
+
literalStdinTokenFields.set(target, sourcePolicy);
|
|
452
|
+
return target;
|
|
453
|
+
}
|
|
454
|
+
literalStdinTokenFields.set(target, new Set([...(targetPolicy ?? []), ...sourcePolicy]));
|
|
455
|
+
return target;
|
|
456
|
+
}
|
|
457
|
+
/** Report whether lifecycle input should interpret dash values as stdin tokens. */
|
|
458
|
+
export function shouldResolveMutationStdinTokens(options) {
|
|
459
|
+
return literalStdinTokenFields.get(options) !== ALL_MUTATION_STDIN_FIELDS;
|
|
460
|
+
}
|
|
461
|
+
/** Report whether one mutation field should interpret dash as a stdin token. */
|
|
462
|
+
export function shouldResolveMutationStdinTokenField(options, field) {
|
|
463
|
+
const literalFields = literalStdinTokenFields.get(options);
|
|
464
|
+
return (literalFields !== ALL_MUTATION_STDIN_FIELDS && !literalFields?.has(field));
|
|
465
|
+
}
|
|
466
|
+
/** Refuse competing stdin-token fields before any resolver starts reading. */
|
|
467
|
+
export function assertSingleStdinTokenConsumer(candidates) {
|
|
468
|
+
let stdinConsumerOption;
|
|
469
|
+
for (const candidate of candidates) {
|
|
470
|
+
if (candidate.resolveToken === false || candidate.value === undefined) {
|
|
471
|
+
continue;
|
|
472
|
+
}
|
|
473
|
+
const values = Array.isArray(candidate.value)
|
|
474
|
+
? candidate.value
|
|
475
|
+
: [candidate.value];
|
|
476
|
+
const tokenCount = values.filter((value) => value.trim() === STDIN_TOKEN).length;
|
|
477
|
+
if (tokenCount > 1) {
|
|
478
|
+
throw new PmCliError(`${candidate.optionName} accepts "${STDIN_TOKEN}" stdin token at most once per command invocation`, EXIT_CODE.USAGE);
|
|
479
|
+
}
|
|
480
|
+
if (tokenCount === 0)
|
|
481
|
+
continue;
|
|
482
|
+
if (stdinConsumerOption !== undefined &&
|
|
483
|
+
stdinConsumerOption !== candidate.optionName) {
|
|
484
|
+
throw new PmCliError(`Only one option may use "${STDIN_TOKEN}" stdin token per command invocation. Already used by ${stdinConsumerOption}.`, EXIT_CODE.USAGE);
|
|
485
|
+
}
|
|
486
|
+
stdinConsumerOption = candidate.optionName;
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
/** Resolve a typed mutation option bag only after its complete stdin plan is conflict-free. */
|
|
490
|
+
export async function resolveMutationStdinTokenFields(options, scalarFields, listFields) {
|
|
491
|
+
const source = options;
|
|
492
|
+
const definitions = [...scalarFields, ...listFields];
|
|
493
|
+
assertSingleStdinTokenConsumer(definitions.map(([field, optionName]) => ({
|
|
494
|
+
value: source[field],
|
|
495
|
+
optionName,
|
|
496
|
+
resolveToken: shouldResolveMutationStdinTokenField(options, field),
|
|
497
|
+
})));
|
|
498
|
+
const stdinResolver = createStdinTokenResolver();
|
|
499
|
+
const resolved = { ...source };
|
|
500
|
+
for (const [field, optionName] of scalarFields) {
|
|
501
|
+
resolved[field] = await stdinResolver.resolveValue(source[field], optionName, shouldResolveMutationStdinTokenField(options, field));
|
|
502
|
+
}
|
|
503
|
+
for (const [field, optionName] of listFields) {
|
|
504
|
+
resolved[field] = await stdinResolver.resolveList(source[field], optionName, shouldResolveMutationStdinTokenField(options, field));
|
|
505
|
+
}
|
|
506
|
+
return preserveMutationStdinTokenLiterals(resolved);
|
|
507
|
+
}
|
|
419
508
|
/** Implements create stdin token resolver for the public runtime surface of this module. */
|
|
420
509
|
export function createStdinTokenResolver() {
|
|
421
510
|
let stdinValuePromise;
|
|
@@ -430,7 +519,9 @@ export function createStdinTokenResolver() {
|
|
|
430
519
|
}
|
|
431
520
|
return await stdinValuePromise;
|
|
432
521
|
};
|
|
433
|
-
const resolveValue = async (value, optionName) => {
|
|
522
|
+
const resolveValue = async (value, optionName, resolveToken = true) => {
|
|
523
|
+
if (!resolveToken)
|
|
524
|
+
return value;
|
|
434
525
|
if (value === undefined) {
|
|
435
526
|
return undefined;
|
|
436
527
|
}
|
|
@@ -439,7 +530,9 @@ export function createStdinTokenResolver() {
|
|
|
439
530
|
}
|
|
440
531
|
return await consumeStdin(optionName);
|
|
441
532
|
};
|
|
442
|
-
const resolveList = async (values, optionName) => {
|
|
533
|
+
const resolveList = async (values, optionName, resolveToken = true) => {
|
|
534
|
+
if (!resolveToken)
|
|
535
|
+
return values;
|
|
443
536
|
if (!values) {
|
|
444
537
|
return undefined;
|
|
445
538
|
}
|
|
@@ -486,4 +579,4 @@ export const _testOnly = {
|
|
|
486
579
|
parseMarkdownKeyValueLines,
|
|
487
580
|
};
|
|
488
581
|
//# sourceMappingURL=parse.js.map
|
|
489
|
-
//# debugId=
|
|
582
|
+
//# debugId=2252cfb9-37ea-57f1-b7ea-2b0c0f87ecb2
|
package/dist/mcp/server.d.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { readRequiredString,
|
|
2
|
+
import { readRequiredString, type PmActionInput } from "../sdk/runtime.js";
|
|
3
3
|
interface JsonRpcRequest {
|
|
4
4
|
jsonrpc?: string;
|
|
5
5
|
id?: string | number | null;
|
|
6
6
|
method?: string;
|
|
7
7
|
params?: Record<string, unknown>;
|
|
8
8
|
}
|
|
9
|
+
declare function runMcpAction(args: PmActionInput): Promise<unknown>;
|
|
9
10
|
declare function nearestDeclaredKey(unexpected: string, declared: string[]): string | undefined;
|
|
10
11
|
declare function detectUnexpectedTopLevelKeys(toolName: string, args: Record<string, unknown>, toolDeclaredKeys?: Map<string, string[]>): string[];
|
|
11
12
|
declare function collectMutationGuardWarnings(toolName: string, action: string | undefined, args: Record<string, unknown>): Promise<string[]>;
|
|
@@ -53,7 +54,7 @@ export declare const _testOnly: {
|
|
|
53
54
|
readonly readScalarString: typeof import("../sdk/runtime-input.js").readRuntimeScalarString;
|
|
54
55
|
readonly readScalarStringAllowBlank: typeof import("../sdk/runtime-input.js").readRuntimeScalarStringAllowBlank;
|
|
55
56
|
readonly readStringArray: typeof import("../sdk/runtime-input.js").readRuntimeStringArray;
|
|
56
|
-
runAction: typeof
|
|
57
|
+
runAction: typeof runMcpAction;
|
|
57
58
|
readonly updateManyOptionsFromFlat: typeof import("../sdk/runtime-input.js").updateManyOptionsFromFlat;
|
|
58
59
|
readonly withAddNoteOption: typeof import("../sdk/runtime-input.js").withAddNoteOption;
|
|
59
60
|
readonly withFilesDiscoveryOptions: typeof import("../sdk/runtime-input.js").withFilesDiscoveryOptions;
|
package/dist/mcp/server.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* Runs the MCP server adapter that exposes pm actions and contracts to external agents.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
8
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="8ce8addc-e47e-5bb9-8a94-0959a1a535e9")}catch(e){}}();
|
|
9
9
|
import { realpathSync } from "node:fs";
|
|
10
10
|
import { readFile } from "node:fs/promises";
|
|
11
11
|
import path from "node:path";
|
|
@@ -18,11 +18,14 @@ import { NARROW_TOOL_ACTIONS, TOOLS } from "./tool-definitions.js";
|
|
|
18
18
|
import { normalizeWorkspaceToolArguments, resolveMcpToolAccess, resolveMcpToolSurface, } from "./runtime-capabilities.js";
|
|
19
19
|
import { PM_MCP_PROMPT_CONTRACTS, PM_MCP_RESOURCE_CONTRACTS, } from "../sdk/agent-capability-contracts.js";
|
|
20
20
|
import { commitItemMutations } from "../sdk/item-transaction.js";
|
|
21
|
-
import { isRuntimeRecord } from "../sdk/runtime-input.js";
|
|
21
|
+
import { isRuntimeRecord, markMcpMutationTransportInput, } from "../sdk/runtime-input.js";
|
|
22
22
|
import { attachOutputTokenAccounting } from "../sdk/output-token-accounting.js";
|
|
23
23
|
import { createReproducibleProcessRunner, runWithReproducibleProcessEnvironment, } from "../sdk/reproducibility/process.js";
|
|
24
24
|
import { parseAtomicMutationControls, resolveItemMutationDocument, } from "../sdk/structured-mutations.js";
|
|
25
25
|
import { resolveAuthor, resolvePmRoot } from "../sdk/runtime-primitives.js";
|
|
26
|
+
function runMcpAction(args) {
|
|
27
|
+
return runAction(markMcpMutationTransportInput(args));
|
|
28
|
+
}
|
|
26
29
|
const PM_PACKAGE_ROOT_ENV = "PM_CLI_PACKAGE_ROOT";
|
|
27
30
|
function resolvePmPackageRoot() {
|
|
28
31
|
return fileURLToPath(new URL("../..", import.meta.url));
|
|
@@ -97,7 +100,7 @@ function detectUnexpectedTopLevelKeys(toolName, args, toolDeclaredKeys = declare
|
|
|
97
100
|
return warnings;
|
|
98
101
|
}
|
|
99
102
|
const HANDLERS = {
|
|
100
|
-
pm_run: (args) =>
|
|
103
|
+
pm_run: (args) => runMcpAction(args),
|
|
101
104
|
pm_mutate: async (args) => {
|
|
102
105
|
const transactionId = readRequiredString(args, "transactionId");
|
|
103
106
|
const controls = parseAtomicMutationControls(args);
|
|
@@ -138,7 +141,7 @@ const HANDLERS = {
|
|
|
138
141
|
},
|
|
139
142
|
...Object.fromEntries(Object.entries(NARROW_TOOL_ACTIONS).map(([tool, action]) => [
|
|
140
143
|
tool,
|
|
141
|
-
(args) =>
|
|
144
|
+
(args) => runMcpAction({ ...args, action }),
|
|
142
145
|
])),
|
|
143
146
|
};
|
|
144
147
|
/** Resolve the pm action a tools/call invocation will dispatch, when knowable. */
|
|
@@ -353,10 +356,10 @@ async function readWorkspaceResource(uri, params) {
|
|
|
353
356
|
}
|
|
354
357
|
let value;
|
|
355
358
|
if (uri === "pm://workspace/context") {
|
|
356
|
-
value = await
|
|
359
|
+
value = await runMcpAction({ ...args, action: "context", limit: 10 });
|
|
357
360
|
}
|
|
358
361
|
else if (uri === "pm://workspace/claims") {
|
|
359
|
-
value = await
|
|
362
|
+
value = await runMcpAction({
|
|
360
363
|
...args,
|
|
361
364
|
action: "list",
|
|
362
365
|
status: "in_progress",
|
|
@@ -364,7 +367,11 @@ async function readWorkspaceResource(uri, params) {
|
|
|
364
367
|
});
|
|
365
368
|
}
|
|
366
369
|
else if (uri === "pm://workspace/focus") {
|
|
367
|
-
value = await
|
|
370
|
+
value = await runMcpAction({
|
|
371
|
+
...args,
|
|
372
|
+
action: "focus",
|
|
373
|
+
subcommand: "show",
|
|
374
|
+
});
|
|
368
375
|
}
|
|
369
376
|
else {
|
|
370
377
|
const guidePath = path.join(cwd, "AGENTS.md");
|
|
@@ -621,7 +628,7 @@ export const _testOnly = {
|
|
|
621
628
|
get readStringArray() {
|
|
622
629
|
return readRuntimeTestHook("readStringArray");
|
|
623
630
|
},
|
|
624
|
-
runAction,
|
|
631
|
+
runAction: runMcpAction,
|
|
625
632
|
get updateManyOptionsFromFlat() {
|
|
626
633
|
return readRuntimeTestHook("updateManyOptionsFromFlat");
|
|
627
634
|
},
|
|
@@ -642,4 +649,4 @@ if (isInvokedAsMcpMainModule(process.argv[1], import.meta.url)) {
|
|
|
642
649
|
}
|
|
643
650
|
/* c8 ignore stop */
|
|
644
651
|
//# sourceMappingURL=server.js.map
|
|
645
|
-
//# debugId=
|
|
652
|
+
//# debugId=8ce8addc-e47e-5bb9-8a94-0959a1a535e9
|