@unbrained/pm-cli 2026.5.10 → 2026.5.12

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 (172) hide show
  1. package/.claude-plugin/marketplace.json +4 -4
  2. package/AGENTS.md +3 -116
  3. package/CHANGELOG.md +14 -0
  4. package/PRD.md +11 -11
  5. package/README.md +20 -2
  6. package/dist/cli/argv-utils.d.ts +5 -0
  7. package/dist/cli/argv-utils.js +34 -0
  8. package/dist/cli/argv-utils.js.map +1 -0
  9. package/dist/cli/bootstrap-args.d.ts +15 -0
  10. package/dist/cli/bootstrap-args.js +211 -0
  11. package/dist/cli/bootstrap-args.js.map +1 -1
  12. package/dist/cli/commander-usage.js +109 -3
  13. package/dist/cli/commander-usage.js.map +1 -1
  14. package/dist/cli/commands/completion.js +7 -3
  15. package/dist/cli/commands/completion.js.map +1 -1
  16. package/dist/cli/commands/contracts.d.ts +19 -0
  17. package/dist/cli/commands/contracts.js +40 -2
  18. package/dist/cli/commands/contracts.js.map +1 -1
  19. package/dist/cli/commands/create.js +112 -51
  20. package/dist/cli/commands/create.js.map +1 -1
  21. package/dist/cli/commands/docs.js +9 -2
  22. package/dist/cli/commands/docs.js.map +1 -1
  23. package/dist/cli/commands/extension.d.ts +12 -3
  24. package/dist/cli/commands/extension.js +421 -69
  25. package/dist/cli/commands/extension.js.map +1 -1
  26. package/dist/cli/commands/files.js +9 -2
  27. package/dist/cli/commands/files.js.map +1 -1
  28. package/dist/cli/commands/index.d.ts +1 -0
  29. package/dist/cli/commands/index.js +1 -0
  30. package/dist/cli/commands/index.js.map +1 -1
  31. package/dist/cli/commands/init.d.ts +2 -0
  32. package/dist/cli/commands/init.js +21 -1
  33. package/dist/cli/commands/init.js.map +1 -1
  34. package/dist/cli/commands/metadata-normalizers.d.ts +4 -0
  35. package/dist/cli/commands/metadata-normalizers.js +37 -0
  36. package/dist/cli/commands/metadata-normalizers.js.map +1 -0
  37. package/dist/cli/commands/reindex.js +173 -135
  38. package/dist/cli/commands/reindex.js.map +1 -1
  39. package/dist/cli/commands/search.js +16 -6
  40. package/dist/cli/commands/search.js.map +1 -1
  41. package/dist/cli/commands/test.js +23 -8
  42. package/dist/cli/commands/test.js.map +1 -1
  43. package/dist/cli/commands/update.js +70 -39
  44. package/dist/cli/commands/update.js.map +1 -1
  45. package/dist/cli/commands/upgrade.d.ts +63 -0
  46. package/dist/cli/commands/upgrade.js +260 -0
  47. package/dist/cli/commands/upgrade.js.map +1 -0
  48. package/dist/cli/error-guidance.d.ts +9 -1
  49. package/dist/cli/error-guidance.js +147 -6
  50. package/dist/cli/error-guidance.js.map +1 -1
  51. package/dist/cli/guide-topics.js +18 -16
  52. package/dist/cli/guide-topics.js.map +1 -1
  53. package/dist/cli/help-content.js +42 -2
  54. package/dist/cli/help-content.js.map +1 -1
  55. package/dist/cli/help-json-payload.js +11 -1
  56. package/dist/cli/help-json-payload.js.map +1 -1
  57. package/dist/cli/main.js +69 -6
  58. package/dist/cli/main.js.map +1 -1
  59. package/dist/cli/register-setup.js +174 -82
  60. package/dist/cli/register-setup.js.map +1 -1
  61. package/dist/cli/telemetry-flush.d.ts +2 -0
  62. package/dist/cli/telemetry-flush.js +4 -0
  63. package/dist/cli/telemetry-flush.js.map +1 -0
  64. package/dist/cli.js +1 -2
  65. package/dist/cli.js.map +1 -1
  66. package/dist/core/extensions/extension-types.d.ts +72 -0
  67. package/dist/core/extensions/extension-types.js +24 -0
  68. package/dist/core/extensions/extension-types.js.map +1 -1
  69. package/dist/core/extensions/loader.d.ts +1 -0
  70. package/dist/core/extensions/loader.js +766 -7
  71. package/dist/core/extensions/loader.js.map +1 -1
  72. package/dist/core/lock/lock.js +2 -0
  73. package/dist/core/lock/lock.js.map +1 -1
  74. package/dist/core/packages/manifest.d.ts +13 -0
  75. package/dist/core/packages/manifest.js +139 -0
  76. package/dist/core/packages/manifest.js.map +1 -0
  77. package/dist/core/sentry/instrument.d.ts +15 -0
  78. package/dist/core/sentry/instrument.js +35 -3
  79. package/dist/core/sentry/instrument.js.map +1 -1
  80. package/dist/core/shared/constants.js +20 -0
  81. package/dist/core/shared/constants.js.map +1 -1
  82. package/dist/core/shared/errors.d.ts +8 -0
  83. package/dist/core/shared/errors.js.map +1 -1
  84. package/dist/core/shared/levenshtein.d.ts +1 -0
  85. package/dist/core/shared/levenshtein.js +37 -0
  86. package/dist/core/shared/levenshtein.js.map +1 -0
  87. package/dist/core/store/paths.js +34 -1
  88. package/dist/core/store/paths.js.map +1 -1
  89. package/dist/core/store/settings.js +210 -1
  90. package/dist/core/store/settings.js.map +1 -1
  91. package/dist/core/telemetry/runtime.d.ts +1 -0
  92. package/dist/core/telemetry/runtime.js +102 -3
  93. package/dist/core/telemetry/runtime.js.map +1 -1
  94. package/dist/mcp/server.js +11 -2
  95. package/dist/mcp/server.js.map +1 -1
  96. package/dist/sdk/cli-contracts.d.ts +38 -17
  97. package/dist/sdk/cli-contracts.js +387 -35
  98. package/dist/sdk/cli-contracts.js.map +1 -1
  99. package/dist/sdk/index.d.ts +13 -1
  100. package/dist/sdk/index.js +9 -1
  101. package/dist/sdk/index.js.map +1 -1
  102. package/dist/types.d.ts +41 -0
  103. package/dist/types.js.map +1 -1
  104. package/docs/ARCHITECTURE.md +1 -1
  105. package/docs/CLAUDE_CODE_PLUGIN.md +39 -0
  106. package/docs/COMMANDS.md +14 -1
  107. package/docs/EXTENSIONS.md +782 -12
  108. package/docs/MIGRATION_CLI_SIMPLIFICATION.md +64 -0
  109. package/docs/QUICKSTART.md +10 -2
  110. package/docs/README.md +4 -6
  111. package/docs/SDK.md +445 -0
  112. package/docs/examples/ci/github-actions-pm-extension-gate.yml +53 -0
  113. package/docs/examples/ci/gitlab-ci-pm-extension-gate.yml +41 -0
  114. package/docs/examples/ci/jenkins-pm-extension-gate.Jenkinsfile +45 -0
  115. package/docs/examples/policy-restricted-extension/README.md +74 -0
  116. package/docs/examples/policy-restricted-extension/index.js +21 -0
  117. package/docs/examples/policy-restricted-extension/manifest.json +21 -0
  118. package/docs/examples/policy-restricted-extension/package.json +8 -0
  119. package/docs/examples/sdk-app-embedding/README.md +39 -0
  120. package/docs/examples/sdk-app-embedding/package.json +9 -0
  121. package/docs/examples/sdk-app-embedding/run-embedded-pm.mjs +61 -0
  122. package/docs/examples/sdk-contract-consumer/README.md +57 -0
  123. package/docs/examples/sdk-contract-consumer/inspect-contracts.mjs +47 -0
  124. package/docs/examples/sdk-contract-consumer/package.json +10 -0
  125. package/docs/examples/starter-extension/README.md +57 -42
  126. package/docs/examples/starter-extension/manifest.json +15 -0
  127. package/marketplace.json +3 -3
  128. package/package.json +5 -23
  129. package/packages/pm-beads/README.md +10 -0
  130. package/{.agents/pm → packages/pm-beads}/extensions/beads/index.js +24 -9
  131. package/packages/pm-beads/extensions/beads/index.ts +131 -0
  132. package/packages/pm-beads/package.json +17 -0
  133. package/packages/pm-todos/README.md +11 -0
  134. package/{.agents/pm → packages/pm-todos}/extensions/todos/index.js +24 -9
  135. package/packages/pm-todos/extensions/todos/index.ts +149 -0
  136. package/{.agents/pm → packages/pm-todos}/extensions/todos/runtime.js +1 -1
  137. package/{.agents/pm → packages/pm-todos}/extensions/todos/runtime.ts +1 -1
  138. package/packages/pm-todos/package.json +17 -0
  139. package/plugins/pm-cli-claude/.claude-plugin/plugin.json +2 -2
  140. package/plugins/pm-cli-claude/README.md +54 -14
  141. package/plugins/pm-cli-claude/agents/pm-delivery-chain.md +88 -0
  142. package/plugins/pm-cli-claude/agents/pm-triage-agent.md +83 -0
  143. package/plugins/pm-cli-claude/agents/pm-verification-agent.md +88 -0
  144. package/plugins/pm-cli-claude/hooks/session-start.mjs +35 -21
  145. package/.agents/pm/extensions/.managed-extensions.json +0 -42
  146. package/.agents/skills/HARNESS_COMPATIBILITY.md +0 -45
  147. package/.agents/skills/README.md +0 -21
  148. package/.agents/skills/pm-developer/SKILL.md +0 -73
  149. package/.agents/skills/pm-developer/references/COMMAND_PLAYBOOK.md +0 -48
  150. package/.agents/skills/pm-developer/references/PROMPTS.md +0 -17
  151. package/.agents/skills/pm-extensions/SKILL.md +0 -57
  152. package/.agents/skills/pm-extensions/references/LIFECYCLE.md +0 -40
  153. package/.agents/skills/pm-extensions/references/TROUBLESHOOTING.md +0 -25
  154. package/.agents/skills/pm-sdk/SKILL.md +0 -50
  155. package/.agents/skills/pm-sdk/references/INTEGRATION_CHECKLIST.md +0 -31
  156. package/.agents/skills/pm-sdk/references/PROMPTS.md +0 -13
  157. package/.agents/skills/pm-user/SKILL.md +0 -59
  158. package/.agents/skills/pm-user/references/PROMPTS.md +0 -17
  159. package/.agents/skills/pm-user/references/WORKFLOWS.md +0 -35
  160. package/.pi/README.md +0 -26
  161. package/.pi/extensions/pm-cli/index.js +0 -147
  162. package/.pi/prompts/pm-workflow.md +0 -5
  163. package/.pi/skills/pm-native/SKILL.md +0 -40
  164. package/.pi/skills/pm-release/SKILL.md +0 -35
  165. package/dist/pi/native.d.ts +0 -5
  166. package/dist/pi/native.js +0 -183
  167. package/dist/pi/native.js.map +0 -1
  168. package/docs/PI_PACKAGE.md +0 -56
  169. /package/{.agents/pm → packages/pm-beads}/extensions/beads/manifest.json +0 -0
  170. /package/{.agents/pm → packages/pm-beads}/extensions/beads/runtime.js +0 -0
  171. /package/{.agents/pm → packages/pm-beads}/extensions/beads/runtime.ts +0 -0
  172. /package/{.agents/pm → packages/pm-todos}/extensions/todos/manifest.json +0 -0
@@ -1,3 +1,779 @@
1
+ # Packages and Extensions
2
+
3
+ Packages let you add or override `pm` runtime behavior without modifying core `pm-cli` sources. A package can currently contain one or more runtime extensions, and the package-first command surface is the preferred user-facing workflow.
4
+
5
+ `pm extension ...` remains supported for compatibility. New scripts and docs should prefer `pm install ...` and `pm package ...`.
6
+
7
+ This document is the canonical package/extension reference for manifest contracts, governance policy, trust and sandbox controls, reload workflows, and diagnostics.
8
+
9
+ ## Quick Start
10
+
11
+ ```bash
12
+ # 1) Scaffold a package extension
13
+ pm package init ./my-package-extension
14
+
15
+ # 2) Install in project scope
16
+ pm install ./my-package --project
17
+
18
+ # Or install all bundled first-party packages
19
+ pm install '*' --project
20
+
21
+ # 3) Run diagnostics
22
+ pm package doctor --project --detail summary
23
+
24
+ # 4) Plan CLI/SDK and package upgrades
25
+ pm upgrade --dry-run
26
+
27
+ # 5) Reload runtime modules after local edits
28
+ pm package reload --project
29
+ ```
30
+
31
+ Compatibility equivalents:
32
+
33
+ ```bash
34
+ pm extension init ./my-package
35
+ pm extension install ./my-package --project
36
+ pm extension doctor --project --detail summary
37
+ pm extension reload --project
38
+ ```
39
+
40
+ ## Upgrade Workflow
41
+
42
+ `pm upgrade` is the package-first update entrypoint:
43
+
44
+ ```bash
45
+ pm upgrade --dry-run # plan CLI/SDK and project package updates
46
+ pm upgrade # update the global pm CLI/SDK, then refresh project packages
47
+ pm upgrade --packages-only # refresh managed packages without changing the CLI
48
+ pm upgrade todos --dry-run # plan one managed package refresh
49
+ pm upgrade --cli-only --repair # force a global CLI/SDK reinstall through npm
50
+ ```
51
+
52
+ CLI/SDK upgrades use `npm install -g @unbrained/pm-cli@<tag>`.
53
+ Managed package upgrades reuse the source recorded at install time, including `npm:`, GitHub, local, and first-party package paths.
54
+ Use `--tag <version-or-dist-tag>` to target a registry tag such as `latest` or `next`.
55
+
56
+ ## Extension Locations
57
+
58
+ - project scope: `.agents/pm/extensions/<name>/`
59
+ - global scope: `~/.pm-cli/extensions/<name>/`
60
+ - project entries override global entries for matching command paths
61
+
62
+ Runtime path overrides:
63
+
64
+ - `PM_PATH`: project tracker root override
65
+ - `PM_GLOBAL_PATH`: global profile root override
66
+
67
+ ## Package Sources
68
+
69
+ `pm install` accepts these package sources:
70
+
71
+ ```bash
72
+ pm install ./local-package
73
+ pm install /absolute/path/to/package
74
+ pm install npm:@scope/package
75
+ pm install npm:package@1.2.3
76
+ pm install https://github.com/org/repo
77
+ pm install --github org/repo/path --ref main
78
+ ```
79
+
80
+ Package roots can expose resources with a `pm` manifest in `package.json`:
81
+
82
+ ```json
83
+ {
84
+ "name": "my-pm-package",
85
+ "keywords": ["pm-package"],
86
+ "pm": {
87
+ "extensions": ["extensions/my-extension"]
88
+ }
89
+ }
90
+ ```
91
+
92
+ The SDK exposes this project-management package model through `PM_PACKAGE_RESOURCE_KINDS`, `PM_PACKAGE_CONVENTIONAL_RESOURCE_ROOTS`, and `readPmPackageManifest`. Package installation activates runtime extension resources. Agent-specific bundles such as prompts, skills, and MCP servers should live in separate agent adapter packages rather than the core `pm` package contract.
93
+
94
+ When no manifest is present, `pm` discovers conventional extension directories:
95
+
96
+ - `.agents/pm/extensions/`
97
+ - `extensions/`
98
+ - `.custom/pm-extensions/`
99
+ - `.custom/pm-extension/`
100
+
101
+ If a package contains multiple extension manifests, install the exact extension path so the managed state has one deterministic package target.
102
+
103
+ First-party optional packages are shipped as package roots under `packages/`:
104
+
105
+ ```bash
106
+ pm install '*' --project
107
+ pm install all --project
108
+ pm install packages/pm-beads --project
109
+ pm install packages/pm-todos --project
110
+ ```
111
+
112
+ `pm install '*'` and `pm install all` install every bundled first-party package in deterministic alias order. If your shell expands `pm install *`, pm recognizes that expansion and treats it as the same bundled-package install-all request.
113
+
114
+ Compatibility aliases remain available:
115
+
116
+ ```bash
117
+ pm install beads --project
118
+ pm install todos --project
119
+ ```
120
+
121
+ Those aliases install package-shipped extension sources. They are then tracked in managed package state and can be refreshed with `pm upgrade --packages-only`.
122
+
123
+ ## Manifest Contract
124
+
125
+ ### Manifest v1 (supported)
126
+
127
+ ```json
128
+ {
129
+ "name": "my-ext",
130
+ "version": "0.1.0",
131
+ "entry": "./index.js",
132
+ "priority": 100,
133
+ "capabilities": ["commands"]
134
+ }
135
+ ```
136
+
137
+ ### Manifest v2 (recommended)
138
+
139
+ ```json
140
+ {
141
+ "name": "my-ext",
142
+ "version": "0.2.0",
143
+ "entry": "./index.js",
144
+ "priority": 100,
145
+ "manifest_version": 2,
146
+ "trusted": true,
147
+ "provenance": {
148
+ "source": "github://org/repo/path",
149
+ "verified": true
150
+ },
151
+ "sandbox_profile": "restricted",
152
+ "permissions": {
153
+ "fs_read": true,
154
+ "fs_write": false,
155
+ "network": false,
156
+ "env_read": true,
157
+ "env_write": false,
158
+ "process_spawn": false
159
+ },
160
+ "capabilities": ["commands", "hooks"]
161
+ }
162
+ ```
163
+
164
+ ### Capability values
165
+
166
+ - `commands`
167
+ - `parser`
168
+ - `preflight`
169
+ - `services`
170
+ - `renderers`
171
+ - `hooks`
172
+ - `schema`
173
+ - `importers`
174
+ - `search`
175
+
176
+ ## Governance Policy (`extensions.policy`)
177
+
178
+ Policy is configured in `settings.json` under `extensions.policy`.
179
+
180
+ ```json
181
+ {
182
+ "extensions": {
183
+ "policy": {
184
+ "mode": "enforce",
185
+ "trust_mode": "warn",
186
+ "require_provenance": true,
187
+ "default_sandbox_profile": "restricted",
188
+ "allowed_extensions": [],
189
+ "blocked_extensions": [],
190
+ "allowed_capabilities": [],
191
+ "blocked_capabilities": ["services"],
192
+ "allowed_surfaces": [],
193
+ "blocked_surfaces": ["commands.override"],
194
+ "allowed_commands": [],
195
+ "blocked_commands": ["dangerous command"],
196
+ "allowed_actions": [],
197
+ "blocked_actions": ["dangerous-command"],
198
+ "allowed_services": [],
199
+ "blocked_services": ["output_format"]
200
+ }
201
+ }
202
+ }
203
+ ```
204
+
205
+ Mode semantics:
206
+
207
+ - `mode`: `off|warn|enforce` for extension/capability/surface/command/action/service checks
208
+ - `trust_mode`: `off|warn|enforce` for trust checks
209
+ - `default_sandbox_profile`: `none|restricted|strict`
210
+
211
+ Sandbox profiles:
212
+
213
+ - `none`: no sandbox permission gating
214
+ - `restricted`: blocks sensitive writes and spawn (`process_spawn`, `env_write`)
215
+ - `strict`: blocks spawn/network/write style permissions (`process_spawn`, `network`, `fs_write`, `env_write`)
216
+
217
+ If profile is non-`none` and manifest permissions are missing, policy emits a deterministic warning or block.
218
+
219
+ ## Supported Surface Tokens
220
+
221
+ Use these values with `allowed_surfaces` and `blocked_surfaces`:
222
+
223
+ - `commands.override`
224
+ - `commands.handler`
225
+ - `hooks.beforecommand`
226
+ - `hooks.aftercommand`
227
+ - `hooks.onwrite`
228
+ - `hooks.onread`
229
+ - `hooks.onindex`
230
+ - `schema.flags`
231
+ - `schema.itemfields`
232
+ - `schema.itemtypes`
233
+ - `schema.migrations`
234
+ - `parser.override`
235
+ - `preflight.override`
236
+ - `services.override`
237
+ - `renderers.override`
238
+ - `importers.importer`
239
+ - `importers.exporter`
240
+ - `search.provider`
241
+ - `search.vectorstore`
242
+
243
+ ## Reload and Watch Workflows
244
+
245
+ Manual reload:
246
+
247
+ ```bash
248
+ pm extension --reload --project
249
+ ```
250
+
251
+ Watch-mode semantics:
252
+
253
+ ```bash
254
+ pm extension --reload --project --watch
255
+ ```
256
+
257
+ In non-interactive automation, `--watch` performs a deterministic single-pass reload and emits a watch-hint warning.
258
+
259
+ ## Diagnostics and Management
260
+
261
+ Basic diagnostics:
262
+
263
+ ```bash
264
+ pm extension --doctor --project --detail summary
265
+ ```
266
+
267
+ Deep diagnostics:
268
+
269
+ ```bash
270
+ pm extension --doctor --project --detail deep --trace
271
+ ```
272
+
273
+ Management commands:
274
+
275
+ ```bash
276
+ pm package explore
277
+ pm package manage --project
278
+ pm package manage --project --runtime-probe
279
+ pm package manage --project --fix-managed-state
280
+ pm package activate my-extension --project
281
+ pm package deactivate my-extension --project
282
+ pm package uninstall my-extension --project
283
+ ```
284
+
285
+ Common warning prefixes:
286
+
287
+ - `extension_policy_violation_extension`
288
+ - `extension_policy_violation_capability`
289
+ - `extension_policy_violation_registration`
290
+ - `extension_policy_violation_trust`
291
+ - `extension_policy_blocked_extension`
292
+ - `extension_policy_blocked_capability`
293
+ - `extension_policy_blocked_registration`
294
+ - `extension_policy_blocked_trust`
295
+
296
+ ## Migration Checklist (v1 -> v2)
297
+
298
+ 1. Keep existing manifest fields.
299
+ 2. Add `manifest_version: 2`.
300
+ 3. Add `trusted`, `provenance`, `sandbox_profile`, and `permissions`.
301
+ 4. Extend `extensions.policy` with trust/sandbox and command/action/service controls.
302
+ 5. Run:
303
+
304
+ ```bash
305
+ pm contracts --json
306
+ pm package doctor --project --detail summary --strict-exit
307
+ ```
308
+
309
+ 6. Resolve warnings before enforcing `mode=enforce` and `trust_mode=enforce`.
310
+
311
+ ## Runnable Examples
312
+
313
+ - `docs/examples/starter-extension/`
314
+ - `docs/examples/policy-restricted-extension/`
315
+ - `docs/examples/sdk-contract-consumer/`
316
+ - `docs/examples/sdk-app-embedding/`
317
+ - `docs/examples/ci/github-actions-pm-extension-gate.yml`
318
+ - `docs/examples/ci/gitlab-ci-pm-extension-gate.yml`
319
+ - `docs/examples/ci/jenkins-pm-extension-gate.Jenkinsfile`
320
+ # Extensions
321
+
322
+ Extensions let you add or override `pm` runtime behavior without modifying core `pm-cli`.
323
+
324
+ This guide is the authoritative reference for:
325
+
326
+ - manifest `v1` and `v2` contracts
327
+ - governance policy (`extensions.policy`) controls
328
+ - trust/provenance and sandbox restrictions
329
+ - manual reload and watch-mode workflows
330
+ - migration from policy-only setups to enterprise controls
331
+
332
+ ## Quick Start
333
+
334
+ ```bash
335
+ # 1) Scaffold an extension
336
+ pm extension --init ./my-extension
337
+
338
+ # 2) Install in project scope
339
+ pm extension --install --project ./my-extension
340
+
341
+ # 3) Run diagnostics
342
+ pm extension --doctor --project --detail summary
343
+
344
+ # 4) Reload runtime modules after local edits
345
+ pm extension --reload --project
346
+ ```
347
+
348
+ ## Delta From Previous Scope
349
+
350
+ Compared to the previous policy-only extension surface, this release adds:
351
+
352
+ - **Manifest v2 metadata** for trust, provenance, sandbox profile, and runtime permission declarations.
353
+ - **Policy v2 controls** for trust mode, provenance requirement, sandbox defaults, and command/action/service allow/block maps.
354
+ - **Registration enforcement upgrades** so command/action/service restrictions are evaluated at registration boundaries.
355
+ - **Hot reload controls** via cache-busted extension reload (`pm extension --reload`) with watch-mode semantics (`--watch`).
356
+ - **Contracts metadata upgrades** for trust/sandbox compatibility information in `pm contracts`.
357
+
358
+ ## Extension Locations
359
+
360
+ - Project scope: `.agents/pm/extensions/<name>/`
361
+ - Global scope: `~/.pm-cli/extensions/<name>/`
362
+ - Project entries override global entries when command paths collide.
363
+
364
+ Overrides:
365
+
366
+ - `PM_PATH`: project tracker root override
367
+ - `PM_GLOBAL_PATH`: global profile root override
368
+
369
+ ## Manifest Contract
370
+
371
+ ### Manifest v1 (still supported)
372
+
373
+ ```json
374
+ {
375
+ "name": "my-ext",
376
+ "version": "0.1.0",
377
+ "entry": "./index.js",
378
+ "priority": 100,
379
+ "capabilities": ["commands"]
380
+ }
381
+ ```
382
+
383
+ ### Manifest v2 (recommended)
384
+
385
+ ```json
386
+ {
387
+ "name": "my-ext",
388
+ "version": "0.2.0",
389
+ "entry": "./index.js",
390
+ "priority": 100,
391
+ "manifest_version": 2,
392
+ "trusted": true,
393
+ "provenance": {
394
+ "source": "github://org/repo/path",
395
+ "verified": true
396
+ },
397
+ "sandbox_profile": "restricted",
398
+ "permissions": {
399
+ "fs_read": true,
400
+ "fs_write": false,
401
+ "network": false,
402
+ "env_read": true,
403
+ "env_write": false,
404
+ "process_spawn": false
405
+ },
406
+ "capabilities": ["commands", "hooks"]
407
+ }
408
+ ```
409
+
410
+ ### Capability Values
411
+
412
+ - `commands`
413
+ - `parser`
414
+ - `preflight`
415
+ - `services`
416
+ - `renderers`
417
+ - `hooks`
418
+ - `schema`
419
+ - `importers`
420
+ - `search`
421
+
422
+ ## Governance Policy v2
423
+
424
+ Policy is configured under `settings.json` -> `extensions.policy`.
425
+
426
+ ```json
427
+ {
428
+ "extensions": {
429
+ "policy": {
430
+ "mode": "enforce",
431
+ "trust_mode": "warn",
432
+ "require_provenance": true,
433
+ "trusted_extensions": ["policy-restricted-extension"],
434
+ "default_sandbox_profile": "restricted",
435
+ "allowed_extensions": [],
436
+ "blocked_extensions": [],
437
+ "allowed_capabilities": [],
438
+ "blocked_capabilities": ["services"],
439
+ "allowed_surfaces": [],
440
+ "blocked_surfaces": ["commands.override"],
441
+ "allowed_commands": [],
442
+ "blocked_commands": ["dangerous command"],
443
+ "allowed_actions": [],
444
+ "blocked_actions": ["dangerous-command"],
445
+ "allowed_services": [],
446
+ "blocked_services": ["output_format"],
447
+ "extension_overrides": [
448
+ {
449
+ "name": "policy-restricted-extension",
450
+ "require_trusted": true,
451
+ "require_provenance": true,
452
+ "sandbox_profile": "strict",
453
+ "allowed_surfaces": ["commands.handler", "hooks.beforecommand"],
454
+ "blocked_surfaces": ["services.override"]
455
+ }
456
+ ]
457
+ }
458
+ }
459
+ }
460
+ ```
461
+
462
+ ### Mode Semantics
463
+
464
+ - `mode`: `off|warn|enforce` for extension/capability/surface/command/action/service restrictions
465
+ - `trust_mode`: `off|warn|enforce` for trust checks
466
+ - `default_sandbox_profile`: `none|restricted|strict`
467
+
468
+ ### Sandbox Profiles
469
+
470
+ Sandbox profiles are policy-driven gates evaluated against manifest permission declarations:
471
+
472
+ - `none`: no sandbox permission gating
473
+ - `restricted`: blocks sensitive writes/spawn (`process_spawn`, `env_write`)
474
+ - `strict`: blocks spawn/network/write-style permissions (`process_spawn`, `network`, `fs_write`, `env_write`)
475
+
476
+ If a non-`none` profile is active and manifest permissions are missing, a deterministic policy warning/block is emitted.
477
+
478
+ ### Surface Tokens
479
+
480
+ Supported `allowed_surfaces` / `blocked_surfaces` values:
481
+
482
+ - `commands.override`
483
+ - `commands.handler`
484
+ - `hooks.beforecommand`
485
+ - `hooks.aftercommand`
486
+ - `hooks.onwrite`
487
+ - `hooks.onread`
488
+ - `hooks.onindex`
489
+ - `schema.flags`
490
+ - `schema.itemfields`
491
+ - `schema.itemtypes`
492
+ - `schema.migrations`
493
+ - `parser.override`
494
+ - `preflight.override`
495
+ - `services.override`
496
+ - `renderers.override`
497
+ - `importers.importer`
498
+ - `importers.exporter`
499
+ - `search.provider`
500
+ - `search.vectorstore`
501
+
502
+ ## Hot Reload
503
+
504
+ ### Manual reload
505
+
506
+ ```bash
507
+ pm extension --reload --project
508
+ ```
509
+
510
+ This runs extension discovery/load with cache-busted import URLs and returns deterministic load/activation diagnostics.
511
+
512
+ ### Watch mode
513
+
514
+ ```bash
515
+ pm extension --reload --project --watch
516
+ ```
517
+
518
+ `--watch` enables watch-mode semantics for reload workflows. In non-interactive automation, it executes a deterministic single-pass reload and emits a watch hint warning.
519
+
520
+ ## Diagnostics and Warning Codes
521
+
522
+ Common warning prefixes:
523
+
524
+ - `extension_policy_violation_extension`
525
+ - `extension_policy_violation_capability`
526
+ - `extension_policy_violation_registration`
527
+ - `extension_policy_violation_trust`
528
+ - `extension_policy_blocked_extension`
529
+ - `extension_policy_blocked_capability`
530
+ - `extension_policy_blocked_registration`
531
+ - `extension_policy_blocked_trust`
532
+
533
+ Use:
534
+
535
+ ```bash
536
+ pm extension --doctor --project --detail deep --trace
537
+ ```
538
+
539
+ for full activation traces.
540
+
541
+ ## Migration (v1 -> v2)
542
+
543
+ 1. Keep existing manifest fields unchanged.
544
+ 2. Add `manifest_version: 2`.
545
+ 3. Add `trusted`, `provenance`, `sandbox_profile`, and `permissions`.
546
+ 4. Extend `extensions.policy` with trust/sandbox/command-action-service fields.
547
+ 5. Run:
548
+
549
+ ```bash
550
+ pm contracts --json
551
+ pm extension --doctor --project --detail summary --strict-exit
552
+ ```
553
+
554
+ 6. Fix any policy warnings before enforcing (`mode=enforce`, `trust_mode=enforce`).
555
+
556
+ ## Runnable Examples
557
+
558
+ - `docs/examples/starter-extension/`
559
+ - `docs/examples/policy-restricted-extension/`
560
+ - `docs/examples/sdk-contract-consumer/`
561
+ - `docs/examples/sdk-app-embedding/`
562
+ - `docs/examples/ci/github-actions-pm-extension-gate.yml`
563
+ - `docs/examples/ci/gitlab-ci-pm-extension-gate.yml`
564
+ - `docs/examples/ci/jenkins-pm-extension-gate.Jenkinsfile`
565
+ # Extensions
566
+
567
+ Extensions let you add or override `pm` runtime behavior without editing core `pm-cli` sources. They are loaded at runtime, gated by manifest capabilities, and now support granular governance policies for capability/surface allow/block controls.
568
+
569
+ ## Quick Start
570
+
571
+ ```bash
572
+ # 1) Scaffold a new extension
573
+ pm extension --init ./my-extension
574
+
575
+ # 2) Install into project scope
576
+ pm extension --install --project ./my-extension
577
+
578
+ # 3) Run extension diagnostics
579
+ pm extension --doctor --project --detail summary
580
+
581
+ # 4) Deep diagnostics with traces
582
+ pm extension --doctor --project --detail deep --trace
583
+ ```
584
+
585
+ Expected summary signals from `extension --doctor`:
586
+
587
+ - `details.summary.status`: `ok` or `warn`
588
+ - `details.summary.warning_codes`: deterministic warning code list
589
+ - `details.summary.policy`: active policy mode and configured counts
590
+ - `details.triage.remediation`: actionable follow-up guidance
591
+
592
+ ## Extension Locations and Precedence
593
+
594
+ - Project extensions: `.agents/pm/extensions/<name>/`
595
+ - Global extensions: `~/.pm-cli/extensions/<name>/`
596
+ - Project takes precedence when both scopes register the same command/surface.
597
+ - Discovery and activation remain deterministic across runs.
598
+
599
+ Environment overrides:
600
+
601
+ - `PM_PATH`: project tracker root override
602
+ - `PM_GLOBAL_PATH`: global profile root override
603
+
604
+ ## Manifest and Capabilities
605
+
606
+ Minimal `manifest.json`:
607
+
608
+ ```json
609
+ {
610
+ "name": "pm-ext-example",
611
+ "version": "0.1.0",
612
+ "entry": "./index.js",
613
+ "priority": 100,
614
+ "capabilities": ["commands"]
615
+ }
616
+ ```
617
+
618
+ Rules:
619
+
620
+ - `entry` must resolve inside extension directory (symlink-safe canonical checks apply).
621
+ - Declare only capabilities actually used.
622
+ - Unknown capabilities produce deterministic warnings with guidance.
623
+ - Legacy aliases (`migration`, `validation`) are remapped to `schema` with guidance warnings.
624
+
625
+ Supported capabilities:
626
+
627
+ - `commands`
628
+ - `parser`
629
+ - `preflight`
630
+ - `services`
631
+ - `renderers`
632
+ - `hooks`
633
+ - `schema`
634
+ - `importers`
635
+ - `search`
636
+
637
+ ## Governance Policy (Granular Controls)
638
+
639
+ Extension governance policy is configured in `settings.json` under `extensions.policy`.
640
+
641
+ Policy modes:
642
+
643
+ - `off`: no policy enforcement/warnings
644
+ - `warn`: allow registrations but emit policy violation warnings
645
+ - `enforce`: block disallowed extensions/capabilities/surfaces
646
+
647
+ Example policy:
648
+
649
+ ```json
650
+ {
651
+ "extensions": {
652
+ "policy": {
653
+ "mode": "enforce",
654
+ "allowed_extensions": ["release-audit-ext"],
655
+ "blocked_extensions": [],
656
+ "allowed_capabilities": [],
657
+ "blocked_capabilities": ["services"],
658
+ "allowed_surfaces": [],
659
+ "blocked_surfaces": ["commands.override"],
660
+ "extension_overrides": [
661
+ {
662
+ "name": "release-audit-ext",
663
+ "allowed_surfaces": ["commands.handler", "hooks.beforecommand"],
664
+ "blocked_surfaces": ["services.override"]
665
+ }
666
+ ]
667
+ }
668
+ }
669
+ }
670
+ ```
671
+
672
+ ### Surface Tokens
673
+
674
+ Use these exact values for `allowed_surfaces` / `blocked_surfaces`:
675
+
676
+ - `commands.override`
677
+ - `commands.handler`
678
+ - `hooks.beforecommand`
679
+ - `hooks.aftercommand`
680
+ - `hooks.onwrite`
681
+ - `hooks.onread`
682
+ - `hooks.onindex`
683
+ - `schema.flags`
684
+ - `schema.itemfields`
685
+ - `schema.itemtypes`
686
+ - `schema.migrations`
687
+ - `parser.override`
688
+ - `preflight.override`
689
+ - `services.override`
690
+ - `renderers.override`
691
+ - `importers.importer`
692
+ - `importers.exporter`
693
+ - `search.provider`
694
+ - `search.vectorstore`
695
+
696
+ Policy diagnostics use deterministic warning codes:
697
+
698
+ - `extension_policy_violation_extension`
699
+ - `extension_policy_violation_capability`
700
+ - `extension_policy_violation_registration`
701
+ - `extension_policy_blocked_extension`
702
+ - `extension_policy_blocked_capability`
703
+ - `extension_policy_blocked_registration`
704
+
705
+ ## Runtime APIs (Public SDK)
706
+
707
+ Use `@unbrained/pm-cli/sdk` only (no internal imports).
708
+
709
+ - `api.registerCommand(def)` -> `commands`
710
+ - `api.registerParser(command, fn)` -> `parser`
711
+ - `api.registerPreflight(fn)` -> `preflight`
712
+ - `api.registerService(name, fn)` -> `services`
713
+ - `api.registerRenderer(format, fn)` -> `renderers`
714
+ - `api.registerFlags(command, flags)` -> `schema`
715
+ - `api.registerItemFields(fields)` -> `schema`
716
+ - `api.registerItemTypes(types)` -> `schema`
717
+ - `api.registerMigration(def)` -> `schema`
718
+ - `api.registerImporter(name, fn)` -> `importers`
719
+ - `api.registerExporter(name, fn)` -> `importers`
720
+ - `api.registerSearchProvider(provider)` -> `search`
721
+ - `api.registerVectorStoreAdapter(adapter)` -> `search`
722
+ - `api.hooks.beforeCommand/afterCommand/onWrite/onRead/onIndex(fn)` -> `hooks`
723
+
724
+ ## Lifecycle Commands
725
+
726
+ ```bash
727
+ # Explore
728
+ pm extension --explore --project
729
+
730
+ # Manage (update checks + managed state diagnostics)
731
+ pm extension --manage --project
732
+
733
+ # Optional runtime probe parity in manage mode
734
+ pm extension --manage --project --runtime-probe
735
+
736
+ # Auto-adopt unmanaged extensions into managed state
737
+ pm extension --manage --project --fix-managed-state
738
+
739
+ # Activation/deactivation
740
+ pm extension --activate my-extension --project
741
+ pm extension --deactivate my-extension --project
742
+
743
+ # Uninstall
744
+ pm extension --uninstall my-extension --project
745
+ ```
746
+
747
+ ## Non-Interactive Automation Patterns
748
+
749
+ For CI/CD and agents:
750
+
751
+ - Prefer `--json` outputs.
752
+ - Use `pm contracts --schema-only --json` before invoking action payloads.
753
+ - Run `pm extension --doctor --detail summary --strict-exit` as a gate.
754
+ - Add `--detail deep --trace` on failure paths for remediation payloads.
755
+ - Use `--no-extensions` as a deterministic fallback for core-only triage.
756
+
757
+ ## Runnable Examples
758
+
759
+ - Full starter extension: `docs/examples/starter-extension/`
760
+ - Capability-restricted policy example: `docs/examples/policy-restricted-extension/`
761
+ - Programmatic contracts consumer: `docs/examples/sdk-contract-consumer/`
762
+ - CI gating workflow: `docs/examples/ci/github-actions-pm-extension-gate.yml`
763
+
764
+ ## Troubleshooting
765
+
766
+ - Manifest/entry failures: run `pm extension --explore --project`
767
+ - Activation failures: run `pm extension --doctor --detail deep --trace`
768
+ - Policy blocks: review `settings.extensions.policy` and `details.summary.policy`
769
+ - Runtime drift suspicion: compare with `pm --no-extensions <command>`
770
+ - Managed-state update-check gaps: run `pm extension --manage --fix-managed-state`
771
+
772
+ ## Related Docs
773
+
774
+ - `docs/SDK.md`
775
+ - `docs/examples/starter-extension/README.md`
776
+ - `docs/CLAUDE_CODE_PLUGIN.md`
1
777
  # Extensions
2
778
 
3
779
  Extensions add commands, schema, renderers, importers/exporters, search adapters, lifecycle hooks, and selected runtime overrides without modifying core `pm-cli`.
@@ -39,9 +815,9 @@ pm extension scaffold ./my-extension
39
815
  Install:
40
816
 
41
817
  ```bash
42
- pm extension install ./my-extension --project
43
- pm extension install github.com/unbraind/pm-cli/.agents/pm/extensions/todos --project
44
- pm extension --install --project todos
818
+ pm package install ./my-package --project
819
+ pm package install github.com/unbraind/pm-cli/packages/pm-todos --project
820
+ pm install todos --project
45
821
  ```
46
822
 
47
823
  Inspect and manage:
@@ -211,7 +987,7 @@ pm health --check-only
211
987
 
212
988
  ## Bundled Managed Extensions
213
989
 
214
- `pm-cli` ships bundled extension sources that are not auto-installed:
990
+ `pm-cli` ships optional first-party package roots that are not auto-installed:
215
991
 
216
992
  | Alias | Commands after install | Purpose |
217
993
  |-------|------------------------|---------|
@@ -221,16 +997,10 @@ pm health --check-only
221
997
  Install:
222
998
 
223
999
  ```bash
224
- pm extension --install --project beads
225
- pm extension --install --project todos
1000
+ pm install beads --project
1001
+ pm install todos --project
226
1002
  ```
227
1003
 
228
1004
  ## Starter Extension
229
1005
 
230
1006
  See [examples/starter-extension](examples/starter-extension/README.md) for a compact extension that demonstrates all capability categories through the public SDK.
231
-
232
- ## Pi Wrapper
233
-
234
- The Pi wrapper source is `.pi/extensions/pm-cli/index.ts`. It is an agent wrapper, not a runtime extension managed by `pm extension`.
235
-
236
- Use [AGENTS.md](../AGENTS.md) for repository-specific Pi wrapper operating rules.