@unbrained/pm-cli 2026.5.6 → 2026.5.11

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.
Files changed (268) hide show
  1. package/.agents/pm/extensions/.managed-extensions.json +2 -2
  2. package/.agents/pm/extensions/beads/runtime.js +4 -4
  3. package/.agents/pm/extensions/beads/runtime.ts +5 -5
  4. package/.agents/pm/extensions/todos/runtime.js +7 -7
  5. package/.agents/pm/extensions/todos/runtime.ts +10 -10
  6. package/.agents/skills/HARNESS_COMPATIBILITY.md +45 -0
  7. package/.agents/skills/README.md +21 -0
  8. package/.agents/skills/pm-developer/SKILL.md +73 -0
  9. package/.agents/skills/pm-developer/references/COMMAND_PLAYBOOK.md +48 -0
  10. package/.agents/skills/pm-developer/references/PROMPTS.md +17 -0
  11. package/.agents/skills/pm-extensions/SKILL.md +57 -0
  12. package/.agents/skills/pm-extensions/references/LIFECYCLE.md +40 -0
  13. package/.agents/skills/pm-extensions/references/TROUBLESHOOTING.md +25 -0
  14. package/.agents/skills/pm-sdk/SKILL.md +50 -0
  15. package/.agents/skills/pm-sdk/references/INTEGRATION_CHECKLIST.md +31 -0
  16. package/.agents/skills/pm-sdk/references/PROMPTS.md +13 -0
  17. package/.agents/skills/pm-user/SKILL.md +59 -0
  18. package/.agents/skills/pm-user/references/PROMPTS.md +17 -0
  19. package/.agents/skills/pm-user/references/WORKFLOWS.md +35 -0
  20. package/.claude-plugin/marketplace.json +38 -0
  21. package/.pi/README.md +35 -0
  22. package/.pi/agents/pm-triage-agent.md +19 -0
  23. package/.pi/agents/pm-verification-agent.md +21 -0
  24. package/.pi/chains/pm-native-delivery.chain.md +11 -0
  25. package/.pi/extensions/pm-cli/index.js +387 -0
  26. package/.pi/prompts/pm-workflow.md +5 -0
  27. package/.pi/skills/pm-native/SKILL.md +44 -0
  28. package/.pi/skills/pm-release/SKILL.md +35 -0
  29. package/AGENTS.md +1 -1
  30. package/CHANGELOG.md +13 -0
  31. package/PRD.md +16 -16
  32. package/README.md +30 -4
  33. package/dist/cli/argv-utils.d.ts +5 -0
  34. package/dist/cli/argv-utils.js +34 -0
  35. package/dist/cli/argv-utils.js.map +1 -0
  36. package/dist/cli/bootstrap-args.d.ts +15 -0
  37. package/dist/cli/bootstrap-args.js +211 -0
  38. package/dist/cli/bootstrap-args.js.map +1 -1
  39. package/dist/cli/commander-usage.js +109 -3
  40. package/dist/cli/commander-usage.js.map +1 -1
  41. package/dist/cli/commands/claim.js +6 -6
  42. package/dist/cli/commands/claim.js.map +1 -1
  43. package/dist/cli/commands/close.js +9 -9
  44. package/dist/cli/commands/close.js.map +1 -1
  45. package/dist/cli/commands/comments.d.ts +2 -0
  46. package/dist/cli/commands/comments.js +57 -8
  47. package/dist/cli/commands/comments.js.map +1 -1
  48. package/dist/cli/commands/completion.js +40 -7
  49. package/dist/cli/commands/completion.js.map +1 -1
  50. package/dist/cli/commands/config.js +6 -3
  51. package/dist/cli/commands/config.js.map +1 -1
  52. package/dist/cli/commands/contracts.d.ts +19 -0
  53. package/dist/cli/commands/contracts.js +36 -1
  54. package/dist/cli/commands/contracts.js.map +1 -1
  55. package/dist/cli/commands/create.d.ts +2 -2
  56. package/dist/cli/commands/create.js +116 -55
  57. package/dist/cli/commands/create.js.map +1 -1
  58. package/dist/cli/commands/docs.js +13 -6
  59. package/dist/cli/commands/docs.js.map +1 -1
  60. package/dist/cli/commands/extension.d.ts +3 -1
  61. package/dist/cli/commands/extension.js +174 -2
  62. package/dist/cli/commands/extension.js.map +1 -1
  63. package/dist/cli/commands/files.js +19 -12
  64. package/dist/cli/commands/files.js.map +1 -1
  65. package/dist/cli/commands/get.js +5 -5
  66. package/dist/cli/commands/get.js.map +1 -1
  67. package/dist/cli/commands/guide.d.ts +55 -0
  68. package/dist/cli/commands/guide.js +260 -0
  69. package/dist/cli/commands/guide.js.map +1 -0
  70. package/dist/cli/commands/health.js +1 -1
  71. package/dist/cli/commands/health.js.map +1 -1
  72. package/dist/cli/commands/history.js +30 -10
  73. package/dist/cli/commands/history.js.map +1 -1
  74. package/dist/cli/commands/index.d.ts +1 -0
  75. package/dist/cli/commands/index.js +1 -0
  76. package/dist/cli/commands/index.js.map +1 -1
  77. package/dist/cli/commands/init.d.ts +2 -0
  78. package/dist/cli/commands/init.js +21 -1
  79. package/dist/cli/commands/init.js.map +1 -1
  80. package/dist/cli/commands/learnings.js +3 -3
  81. package/dist/cli/commands/learnings.js.map +1 -1
  82. package/dist/cli/commands/metadata-normalizers.d.ts +4 -0
  83. package/dist/cli/commands/metadata-normalizers.js +37 -0
  84. package/dist/cli/commands/metadata-normalizers.js.map +1 -0
  85. package/dist/cli/commands/notes.js +3 -3
  86. package/dist/cli/commands/notes.js.map +1 -1
  87. package/dist/cli/commands/reindex.js +180 -156
  88. package/dist/cli/commands/reindex.js.map +1 -1
  89. package/dist/cli/commands/restore.d.ts +2 -2
  90. package/dist/cli/commands/restore.js +44 -24
  91. package/dist/cli/commands/restore.js.map +1 -1
  92. package/dist/cli/commands/search.d.ts +2 -0
  93. package/dist/cli/commands/search.js +45 -26
  94. package/dist/cli/commands/search.js.map +1 -1
  95. package/dist/cli/commands/test-all.d.ts +2 -0
  96. package/dist/cli/commands/test-all.js +2 -0
  97. package/dist/cli/commands/test-all.js.map +1 -1
  98. package/dist/cli/commands/test.d.ts +1 -0
  99. package/dist/cli/commands/test.js +13 -5
  100. package/dist/cli/commands/test.js.map +1 -1
  101. package/dist/cli/commands/update.js +188 -157
  102. package/dist/cli/commands/update.js.map +1 -1
  103. package/dist/cli/commands/validate.js +1 -1
  104. package/dist/cli/commands/validate.js.map +1 -1
  105. package/dist/cli/error-guidance.d.ts +9 -1
  106. package/dist/cli/error-guidance.js +147 -6
  107. package/dist/cli/error-guidance.js.map +1 -1
  108. package/dist/cli/guide-topics.d.ts +25 -0
  109. package/dist/cli/guide-topics.js +283 -0
  110. package/dist/cli/guide-topics.js.map +1 -0
  111. package/dist/cli/help-content.js +25 -1
  112. package/dist/cli/help-content.js.map +1 -1
  113. package/dist/cli/help-json-payload.js +11 -1
  114. package/dist/cli/help-json-payload.js.map +1 -1
  115. package/dist/cli/main.js +69 -6
  116. package/dist/cli/main.js.map +1 -1
  117. package/dist/cli/register-list-query.js +38 -1
  118. package/dist/cli/register-list-query.js.map +1 -1
  119. package/dist/cli/register-mutation.js +17 -4
  120. package/dist/cli/register-mutation.js.map +1 -1
  121. package/dist/cli/register-setup.js +15 -1
  122. package/dist/cli/register-setup.js.map +1 -1
  123. package/dist/cli/telemetry-flush.d.ts +2 -0
  124. package/dist/cli/telemetry-flush.js +4 -0
  125. package/dist/cli/telemetry-flush.js.map +1 -0
  126. package/dist/cli.js +1 -2
  127. package/dist/cli.js.map +1 -1
  128. package/dist/core/extensions/extension-types.d.ts +72 -0
  129. package/dist/core/extensions/extension-types.js +24 -0
  130. package/dist/core/extensions/extension-types.js.map +1 -1
  131. package/dist/core/extensions/loader.d.ts +1 -0
  132. package/dist/core/extensions/loader.js +766 -7
  133. package/dist/core/extensions/loader.js.map +1 -1
  134. package/dist/core/history/history.js +32 -11
  135. package/dist/core/history/history.js.map +1 -1
  136. package/dist/core/item/item-format.d.ts +2 -2
  137. package/dist/core/item/item-format.js +16 -16
  138. package/dist/core/item/item-format.js.map +1 -1
  139. package/dist/core/lock/lock.js +2 -0
  140. package/dist/core/lock/lock.js.map +1 -1
  141. package/dist/core/schema/runtime-field-filters.js +1 -1
  142. package/dist/core/schema/runtime-field-filters.js.map +1 -1
  143. package/dist/core/schema/runtime-field-values.js +2 -2
  144. package/dist/core/schema/runtime-field-values.js.map +1 -1
  145. package/dist/core/schema/runtime-schema.d.ts +1 -1
  146. package/dist/core/schema/runtime-schema.js +3 -3
  147. package/dist/core/schema/runtime-schema.js.map +1 -1
  148. package/dist/core/search/cache.js +7 -21
  149. package/dist/core/search/cache.js.map +1 -1
  150. package/dist/core/search/corpus.d.ts +13 -0
  151. package/dist/core/search/corpus.js +74 -0
  152. package/dist/core/search/corpus.js.map +1 -0
  153. package/dist/core/search/embedding-batches.js +90 -30
  154. package/dist/core/search/embedding-batches.js.map +1 -1
  155. package/dist/core/sentry/instrument.d.ts +18 -1
  156. package/dist/core/sentry/instrument.js +128 -12
  157. package/dist/core/sentry/instrument.js.map +1 -1
  158. package/dist/core/shared/constants.d.ts +1 -1
  159. package/dist/core/shared/constants.js +21 -1
  160. package/dist/core/shared/constants.js.map +1 -1
  161. package/dist/core/shared/errors.d.ts +8 -0
  162. package/dist/core/shared/errors.js.map +1 -1
  163. package/dist/core/shared/levenshtein.d.ts +1 -0
  164. package/dist/core/shared/levenshtein.js +37 -0
  165. package/dist/core/shared/levenshtein.js.map +1 -0
  166. package/dist/core/store/front-matter-cache.d.ts +1 -1
  167. package/dist/core/store/front-matter-cache.js +13 -13
  168. package/dist/core/store/front-matter-cache.js.map +1 -1
  169. package/dist/core/store/item-format-migration.js +5 -2
  170. package/dist/core/store/item-format-migration.js.map +1 -1
  171. package/dist/core/store/item-store.js +16 -15
  172. package/dist/core/store/item-store.js.map +1 -1
  173. package/dist/core/store/paths.js +35 -2
  174. package/dist/core/store/paths.js.map +1 -1
  175. package/dist/core/store/settings.js +216 -2
  176. package/dist/core/store/settings.js.map +1 -1
  177. package/dist/core/telemetry/runtime.d.ts +1 -0
  178. package/dist/core/telemetry/runtime.js +102 -3
  179. package/dist/core/telemetry/runtime.js.map +1 -1
  180. package/dist/core/test/item-test-run-tracking.js +2 -2
  181. package/dist/core/test/item-test-run-tracking.js.map +1 -1
  182. package/dist/mcp/server.d.ts +2 -0
  183. package/dist/mcp/server.js +407 -0
  184. package/dist/mcp/server.js.map +1 -0
  185. package/dist/pi/native.d.ts +5 -0
  186. package/dist/pi/native.js +236 -0
  187. package/dist/pi/native.js.map +1 -0
  188. package/dist/sdk/cli-contracts.d.ts +24 -2
  189. package/dist/sdk/cli-contracts.js +317 -2
  190. package/dist/sdk/cli-contracts.js.map +1 -1
  191. package/dist/sdk/index.d.ts +12 -1
  192. package/dist/sdk/index.js +8 -1
  193. package/dist/sdk/index.js.map +1 -1
  194. package/dist/types.d.ts +51 -2
  195. package/dist/types.js.map +1 -1
  196. package/docs/AGENT_GUIDE.md +15 -0
  197. package/docs/ARCHITECTURE.md +2 -2
  198. package/docs/CLAUDE_CODE_PLUGIN.md +225 -0
  199. package/docs/CODEX_PLUGIN.md +33 -0
  200. package/docs/COMMANDS.md +6 -2
  201. package/docs/CONFIGURATION.md +2 -8
  202. package/docs/EXTENSIONS.md +688 -0
  203. package/docs/MIGRATION_CLI_SIMPLIFICATION.md +64 -0
  204. package/docs/PI_PACKAGE.md +141 -0
  205. package/docs/QUICKSTART.md +1 -0
  206. package/docs/README.md +30 -1
  207. package/docs/RELEASING.md +4 -2
  208. package/docs/SDK.md +444 -2
  209. package/docs/examples/ci/github-actions-pm-extension-gate.yml +53 -0
  210. package/docs/examples/ci/gitlab-ci-pm-extension-gate.yml +41 -0
  211. package/docs/examples/ci/jenkins-pm-extension-gate.Jenkinsfile +45 -0
  212. package/docs/examples/policy-restricted-extension/README.md +74 -0
  213. package/docs/examples/policy-restricted-extension/index.js +21 -0
  214. package/docs/examples/policy-restricted-extension/manifest.json +21 -0
  215. package/docs/examples/policy-restricted-extension/package.json +8 -0
  216. package/docs/examples/sdk-app-embedding/README.md +39 -0
  217. package/docs/examples/sdk-app-embedding/package.json +9 -0
  218. package/docs/examples/sdk-app-embedding/run-embedded-pm.mjs +61 -0
  219. package/docs/examples/sdk-contract-consumer/README.md +57 -0
  220. package/docs/examples/sdk-contract-consumer/inspect-contracts.mjs +47 -0
  221. package/docs/examples/sdk-contract-consumer/package.json +10 -0
  222. package/docs/examples/starter-extension/README.md +57 -42
  223. package/docs/examples/starter-extension/manifest.json +15 -0
  224. package/marketplace.json +34 -0
  225. package/package.json +38 -4
  226. package/plugins/pm-cli-claude/.claude-plugin/plugin.json +23 -0
  227. package/plugins/pm-cli-claude/.mcp.json +12 -0
  228. package/plugins/pm-cli-claude/README.md +225 -0
  229. package/plugins/pm-cli-claude/agents/pm-coordinator.md +48 -0
  230. package/plugins/pm-cli-claude/agents/pm-delivery-chain.md +88 -0
  231. package/plugins/pm-cli-claude/agents/pm-triage-agent.md +83 -0
  232. package/plugins/pm-cli-claude/agents/pm-verification-agent.md +88 -0
  233. package/plugins/pm-cli-claude/commands/pm-audit.md +39 -0
  234. package/plugins/pm-cli-claude/commands/pm-calendar.md +41 -0
  235. package/plugins/pm-cli-claude/commands/pm-close-task.md +20 -0
  236. package/plugins/pm-cli-claude/commands/pm-developer.md +38 -0
  237. package/plugins/pm-cli-claude/commands/pm-init.md +44 -0
  238. package/plugins/pm-cli-claude/commands/pm-list.md +39 -0
  239. package/plugins/pm-cli-claude/commands/pm-new.md +36 -0
  240. package/plugins/pm-cli-claude/commands/pm-planner.md +51 -0
  241. package/plugins/pm-cli-claude/commands/pm-release.md +41 -0
  242. package/plugins/pm-cli-claude/commands/pm-search.md +21 -0
  243. package/plugins/pm-cli-claude/commands/pm-start-task.md +27 -0
  244. package/plugins/pm-cli-claude/commands/pm-status.md +15 -0
  245. package/plugins/pm-cli-claude/commands/pm-triage.md +35 -0
  246. package/plugins/pm-cli-claude/commands/pm-workflow.md +49 -0
  247. package/plugins/pm-cli-claude/hooks/hooks.json +17 -0
  248. package/plugins/pm-cli-claude/hooks/session-start.mjs +120 -0
  249. package/plugins/pm-cli-claude/scripts/pm-mcp-server.mjs +60 -0
  250. package/plugins/pm-cli-claude/skills/pm-audit/SKILL.md +88 -0
  251. package/plugins/pm-cli-claude/skills/pm-developer/SKILL.md +116 -0
  252. package/plugins/pm-cli-claude/skills/pm-planner/SKILL.md +118 -0
  253. package/plugins/pm-cli-claude/skills/pm-release/SKILL.md +83 -0
  254. package/plugins/pm-cli-claude/skills/pm-workflow/SKILL.md +148 -0
  255. package/plugins/pm-cli-codex/.codex-plugin/plugin.json +45 -0
  256. package/plugins/pm-cli-codex/.mcp.json +14 -0
  257. package/plugins/pm-cli-codex/README.md +30 -0
  258. package/plugins/pm-cli-codex/assets/pm-cli-small.svg +4 -0
  259. package/plugins/pm-cli-codex/commands/pm-audit.md +8 -0
  260. package/plugins/pm-cli-codex/commands/pm-close-task.md +9 -0
  261. package/plugins/pm-cli-codex/commands/pm-start-task.md +9 -0
  262. package/plugins/pm-cli-codex/scripts/pm-mcp-server.mjs +54 -0
  263. package/plugins/pm-cli-codex/skills/pm-auditor/SKILL.md +21 -0
  264. package/plugins/pm-cli-codex/skills/pm-auditor/agents/openai.yaml +6 -0
  265. package/plugins/pm-cli-codex/skills/pm-native/SKILL.md +57 -0
  266. package/plugins/pm-cli-codex/skills/pm-native/agents/openai.yaml +6 -0
  267. package/plugins/pm-cli-codex/skills/pm-release/SKILL.md +19 -0
  268. package/plugins/pm-cli-codex/skills/pm-release/agents/openai.yaml +6 -0
package/docs/SDK.md CHANGED
@@ -1,5 +1,429 @@
1
1
  # SDK
2
2
 
3
+ The supported programmatic surface is `@unbrained/pm-cli/sdk`.
4
+
5
+ Use this package for extension authoring, command/action contract discovery, and deterministic app or CI automation. Do not import private `src/core/...` modules from external integrations.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ npm install @unbrained/pm-cli
11
+ ```
12
+
13
+ ## Core Exports
14
+
15
+ ### Extension authoring
16
+
17
+ - `defineExtension`
18
+ - `EXTENSION_CAPABILITIES`
19
+ - `EXTENSION_CAPABILITY_CONTRACT`
20
+ - `EXTENSION_CAPABILITY_CONTRACT_VERSION`
21
+ - `EXTENSION_CAPABILITY_LEGACY_ALIASES`
22
+ - `EXTENSION_POLICY_MODES`
23
+ - `EXTENSION_POLICY_SURFACES`
24
+ - `EXTENSION_TRUST_MODES`
25
+ - `EXTENSION_SANDBOX_PROFILES`
26
+
27
+ ### Command and action contracts
28
+
29
+ - `PM_CORE_COMMAND_NAMES`
30
+ - `PM_TOOL_ACTIONS`
31
+ - `PM_TOOL_PARAMETERS_SCHEMA`
32
+ - `PM_PI_TOOL_PARAMETERS_SCHEMA`
33
+ - `PM_TOOL_ACTION_PARAMETER_CONTRACTS`
34
+
35
+ ### Runtime contract constants
36
+
37
+ - `PM_EXTENSION_CAPABILITY_CONTRACTS`
38
+ - `PM_EXTENSION_SERVICE_NAME_CONTRACTS`
39
+ - `PM_EXTENSION_POLICY_MODE_CONTRACTS`
40
+ - `PM_EXTENSION_POLICY_SURFACE_CONTRACTS`
41
+ - `PM_EXTENSION_TRUST_MODE_CONTRACTS`
42
+ - `PM_EXTENSION_SANDBOX_PROFILE_CONTRACTS`
43
+
44
+ ### Type guards
45
+
46
+ - `isPmToolAction`
47
+ - `isPmExtensionCapabilityContract`
48
+ - `isPmExtensionServiceNameContract`
49
+ - `isPmExtensionPolicyModeContract`
50
+ - `isPmExtensionPolicySurfaceContract`
51
+
52
+ ## Capability Mapping
53
+
54
+ - `commands` -> `registerCommand`
55
+ - `schema` -> `registerFlags`, `registerItemFields`, `registerItemTypes`, `registerMigration`
56
+ - `importers` -> `registerImporter`, `registerExporter`
57
+ - `search` -> `registerSearchProvider`, `registerVectorStoreAdapter`
58
+ - `hooks` -> `api.hooks.*`
59
+ - `parser` -> `registerParser`
60
+ - `preflight` -> `registerPreflight`
61
+ - `services` -> `registerService`
62
+ - `renderers` -> `registerRenderer`
63
+
64
+ ## Extension Example
65
+
66
+ ```ts
67
+ import { defineExtension } from "@unbrained/pm-cli/sdk";
68
+
69
+ export default defineExtension({
70
+ activate(api) {
71
+ api.registerCommand({
72
+ name: "release audit",
73
+ action: "release-audit",
74
+ description: "Collect release-readiness diagnostics.",
75
+ intent: "Produce deterministic gate payloads for CI.",
76
+ flags: [{ long: "--strict", description: "Enable strict gate mode." }],
77
+ run: async (context) => ({
78
+ ok: true,
79
+ command: context.command,
80
+ strict: context.options.strict === true,
81
+ }),
82
+ });
83
+ },
84
+ });
85
+ ```
86
+
87
+ ## Contracts-First Automation
88
+
89
+ Use runtime contracts for extension-aware schemas:
90
+
91
+ ```bash
92
+ pm contracts --json
93
+ pm contracts --schema-only --json
94
+ pm contracts --command extension --flags-only --json
95
+ pm contracts --action create --schema-only --json
96
+ ```
97
+
98
+ Minimal script pattern:
99
+
100
+ ```ts
101
+ import { PM_TOOL_ACTION_PARAMETER_CONTRACTS, isPmToolAction } from "@unbrained/pm-cli/sdk";
102
+ import { spawnSync } from "node:child_process";
103
+
104
+ const action = "extension-reload";
105
+ if (!isPmToolAction(action)) throw new Error("Unsupported action");
106
+ const contract = PM_TOOL_ACTION_PARAMETER_CONTRACTS[action];
107
+ console.log(contract.required, contract.optional);
108
+
109
+ const result = spawnSync("pm", ["contracts", "--json"], { encoding: "utf8" });
110
+ if (result.status !== 0) throw new Error(result.stderr);
111
+ ```
112
+
113
+ ## Compatibility Metadata
114
+
115
+ `pm contracts --json` includes compatibility metadata for extension integrations:
116
+
117
+ - `extension_contracts.trust_modes`
118
+ - `extension_contracts.sandbox_profiles`
119
+ - `extension_contracts.manifest_versions`
120
+ - `extension_contracts.compatibility`
121
+ - `action_availability[].policy_state`
122
+
123
+ Current compatibility model:
124
+
125
+ - manifest current: `v2`
126
+ - supported previous: `v1`
127
+ - strategy: `versioned_breaking`
128
+
129
+ ## Runnable Examples
130
+
131
+ - `docs/examples/sdk-contract-consumer/`
132
+ - `docs/examples/sdk-app-embedding/`
133
+ - `docs/examples/ci/`
134
+
135
+ ## Related Docs
136
+
137
+ - `docs/EXTENSIONS.md`
138
+ - `docs/CLAUDE_CODE_PLUGIN.md`
139
+ # SDK
140
+
141
+ The supported programmatic surface is `@unbrained/pm-cli/sdk`.
142
+
143
+ Use this for:
144
+
145
+ - extension authoring (`defineExtension`)
146
+ - command/action schema discovery (`PM_TOOL_PARAMETERS_SCHEMA`)
147
+ - runtime action contracts (`PM_TOOL_ACTION_PARAMETER_CONTRACTS`)
148
+ - capability/policy/trust/sandbox contract constants
149
+
150
+ Do not import private `src/core/...` modules from external integrations.
151
+
152
+ ## Install
153
+
154
+ ```bash
155
+ npm install @unbrained/pm-cli
156
+ ```
157
+
158
+ ## Key Exports
159
+
160
+ ### Extension Authoring
161
+
162
+ - `defineExtension`
163
+ - `EXTENSION_CAPABILITIES`
164
+ - `EXTENSION_POLICY_MODES`
165
+ - `EXTENSION_POLICY_SURFACES`
166
+ - `EXTENSION_TRUST_MODES`
167
+ - `EXTENSION_SANDBOX_PROFILES`
168
+ - `EXTENSION_CAPABILITY_CONTRACT`
169
+ - `EXTENSION_CAPABILITY_CONTRACT_VERSION`
170
+ - `EXTENSION_CAPABILITY_LEGACY_ALIASES`
171
+
172
+ ### Command/Action Contracts
173
+
174
+ - `PM_CORE_COMMAND_NAMES`
175
+ - `PM_TOOL_ACTIONS`
176
+ - `PM_TOOL_PARAMETERS_SCHEMA`
177
+ - `PM_PI_TOOL_PARAMETERS_SCHEMA`
178
+ - `PM_TOOL_ACTION_PARAMETER_CONTRACTS`
179
+
180
+ ### Extension Runtime Contract Constants
181
+
182
+ - `PM_EXTENSION_CAPABILITY_CONTRACTS`
183
+ - `PM_EXTENSION_SERVICE_NAME_CONTRACTS`
184
+ - `PM_EXTENSION_POLICY_MODE_CONTRACTS`
185
+ - `PM_EXTENSION_POLICY_SURFACE_CONTRACTS`
186
+ - `PM_EXTENSION_TRUST_MODE_CONTRACTS`
187
+ - `PM_EXTENSION_SANDBOX_PROFILE_CONTRACTS`
188
+
189
+ ### Type Guards
190
+
191
+ - `isPmToolAction`
192
+ - `isPmExtensionCapabilityContract`
193
+ - `isPmExtensionServiceNameContract`
194
+ - `isPmExtensionPolicyModeContract`
195
+ - `isPmExtensionPolicySurfaceContract`
196
+
197
+ ## Extension Example
198
+
199
+ ```ts
200
+ import { defineExtension } from "@unbrained/pm-cli/sdk";
201
+
202
+ export default defineExtension({
203
+ activate(api) {
204
+ api.registerCommand({
205
+ name: "release audit",
206
+ action: "release-audit",
207
+ description: "Collect release-readiness diagnostics.",
208
+ intent: "Produce deterministic gate payloads for CI.",
209
+ run: async (context) => ({
210
+ ok: true,
211
+ command: context.command,
212
+ }),
213
+ });
214
+ },
215
+ });
216
+ ```
217
+
218
+ ## Contracts-First Automation Pattern
219
+
220
+ ```ts
221
+ import { PM_TOOL_ACTION_PARAMETER_CONTRACTS, isPmToolAction } from "@unbrained/pm-cli/sdk";
222
+ import { spawnSync } from "node:child_process";
223
+
224
+ const action = "extension-reload";
225
+ if (!isPmToolAction(action)) throw new Error("Unsupported action");
226
+ const contract = PM_TOOL_ACTION_PARAMETER_CONTRACTS[action];
227
+ console.log(contract.required, contract.optional);
228
+
229
+ const contracts = spawnSync("pm", ["contracts", "--json"], { encoding: "utf8" });
230
+ if (contracts.status !== 0) throw new Error(contracts.stderr);
231
+ ```
232
+
233
+ ## Runtime Metadata Added For v2
234
+
235
+ `pm contracts --json` now includes richer extension metadata:
236
+
237
+ - `extension_contracts.trust_modes`
238
+ - `extension_contracts.sandbox_profiles`
239
+ - `extension_contracts.manifest_versions`
240
+ - `extension_contracts.compatibility`
241
+ - `action_availability[].policy_state` for extension-backed actions
242
+
243
+ Use these fields to gate CI and to route compatibility behavior in embedded runtimes.
244
+
245
+ ## Versioned-Breaking Compatibility
246
+
247
+ Current contract compatibility model:
248
+
249
+ - `manifest` current: `v2`
250
+ - supported previous: `v1`
251
+ - strategy: `versioned_breaking`
252
+
253
+ Recommended migration flow:
254
+
255
+ 1. read runtime contracts (`pm contracts --json`)
256
+ 2. branch behavior by compatibility metadata
257
+ 3. migrate manifests/policy to v2
258
+ 4. enforce trust/sandbox policy gates in CI
259
+
260
+ ## Runnable Examples
261
+
262
+ - contracts consumer: `docs/examples/sdk-contract-consumer/`
263
+ - app embedding runner: `docs/examples/sdk-app-embedding/`
264
+ - CI gates: `docs/examples/ci/`
265
+
266
+ ## Related Docs
267
+
268
+ - `docs/EXTENSIONS.md`
269
+ - `docs/CLAUDE_CODE_PLUGIN.md`
270
+ # SDK
271
+
272
+ The stable integration surface is `@unbrained/pm-cli/sdk`. Use it for extension authoring, action/flag contract discovery, and deterministic app/CI automation.
273
+
274
+ ## Install
275
+
276
+ ```bash
277
+ npm install @unbrained/pm-cli
278
+ ```
279
+
280
+ ```ts
281
+ import {
282
+ defineExtension,
283
+ EXTENSION_CAPABILITIES,
284
+ EXTENSION_POLICY_MODES,
285
+ EXTENSION_POLICY_SURFACES,
286
+ PM_TOOL_ACTIONS,
287
+ PM_TOOL_PARAMETERS_SCHEMA,
288
+ PM_TOOL_ACTION_PARAMETER_CONTRACTS,
289
+ PM_EXTENSION_CAPABILITY_CONTRACTS,
290
+ PM_EXTENSION_SERVICE_NAME_CONTRACTS,
291
+ PM_EXTENSION_POLICY_MODE_CONTRACTS,
292
+ PM_EXTENSION_POLICY_SURFACE_CONTRACTS,
293
+ isPmToolAction,
294
+ isPmExtensionCapabilityContract,
295
+ } from "@unbrained/pm-cli/sdk";
296
+ ```
297
+
298
+ ## What Is Exported
299
+
300
+ Core authoring exports:
301
+
302
+ - `defineExtension`
303
+ - `EXTENSION_CAPABILITIES`
304
+ - `EXTENSION_CAPABILITY_CONTRACT`
305
+ - `EXTENSION_POLICY_MODES`
306
+ - `EXTENSION_POLICY_SURFACES`
307
+
308
+ Command/action contract exports:
309
+
310
+ - `PM_CORE_COMMAND_NAMES`
311
+ - `PM_TOOL_ACTIONS`
312
+ - `PM_TOOL_PARAMETERS_SCHEMA`
313
+ - `PM_PI_TOOL_PARAMETERS_SCHEMA`
314
+ - `PM_TOOL_ACTION_PARAMETER_CONTRACTS`
315
+
316
+ Extension runtime contract exports:
317
+
318
+ - `PM_EXTENSION_CAPABILITY_CONTRACTS`
319
+ - `PM_EXTENSION_SERVICE_NAME_CONTRACTS`
320
+ - `PM_EXTENSION_POLICY_MODE_CONTRACTS`
321
+ - `PM_EXTENSION_POLICY_SURFACE_CONTRACTS`
322
+
323
+ Type guards:
324
+
325
+ - `isPmToolAction(value)`
326
+ - `isPmExtensionCapabilityContract(value)`
327
+ - `isPmExtensionServiceNameContract(value)`
328
+ - `isPmExtensionPolicyModeContract(value)`
329
+ - `isPmExtensionPolicySurfaceContract(value)`
330
+
331
+ ## Capability Mapping
332
+
333
+ - `commands` -> `registerCommand`
334
+ - `schema` -> `registerFlags`, `registerItemFields`, `registerItemTypes`, `registerMigration`
335
+ - `importers` -> `registerImporter`, `registerExporter`
336
+ - `search` -> `registerSearchProvider`, `registerVectorStoreAdapter`
337
+ - `hooks` -> `api.hooks.*`
338
+ - `parser` -> `registerParser`
339
+ - `preflight` -> `registerPreflight`
340
+ - `services` -> `registerService`
341
+ - `renderers` -> `registerRenderer`
342
+
343
+ ## Extension Authoring Example
344
+
345
+ ```ts
346
+ import { defineExtension } from "@unbrained/pm-cli/sdk";
347
+
348
+ export default defineExtension({
349
+ activate(api) {
350
+ api.registerCommand({
351
+ name: "release audit",
352
+ action: "release-audit",
353
+ description: "Collect release readiness diagnostics.",
354
+ intent: "provide deterministic audit payloads for CI gates",
355
+ examples: ["pm release audit --strict"],
356
+ failure_hints: ["Run pm extension --doctor --detail deep --trace on activation failures."],
357
+ flags: [{ long: "--strict", description: "Enable strict gate mode." }],
358
+ run: async (context) => ({
359
+ ok: true,
360
+ command: context.command,
361
+ strict: context.options.strict === true,
362
+ }),
363
+ });
364
+ },
365
+ });
366
+ ```
367
+
368
+ ## Programmatic Contracts (App/Script)
369
+
370
+ Use runtime `pm contracts` for extension-aware schemas:
371
+
372
+ ```bash
373
+ pm contracts --json
374
+ pm contracts --schema-only --json
375
+ pm contracts --command extension --flags-only --json
376
+ pm contracts --action create --schema-only --json
377
+ ```
378
+
379
+ The result includes:
380
+
381
+ - `actions`: runtime-invocable action list
382
+ - `action_availability`: invocable/disabled reasons
383
+ - `schema`: strict action-scoped JSON schema
384
+ - `command_flags`: merged core + extension + runtime field flags
385
+ - `extension_contracts`: capabilities/services/policy mode/surface contract metadata
386
+
387
+ ## Robust Script Pattern
388
+
389
+ See runnable example: `docs/examples/sdk-contract-consumer/inspect-contracts.mjs`.
390
+
391
+ Minimal pattern:
392
+
393
+ 1. Read contracts JSON.
394
+ 2. Validate action exists in `actions`.
395
+ 3. Validate required fields with `PM_TOOL_ACTION_PARAMETER_CONTRACTS`.
396
+ 4. Execute the action only after preflight passes.
397
+
398
+ ## CI/CD Pattern
399
+
400
+ Recommended gate sequence:
401
+
402
+ ```bash
403
+ pnpm build
404
+ pm contracts --schema-only --json > /tmp/pm-contracts.json
405
+ pm extension --doctor --project --detail summary --strict-exit
406
+ node scripts/run-tests.mjs test -- tests/unit/contracts-command.spec.ts
407
+ node scripts/run-tests.mjs coverage
408
+ ```
409
+
410
+ Reference workflow file:
411
+
412
+ - `docs/examples/ci/github-actions-pm-extension-gate.yml`
413
+
414
+ ## Pi / Tooling Compatibility
415
+
416
+ For provider-safe schemas, use `PM_PI_TOOL_PARAMETERS_SCHEMA`. It is flat, non-`oneOf`, and designed for tool providers that reject advanced schema constructs.
417
+
418
+ The bundled Pi wrapper (`.pi/extensions/pm-cli/index.js`) consumes this schema directly to reduce contract drift.
419
+
420
+ ## Related Docs
421
+
422
+ - `docs/EXTENSIONS.md`
423
+ - `docs/examples/starter-extension/README.md`
424
+ - `docs/examples/sdk-contract-consumer/README.md`
425
+ # SDK
426
+
3
427
  The public SDK is exported from `@unbrained/pm-cli/sdk`. Use it for extension authoring and command-contract introspection. Do not import internal `src/core/...` modules from extensions.
4
428
 
5
429
  ## Agent Quick Context
@@ -7,6 +431,7 @@ The public SDK is exported from `@unbrained/pm-cli/sdk`. Use it for extension au
7
431
  - Primary import: `@unbrained/pm-cli/sdk`.
8
432
  - Runtime extension lifecycle is documented in [Extensions](EXTENSIONS.md).
9
433
  - Exact command/action contracts are available through `pm contracts`.
434
+ - Local deep-dive routing is available through `pm guide sdk --depth deep`.
10
435
 
11
436
  Tracked documentation work: [pm-1sb2](../.agents/pm/tasks/pm-1sb2.toon).
12
437
 
@@ -144,8 +569,8 @@ export default defineExtension({
144
569
  name: "example-search",
145
570
  async query(context) {
146
571
  return context.documents
147
- .filter((doc) => doc.front_matter.title?.toLowerCase().includes(context.query.toLowerCase()))
148
- .map((doc) => ({ id: doc.front_matter.id, score: 0.5, matched_fields: ["title"] }));
572
+ .filter((doc) => doc.metadata.title?.toLowerCase().includes(context.query.toLowerCase()))
573
+ .map((doc) => ({ id: doc.metadata.id, score: 0.5, matched_fields: ["title"] }));
149
574
  },
150
575
  });
151
576
  },
@@ -166,6 +591,22 @@ pm contracts --action create --schema-only --json
166
591
 
167
592
  Use the runtime command because active extensions can add command/action metadata.
168
593
 
594
+ ## CLI Simplification Migration
595
+
596
+ The conservative full-surface simplification pass updated invocation parsing and error envelopes. Integration details are documented in:
597
+
598
+ - [CLI Simplification Migration](MIGRATION_CLI_SIMPLIFICATION.md)
599
+
600
+ For SDK and automation consumers, the key runtime change is the optional `recovery` object in CLI usage/error JSON payloads:
601
+
602
+ - `attempted_command`
603
+ - `normalized_args`
604
+ - `provided_fields`
605
+ - `missing`
606
+ - `suggested_retry`
607
+
608
+ Treat `recovery.suggested_retry` as the first-choice deterministic replay command when present.
609
+
169
610
  ## Authoring Pattern
170
611
 
171
612
  - Keep handlers deterministic and JSON-like.
@@ -178,5 +619,6 @@ Use the runtime command because active extensions can add command/action metadat
178
619
  ## Related Docs
179
620
 
180
621
  - [Extensions](EXTENSIONS.md)
622
+ - [CLI Simplification Migration](MIGRATION_CLI_SIMPLIFICATION.md)
181
623
  - [Architecture](ARCHITECTURE.md)
182
624
  - [starter extension](examples/starter-extension/README.md)
@@ -0,0 +1,53 @@
1
+ name: pm-extension-gate
2
+
3
+ on:
4
+ pull_request:
5
+ push:
6
+ branches:
7
+ - main
8
+
9
+ jobs:
10
+ extension-gate:
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - name: Checkout
14
+ uses: actions/checkout@v4
15
+
16
+ - name: Setup Node
17
+ uses: actions/setup-node@v4
18
+ with:
19
+ node-version: 22
20
+ cache: pnpm
21
+
22
+ - name: Setup pnpm
23
+ uses: pnpm/action-setup@v4
24
+ with:
25
+ version: 10
26
+
27
+ - name: Install dependencies
28
+ run: pnpm install --frozen-lockfile
29
+
30
+ - name: Build
31
+ run: pnpm build
32
+
33
+ - name: Export contracts (schema + flags)
34
+ run: |
35
+ pm contracts --schema-only --json > contracts-schema.json
36
+ pm contracts --command extension --flags-only --json > contracts-extension-flags.json
37
+ pm contracts --json > contracts-runtime.json
38
+
39
+ - name: Verify extension contract compatibility metadata
40
+ run: |
41
+ node -e 'const fs=require("node:fs");const c=JSON.parse(fs.readFileSync("contracts-runtime.json","utf8"));if(!c.extension_contracts?.compatibility){throw new Error("missing extension compatibility metadata");}'
42
+
43
+ - name: Reload extensions
44
+ run: pm extension --reload --project --json
45
+
46
+ - name: Extension governance diagnostics gate
47
+ run: pm extension --doctor --project --detail summary --strict-exit
48
+
49
+ - name: Unit tests
50
+ run: node scripts/run-tests.mjs test -- tests/unit/contracts-command.spec.ts tests/unit/extension-loader.spec.ts tests/unit/extension-command.spec.ts
51
+
52
+ - name: Coverage
53
+ run: node scripts/run-tests.mjs coverage
@@ -0,0 +1,41 @@
1
+ image: node:22
2
+
3
+ stages:
4
+ - build
5
+ - contracts
6
+ - extension_gate
7
+ - test
8
+
9
+ before_script:
10
+ - corepack enable
11
+ - corepack prepare pnpm@10 --activate
12
+ - pnpm install --frozen-lockfile
13
+
14
+ build:
15
+ stage: build
16
+ script:
17
+ - pnpm build
18
+
19
+ contracts:
20
+ stage: contracts
21
+ script:
22
+ - node dist/cli.js contracts --schema-only --json > contracts-schema.json
23
+ - node dist/cli.js contracts --command extension --flags-only --json > contracts-extension-flags.json
24
+ - node dist/cli.js contracts --json > contracts-runtime.json
25
+ artifacts:
26
+ paths:
27
+ - contracts-schema.json
28
+ - contracts-extension-flags.json
29
+ - contracts-runtime.json
30
+
31
+ extension_gate:
32
+ stage: extension_gate
33
+ script:
34
+ - node dist/cli.js extension --reload --project --json
35
+ - node dist/cli.js extension --doctor --project --detail summary --strict-exit --json
36
+
37
+ test:
38
+ stage: test
39
+ script:
40
+ - node scripts/run-tests.mjs test -- tests/unit/contracts-command.spec.ts tests/unit/extension-loader.spec.ts tests/unit/extension-command.spec.ts
41
+ - node scripts/run-tests.mjs coverage
@@ -0,0 +1,45 @@
1
+ pipeline {
2
+ agent any
3
+
4
+ tools {
5
+ nodejs "node-22"
6
+ }
7
+
8
+ stages {
9
+ stage("Install") {
10
+ steps {
11
+ sh "corepack enable"
12
+ sh "corepack prepare pnpm@10 --activate"
13
+ sh "pnpm install --frozen-lockfile"
14
+ }
15
+ }
16
+
17
+ stage("Build") {
18
+ steps {
19
+ sh "pnpm build"
20
+ }
21
+ }
22
+
23
+ stage("Contracts") {
24
+ steps {
25
+ sh "node dist/cli.js contracts --schema-only --json > contracts-schema.json"
26
+ sh "node dist/cli.js contracts --command extension --flags-only --json > contracts-extension-flags.json"
27
+ sh "node dist/cli.js contracts --json > contracts-runtime.json"
28
+ }
29
+ }
30
+
31
+ stage("Extension Gate") {
32
+ steps {
33
+ sh "node dist/cli.js extension --reload --project --json"
34
+ sh "node dist/cli.js extension --doctor --project --detail summary --strict-exit --json"
35
+ }
36
+ }
37
+
38
+ stage("Tests") {
39
+ steps {
40
+ sh "node scripts/run-tests.mjs test -- tests/unit/contracts-command.spec.ts tests/unit/extension-loader.spec.ts tests/unit/extension-command.spec.ts"
41
+ sh "node scripts/run-tests.mjs coverage"
42
+ }
43
+ }
44
+ }
45
+ }
@@ -0,0 +1,74 @@
1
+ # Policy-Restricted Extension Example
2
+
3
+ This example demonstrates governance policy behavior with real registrations.
4
+
5
+ The extension declares:
6
+
7
+ - `commands` (handler registration)
8
+ - `hooks` (beforeCommand)
9
+ - `services` (output_format override)
10
+
11
+ You can enforce policy so command/hooks remain allowed while service override is blocked.
12
+
13
+ ## Run It
14
+
15
+ From repository root:
16
+
17
+ ```bash
18
+ mkdir -p .agents/pm/extensions
19
+ cp -R docs/examples/policy-restricted-extension .agents/pm/extensions/policy-restricted-extension
20
+ cd .agents/pm/extensions/policy-restricted-extension
21
+ npm install
22
+ cd -
23
+ pm extension --install --project .agents/pm/extensions/policy-restricted-extension
24
+ ```
25
+
26
+ Add policy in `.agents/pm/settings.json`:
27
+
28
+ ```json
29
+ {
30
+ "extensions": {
31
+ "policy": {
32
+ "mode": "enforce",
33
+ "trust_mode": "enforce",
34
+ "require_provenance": true,
35
+ "trusted_extensions": ["policy-restricted-extension"],
36
+ "default_sandbox_profile": "restricted",
37
+ "allowed_extensions": ["policy-restricted-extension"],
38
+ "blocked_extensions": [],
39
+ "allowed_capabilities": [],
40
+ "blocked_capabilities": [],
41
+ "allowed_surfaces": [],
42
+ "blocked_surfaces": ["services.override"],
43
+ "allowed_commands": [],
44
+ "blocked_commands": [],
45
+ "allowed_actions": [],
46
+ "blocked_actions": [],
47
+ "allowed_services": [],
48
+ "blocked_services": ["output_format"],
49
+ "extension_overrides": [
50
+ {
51
+ "name": "policy-restricted-extension",
52
+ "require_trusted": true,
53
+ "require_provenance": true,
54
+ "sandbox_profile": "strict"
55
+ }
56
+ ]
57
+ }
58
+ }
59
+ }
60
+ ```
61
+
62
+ Then validate:
63
+
64
+ ```bash
65
+ pm extension --doctor --project --detail summary
66
+ pm policy demo
67
+ ```
68
+
69
+ Expected behavior:
70
+
71
+ - `pm policy demo` still works (command handler allowed).
72
+ - `extension --doctor` includes `extension_policy_blocked_registration`.
73
+ - `details.triage.policy_blocked_count` is greater than `0`.
74
+ - trust/provenance contract fields are visible in `pm contracts --json` metadata.
@@ -0,0 +1,21 @@
1
+ import { defineExtension } from "@unbrained/pm-cli/sdk";
2
+
3
+ export default defineExtension({
4
+ activate(api) {
5
+ api.registerCommand({
6
+ name: "policy demo",
7
+ action: "policy-demo",
8
+ description: "Emit a deterministic payload to validate policy-gated activation.",
9
+ run: async (context) => ({
10
+ ok: true,
11
+ command: context.command,
12
+ source: "policy-restricted-extension",
13
+ }),
14
+ });
15
+
16
+ api.hooks.beforeCommand(() => {});
17
+
18
+ // This registration is intentionally useful for policy demos.
19
+ api.registerService("output_format", (payload) => payload);
20
+ },
21
+ });