@unbrained/pm-cli 2026.8.25 → 2026.8.27
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/.agents/skills/HARNESS_COMPATIBILITY.md +32 -0
- package/.agents/skills/README.md +47 -0
- package/.agents/skills/pm-developer/SKILL.md +117 -0
- package/.agents/skills/pm-developer/references/COMMAND_PLAYBOOK.md +49 -0
- package/.agents/skills/pm-developer/references/GRAPH_AND_RELATIONSHIPS.md +91 -0
- package/.agents/skills/pm-developer/references/MULTI_AGENT_MERGE.md +72 -0
- package/.agents/skills/pm-developer/references/PROMPTS.md +17 -0
- package/.agents/skills/pm-developer/references/SCRIPTING_COMPOSITION.md +82 -0
- package/.agents/skills/pm-developer/references/TOKEN_BUDGETS.md +85 -0
- package/.agents/skills/pm-extensions/SKILL.md +106 -0
- package/.agents/skills/pm-extensions/references/AUTHORING.md +95 -0
- package/.agents/skills/pm-extensions/references/LIFECYCLE.md +40 -0
- package/.agents/skills/pm-extensions/references/TROUBLESHOOTING.md +25 -0
- package/.agents/skills/pm-sdk/SKILL.md +107 -0
- package/.agents/skills/pm-sdk/references/DOMAIN_MODELING.md +78 -0
- package/.agents/skills/pm-sdk/references/INTEGRATION_CHECKLIST.md +31 -0
- package/.agents/skills/pm-sdk/references/PROMPTS.md +13 -0
- package/.agents/skills/pm-sdk/references/SURFACE_MAP.md +82 -0
- package/.agents/skills/pm-user/SKILL.md +111 -0
- package/.agents/skills/pm-user/references/BACKLOG_SHAPING.md +105 -0
- package/.agents/skills/pm-user/references/PROMPTS.md +17 -0
- package/.agents/skills/pm-user/references/WORKFLOWS.md +35 -0
- package/.claude-plugin/marketplace.json +2 -2
- package/CHANGELOG.md +58 -3
- package/README.md +8 -5
- package/dist/cli/commander-usage.js +11 -7
- package/dist/cli/error-guidance.js +3 -3
- package/dist/cli/help-content.d.ts +2 -0
- package/dist/cli/help-content.js +53 -17
- package/dist/cli/help-json-payload.d.ts +8 -2
- package/dist/cli/help-json-payload.js +46 -12
- package/dist/cli/main.js +52 -74
- package/dist/cli/register-annotations.js +27 -21
- package/dist/cli/register-setup.js +98 -57
- package/dist/cli-bundle/bundle-manifest.json +156 -156
- package/dist/cli-bundle/chunks/chunk-3OO3W6FW.js +202 -0
- package/dist/cli-bundle/chunks/chunk-52EKTW6V.js +3 -0
- package/dist/cli-bundle/chunks/{chunk-QLUORNIB.js → chunk-CVBBGWW5.js} +62 -44
- package/dist/cli-bundle/chunks/chunk-MFNTKMTI.js +13 -0
- package/dist/cli-bundle/chunks/chunk-OS27HHBN.js +35 -0
- package/dist/cli-bundle/chunks/chunk-QTO7USTH.js +2 -0
- package/dist/cli-bundle/chunks/{chunk-5I5RWIJC.js → chunk-R4ETAOJC.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-OWHNAR2B.js → chunk-SH6P7FXI.js} +2 -2
- package/dist/cli-bundle/chunks/chunk-SHMDY36D.js +8 -0
- package/dist/cli-bundle/chunks/{chunk-244MI4GS.js → chunk-SKXLJIEK.js} +60 -60
- package/dist/cli-bundle/chunks/chunk-TNX6HC54.js +3 -0
- package/dist/cli-bundle/chunks/{register-list-query-XVN2ZLI7.js → register-list-query-EUWM6VII.js} +2 -2
- package/dist/cli-bundle/chunks/{register-mutation-QCKAEGIJ.js → register-mutation-FD4HSAVU.js} +4 -4
- package/dist/cli-bundle/chunks/{register-operations-SDEAXE7E.js → register-operations-HRMNFEC3.js} +2 -2
- package/dist/cli-bundle/chunks/register-setup-33GNICLX.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-IBZZZGK3.js → chunk-2AGZ5BRT.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-4BR5UU52.js +50 -0
- package/dist/cli-bundle/focused-chunks/{chunk-OHIHZ7HS.js → chunk-6GCRSLPG.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-OVJL6NZE.js → chunk-AD6ULRAF.js} +4 -4
- package/dist/cli-bundle/focused-chunks/{chunk-7YCDTCBC.js → chunk-AQ5IYEZZ.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-YO3ZF3FI.js → chunk-EKX37ZHA.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-N7W67YIG.js → chunk-FC2AXLB5.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-H5JZEIQV.js → chunk-HC7ODMH3.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-NOOZGIXP.js → chunk-HVQ22RC4.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-A644DUFQ.js → chunk-MEASX544.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-RAFKLNZX.js → chunk-MXTYGECH.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-2UIWOP3O.js → chunk-SUBSWYW3.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-VXWATRFL.js → chunk-XDPYBQCF.js} +9 -9
- package/dist/cli-bundle/focused-chunks/{chunk-XUQPEKRN.js → chunk-Y3JJXRVK.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-GQR3WH3F.js → chunk-Y5A7SJJ7.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-YHWHX6YY.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-ONYQCALA.js → chunk-YVVZ3LQ6.js} +6 -6
- package/dist/cli-bundle/focused-chunks/chunk-Z2USIBR2.js +5 -0
- package/dist/cli-bundle/main.js +15 -14
- 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 +31 -31
- package/dist/cli-bundle/sdk-governance.js +1 -1
- package/dist/cli-bundle/sdk-graph.js +1 -1
- package/dist/cli-bundle/sdk-merge.js +31 -31
- 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 +32 -6
- package/dist/core/extensions/manifest-schema.d.ts +20 -0
- package/dist/core/extensions/manifest-schema.js +28 -10
- package/dist/core/governance/issue-codes.d.ts +11 -2
- package/dist/core/governance/issue-codes.js +29 -10
- package/dist/core/item/item-format.js +3 -3
- package/dist/core/store/item-store.js +12 -5
- package/dist/mcp/http-server.d.ts +60 -0
- package/dist/mcp/http-server.js +451 -0
- package/dist/mcp/legacy-adapter.d.ts +50 -0
- package/dist/mcp/legacy-adapter.js +64 -0
- package/dist/mcp/server.d.ts +42 -9
- package/dist/mcp/server.js +572 -59
- package/dist/mcp/tool-definitions.d.ts +2 -0
- package/dist/mcp/tool-definitions.js +2 -2
- package/dist/sdk/agent/closed-domain-contracts.d.ts +1 -1
- package/dist/sdk/agent/closed-domain-contracts.js +24 -2
- package/dist/sdk/agent/refusal-closure-census.d.ts +6 -2
- package/dist/sdk/agent/refusal-closure-census.js +16 -8
- package/dist/sdk/agent-capability-contracts.js +6 -2
- package/dist/sdk/cli-bootstrap.js +3 -2
- package/dist/sdk/cli-contracts/command-aliases.js +15 -2
- package/dist/sdk/cli-contracts/enum-contracts.d.ts +4 -1
- package/dist/sdk/cli-contracts/enum-contracts.js +7 -2
- package/dist/sdk/cli-contracts/flag-contracts.js +9 -5
- package/dist/sdk/cli-contracts/grammar-contracts.d.ts +3 -3
- package/dist/sdk/cli-contracts/grammar-contracts.js +24 -17
- package/dist/sdk/cli-contracts/runtime-contracts.js +13 -11
- package/dist/sdk/cli-contracts/tool-schema.js +18 -15
- package/dist/sdk/cli-contracts.d.ts +1 -1
- package/dist/sdk/cli-contracts.js +3 -3
- package/dist/sdk/cli-program.js +3 -2
- package/dist/sdk/completion.js +40 -13
- package/dist/sdk/compose.d.ts +4 -1
- package/dist/sdk/compose.js +23 -36
- package/dist/sdk/extension/author-manifest.d.ts +22 -0
- package/dist/sdk/extension/author-manifest.js +93 -0
- package/dist/sdk/extension.js +6 -3
- package/dist/sdk/generated/generated-error-code-catalog-part-1.js +20 -5
- package/dist/sdk/generated/generated-error-code-catalog-part-2.js +18 -3
- package/dist/sdk/governance/health.js +7 -2
- package/dist/sdk/governance/upgrade.d.ts +2 -0
- package/dist/sdk/governance/upgrade.js +30 -8
- package/dist/sdk/governance/validate.js +8 -6
- package/dist/sdk/guide-topics.js +6 -6
- package/dist/sdk/index.d.ts +10 -2
- package/dist/sdk/index.js +11 -3
- package/dist/sdk/mcp/apps.d.ts +70 -0
- package/dist/sdk/mcp/apps.js +154 -0
- package/dist/sdk/mcp/authorization.d.ts +134 -0
- package/dist/sdk/mcp/authorization.js +405 -0
- package/dist/sdk/mcp/interactions.d.ts +118 -0
- package/dist/sdk/mcp/interactions.js +337 -0
- package/dist/sdk/mcp/protocol.d.ts +142 -0
- package/dist/sdk/mcp/protocol.js +174 -0
- package/dist/sdk/mcp/skills.d.ts +127 -0
- package/dist/sdk/mcp/skills.js +390 -0
- package/dist/sdk/mcp/subscriptions.d.ts +65 -0
- package/dist/sdk/mcp/subscriptions.js +212 -0
- package/dist/sdk/mcp/tasks.d.ts +107 -0
- package/dist/sdk/mcp/tasks.js +431 -0
- package/dist/sdk/mcp/transport.d.ts +30 -0
- package/dist/sdk/mcp/transport.js +261 -0
- package/dist/sdk/merge/receipts.d.ts +16 -0
- package/dist/sdk/merge/receipts.js +9 -8
- package/dist/sdk/read-output-contracts.js +16 -3
- package/dist/sdk/runtime-action-aliases.js +7 -3
- package/dist/sdk/runtime-input.js +12 -4
- package/dist/sdk/runtime-primitives.d.ts +2 -2
- package/dist/sdk/runtime-primitives.js +4 -4
- package/dist/sdk/test/execution.d.ts +6 -0
- package/dist/sdk/test/execution.js +32 -3
- package/docs/AGENT_PROVENANCE_ADR.md +6 -4
- package/docs/AGENT_RUNTIME_PRIMITIVES.md +6 -5
- package/docs/CLAUDE_CODE_PLUGIN.md +12 -5
- package/docs/CLI_GRAMMAR.md +7 -1
- package/docs/COMMANDS.md +2 -2
- package/docs/DIAGNOSTIC_OUTPUT_CONTRACTS.md +8 -0
- package/docs/EXTENSIONS.md +36 -36
- package/docs/MCP_2026_07_28.md +160 -0
- package/docs/MCP_2026_07_28_CONFORMANCE.md +30 -0
- package/docs/MCP_REMOTE_TRANSPORT_SECURITY.md +180 -0
- package/docs/MCP_SKILLS_AND_APPS.md +107 -0
- package/docs/QUICKSTART.md +15 -15
- package/docs/README.md +5 -0
- package/docs/RELEASING.md +12 -3
- package/docs/SDK.md +22 -1
- package/docs/SDK_AGENT_SESSION_CONTEXT.md +18 -13
- package/docs/SDK_CONTEXT_INTEGRITY.md +6 -0
- package/docs/SDK_EVIDENCE_TRACEABILITY.md +9 -1
- package/docs/SDK_MCP_INTERACTIONS.md +227 -0
- package/docs/TESTING.md +4 -0
- package/docs/generated/AGENT_CAPABILITY_ROUTING.md +1 -1
- package/docs/generated/REFUSAL_CLOSURE_CENSUS.md +13 -11
- package/marketplace.json +2 -2
- package/package.json +15 -11
- package/packages/pm-beads/README.md +12 -6
- package/packages/pm-beads/docs/MIGRATION.md +53 -0
- package/packages/pm-beads/extensions/beads/index.ts +8 -0
- package/packages/pm-beads/extensions/beads/runtime.ts +671 -112
- 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/finalize-build.mjs +1 -0
- package/sdk/public-surface.json +902 -54
- package/dist/cli-bundle/chunks/chunk-2F3LUFMW.js +0 -8
- package/dist/cli-bundle/chunks/chunk-65MHLHAA.js +0 -2
- package/dist/cli-bundle/chunks/chunk-6C7GIMIL.js +0 -13
- package/dist/cli-bundle/chunks/chunk-QKGMHGEI.js +0 -202
- package/dist/cli-bundle/chunks/chunk-T2ENPRXF.js +0 -3
- package/dist/cli-bundle/chunks/chunk-TPQIBSL2.js +0 -3
- package/dist/cli-bundle/chunks/chunk-YQMYF3YD.js +0 -35
- package/dist/cli-bundle/chunks/register-setup-LXVBRCJ3.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-42S3GGZ7.js +0 -50
- package/dist/cli-bundle/focused-chunks/chunk-7I23XGWO.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-LMKG3DFE.js +0 -5
|
@@ -73,9 +73,10 @@ Add to the project's `.mcp.json`:
|
|
|
73
73
|
```
|
|
74
74
|
|
|
75
75
|
The repo root `.mcp.json` uses this approach and activates automatically when
|
|
76
|
-
Claude Code opens this repository.
|
|
77
|
-
|
|
78
|
-
|
|
76
|
+
Claude Code opens this repository. Under MCP `2026-07-28`, every request carries
|
|
77
|
+
the protocol version, client capabilities, and client identity in `_meta`, so
|
|
78
|
+
pm's bounded identity detector does not depend on session state and normal
|
|
79
|
+
agent mutations do not need a hard-wired `PM_AUTHOR`.
|
|
79
80
|
|
|
80
81
|
## MCP Server Launcher
|
|
81
82
|
|
|
@@ -115,7 +116,10 @@ node scripts/smoke-claude-plugin.mjs
|
|
|
115
116
|
pnpm smoke:claude-plugin
|
|
116
117
|
```
|
|
117
118
|
|
|
118
|
-
Verifies: plugin file structure, manifest name consistency, MCP
|
|
119
|
+
Verifies: plugin file structure, manifest name consistency, stateless MCP
|
|
120
|
+
discovery for `2026-07-28`, 31 tools present, full workflow (init → create →
|
|
121
|
+
claim → update → link files/docs/tests → get → context → search → validate →
|
|
122
|
+
health), and session-start hook.
|
|
119
123
|
|
|
120
124
|
### MCP server smoke test
|
|
121
125
|
|
|
@@ -182,7 +186,10 @@ After installing the plugin:
|
|
|
182
186
|
|
|
183
187
|
The authoritative plugin version is `plugins/pm-claude/.claude-plugin/plugin.json`; this row stays on the `1.x` major line so it does not drift with each plugin release.
|
|
184
188
|
|
|
185
|
-
The MCP server uses JSON-RPC 2.0 over stdio with protocol version
|
|
189
|
+
The MCP server uses JSON-RPC 2.0 over stdio with canonical protocol version
|
|
190
|
+
`2026-07-28`. A bounded legacy path remains for unversioned older hosts, with
|
|
191
|
+
`2025-06-18` initialize available to enrich client identity; current hosts
|
|
192
|
+
discover the server and send metadata on every request.
|
|
186
193
|
|
|
187
194
|
## Extension Policy Diagnostics
|
|
188
195
|
|
package/docs/CLI_GRAMMAR.md
CHANGED
|
@@ -1,11 +1,17 @@
|
|
|
1
1
|
# Noun–Verb CLI Grammar and Compatibility Policy
|
|
2
2
|
|
|
3
|
-
Tracked by [pm-pbyu](../.agents/pm/decisions/pm-pbyu.toon), implemented through [pm-0z7n](../.agents/pm/features/pm-0z7n.toon), [pm-pfqi](../.agents/pm/tasks/pm-pfqi.toon), [pm-yy8rmx](../.agents/pm/tasks/pm-yy8rmx.toon),
|
|
3
|
+
Tracked by [pm-pbyu](../.agents/pm/decisions/pm-pbyu.toon), implemented through [pm-0z7n](../.agents/pm/features/pm-0z7n.toon), [pm-pfqi](../.agents/pm/tasks/pm-pfqi.toon), [pm-yy8rmx](../.agents/pm/tasks/pm-yy8rmx.toon), [pm-wt43zj](../.agents/pm/tasks/pm-wt43zj.toon), [pm-e2bq](../.agents/pm/features/pm-e2bq.toon), and [pm-yql1](../.agents/pm/tasks/pm-yql1.toon).
|
|
4
4
|
|
|
5
5
|
## Agent Quick Context
|
|
6
6
|
|
|
7
7
|
Use the canonical noun-first form when generating commands. Existing spellings remain executable, but deprecated compatibility aliases are absent from default help and completion discovery and emit one migration hint on stderr. Machine clients can read alias lifecycle and replacement tokens from `pm contracts --full --json`.
|
|
8
8
|
|
|
9
|
+
Default `pm --help` stays within the core one-screen budget. Use
|
|
10
|
+
`pm help --all` for every public command or `pm help --all --json` for the same
|
|
11
|
+
surface with per-command visibility/family metadata and the complete alias
|
|
12
|
+
lifecycle table. `--explain` also expands command discovery while adding the
|
|
13
|
+
detailed narrative.
|
|
14
|
+
|
|
9
15
|
The first completed consolidation is the list family:
|
|
10
16
|
|
|
11
17
|
```bash
|
package/docs/COMMANDS.md
CHANGED
|
@@ -178,7 +178,7 @@ As a read-only structured surface, `duplicates` accepts the universal output
|
|
|
178
178
|
controls, including `--output-format json`, `--lean`, projection/amount
|
|
179
179
|
controls, and token accounting, while its default TOON output remains bounded.
|
|
180
180
|
Tracked by [pm-gh1076](../.agents/pm/issues/pm-gh1076.toon).
|
|
181
|
-
Use `pm get <id>` to read a single item by ID — the single-item read primitive used throughout the agent loop. It accepts `--fields <list>` and `--depth brief|standard|deep|full` for token-minimal projections, and `--tree`/`--tree-depth <n>` to include descendants. Standard/deep reads expose a normalized `schedule` facet (`deadline`, `start_at`, `end_at`, `location`, reminders, and events) when scheduling metadata exists. Container-oriented built-ins (Epic, Feature, Milestone, and Plan) plus custom types automatically expose type-agnostic child counts and continuation metadata. Standard depth keeps that rollup counts-only; `--depth deep|full` or an explicit `--fields id,children` request adds the deterministic bounded child sample. Built-in leaf reads avoid a workspace scan unless children are explicitly requested. `pm get <id> --json` returns the `body` inside the `item` object (`.item.body`); see [Full results, totals, and bodies](#full-results-totals-and-bodies). To duplicate an existing item as a starting point, `pm copy <id> --title "New title"` clones it into a fresh id with lifecycle fields reset.
|
|
181
|
+
Use `pm get <id>` to read a single item by ID — the single-item read primitive used throughout the agent loop. It accepts `--fields <list>` and `--depth brief|standard|deep|full` for token-minimal projections, and `--tree`/`--tree-depth <n>` to include descendants. The universal `--output-include` selector can request stored collections directly, for example `pm get <id> --output-include comments,learnings,tests`; the same bare and `item.<field>` grammar works through CLI, SDK, and MCP transports. Standard/deep reads expose a normalized `schedule` facet (`deadline`, `start_at`, `end_at`, `location`, reminders, and events) when scheduling metadata exists. Container-oriented built-ins (Epic, Feature, Milestone, and Plan) plus custom types automatically expose type-agnostic child counts and continuation metadata. Standard depth keeps that rollup counts-only; `--depth deep|full` or an explicit `--fields id,children` request adds the deterministic bounded child sample. Built-in leaf reads avoid a workspace scan unless children are explicitly requested. `pm get <id> --json` returns the `body` inside the `item` object (`.item.body`); see [Full results, totals, and bodies](#full-results-totals-and-bodies). To duplicate an existing item as a starting point, `pm copy <id> --title "New title"` clones it into a fresh id with lifecycle fields reset.
|
|
182
182
|
|
|
183
183
|
When the strongest duplicate match is terminal because the same work recurred,
|
|
184
184
|
reuse its lineage instead of creating or copying another item:
|
|
@@ -743,7 +743,7 @@ pm notes <id> --add "Keep renderer changes isolated to TOON output."
|
|
|
743
743
|
pm learnings <id> --add "Use runtime contracts instead of duplicating flag lists."
|
|
744
744
|
```
|
|
745
745
|
|
|
746
|
-
Use comments for progress and evidence, notes for implementation context, and learnings for durable future guidance. `--
|
|
746
|
+
Use comments for progress and evidence, notes for implementation context, and learnings for durable future guidance. All three accept `--text` as a hidden compatibility alias for canonical `--add`; comments also retain `--body`/`--comment`, and notes retain `--note`. Choose exactly one input source (`[text]`, an add alias, `--stdin`, or `--file`) per invocation. Conflicting alias values fail before mutation. To clean up obsolete orchestration notes, `--edit <index>` rewrites the comment at a 1-based index and `--delete <index>` removes it; both record history and honor ownership rules.
|
|
747
747
|
|
|
748
748
|
## Linked Artifacts
|
|
749
749
|
|
|
@@ -103,6 +103,14 @@ refusal; schema, items, history, settings, and package state must not change.
|
|
|
103
103
|
Ephemeral runtime lock/cache directories are excluded from that semantic
|
|
104
104
|
snapshot.
|
|
105
105
|
|
|
106
|
+
The complete error-code census currently retains executable evidence for 18
|
|
107
|
+
catalog rows across 17 canonical groups. Two of those rows are author-manifest
|
|
108
|
+
schema findings reached through a real `pm health --full --strict-exit --json`
|
|
109
|
+
process: an unknown top-level key and omitted canonical pm version bounds. The
|
|
110
|
+
remaining rows stay explicit `uncovered` obligations in
|
|
111
|
+
[the generated census](generated/REFUSAL_CLOSURE_CENSUS.md); the ratchet does not
|
|
112
|
+
turn partial catalog closure into an approval claim.
|
|
113
|
+
|
|
106
114
|
Run the focused proof with:
|
|
107
115
|
|
|
108
116
|
```bash
|
package/docs/EXTENSIONS.md
CHANGED
|
@@ -1,48 +1,48 @@
|
|
|
1
1
|
# Packages and Extensions
|
|
2
2
|
|
|
3
|
-
Extension flags declared with `list: true` accumulate repeated long/short alias occurrences and comma-separated values into one array. Dynamic commands preserve flag-like variadic content after `--`, and package handlers can use the public `suppressHostOutput()` protocol when they already emitted streaming, binary, or pre-rendered output. Declarative blueprints are also checked for reserved item-field collisions during SDK lint/preflight and harness activation, so a package cannot pass author-time validation and then fail only when users create or update items. Local archive installation, command ownership,
|
|
3
|
+
Extension flags declared with `list: true` accumulate repeated long/short alias occurrences and comma-separated values into one array. Dynamic commands preserve flag-like variadic content after `--`, and package handlers can use the public `suppressHostOutput()` protocol when they already emitted streaming, binary, or pre-rendered output. Declarative blueprints are also checked for reserved item-field collisions during SDK lint/preflight and harness activation, so a package cannot pass author-time validation and then fail only when users create or update items. Local archive installation, command ownership, MCP custom-field diagnostics, and author-manifest schema diagnostics are tracked by [pm-lw6acw](../.agents/pm/issues/pm-lw6acw.toon), [pm-6z0wzf](../.agents/pm/issues/pm-6z0wzf.toon), [pm-yfdav2](../.agents/pm/issues/pm-yfdav2.toon), and [pm-gh1091](../.agents/pm/issues/pm-gh1091.toon). Transactional mutation guards, host-bound command test SDKs, and installed custom-type lifecycle parity are tracked by [pm-hx23u5](../.agents/pm/issues/pm-hx23u5.toon), [pm-wx2lr5](../.agents/pm/issues/pm-wx2lr5.toon), and [pm-scga6k](../.agents/pm/issues/pm-scga6k.toon). Durable migration application, explicit source resolution, and composable preflight ownership are covered in [Extension Lifecycle Contracts](EXTENSION_LIFECYCLE.md).
|
|
4
4
|
|
|
5
5
|
Packages add optional `pm` workflows without changing the core CLI. A package can ship one or more runtime extensions plus metadata such as docs and examples. Prefer the package-first commands in new docs and automation:
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
8
|
pm package init ./my-package
|
|
9
9
|
pm package init ./my-hook-package --capability hooks
|
|
10
|
-
pm install ./my-package --project
|
|
10
|
+
pm package install ./my-package --project
|
|
11
11
|
pm package doctor --project --detail summary
|
|
12
12
|
pm package reload --project
|
|
13
|
-
pm upgrade --dry-run
|
|
13
|
+
pm package upgrade --dry-run
|
|
14
14
|
```
|
|
15
15
|
|
|
16
|
-
`pm extension ...`
|
|
16
|
+
Hidden `pm extension ...`, `pm install ...`, and `pm upgrade ...` aliases remain supported for compatibility. They execute the canonical package handlers, keep stdout machine-compatible, and emit one migration hint on stderr unless the public config key `ux_deprecation_hints` (stored at `ux.deprecation_hints`) is disabled. Related docs: [SDK](SDK.md), [Configuration](CONFIGURATION.md), [Testing](TESTING.md), [Command Reference](COMMANDS.md), [Extension Author Contracts](EXTENSION_AUTHOR_CONTRACTS.md).
|
|
17
17
|
|
|
18
18
|
## Package Sources
|
|
19
19
|
|
|
20
|
-
`pm install` accepts local, registry, and GitHub sources:
|
|
20
|
+
`pm package install` accepts local, registry, and GitHub sources:
|
|
21
21
|
|
|
22
22
|
```bash
|
|
23
|
-
pm install ./local-package --project
|
|
24
|
-
pm install /absolute/path/to/package --project
|
|
25
|
-
pm install ./my-package-1.2.3.tgz --project
|
|
26
|
-
pm install npm:./my-package-1.2.3.tar.gz --project
|
|
27
|
-
pm install npm:@scope/package --project
|
|
28
|
-
pm install npm:package@1.2.3 --project
|
|
29
|
-
pm install https://github.com/org/repo --project
|
|
30
|
-
pm install --github org/repo/path --ref main --project
|
|
23
|
+
pm package install ./local-package --project
|
|
24
|
+
pm package install /absolute/path/to/package --project
|
|
25
|
+
pm package install ./my-package-1.2.3.tgz --project
|
|
26
|
+
pm package install npm:./my-package-1.2.3.tar.gz --project
|
|
27
|
+
pm package install npm:@scope/package --project
|
|
28
|
+
pm package install npm:package@1.2.3 --project
|
|
29
|
+
pm package install https://github.com/org/repo --project
|
|
30
|
+
pm package install --github org/repo/path --ref main --project
|
|
31
31
|
```
|
|
32
32
|
|
|
33
33
|
Bundled first-party packages live under `packages/pm-*`:
|
|
34
34
|
|
|
35
35
|
```bash
|
|
36
36
|
pm package catalog --project
|
|
37
|
-
pm install all --project
|
|
38
|
-
pm install calendar --project
|
|
39
|
-
pm install search-advanced --project
|
|
40
|
-
pm install kanban --project
|
|
37
|
+
pm package install all --project
|
|
38
|
+
pm package install calendar --project
|
|
39
|
+
pm package install search-advanced --project
|
|
40
|
+
pm package install kanban --project
|
|
41
41
|
```
|
|
42
42
|
|
|
43
|
-
`pm install '*'
|
|
43
|
+
`pm package install '*'` and `pm package install all` are normalized to the same bundled install-all request. First-party package aliases come from each package manifest, with a fallback derived from the `packages/pm-*` directory name. A bare bundled alias that also names an installed npm package reports both explicit choices in `source_resolution`; see [Extension Lifecycle Contracts](EXTENSION_LIFECYCLE.md).
|
|
44
44
|
|
|
45
|
-
External registry packages are installed by exact package name. If `npm:<name>` returns a registry 404, JSON error output includes `fallback_candidates` and `next_best_command`; unpublished first-party packages fall back to `pm install --project github.com/unbraind/<name>`. Install results include package-owned `command_paths`, `action_paths`, `contributions`, `command_discovery`, and a light `verification` block covering the target tracker, activation status, registered commands/actions/item types, and health verdict. Agents should consume those fields instead of guessing from the package name or immediately spending another invocation on doctor. A successful activation persists the versioned contribution inventory in `.managed-extensions.json`; subsequent discovery can enumerate command handlers, hooks, parser/renderer targets, schema names, and the other registered surfaces without importing the package module. A failed runtime activation returns `ok: false`, `activated: false`, a non-zero CLI exit, and actionable diagnostics; missing SDK resolution adds an explicit dependency recovery step. Local installs are containment-safe when the extension destination is nested inside the source checkout: pm stages the package outside the source and prunes the destination, `.agents`, `node_modules`, and install-backup directories before copying, so reinstalling cannot recursively copy tracker history, host dependencies, or prior backups.
|
|
45
|
+
External registry packages are installed by exact package name. If `npm:<name>` returns a registry 404, JSON error output includes `fallback_candidates` and `next_best_command`; unpublished first-party packages fall back to `pm package install --project github.com/unbraind/<name>`. Install results include package-owned `command_paths`, `action_paths`, `contributions`, `command_discovery`, and a light `verification` block covering the target tracker, activation status, registered commands/actions/item types, and health verdict. Agents should consume those fields instead of guessing from the package name or immediately spending another invocation on doctor. A successful activation persists the versioned contribution inventory in `.managed-extensions.json`; subsequent discovery can enumerate command handlers, hooks, parser/renderer targets, schema names, and the other registered surfaces without importing the package module. A failed runtime activation returns `ok: false`, `activated: false`, a non-zero CLI exit, and actionable diagnostics; missing SDK resolution adds an explicit dependency recovery step. Local installs are containment-safe when the extension destination is nested inside the source checkout: pm stages the package outside the source and prunes the destination, `.agents`, `node_modules`, and install-backup directories before copying, so reinstalling cannot recursively copy tracker history, host dependencies, or prior backups.
|
|
46
46
|
Local `.tgz` and `.tar.gz` npm archives are inspected and extracted in an isolated temporary directory without invoking a shell. Archives must contain one `package/package.json` root, regular files/directories only, and bounded entry and expanded-byte totals. Absolute paths, traversal, alternate roots, links, device entries, oversized entries, and decompression-ratio abuse fail before installation. The managed source remains the original archive path, so reload and upgrade provenance do not point at a temporary extraction directory.
|
|
47
47
|
Registry dependency names and versions are parsed as npm package specs before the install subprocess starts. Leading-option names and shell control syntax are rejected. npm reads those validated dependencies from an isolated runtime-only manifest; no caller-controlled spec is forwarded through the Windows command shell, and the fixed invocation still ends option parsing with `--`. Runtime verification then activates a temporary snapshot of the complete installed extension directory, so an upgrade cannot silently reuse stale transitive ESM dependencies from the current process. Successful install details expose `module_graph_verification: "fresh_snapshot"` for this check.
|
|
48
48
|
pm-owned npm subprocesses clear any inherited, case-insensitive `npm_config_allow_scripts` value while retaining registry, auth, proxy, and executable-path environment; `--ignore-scripts` remains authoritative. Tracked by [pm-gh1072](../.agents/pm/issues/pm-gh1072.toon).
|
|
@@ -50,8 +50,8 @@ An explicit `--pm-path` scopes project installs to that tracker root, including
|
|
|
50
50
|
|
|
51
51
|
```bash
|
|
52
52
|
npm search "pm-cli pm-package"
|
|
53
|
-
pm install npm:pm-changelog --project
|
|
54
|
-
pm install npm:pm-github --project
|
|
53
|
+
pm package install npm:pm-changelog --project
|
|
54
|
+
pm package install npm:pm-github --project
|
|
55
55
|
pm package doctor --project --detail deep --trace
|
|
56
56
|
pm github validate --repo owner/repo
|
|
57
57
|
```
|
|
@@ -91,7 +91,7 @@ Package roots declare resources in `package.json` under `pm`:
|
|
|
91
91
|
```
|
|
92
92
|
|
|
93
93
|
Installation activates `pm.extensions`. `pm.docs`, `pm.examples`, `pm.assets`, and `pm.prompts` are catalog metadata (metadata-only — they are discovered and surfaced in the catalog but not executed). Declare agent-facing prompt/slash-command markdown under `pm.prompts` and non-code assets (images, skills, fixtures) under `pm.assets`; their conventional roots are `prompts/` (also `.agents/pm/prompts/`) and `assets/` (also `.agents/pm/assets/`).
|
|
94
|
-
`pm package init` and its compatibility spelling `pm extension init` emit the same publishable root-extension artifact (`"extensions": ["."]`): package metadata, a typed `index.ts`, a colocated `node:test` suite, a strict type-check-only `tsconfig.json`, and `typecheck`/`test` scripts. Both results report the canonical `package_name` and exact `invocation_command`; an already prefixed target such as `pm-my-workflow` stays `pm-my-workflow` instead of becoming `pm-pm-my-workflow`. The manifest `entry` points at `./index.ts` itself (ADR [pm-2c28](../.agents/pm/decisions/pm-2c28.toon) / [pm-m1uz](../.agents/pm/decisions/pm-m1uz.toon)). pm loads that `.ts` entry directly via Node's native type stripping (Node >=22.18), so there is no build step — run `npm install` (for the peer SDK and type-checking) before `pm install`. The generated README shows how to author exported command/hook definitions with the SDK [define\* builders](../.agents/pm/decisions/pm-3mph.toon). `--capability` selects one of ten starters
|
|
94
|
+
`pm package init` and its compatibility spelling `pm extension init` emit the same publishable root-extension artifact (`"extensions": ["."]`): package metadata, a typed `index.ts`, a colocated `node:test` suite, a strict type-check-only `tsconfig.json`, and `typecheck`/`test` scripts. Both results report the canonical `package_name` and exact `invocation_command`; an already prefixed target such as `pm-my-workflow` stays `pm-my-workflow` instead of becoming `pm-pm-my-workflow`. The manifest `entry` points at `./index.ts` itself (ADR [pm-2c28](../.agents/pm/decisions/pm-2c28.toon) / [pm-m1uz](../.agents/pm/decisions/pm-m1uz.toon)). pm loads that `.ts` entry directly via Node's native type stripping (Node >=22.18), so there is no build step — run `npm install` (for the peer SDK and type-checking) before `pm package install`. The generated README shows how to author exported command/hook definitions with the SDK [define\* builders](../.agents/pm/decisions/pm-3mph.toon). `--capability` selects one of ten scaffold starters (`commands`, `hooks`, `search`, `importers`, `schema`, `profile`, `renderers`, `parser`, `preflight`, `services`), each keeping a runnable starter command and adding the selected registration pattern plus a colocated `node:test` suite built on the matching SDK `assertRegistered*`/`runRegistered*ForTest` helpers. These are authoring selectors, not a one-to-one manifest-capability vocabulary: the `profile` starter registers a profile but declares the supported `schema` manifest capability because `api.registerProfile` is schema-governed. The option is repeatable for shell and config composition: repeating the same capability is idempotent, while combining distinct starter shapes fails with a usage error that asks the author to select one explicit scaffold capability. The full per-capability matrix (what each starter registers, which starters also declare `schema` because flag metadata is schema-governed, and why `schema`/`profile` omit `activation.commands` so their global contributions activate conservatively for every command) lives in [SDK.md — Minimal Command Extension](./SDK.md#minimal-command-extension). Starter manifests use the same least-privilege policy metadata as pure first-party command packages: `trusted: true`, `sandbox_profile: "strict"`, and explicit `false` permissions for `fs_read`, `fs_write`, `network`, `env_read`, `env_write`, and `process_spawn`. Declarative starters import `manifest.json` in their generated test and call `assertExtensionManifestMatchesBlueprint`, so capability drift fails locally before publication. Larger packages may point at nested extension directories after declaring runtime dependencies, relaxing only the permissions they actually need, and validating with `pm package doctor`, which additionally emits the advisory `extension_schema_narrow_activation` warning when a package registers custom item types/fields yet declares narrow `activation.commands` (the schema footgun above), recommending the field be dropped so the type stays globally available.
|
|
95
95
|
Package tests can pair `readPmPackageManifest(packageRoot)` with
|
|
96
96
|
`assertPackageManifest(manifest, { resources: ... })` from
|
|
97
97
|
`@unbrained/pm-cli/sdk` to prove aliases and resource paths without duplicating
|
|
@@ -191,10 +191,9 @@ useful for agents without inflating context or leaking private item content.
|
|
|
191
191
|
|
|
192
192
|
Runnable manifest examples are the source of truth: [starter extension manifest](examples/starter-extension/manifest.json) and [policy-restricted manifest](examples/policy-restricted-extension/manifest.json).
|
|
193
193
|
|
|
194
|
-
Use [extension-manifest.schema.json](schemas/extension-manifest.schema.json) as the `$schema` value for inline editor validation. The loader ignores `$schema` and tolerates future manifest fields, but the schema documents the fields pm reads.
|
|
195
|
-
|
|
196
|
-
Rules:
|
|
194
|
+
Use [extension-manifest.schema.json](schemas/extension-manifest.schema.json) as the `$schema` value for inline editor validation. The loader ignores `$schema` and tolerates future manifest fields, but the schema documents the fields pm reads. Rules:
|
|
197
195
|
|
|
196
|
+
- `manifest.json` is the runtime declaration; package catalog metadata belongs in `package.json#pm`, and a top-level `compatibility` object is ignored. Use the public `inspectExtensionManifestSchema` / `lintExtensionManifestSchema` helpers for schema-only checks. In author workspaces, `pm health --full`, `pm package doctor`, and `pm extension --doctor` expose the same read-only `author_manifest` findings without activating the extension.
|
|
198
197
|
- `entry` must resolve inside the extension directory.
|
|
199
198
|
- `manifest_version` is an optional integer identifying the manifest schema generation. Runtime contracts currently support manifest versions `1` and `2`, and first-party runnable examples use `2`. First-party packages declare it; the manifest governance test requires it on every first-party package.
|
|
200
199
|
- `pm_min_version` is an inclusive minimum pm CLI version. If the running CLI is older, discovery emits `extension_pm_min_version_unmet:<layer>:<name>:required=<version>:current=<version>` and skips the extension before import.
|
|
@@ -203,11 +202,11 @@ Rules:
|
|
|
203
202
|
- An empty-string or non-string `pm_min_version`/`pm_max_version` makes the whole manifest malformed (`extension_manifest_invalid:<layer>:<name>`). Omit the field instead of leaving it blank.
|
|
204
203
|
- Optional `engines.pm` and `engines.node` metadata is accepted for tooling, but `pm_min_version`/`pm_max_version` are the loader-enforced compatibility fields.
|
|
205
204
|
- Declare only capabilities the extension actually uses. Declaring a capability it never registers against is over-broad: `pm package doctor` emits an advisory `extension_capability_unused:<layer>:<name>:<capability>` warning (never blocking) so you can trim the manifest, while the inverse — registering a surface whose capability is undeclared — is the blocking `extension_capability_missing` activation failure. Catch over-declaration earlier with the `assertExtensionCapabilityUsage` SDK testing helper.
|
|
206
|
-
- `contributions` is the versioned, serializable surface inventory. `schema_version: 1` supports command definitions/handlers/overrides, hook phases, flag/parser targets, item types and fields, relationship kinds, migrations, profiles, importers/exporters, search/vector providers, service/renderer targets, renderer command ownership, and the preflight count. `pm install` derives and persists this block mechanically from the real activation result; authors may also declare it in `manifest.json` for build-time/static discovery.
|
|
205
|
+
- `contributions` is the versioned, serializable surface inventory. `schema_version: 1` supports command definitions/handlers/overrides, hook phases, flag/parser targets, item types and fields, relationship kinds, migrations, profiles, importers/exporters, search/vector providers, service/renderer targets, renderer command ownership, and the preflight count. `pm package install` derives and persists this block mechanically from the real activation result; authors may also declare it in `manifest.json` for build-time/static discovery.
|
|
207
206
|
- `activation.commands` is an optional array of the command paths on which the extension may activate (e.g. `["hello", "tickets import"]`). An explicit list is authoritative for every capability, including hooks and parser/preflight/renderer packages: when no declared path matches, pm does not import the module. Omit it and pm first uses the static contribution inventory, then falls back to conservative capability heuristics for legacy packages whose contributions are unknown.
|
|
208
207
|
- Unknown capabilities emit deterministic warnings; legacy aliases such as `migration` and `validation` are normalized to `schema` with warnings.
|
|
209
208
|
|
|
210
|
-
Supported capabilities:
|
|
209
|
+
Supported manifest capabilities (the `profile` scaffold selector emits a profile registration under `schema`; it is not a manifest capability):
|
|
211
210
|
|
|
212
211
|
- `commands`
|
|
213
212
|
- `parser`
|
|
@@ -294,9 +293,11 @@ Doctor JSON also includes `triage.collision_plan` with grouped surfaces, ranked
|
|
|
294
293
|
## Runtime APIs
|
|
295
294
|
|
|
296
295
|
Use the public SDK barrel. Do not deep-import from `src/core` or `dist/core`.
|
|
296
|
+
|
|
297
297
|
```ts
|
|
298
298
|
import { defineExtension } from "@unbrained/pm-cli/sdk";
|
|
299
299
|
```
|
|
300
|
+
|
|
300
301
|
Common APIs:
|
|
301
302
|
|
|
302
303
|
- `api.extension` is a read-only identity (`name`, `layer`, `version`, `capabilities`, `pm_min_version?`, `pm_max_version?`, `source_package?`) for self-identifying logs and version gating without re-reading the manifest.
|
|
@@ -384,14 +385,14 @@ Compatibility equivalents remain available through `pm extension ...` for existi
|
|
|
384
385
|
|
|
385
386
|
## Upgrade Workflow
|
|
386
387
|
|
|
387
|
-
`pm upgrade` is the package-first update entrypoint:
|
|
388
|
+
`pm package upgrade` is the package-first update entrypoint:
|
|
388
389
|
|
|
389
390
|
```bash
|
|
390
|
-
pm upgrade --dry-run
|
|
391
|
-
pm upgrade
|
|
392
|
-
pm upgrade --packages-only
|
|
393
|
-
pm upgrade todos --dry-run
|
|
394
|
-
pm upgrade --cli-only --repair
|
|
391
|
+
pm package upgrade --dry-run
|
|
392
|
+
pm package upgrade
|
|
393
|
+
pm package upgrade --packages-only
|
|
394
|
+
pm package upgrade todos --dry-run
|
|
395
|
+
pm package upgrade --cli-only --repair
|
|
395
396
|
```
|
|
396
397
|
|
|
397
398
|
CLI/SDK upgrades use `npm install -g @unbrained/pm-cli@<tag>`. Managed package upgrades reuse the source recorded at install time, including registry, GitHub, local, and first-party package sources.
|
|
@@ -402,7 +403,7 @@ Use non-interactive commands with explicit project scope:
|
|
|
402
403
|
|
|
403
404
|
```bash
|
|
404
405
|
pm init --defaults --author codex-agent
|
|
405
|
-
pm install '*' --project
|
|
406
|
+
pm package install '*' --project
|
|
406
407
|
pm package doctor --project --detail summary --json
|
|
407
408
|
pm contracts --flags-only --json
|
|
408
409
|
pm health --check-only --json
|
|
@@ -422,8 +423,7 @@ import { createExtensionTestHarness } from "@unbrained/pm-cli/sdk/testing";
|
|
|
422
423
|
import { activateExtensionForTest } from "@unbrained/pm-cli/sdk/testing";
|
|
423
424
|
```
|
|
424
425
|
|
|
425
|
-
Runtime modules use static SDK imports; installed copies receive a host SDK link. Use `createPmCliExpectedError(message, { exitCode, context })` for expected user/action failures from package commands. It creates an `Error` named `PmCliError` with a structural `exitCode`, so separately installed package code still gets expected-error handling and Sentry filtering.
|
|
426
|
-
Commands that need to render a structured gate report and still fail CI may instead return an object with `exit_code` from `1` through `255`; optional string `code` and `remediation` fields are preserved by the host. The result is rendered normally, and the CLI exits with the declared status. Thrown plain objects also preserve bounded `code` and `remediation` fields in the host error contract.
|
|
426
|
+
Runtime modules use static SDK imports; installed copies receive a host SDK link. Use `createPmCliExpectedError(message, { exitCode, context })` for expected user/action failures from package commands. It creates an `Error` named `PmCliError` with a structural `exitCode`, so separately installed package code still gets expected-error handling and Sentry filtering. Commands that need to render a structured gate report and still fail CI may instead return an object with `exit_code` from `1` through `255`; optional string `code` and `remediation` fields are preserved by the host. The result is rendered normally, and the CLI exits with the declared status. Thrown plain objects also preserve bounded `code` and `remediation` fields in the host error contract.
|
|
427
427
|
Prefer the `define*` builders for exported registration definitions (`defineCommand`, `defineFlag`, `defineSearchProvider`, `defineAfterCommandHook`, and the matching override/import/export/hook helpers; see ADR [pm-3mph](../.agents/pm/decisions/pm-3mph.toon)). They are zero-cost identity functions that preserve object literal types and contextually type function parameters before the definitions reach `api.register*`; runtime validation remains in the loader, and behavior validation remains in `sdk/testing`.
|
|
428
428
|
Packages that extend core list or search behavior should import `LIST_FILTER_EXTENSION_FLAG_DEFINITIONS`, `SEARCH_EXTENSION_FLAG_DEFINITIONS`, or `toExtensionFlagDefinitions` from `@unbrained/pm-cli/sdk/authoring` instead of copying CLI option tables. For example: `api.registerFlags("my search", SEARCH_EXTENSION_FLAG_DEFINITIONS)`.
|
|
429
429
|
The adapter expands aliases into registration-ready definitions and preserves string/boolean behavior, list accumulation, repeatability, requiredness, descriptions, and value names from the canonical CLI contracts. Use `toExtensionFlagDefinitions` with another exported CLI flag contract for a narrower baseline.
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
# MCP 2026-07-28 Protocol and Compatibility Decision
|
|
2
|
+
|
|
3
|
+
Tracker references: [pm-sqvshj](../.agents/pm/decisions/pm-sqvshj.toon),
|
|
4
|
+
[pm-vae5ec](../.agents/pm/features/pm-vae5ec.toon), and
|
|
5
|
+
[pm-55yf1t](../.agents/pm/tasks/pm-55yf1t.toon). MRTR, durable tasks,
|
|
6
|
+
and the cache/schema surface are tracked by
|
|
7
|
+
[pm-rz9gep](../.agents/pm/features/pm-rz9gep.toon),
|
|
8
|
+
[pm-rzs24j](../.agents/pm/features/pm-rzs24j.toon), and
|
|
9
|
+
[pm-hv1x1x](../.agents/pm/features/pm-hv1x1x.toon). Subscriptions,
|
|
10
|
+
Streamable HTTP, remote authorization, and the deprecation ratchet are tracked
|
|
11
|
+
by [pm-v7e337](../.agents/pm/features/pm-v7e337.toon),
|
|
12
|
+
[pm-3zh9s4](../.agents/pm/features/pm-3zh9s4.toon), and
|
|
13
|
+
[pm-vzcisw](../.agents/pm/chores/pm-vzcisw.toon). Skills and Apps are tracked
|
|
14
|
+
by [pm-8nzivt](../.agents/pm/features/pm-8nzivt.toon) and
|
|
15
|
+
[pm-pznhee](../.agents/pm/features/pm-pznhee.toon).
|
|
16
|
+
|
|
17
|
+
Status: accepted. MCP `2026-07-28` is pm's canonical protocol revision.
|
|
18
|
+
|
|
19
|
+
## Decision
|
|
20
|
+
|
|
21
|
+
The public pm SDK owns protocol versions, request metadata validation,
|
|
22
|
+
capability checks, discovery, result envelopes, error codes, HTTP header
|
|
23
|
+
parity, subscriptions, authorization boundaries, trace isolation, and legacy
|
|
24
|
+
result interpretation. `pm-mcp` is a JSON-RPC/stdio adapter over those
|
|
25
|
+
contracts; `pm-mcp-http` binds the same dispatcher to sessionless Streamable
|
|
26
|
+
HTTP POST.
|
|
27
|
+
|
|
28
|
+
Modern requests are stateless. Every request carries:
|
|
29
|
+
|
|
30
|
+
- `io.modelcontextprotocol/protocolVersion` = `2026-07-28`;
|
|
31
|
+
- `io.modelcontextprotocol/clientCapabilities` as an object, including `{}`;
|
|
32
|
+
- optional `io.modelcontextprotocol/clientInfo` with `name` and `version`.
|
|
33
|
+
|
|
34
|
+
Every modern result carries an explicit `resultType` (`complete`,
|
|
35
|
+
`input_required`, or `task`) and `io.modelcontextprotocol/serverInfo` in
|
|
36
|
+
result `_meta`. The mandatory
|
|
37
|
+
`server/discover` method returns the supported modern revisions, deterministic
|
|
38
|
+
capabilities, public cache policy, server identity, and bounded instructions.
|
|
39
|
+
No modern request reads identity, capabilities, or version from a previous
|
|
40
|
+
request.
|
|
41
|
+
|
|
42
|
+
## Legacy boundary
|
|
43
|
+
|
|
44
|
+
The sole supported legacy revision is `2025-06-18`, accepted through the
|
|
45
|
+
existing stdio adapter. Unversioned requests stay on this legacy path because
|
|
46
|
+
they cannot claim the current revision; `initialize` enriches their client
|
|
47
|
+
identity but is not required for compatibility with older pm hosts. The
|
|
48
|
+
adapter has no session id, does not affect modern requests, and is excluded
|
|
49
|
+
from `server/discover`'s `supportedVersions` because it cannot be selected
|
|
50
|
+
through modern per-request metadata.
|
|
51
|
+
|
|
52
|
+
The adapter is scheduled for removal only after published-client telemetry and
|
|
53
|
+
release probes show no required legacy consumers for two consecutive release
|
|
54
|
+
windows. Removal is a reviewed compatibility change, never a history rewrite.
|
|
55
|
+
|
|
56
|
+
## Transport behavior
|
|
57
|
+
|
|
58
|
+
- Stdio modern clients call `server/discover` with current request metadata,
|
|
59
|
+
then send the same version and capability keys on every request.
|
|
60
|
+
- Stdio legacy clients retain their existing response shapes and may use
|
|
61
|
+
`initialize` with `2025-06-18` to supply client identity.
|
|
62
|
+
- Streamable HTTP requires `MCP-Protocol-Version` and `Mcp-Method` on every
|
|
63
|
+
request. `Mcp-Name` is required only for `prompts/get`, `resources/read`, and
|
|
64
|
+
`tools/call`; other methods omit it. Schema-declared `x-mcp-header` values are
|
|
65
|
+
encoded, decoded, and compared with tool arguments before dispatch.
|
|
66
|
+
Header/version mismatch uses code `-32020` and HTTP 400.
|
|
67
|
+
- `subscriptions/listen` is a request-scoped stdio or SSE stream. The first
|
|
68
|
+
message acknowledges the supported filter; later messages carry its request
|
|
69
|
+
id as `io.modelcontextprotocol/subscriptionId`. Disconnect deletes the
|
|
70
|
+
subscription and a caller retries lost work with a new request id.
|
|
71
|
+
- The remote adapter defaults to loopback, enforces exact browser origins,
|
|
72
|
+
bounds bodies, maps parse/invalid requests to HTTP 400, and can require an
|
|
73
|
+
issuer-, audience-, and scope-bound bearer token.
|
|
74
|
+
- Unsupported modern versions return `-32022` plus the exact supported modern
|
|
75
|
+
list. Missing required capabilities return `-32021` with a structured
|
|
76
|
+
capability map. Malformed metadata uses JSON-RPC Invalid Params `-32602`.
|
|
77
|
+
|
|
78
|
+
## Removed, migrated, and deprecated behavior
|
|
79
|
+
|
|
80
|
+
| Prior behavior | Disposition |
|
|
81
|
+
| ----------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
|
|
82
|
+
| `initialize` and `notifications/initialized` | Legacy stdio adapter only; absent from modern behavior. |
|
|
83
|
+
| `Mcp-Session-Id` and protocol sessions | Removed; explicit application handles are ordinary arguments. |
|
|
84
|
+
| `ping` | Legacy adapter only; modern calls return Method Not Found. |
|
|
85
|
+
| `resources/subscribe` and `resources/unsubscribe` | Replaced by the implemented `subscriptions/listen` filter. |
|
|
86
|
+
| SSE event ids and `Last-Event-ID` replay | Removed; callers retry with a new request id. |
|
|
87
|
+
| Reverse `roots/list`, sampling, and elicitation requests | Migrate to MRTR `input_required` under `pm-rz9gep`. |
|
|
88
|
+
| Core tasks | Migrate to `io.modelcontextprotocol/tasks` under `pm-rzs24j`. |
|
|
89
|
+
| `logging/setLevel` | Removed; optional request-local log metadata is never shared, and remote operations use host OpenTelemetry. |
|
|
90
|
+
| Roots, Sampling, Logging, HTTP+SSE, and non-none `includeContext` | Retain only in bounded legacy compatibility while `pm-vzcisw` drives deprecation removal. |
|
|
91
|
+
| Dynamic Client Registration | Legacy authorization fallback; Client ID Metadata Documents are canonical under `pm-3zh9s4`. |
|
|
92
|
+
|
|
93
|
+
## Rollout, rollback, and proof
|
|
94
|
+
|
|
95
|
+
Local and hosted gates must prove SDK primitives, direct server calls, real
|
|
96
|
+
stdio, packed artifacts, npx, bunx, and published artifacts agree on discovery
|
|
97
|
+
and the canonical revision. Negative controls cover unsupported versions,
|
|
98
|
+
missing/malformed metadata, missing capabilities, header mismatch, removed
|
|
99
|
+
methods, and omitted modern `resultType`.
|
|
100
|
+
|
|
101
|
+
Rollback preserves the SDK contract and re-enables only the reviewed legacy
|
|
102
|
+
adapter. It must never reintroduce session ids or make modern behavior depend
|
|
103
|
+
on initialization. Release evidence records exact source, package, tag, and
|
|
104
|
+
consumer revisions separately.
|
|
105
|
+
|
|
106
|
+
## MRTR, tasks, and cache behavior
|
|
107
|
+
|
|
108
|
+
An SDK handler that cannot finish without host input throws
|
|
109
|
+
`PmMcpInputRequiredError`. The modern adapter validates the requested
|
|
110
|
+
`elicitation/create`, `roots/list`, or `sampling/createMessage` capability and
|
|
111
|
+
returns `resultType: "input_required"`. Continuation state can be bounded,
|
|
112
|
+
HMAC-sealed, expiry-bound, method-bound, parameter-bound, principal-bound, and
|
|
113
|
+
protected from in-process replay with the public interaction helpers. Retry
|
|
114
|
+
payloads arrive as request-local `inputResponses`; they never depend on a
|
|
115
|
+
protocol session.
|
|
116
|
+
|
|
117
|
+
Clients negotiate `io.modelcontextprotocol/tasks` in request capabilities.
|
|
118
|
+
Eligible long-running `tools/call` operations can then return a durable task
|
|
119
|
+
handle. `tasks/get`, `tasks/update`, and `tasks/cancel` are principal-scoped,
|
|
120
|
+
persist records atomically under the ignored tracker runtime area, enforce
|
|
121
|
+
immutable terminal states, expire abandoned work deterministically, and turn
|
|
122
|
+
a disappeared worker into an actionable terminal failure. Task state remains
|
|
123
|
+
retrieved through the task methods. Change subscriptions do not become
|
|
124
|
+
task-progress channels, and pm's current handlers do not emit request progress
|
|
125
|
+
or deprecated log-message notifications.
|
|
126
|
+
|
|
127
|
+
Modern tool, resource, resource-template, and prompt list/read results carry
|
|
128
|
+
explicit `ttlMs` and `cacheScope`. Tool schemas are validated as bounded JSON
|
|
129
|
+
Schema 2020-12 documents before advertisement. Tool and resource data stay
|
|
130
|
+
private; public metadata lists may be cached for their advertised lifetime.
|
|
131
|
+
|
|
132
|
+
## Skills and Apps extensions
|
|
133
|
+
|
|
134
|
+
Discovery advertises the stable `io.modelcontextprotocol/ui` MCP Apps
|
|
135
|
+
extension and the revision-pinned draft `io.modelcontextprotocol/skills`
|
|
136
|
+
extension. They remain optional and request-local. Apps require the stable
|
|
137
|
+
`2026-01-26` MIME capability; Skills require the exact SEP-2640 commit and
|
|
138
|
+
explicit directory-read support for bulk reads. An incompatible Apps
|
|
139
|
+
declaration is treated as absent by `tools/list` and `resources/list`, so those
|
|
140
|
+
discovery methods degrade to the non-UI surface; direct `ui://` reads remain
|
|
141
|
+
strict and return the allocated missing-capability error. Skills methods fail
|
|
142
|
+
closed on an incompatible draft declaration because their entire method family
|
|
143
|
+
depends on that exact negotiated revision.
|
|
144
|
+
|
|
145
|
+
The public SDK owns skill parsing, digesting, pagination, origin provenance,
|
|
146
|
+
resource bounds, App contracts, tool metadata, sandbox policy, and accessible
|
|
147
|
+
self-contained HTML. The server only applies negotiation and dispatch. See
|
|
148
|
+
[MCP Skills and Apps](MCP_SKILLS_AND_APPS.md) for the wire examples and trust
|
|
149
|
+
model.
|
|
150
|
+
|
|
151
|
+
## Public SDK
|
|
152
|
+
|
|
153
|
+
Use `PM_MCP_PROTOCOL_VERSION`, `resolveMcpRequestContext()`,
|
|
154
|
+
`buildMcpDiscoverResult()`, `buildMcpCompleteResult()`,
|
|
155
|
+
`PmMcpSubscriptionRegistry`, `buildMcpHttpRequestHeaders()`,
|
|
156
|
+
`validateMcpHttpRequestHeaders()`, `buildMcpProtectedResourceMetadata()`, and
|
|
157
|
+
the issuer/trace authorization helpers from `@unbrained/pm-cli/sdk`. See
|
|
158
|
+
[MCP interaction and task SDK](SDK_MCP_INTERACTIONS.md) and
|
|
159
|
+
[remote transport, authorization, and migration](MCP_REMOTE_TRANSPORT_SECURITY.md),
|
|
160
|
+
plus [MCP Skills and Apps](MCP_SKILLS_AND_APPS.md).
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# MCP 2026-07-28 Conformance Matrix
|
|
2
|
+
|
|
3
|
+
Tracker: [pm-55yf1t](../.agents/pm/tasks/pm-55yf1t.toon). The official
|
|
4
|
+
2026-07-28 schema and key-changes document are normative; this matrix assigns
|
|
5
|
+
every revision-level change to one canonical pm owner and records executable
|
|
6
|
+
evidence or an explicit open obligation.
|
|
7
|
+
|
|
8
|
+
| Requirement family | Canonical owner | Current disposition | Executable evidence |
|
|
9
|
+
| -------------------------------------------------------------------------------------------------- | --------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------- |
|
|
10
|
+
| Stateless per-request version, client capabilities, and identity | [pm-vae5ec](../.agents/pm/features/pm-vae5ec.toon) | Implemented | `tests/unit/sdk/mcp/protocol.spec.ts`, `tests/integration/mcp-stateless-protocol.spec.ts` |
|
|
11
|
+
| Mandatory `server/discover`, deterministic capabilities and identity | [pm-vae5ec](../.agents/pm/features/pm-vae5ec.toon) | Implemented | direct SDK/server tests plus plugin and release real-process probes |
|
|
12
|
+
| Unsupported version `-32022` | [pm-vae5ec](../.agents/pm/features/pm-vae5ec.toon) | Implemented | SDK and server negative controls |
|
|
13
|
+
| Header mismatch `-32020` and missing capability `-32021` | [pm-vae5ec](../.agents/pm/features/pm-vae5ec.toon) | Implemented in SDK, stdio, and Streamable HTTP | SDK negative controls and `tests/integration/mcp-streamable-http.spec.ts` |
|
|
14
|
+
| Required result `resultType`; legacy omission means complete only at compatibility boundary | [pm-vae5ec](../.agents/pm/features/pm-vae5ec.toon) | Implemented for modern pm results | SDK unit and modern direct-server tests |
|
|
15
|
+
| No modern initialize, initialized notification, ping, or protocol session | [pm-sqvshj](../.agents/pm/decisions/pm-sqvshj.toon) | Implemented with bounded legacy stdio adapter | modern removed-method and legacy handshake tests |
|
|
16
|
+
| MRTR `input_required`, retry state, and reverse-request removal | [pm-rz9gep](../.agents/pm/features/pm-rz9gep.toon) | Implemented for SDK and stateless stdio adapter | `tests/unit/sdk/mcp/interactions.spec.ts`; direct server negative controls |
|
|
17
|
+
| `subscriptions/listen`, request-scoped streams, no SSE resumability | [pm-v7e337](../.agents/pm/features/pm-v7e337.toon) | Implemented locally; packed and published proof follows merge | subscription SDK, stdio, HTTP, backpressure, disconnect, and retry tests |
|
|
18
|
+
| Official `io.modelcontextprotocol/tasks` extension | [pm-rzs24j](../.agents/pm/features/pm-rzs24j.toon) | Implemented for eligible tool calls, durable lifecycle, and stdio methods; notifications remain with subscriptions owner | `tests/unit/sdk/mcp/tasks.spec.ts`, `tests/integration/mcp-stateless-protocol.spec.ts` |
|
|
19
|
+
| Cacheable list/read results, deterministic tools, JSON Schema 2020-12, any JSON structured content | [pm-hv1x1x](../.agents/pm/features/pm-hv1x1x.toon) | Implemented for current pm tool/resource/prompt surfaces | SDK schema/cache tests and direct modern server surface suite |
|
|
20
|
+
| Issuer-bound authorization, client metadata documents, consent, headers, OpenTelemetry | [pm-3zh9s4](../.agents/pm/features/pm-3zh9s4.toon) | Implemented locally; deployment verifier integration remains host-owned | authorization SDK adversarial tests, real HTTP bearer suite, and threat model |
|
|
21
|
+
| Stable MCP Apps negotiation, tool/resource metadata, fallback, sandboxing, and accessible views | [pm-pznhee](../.agents/pm/features/pm-pznhee.toon) | Implemented in the public SDK and stateless server; packed/published proof follows merge | `tests/unit/sdk/mcp/apps.spec.ts`, `tests/integration/mcp-stateless-protocol.spec.ts` |
|
|
22
|
+
| Draft Skills over MCP list/get/read, compatibility, provenance, digests, bounds, and pagination | [pm-8nzivt](../.agents/pm/features/pm-8nzivt.toon) | Implemented against exact SEP-2640 draft revision; packed/published proof follows merge | `tests/unit/sdk/mcp/skills.spec.ts`, `tests/integration/mcp-stateless-protocol.spec.ts` |
|
|
23
|
+
| Deprecated Roots, Sampling, Logging, HTTP+SSE, `includeContext`, dynamic registration | [pm-vzcisw](../.agents/pm/chores/pm-vzcisw.toon) | Canonical source ratcheted; bounded stdio adapter and dated migration policy remain | generated inventory, negative controls, adapter tests, and migration guide |
|
|
24
|
+
| Official schema, real stdio/HTTP, packed/published, npx/bunx, negative controls | [pm-55yf1t](../.agents/pm/tasks/pm-55yf1t.toon) | Foundation implemented; remains open until every owner above closes | SDK/server suites, plugin smokes, published-release verifier |
|
|
25
|
+
|
|
26
|
+
The programme gate remains intentionally incomplete while local-only rows
|
|
27
|
+
lack their packed and published evidence. Provider
|
|
28
|
+
silence, a successful legacy initialize, or source-only unit coverage cannot
|
|
29
|
+
promote such a row. Completion requires the owner's positive and negative
|
|
30
|
+
tests plus exact packed and published consumer proof.
|