@unbrained/pm-cli 2026.5.24 → 2026.5.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.
Files changed (238) hide show
  1. package/CHANGELOG.md +946 -525
  2. package/README.md +2 -10
  3. package/dist/cli/bootstrap-args.d.ts +18 -1
  4. package/dist/cli/bootstrap-args.js +143 -3
  5. package/dist/cli/bootstrap-args.js.map +1 -1
  6. package/dist/cli/commander-usage.js +134 -11
  7. package/dist/cli/commander-usage.js.map +1 -1
  8. package/dist/cli/commands/append.js +4 -3
  9. package/dist/cli/commands/append.js.map +1 -1
  10. package/dist/cli/commands/claim.js +5 -4
  11. package/dist/cli/commands/claim.js.map +1 -1
  12. package/dist/cli/commands/close.js +4 -3
  13. package/dist/cli/commands/close.js.map +1 -1
  14. package/dist/cli/commands/completion.d.ts +2 -2
  15. package/dist/cli/commands/completion.js +109 -56
  16. package/dist/cli/commands/completion.js.map +1 -1
  17. package/dist/cli/commands/config.d.ts +1 -1
  18. package/dist/cli/commands/config.js +82 -4
  19. package/dist/cli/commands/config.js.map +1 -1
  20. package/dist/cli/commands/create.js +7 -272
  21. package/dist/cli/commands/create.js.map +1 -1
  22. package/dist/cli/commands/delete.js +4 -3
  23. package/dist/cli/commands/delete.js.map +1 -1
  24. package/dist/cli/commands/docs.d.ts +1 -12
  25. package/dist/cli/commands/docs.js +8 -312
  26. package/dist/cli/commands/docs.js.map +1 -1
  27. package/dist/cli/commands/extension/bundled-catalog.d.ts +14 -0
  28. package/dist/cli/commands/extension/bundled-catalog.js +268 -0
  29. package/dist/cli/commands/extension/bundled-catalog.js.map +1 -0
  30. package/dist/cli/commands/extension/doctor.d.ts +31 -0
  31. package/dist/cli/commands/extension/doctor.js +345 -0
  32. package/dist/cli/commands/extension/doctor.js.map +1 -0
  33. package/dist/cli/commands/extension/install-sources.d.ts +37 -0
  34. package/dist/cli/commands/extension/install-sources.js +384 -0
  35. package/dist/cli/commands/extension/install-sources.js.map +1 -0
  36. package/dist/cli/commands/extension/managed-state.d.ts +48 -0
  37. package/dist/cli/commands/extension/managed-state.js +172 -0
  38. package/dist/cli/commands/extension/managed-state.js.map +1 -0
  39. package/dist/cli/commands/extension/scaffold.d.ts +14 -0
  40. package/dist/cli/commands/extension/scaffold.js +169 -0
  41. package/dist/cli/commands/extension/scaffold.js.map +1 -0
  42. package/dist/cli/commands/extension/shared.d.ts +14 -0
  43. package/dist/cli/commands/extension/shared.js +106 -0
  44. package/dist/cli/commands/extension/shared.js.map +1 -0
  45. package/dist/cli/commands/extension.d.ts +36 -68
  46. package/dist/cli/commands/extension.js +143 -1422
  47. package/dist/cli/commands/extension.js.map +1 -1
  48. package/dist/cli/commands/files.d.ts +1 -12
  49. package/dist/cli/commands/files.js +11 -308
  50. package/dist/cli/commands/files.js.map +1 -1
  51. package/dist/cli/commands/get.js +4 -3
  52. package/dist/cli/commands/get.js.map +1 -1
  53. package/dist/cli/commands/health.js +17 -3
  54. package/dist/cli/commands/health.js.map +1 -1
  55. package/dist/cli/commands/history-redact.js +23 -18
  56. package/dist/cli/commands/history-redact.js.map +1 -1
  57. package/dist/cli/commands/history-repair.js +24 -18
  58. package/dist/cli/commands/history-repair.js.map +1 -1
  59. package/dist/cli/commands/legacy-none-tokens.d.ts +3 -0
  60. package/dist/cli/commands/legacy-none-tokens.js +39 -0
  61. package/dist/cli/commands/legacy-none-tokens.js.map +1 -0
  62. package/dist/cli/commands/linked-artifacts.d.ts +96 -0
  63. package/dist/cli/commands/linked-artifacts.js +335 -0
  64. package/dist/cli/commands/linked-artifacts.js.map +1 -0
  65. package/dist/cli/commands/linked-test-parsers.d.ts +28 -0
  66. package/dist/cli/commands/linked-test-parsers.js +192 -0
  67. package/dist/cli/commands/linked-test-parsers.js.map +1 -0
  68. package/dist/cli/commands/list.js +19 -4
  69. package/dist/cli/commands/list.js.map +1 -1
  70. package/dist/cli/commands/normalize.js +4 -3
  71. package/dist/cli/commands/normalize.js.map +1 -1
  72. package/dist/cli/commands/recurrence-parsers.d.ts +26 -0
  73. package/dist/cli/commands/recurrence-parsers.js +98 -0
  74. package/dist/cli/commands/recurrence-parsers.js.map +1 -0
  75. package/dist/cli/commands/restore.js +19 -8
  76. package/dist/cli/commands/restore.js.map +1 -1
  77. package/dist/cli/commands/search.js +5 -4
  78. package/dist/cli/commands/search.js.map +1 -1
  79. package/dist/cli/commands/test/linked-command-detection.d.ts +37 -0
  80. package/dist/cli/commands/test/linked-command-detection.js +200 -0
  81. package/dist/cli/commands/test/linked-command-detection.js.map +1 -0
  82. package/dist/cli/commands/test.d.ts +1 -2
  83. package/dist/cli/commands/test.js +7 -349
  84. package/dist/cli/commands/test.js.map +1 -1
  85. package/dist/cli/commands/update-many.js +4 -3
  86. package/dist/cli/commands/update-many.js.map +1 -1
  87. package/dist/cli/commands/update.js +62 -354
  88. package/dist/cli/commands/update.js.map +1 -1
  89. package/dist/cli/error-guidance.d.ts +1 -0
  90. package/dist/cli/error-guidance.js +6 -2
  91. package/dist/cli/error-guidance.js.map +1 -1
  92. package/dist/cli/main.d.ts +11 -0
  93. package/dist/cli/main.js +76 -28
  94. package/dist/cli/main.js.map +1 -1
  95. package/dist/cli/register-list-query.d.ts +4 -1
  96. package/dist/cli/register-list-query.js +242 -203
  97. package/dist/cli/register-list-query.js.map +1 -1
  98. package/dist/cli/register-mutation.js +24 -9
  99. package/dist/cli/register-mutation.js.map +1 -1
  100. package/dist/cli/register-operations.js +3 -3
  101. package/dist/cli/register-operations.js.map +1 -1
  102. package/dist/cli/register-setup.js +12 -7
  103. package/dist/cli/register-setup.js.map +1 -1
  104. package/dist/cli/registration-helpers.js +3 -2
  105. package/dist/cli/registration-helpers.js.map +1 -1
  106. package/dist/cli.js +4 -3
  107. package/dist/cli.js.map +1 -1
  108. package/dist/core/config/positional-value.d.ts +44 -0
  109. package/dist/core/config/positional-value.js +109 -0
  110. package/dist/core/config/positional-value.js.map +1 -0
  111. package/dist/core/extensions/extension-capability-aliases.d.ts +14 -0
  112. package/dist/core/extensions/extension-capability-aliases.js +159 -0
  113. package/dist/core/extensions/extension-capability-aliases.js.map +1 -0
  114. package/dist/core/extensions/extension-hook-runtime.d.ts +13 -0
  115. package/dist/core/extensions/extension-hook-runtime.js +414 -0
  116. package/dist/core/extensions/extension-hook-runtime.js.map +1 -0
  117. package/dist/core/extensions/extension-policy.d.ts +69 -0
  118. package/dist/core/extensions/extension-policy.js +481 -0
  119. package/dist/core/extensions/extension-policy.js.map +1 -0
  120. package/dist/core/extensions/extension-registries.d.ts +8 -0
  121. package/dist/core/extensions/extension-registries.js +52 -0
  122. package/dist/core/extensions/extension-registries.js.map +1 -0
  123. package/dist/core/extensions/extension-runtime-helpers.d.ts +6 -0
  124. package/dist/core/extensions/extension-runtime-helpers.js +29 -0
  125. package/dist/core/extensions/extension-runtime-helpers.js.map +1 -0
  126. package/dist/core/extensions/extension-types.d.ts +13 -39
  127. package/dist/core/extensions/extension-types.js +34 -2
  128. package/dist/core/extensions/extension-types.js.map +1 -1
  129. package/dist/core/extensions/index.d.ts +7 -0
  130. package/dist/core/extensions/index.js +11 -2
  131. package/dist/core/extensions/index.js.map +1 -1
  132. package/dist/core/extensions/loader.d.ts +4 -22
  133. package/dist/core/extensions/loader.js +22 -1139
  134. package/dist/core/extensions/loader.js.map +1 -1
  135. package/dist/core/history/drift-scan.d.ts +11 -0
  136. package/dist/core/history/drift-scan.js +114 -32
  137. package/dist/core/history/drift-scan.js.map +1 -1
  138. package/dist/core/history/history-rewrite.d.ts +43 -0
  139. package/dist/core/history/history-rewrite.js +48 -0
  140. package/dist/core/history/history-rewrite.js.map +1 -0
  141. package/dist/core/history/history.js +5 -4
  142. package/dist/core/history/history.js.map +1 -1
  143. package/dist/core/history/replay.js +4 -3
  144. package/dist/core/history/replay.js.map +1 -1
  145. package/dist/core/item/item-record.d.ts +19 -0
  146. package/dist/core/item/item-record.js +24 -0
  147. package/dist/core/item/item-record.js.map +1 -0
  148. package/dist/core/output/mutation-projection.d.ts +31 -0
  149. package/dist/core/output/mutation-projection.js +103 -0
  150. package/dist/core/output/mutation-projection.js.map +1 -0
  151. package/dist/core/output/output.d.ts +2 -0
  152. package/dist/core/output/output.js +5 -3
  153. package/dist/core/output/output.js.map +1 -1
  154. package/dist/core/schema/runtime-schema.js +8 -38
  155. package/dist/core/schema/runtime-schema.js.map +1 -1
  156. package/dist/core/search/vector-stores.js +46 -9
  157. package/dist/core/search/vector-stores.js.map +1 -1
  158. package/dist/core/sentry/helpers.d.ts +1 -1
  159. package/dist/core/sentry/helpers.js +20 -3
  160. package/dist/core/sentry/helpers.js.map +1 -1
  161. package/dist/core/shared/command-types.d.ts +1 -0
  162. package/dist/core/shared/command-types.js +2 -2
  163. package/dist/core/shared/command-types.js.map +1 -1
  164. package/dist/core/shared/constants.d.ts +10 -1
  165. package/dist/core/shared/constants.js +56 -58
  166. package/dist/core/shared/constants.js.map +1 -1
  167. package/dist/core/shared/primitives.d.ts +23 -0
  168. package/dist/core/shared/primitives.js +39 -2
  169. package/dist/core/shared/primitives.js.map +1 -1
  170. package/dist/core/store/front-matter-cache.d.ts +16 -2
  171. package/dist/core/store/front-matter-cache.js +99 -33
  172. package/dist/core/store/front-matter-cache.js.map +1 -1
  173. package/dist/core/store/item-store.js +8 -73
  174. package/dist/core/store/item-store.js.map +1 -1
  175. package/dist/mcp/server.js +76 -28
  176. package/dist/mcp/server.js.map +1 -1
  177. package/dist/sdk/cli-contracts/enum-contracts.d.ts +20 -0
  178. package/dist/sdk/cli-contracts/enum-contracts.js +156 -0
  179. package/dist/sdk/cli-contracts/enum-contracts.js.map +1 -0
  180. package/dist/sdk/cli-contracts/tool-option-contracts.d.ts +14 -0
  181. package/dist/sdk/cli-contracts/tool-option-contracts.js +243 -0
  182. package/dist/sdk/cli-contracts/tool-option-contracts.js.map +1 -0
  183. package/dist/sdk/cli-contracts/tool-parameter-tables.d.ts +11 -0
  184. package/dist/sdk/cli-contracts/tool-parameter-tables.js +901 -0
  185. package/dist/sdk/cli-contracts/tool-parameter-tables.js.map +1 -0
  186. package/dist/sdk/cli-contracts.d.ts +11 -33
  187. package/dist/sdk/cli-contracts.js +23 -1356
  188. package/dist/sdk/cli-contracts.js.map +1 -1
  189. package/dist/sdk/package-import-adapters.d.ts +74 -0
  190. package/dist/sdk/package-import-adapters.js +186 -0
  191. package/dist/sdk/package-import-adapters.js.map +1 -0
  192. package/dist/sdk/package-runtime-options.d.ts +26 -0
  193. package/dist/sdk/package-runtime-options.js +71 -0
  194. package/dist/sdk/package-runtime-options.js.map +1 -0
  195. package/dist/sdk/runtime.d.ts +2 -0
  196. package/dist/sdk/runtime.js +4 -2
  197. package/dist/sdk/runtime.js.map +1 -1
  198. package/docs/AGENT_GUIDE.md +6 -10
  199. package/docs/CLAUDE_CODE_PLUGIN.md +5 -28
  200. package/docs/CODEX_PLUGIN.md +5 -5
  201. package/docs/COMMANDS.md +19 -3
  202. package/docs/CONFIGURATION.md +15 -0
  203. package/docs/EXTENSIONS.md +4 -63
  204. package/docs/RELEASING.md +4 -4
  205. package/marketplace.json +7 -3
  206. package/package.json +9 -6
  207. package/packages/pm-beads/extensions/beads/index.js +2 -49
  208. package/packages/pm-beads/extensions/beads/index.ts +2 -54
  209. package/packages/pm-beads/extensions/beads/runtime-loader.js +86 -0
  210. package/packages/pm-beads/extensions/beads/runtime-loader.ts +88 -0
  211. package/packages/pm-beads/extensions/beads/runtime.js +26 -115
  212. package/packages/pm-beads/extensions/beads/runtime.ts +33 -132
  213. package/packages/pm-calendar/extensions/calendar/index.js +47 -2
  214. package/packages/pm-calendar/extensions/calendar/index.ts +52 -2
  215. package/packages/pm-calendar/extensions/calendar/runtime.js +1 -0
  216. package/packages/pm-calendar/extensions/calendar/runtime.ts +1 -0
  217. package/packages/pm-governance-audit/extensions/governance-audit/runtime.js +14 -41
  218. package/packages/pm-governance-audit/extensions/governance-audit/runtime.ts +25 -41
  219. package/packages/pm-guide-shell/extensions/guide-shell/runtime.js +10 -50
  220. package/packages/pm-guide-shell/extensions/guide-shell/runtime.ts +17 -50
  221. package/packages/pm-linked-test-adapters/extensions/linked-test-adapters/runtime.js +8 -40
  222. package/packages/pm-linked-test-adapters/extensions/linked-test-adapters/runtime.ts +10 -40
  223. package/packages/pm-search-advanced/extensions/search-advanced/index.js +1 -1
  224. package/packages/pm-search-advanced/extensions/search-advanced/runtime.js +4 -37
  225. package/packages/pm-search-advanced/extensions/search-advanced/runtime.ts +6 -37
  226. package/packages/pm-todos/extensions/todos/index.js +3 -50
  227. package/packages/pm-todos/extensions/todos/index.ts +3 -55
  228. package/packages/pm-todos/extensions/todos/runtime-loader.js +86 -0
  229. package/packages/pm-todos/extensions/todos/runtime-loader.ts +88 -0
  230. package/packages/pm-todos/extensions/todos/runtime.js +24 -117
  231. package/packages/pm-todos/extensions/todos/runtime.ts +32 -129
  232. package/plugins/pm-claude/README.md +2 -2
  233. package/plugins/pm-claude/commands/pm-planner.md +1 -15
  234. package/plugins/pm-claude/scripts/pm-mcp-server.mjs +5 -2
  235. package/plugins/pm-claude/skills/pm-planner/SKILL.md +3 -21
  236. package/plugins/pm-codex/scripts/pm-mcp-server.mjs +15 -6
  237. package/plugins/pm-codex/skills/pm-native/SKILL.md +1 -13
  238. package/PRD.md +0 -1734
package/docs/COMMANDS.md CHANGED
@@ -6,15 +6,13 @@ This is a task-oriented command guide. For exact flags, use runtime help because
6
6
  pm <command> --help
7
7
  pm <command> --help --json
8
8
  pm contracts --command <command> --flags-only --json
9
- pm install guide-shell --project
10
- pm guide commands --depth standard
11
9
  ```
12
10
 
13
11
  ## Agent Quick Context
14
12
 
15
13
  - Prefer `pm context`, `pm search`, and narrow list commands before mutation.
16
14
  - Prefer TOON for reading and `--json` for strict parsing.
17
- - Use `pm install guide-shell --project` before `pm guide <topic>` when local docs routing is needed.
15
+ - Use the [guide topic map](README.md#guide-topic-map) when optional `pm guide` local docs routing is needed.
18
16
  - Use `pm contracts` for machine clients.
19
17
  - Every mutation writes history.
20
18
 
@@ -82,6 +80,14 @@ pm dedupe-audit --mode parent_scope --limit 20
82
80
 
83
81
  Use `context` first for a compact active-work snapshot. Use `search` when the request names a concept, component, or prior issue.
84
82
 
83
+ `--sort` accepts `priority|deadline|updated_at|created_at|title|parent`, plus the convenience aliases `updated` (→ `updated_at`) and `created` (→ `created_at`):
84
+
85
+ ```bash
86
+ pm list-all --sort updated --order desc
87
+ ```
88
+
89
+ When a flag is rejected with `Unknown option`, the error guidance now suggests the nearest supported flag (including abbreviations like `--desc` → `--description`) and notes when the flag is valid on a different command (for example `--type` on `test-all` points to `create`/`list`).
90
+
85
91
  ## Create and Update
86
92
 
87
93
  Shortest agent-friendly create (positional title + defaults to `Task` type):
@@ -121,6 +127,8 @@ pm create \
121
127
  --message "Create restore replay issue"
122
128
  ```
123
129
 
130
+ Repeated singular/plural list flags now accumulate, so `--tag a --tag b` is equivalent to `--tags a,b` (the same holds for `--status` and `--fields` on read commands). Earlier versions silently kept only the last value.
131
+
124
132
  Update existing work:
125
133
 
126
134
  ```bash
@@ -130,6 +138,14 @@ pm update <id> --parent <parent-id>
130
138
  pm append <id> --body "Detailed implementation notes."
131
139
  ```
132
140
 
141
+ Mutation commands (`create`/`update`/`close`/`append`/...) echo a `changed_fields` array. In high-volume agent loops that array is mostly redundant with the item echo above it, so pass the global `--no-changed-fields` flag to replace it with a compact `changed_field_count`:
142
+
143
+ ```bash
144
+ pm --no-changed-fields create "Probe item" # output keeps changed_field_count, drops the array
145
+ ```
146
+
147
+ Over MCP the mutation tools (`pm_create`/`pm_update`/`pm_close`/`pm_run` append/update-many) are compact by default; pass `options.full=true` to restore the full `changed_fields` delta.
148
+
133
149
  ## Templates
134
150
 
135
151
  After `pm install templates --project`, `pm templates` lists both saved templates and built-in starters:
@@ -21,6 +21,21 @@ pm config project set item-format --format toon
21
21
  pm config project set test-result-tracking --policy enabled
22
22
  ```
23
23
 
24
+ `config set <key> <value>` also accepts the value as a positional argument; pm routes
25
+ it to the right typed flag based on the key (so `--policy`/`--format`/`--criterion`
26
+ remain optional for single values):
27
+
28
+ ```bash
29
+ pm config set telemetry-tracking off # off|on|true|false map to disabled|enabled
30
+ pm config set item-format toon # same as --format toon
31
+ pm config set governance-preset strict # same as --policy strict
32
+ pm config set definition-of-done "Tests pass" # same as --criterion "Tests pass"
33
+ ```
34
+
35
+ The `context` key has no single value and still uses `--default-depth`,
36
+ `--activity-limit`, `--stale-threshold-days`, and `--section-<name>` flags. Use
37
+ `--criterion` (repeatable) to set more than one criteria-list value at once.
38
+
24
39
  Scopes:
25
40
 
26
41
  - `project` updates `.agents/pm/settings.json`.
@@ -130,44 +130,10 @@ export default defineExtension({
130
130
 
131
131
  ## Extension Manifest
132
132
 
133
- Manifest v1 is supported:
133
+ Runnable manifest examples are the source of truth:
134
134
 
135
- ```json
136
- {
137
- "name": "my-ext",
138
- "version": "0.1.0",
139
- "entry": "./index.js",
140
- "priority": 100,
141
- "capabilities": ["commands"]
142
- }
143
- ```
144
-
145
- Manifest v2 is recommended when governance, trust, or sandbox metadata matters:
146
-
147
- ```json
148
- {
149
- "name": "my-ext",
150
- "version": "0.2.0",
151
- "entry": "./index.js",
152
- "priority": 100,
153
- "manifest_version": 2,
154
- "trusted": true,
155
- "provenance": {
156
- "source": "github://org/repo/path",
157
- "verified": true
158
- },
159
- "sandbox_profile": "restricted",
160
- "permissions": {
161
- "fs_read": true,
162
- "fs_write": false,
163
- "network": false,
164
- "env_read": true,
165
- "env_write": false,
166
- "process_spawn": false
167
- },
168
- "capabilities": ["commands", "schema"]
169
- }
170
- ```
135
+ - [starter extension manifest](examples/starter-extension/manifest.json)
136
+ - [policy-restricted manifest](examples/policy-restricted-extension/manifest.json)
171
137
 
172
138
  Rules:
173
139
 
@@ -190,32 +156,7 @@ Supported capabilities:
190
156
 
191
157
  ## Governance Policy
192
158
 
193
- Governance policy is configured in `settings.json` under `extensions.policy`:
194
-
195
- ```json
196
- {
197
- "extensions": {
198
- "policy": {
199
- "mode": "enforce",
200
- "trust_mode": "warn",
201
- "require_provenance": true,
202
- "default_sandbox_profile": "restricted",
203
- "allowed_extensions": [],
204
- "blocked_extensions": [],
205
- "allowed_capabilities": [],
206
- "blocked_capabilities": ["services"],
207
- "allowed_surfaces": [],
208
- "blocked_surfaces": ["commands.override"],
209
- "allowed_commands": [],
210
- "blocked_commands": ["dangerous command"],
211
- "allowed_actions": [],
212
- "blocked_actions": [],
213
- "allowed_services": [],
214
- "blocked_services": []
215
- }
216
- }
217
- }
218
- ```
159
+ Governance policy is configured in `settings.json` under `extensions.policy`. The runnable [policy-restricted example](examples/policy-restricted-extension/README.md) owns the complete policy snippet and expected behavior.
219
160
 
220
161
  Policy modes:
221
162
 
package/docs/RELEASING.md CHANGED
@@ -53,7 +53,7 @@ Policy:
53
53
  - release at most once per UTC day by default
54
54
  - same-day follow-up release (`YYYY.M.D-N`) is manual-only via `allow_same_day_release=true`
55
55
  - release preparation must pass all quality and compatibility gates before commit+tag push
56
- - `CHANGELOG.pm.md` is generated by the latest npm `pm-changelog` package (`pm install npm:pm-changelog --project`, then `pm changelog generate`) from closed tracker items and checked in CI; do not edit it by hand
56
+ - `CHANGELOG.md` is generated by the latest npm `pm-changelog` package (`pm install npm:pm-changelog --project`, then `pm changelog generate --mode replace --all-release-tags`) from closed tracker items across git release tag windows and checked in CI; do not edit it by hand
57
57
  - external Sentry checks run when a Sentry token is configured; local maintainers should run private reliability checks separately and keep raw operational details in ignored local notes
58
58
  - after creating and pushing a new tag, auto-release dispatches `.github/workflows/release.yml` with that tag and waits for the publish workflow to finish, because GitHub does not start normal push/tag workflows from `GITHUB_TOKEN` pushes
59
59
 
@@ -66,13 +66,13 @@ node scripts/release/run-release-pipeline.mjs
66
66
  The pipeline performs:
67
67
 
68
68
  1. change detection + one-release-per-day guard
69
- 2. version bump + changelog promotion from `[Unreleased]`
70
- 3. latest `pm-changelog` install and tracker changelog refresh through `pm changelog generate`
69
+ 2. version bump
70
+ 3. latest `pm-changelog` install and main changelog refresh through package-owned full-history generation; the release pipeline passes `--release-version` with `--all-release-tags` so the pending release section matches post-tag CI checks
71
71
  4. strict gates (build, typecheck, docs/skills freshness, coverage, static quality, compatibility, security, smoke checks, reliability gate)
72
72
  5. release note generation from changelog + pm evidence
73
73
  6. commit and tag creation (plus optional push)
74
74
 
75
- If commits since the last tag touch source, package, script, or workflow files, an empty `[Unreleased]` section is a release blocker. The pipeline exits nonzero and reports `changelog_required_files` plus `release_changelog_required:source_or_package_changes_without_unreleased_entry` so the missing release note is visible in automation instead of becoming a green no-op.
75
+ The generated changelog includes clickable pm item links to the tracked `.toon` files. Missing release evidence should be fixed in pm item history, not by hand-editing `CHANGELOG.md`.
76
76
 
77
77
  ## Local Release Parity Checklist
78
78
 
package/marketplace.json CHANGED
@@ -1,16 +1,19 @@
1
1
  {
2
2
  "name": "pm",
3
- "description": "Official marketplace for pm CLI — native git-based project management for Claude Code and AI coding agents.",
4
3
  "owner": {
5
4
  "name": "unbrained",
6
5
  "url": "https://github.com/unbraind/pm-cli"
7
6
  },
7
+ "metadata": {
8
+ "description": "Official marketplace for pm CLI — native git-based project management for Claude Code and AI coding agents.",
9
+ "version": "1.4.0"
10
+ },
8
11
  "plugins": [
9
12
  {
10
13
  "name": "pm-claude",
14
+ "source": "./plugins/pm-claude",
11
15
  "description": "Native pm CLI integration for Claude Code — 18 MCP tools, 5 workflow skills, 14 slash commands, 3 subagents, hybrid TUI task tracking, session context injection, and coordination subagents for git-based project management without leaving Claude Code.",
12
16
  "version": "1.4.0",
13
- "source": "./plugins/pm-claude",
14
17
  "author": {
15
18
  "name": "unbrained",
16
19
  "url": "https://github.com/unbraind/pm-cli"
@@ -28,7 +31,8 @@
28
31
  "git-native",
29
32
  "task-tracker",
30
33
  "ai"
31
- ]
34
+ ],
35
+ "category": "productivity"
32
36
  }
33
37
  ]
34
38
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unbrained/pm-cli",
3
- "version": "2026.5.24",
3
+ "version": "2026.5.27",
4
4
  "description": "Git-native project management CLI for humans and agents.",
5
5
  "type": "module",
6
6
  "author": "unbrained",
@@ -28,6 +28,11 @@
28
28
  "import": "./dist/sdk/index.js",
29
29
  "default": "./dist/sdk/index.js"
30
30
  },
31
+ "./sdk/runtime": {
32
+ "types": "./dist/sdk/runtime.d.ts",
33
+ "import": "./dist/sdk/runtime.js",
34
+ "default": "./dist/sdk/runtime.js"
35
+ },
31
36
  "./cli": {
32
37
  "types": "./dist/cli/main.d.ts",
33
38
  "import": "./dist/cli/main.js",
@@ -44,7 +49,6 @@
44
49
  "CODE_OF_CONDUCT.md",
45
50
  "LICENSE",
46
51
  "AGENTS.md",
47
- "PRD.md",
48
52
  "docs/**",
49
53
  ".claude-plugin/**",
50
54
  "plugins/**",
@@ -70,10 +74,9 @@
70
74
  "version:check": "node scripts/release-version.mjs check",
71
75
  "version:next": "node scripts/release-version.mjs next",
72
76
  "changelog:pm:install": "node dist/cli.js install npm:pm-changelog --project",
73
- "changelog:pm": "pnpm changelog:pm:install && node dist/cli.js changelog generate --output CHANGELOG.pm.md --title \"pm Tracker Changelog\" --group-by release --status closed",
74
- "changelog:pm:check": "pnpm changelog:pm:install && node dist/cli.js changelog generate --output CHANGELOG.pm.md --title \"pm Tracker Changelog\" --group-by release --status closed --check",
77
+ "changelog:pm": "pnpm changelog:pm:install && node dist/cli.js changelog generate --output CHANGELOG.md --title \"Changelog\" --mode replace --all-release-tags --status closed --item-url-base https://github.com/unbraind/pm-cli/blob/main/.agents/pm",
78
+ "changelog:pm:check": "pnpm changelog:pm:install && node dist/cli.js changelog generate --output CHANGELOG.md --title \"Changelog\" --mode replace --all-release-tags --status closed --item-url-base https://github.com/unbraind/pm-cli/blob/main/.agents/pm --check",
75
79
  "release:notes": "node scripts/generate-release-notes.mjs",
76
- "release:changelog": "node scripts/release/changelog-promote.mjs",
77
80
  "release:gates": "node scripts/release/run-gates.mjs --telemetry-mode best-effort",
78
81
  "release:pipeline": "node scripts/release/run-release-pipeline.mjs",
79
82
  "release:pipeline:dry-run": "node scripts/release/run-release-pipeline.mjs --dry-run",
@@ -111,7 +114,7 @@
111
114
  }
112
115
  },
113
116
  "dependencies": {
114
- "@sentry/node": "^10.51.0",
117
+ "@sentry/node": "^10.54.0",
115
118
  "@toon-format/toon": "^2.3.0",
116
119
  "commander": "^14.0.3",
117
120
  "fast-glob": "^3.3.3",
@@ -1,7 +1,4 @@
1
- import path from "node:path";
2
- import { fileURLToPath, pathToFileURL } from "node:url";
3
- const PM_PACKAGE_ROOT_ENV = "PM_CLI_PACKAGE_ROOT";
4
- const CURRENT_EXTENSION_ROOT = path.dirname(fileURLToPath(import.meta.url));
1
+ import { loadPackageRuntimeModule } from "./runtime-loader.js";
5
2
  export const manifest = {
6
3
  name: "builtin-beads-import",
7
4
  version: "0.1.0",
@@ -23,52 +20,8 @@ function toBeadsImportOptions(options) {
23
20
  preserveSourceIds: asBoolean(options.preserveSourceIds),
24
21
  };
25
22
  }
26
- function resolvePackageRootCandidates() {
27
- const candidates = [];
28
- const envRoot = process.env[PM_PACKAGE_ROOT_ENV];
29
- if (typeof envRoot === "string" && envRoot.trim().length > 0) {
30
- candidates.push(path.resolve(envRoot.trim()));
31
- }
32
- const argvEntry = typeof process.argv[1] === "string" ? process.argv[1].trim() : "";
33
- if (argvEntry.length > 0) {
34
- const resolvedEntry = path.resolve(argvEntry);
35
- const entryDir = path.dirname(resolvedEntry);
36
- candidates.push(path.resolve(entryDir, ".."));
37
- candidates.push(path.resolve(entryDir, "../.."));
38
- candidates.push(path.resolve(entryDir, "../../.."));
39
- }
40
- return [...new Set(candidates)];
41
- }
42
- async function loadRuntimeModule() {
43
- const attempted = [];
44
- for (const packageRoot of resolvePackageRootCandidates()) {
45
- const modulePaths = [
46
- path.join(packageRoot, ".agents", "pm", "extensions", "beads", "runtime.js"),
47
- path.join(packageRoot, "packages", "pm-beads", "extensions", "beads", "runtime.js"),
48
- ];
49
- for (const modulePath of modulePaths) {
50
- attempted.push(modulePath);
51
- try {
52
- return await import(pathToFileURL(modulePath).href);
53
- }
54
- catch {
55
- // Try the next package-root candidate.
56
- }
57
- }
58
- }
59
- const localRuntimePath = path.join(CURRENT_EXTENSION_ROOT, "runtime.js");
60
- attempted.push(localRuntimePath);
61
- try {
62
- return await import(pathToFileURL(localRuntimePath).href);
63
- }
64
- catch {
65
- // Fall through to the diagnostic below.
66
- }
67
- throw new Error("Unable to resolve packaged beads extension runtime module. " +
68
- `Tried: ${attempted.join(", ")}. Ensure the installed extension includes runtime.js or PM_CLI_PACKAGE_ROOT points to an installed pm package root.`);
69
- }
70
23
  async function runBeadsImportFromRuntime(options, global) {
71
- const runtime = await loadRuntimeModule();
24
+ const runtime = await loadPackageRuntimeModule();
72
25
  if (typeof runtime.runBeadsImport !== "function") {
73
26
  throw new Error("Bundled beads runtime module is missing runBeadsImport().");
74
27
  }
@@ -1,10 +1,6 @@
1
- import path from "node:path";
2
- import { fileURLToPath, pathToFileURL } from "node:url";
3
1
  import type { CommandDefinition, ExtensionApi, GlobalOptions } from "../../../../src/sdk/index.js";
4
2
  import type { BeadsImportOptions, BeadsImportResult } from "./runtime.js";
5
-
6
- const PM_PACKAGE_ROOT_ENV = "PM_CLI_PACKAGE_ROOT";
7
- const CURRENT_EXTENSION_ROOT = path.dirname(fileURLToPath(import.meta.url));
3
+ import { loadPackageRuntimeModule } from "./runtime-loader.js";
8
4
 
9
5
  export const manifest = {
10
6
  name: "builtin-beads-import",
@@ -35,56 +31,8 @@ function toBeadsImportOptions(options: Record<string, unknown>): BeadsImportOpti
35
31
  };
36
32
  }
37
33
 
38
- function resolvePackageRootCandidates(): string[] {
39
- const candidates: string[] = [];
40
- const envRoot = process.env[PM_PACKAGE_ROOT_ENV];
41
- if (typeof envRoot === "string" && envRoot.trim().length > 0) {
42
- candidates.push(path.resolve(envRoot.trim()));
43
- }
44
- const argvEntry = typeof process.argv[1] === "string" ? process.argv[1].trim() : "";
45
- if (argvEntry.length > 0) {
46
- const resolvedEntry = path.resolve(argvEntry);
47
- const entryDir = path.dirname(resolvedEntry);
48
- candidates.push(path.resolve(entryDir, ".."));
49
- candidates.push(path.resolve(entryDir, "../.."));
50
- candidates.push(path.resolve(entryDir, "../../.."));
51
- }
52
- return [...new Set(candidates)];
53
- }
54
-
55
- async function loadRuntimeModule(): Promise<RuntimeModule> {
56
- const attempted: string[] = [];
57
- for (const packageRoot of resolvePackageRootCandidates()) {
58
- const modulePaths = [
59
- path.join(packageRoot, ".agents", "pm", "extensions", "beads", "runtime.js"),
60
- path.join(packageRoot, "packages", "pm-beads", "extensions", "beads", "runtime.js"),
61
- ];
62
- for (const modulePath of modulePaths) {
63
- attempted.push(modulePath);
64
- try {
65
- return await import(pathToFileURL(modulePath).href) as RuntimeModule;
66
- } catch {
67
- // Try the next package-root candidate.
68
- }
69
- }
70
- }
71
-
72
- const localRuntimePath = path.join(CURRENT_EXTENSION_ROOT, "runtime.js");
73
- attempted.push(localRuntimePath);
74
- try {
75
- return await import(pathToFileURL(localRuntimePath).href) as RuntimeModule;
76
- } catch {
77
- // Fall through to the diagnostic below.
78
- }
79
-
80
- throw new Error(
81
- "Unable to resolve packaged beads extension runtime module. " +
82
- `Tried: ${attempted.join(", ")}. Ensure the installed extension includes runtime.js or PM_CLI_PACKAGE_ROOT points to an installed pm package root.`,
83
- );
84
- }
85
-
86
34
  async function runBeadsImportFromRuntime(options: BeadsImportOptions, global: GlobalOptions): Promise<BeadsImportResult> {
87
- const runtime = await loadRuntimeModule();
35
+ const runtime = await loadPackageRuntimeModule() as RuntimeModule;
88
36
  if (typeof runtime.runBeadsImport !== "function") {
89
37
  throw new Error("Bundled beads runtime module is missing runBeadsImport().");
90
38
  }
@@ -0,0 +1,86 @@
1
+ import { existsSync } from "node:fs";
2
+ import path from "node:path";
3
+ import { fileURLToPath, pathToFileURL } from "node:url";
4
+
5
+ /**
6
+ * GENERATED by scripts/gen-package-runtime-loaders.mjs - do not edit directly.
7
+ * This file is shipped with the package extension and intentionally avoids
8
+ * static SDK imports so project-local installed extensions can load it.
9
+ */
10
+
11
+ const PM_PACKAGE_ROOT_ENV = "PM_CLI_PACKAGE_ROOT";
12
+ const CURRENT_EXTENSION_ROOT = path.dirname(fileURLToPath(import.meta.url));
13
+ const EXTENSION_NAME = "beads";
14
+ const PACKAGE_NAME = "pm-beads";
15
+ const DIAGNOSTIC_NAME = "beads";
16
+
17
+ function isRecord(value) {
18
+ return typeof value === "object" && value !== null;
19
+ }
20
+
21
+ function isMissingRuntimeModuleError(error, modulePath) {
22
+ if (!isRecord(error) || error.code !== "ERR_MODULE_NOT_FOUND") {
23
+ return false;
24
+ }
25
+ const message = typeof error.message === "string" ? error.message : "";
26
+ const moduleUrl = pathToFileURL(modulePath).href;
27
+ return message.includes(modulePath) || message.includes(moduleUrl);
28
+ }
29
+
30
+ function resolvePackageRootCandidates() {
31
+ const candidates = [];
32
+ const envRoot = process.env[PM_PACKAGE_ROOT_ENV];
33
+ if (typeof envRoot === "string" && envRoot.trim().length > 0) {
34
+ candidates.push(path.resolve(envRoot.trim()));
35
+ }
36
+ const argvEntry = typeof process.argv[1] === "string" ? process.argv[1].trim() : "";
37
+ if (argvEntry.length > 0) {
38
+ const resolvedEntry = path.resolve(argvEntry);
39
+ const entryDir = path.dirname(resolvedEntry);
40
+ candidates.push(path.resolve(entryDir, ".."));
41
+ candidates.push(path.resolve(entryDir, "../.."));
42
+ candidates.push(path.resolve(entryDir, "../../.."));
43
+ }
44
+ return [...new Set(candidates)];
45
+ }
46
+
47
+ export async function loadPackageRuntimeModule() {
48
+ const attempted = [];
49
+ for (const packageRoot of resolvePackageRootCandidates()) {
50
+ const modulePaths = [
51
+ path.join(packageRoot, ".agents", "pm", "extensions", EXTENSION_NAME, "runtime.js"),
52
+ path.join(packageRoot, "packages", PACKAGE_NAME, "extensions", EXTENSION_NAME, "runtime.js"),
53
+ ];
54
+ for (const modulePath of modulePaths) {
55
+ attempted.push(modulePath);
56
+ if (!existsSync(modulePath)) {
57
+ continue;
58
+ }
59
+ try {
60
+ return await import(pathToFileURL(modulePath).href);
61
+ } catch (error) {
62
+ if (isMissingRuntimeModuleError(error, modulePath)) {
63
+ continue;
64
+ }
65
+ throw error;
66
+ }
67
+ }
68
+ }
69
+
70
+ const localRuntimePath = path.join(CURRENT_EXTENSION_ROOT, "runtime.js");
71
+ attempted.push(localRuntimePath);
72
+ if (existsSync(localRuntimePath)) {
73
+ try {
74
+ return await import(pathToFileURL(localRuntimePath).href);
75
+ } catch (error) {
76
+ if (!isMissingRuntimeModuleError(error, localRuntimePath)) {
77
+ throw error;
78
+ }
79
+ }
80
+ }
81
+
82
+ throw new Error(
83
+ `Unable to resolve packaged ${DIAGNOSTIC_NAME} extension runtime module. ` +
84
+ `Tried: ${attempted.join(", ")}. Ensure the installed extension includes runtime.js or PM_CLI_PACKAGE_ROOT points to an installed pm package root.`,
85
+ );
86
+ }
@@ -0,0 +1,88 @@
1
+ import { existsSync } from "node:fs";
2
+ import path from "node:path";
3
+ import { fileURLToPath, pathToFileURL } from "node:url";
4
+
5
+ /**
6
+ * GENERATED by scripts/gen-package-runtime-loaders.mjs - do not edit directly.
7
+ * This file is shipped with the package extension and intentionally avoids
8
+ * static SDK imports so project-local installed extensions can load it.
9
+ */
10
+
11
+ const PM_PACKAGE_ROOT_ENV = "PM_CLI_PACKAGE_ROOT";
12
+ const CURRENT_EXTENSION_ROOT = path.dirname(fileURLToPath(import.meta.url));
13
+ const EXTENSION_NAME = "beads";
14
+ const PACKAGE_NAME = "pm-beads";
15
+ const DIAGNOSTIC_NAME = "beads";
16
+
17
+ export type PackageRuntimeModule = Record<string, unknown>;
18
+
19
+ function isRecord(value: unknown): value is Record<string, unknown> {
20
+ return typeof value === "object" && value !== null;
21
+ }
22
+
23
+ function isMissingRuntimeModuleError(error: unknown, modulePath: string): boolean {
24
+ if (!isRecord(error) || error.code !== "ERR_MODULE_NOT_FOUND") {
25
+ return false;
26
+ }
27
+ const message = typeof error.message === "string" ? error.message : "";
28
+ const moduleUrl = pathToFileURL(modulePath).href;
29
+ return message.includes(modulePath) || message.includes(moduleUrl);
30
+ }
31
+
32
+ function resolvePackageRootCandidates(): string[] {
33
+ const candidates: string[] = [];
34
+ const envRoot = process.env[PM_PACKAGE_ROOT_ENV];
35
+ if (typeof envRoot === "string" && envRoot.trim().length > 0) {
36
+ candidates.push(path.resolve(envRoot.trim()));
37
+ }
38
+ const argvEntry = typeof process.argv[1] === "string" ? process.argv[1].trim() : "";
39
+ if (argvEntry.length > 0) {
40
+ const resolvedEntry = path.resolve(argvEntry);
41
+ const entryDir = path.dirname(resolvedEntry);
42
+ candidates.push(path.resolve(entryDir, ".."));
43
+ candidates.push(path.resolve(entryDir, "../.."));
44
+ candidates.push(path.resolve(entryDir, "../../.."));
45
+ }
46
+ return [...new Set(candidates)];
47
+ }
48
+
49
+ export async function loadPackageRuntimeModule(): Promise<PackageRuntimeModule> {
50
+ const attempted: string[] = [];
51
+ for (const packageRoot of resolvePackageRootCandidates()) {
52
+ const modulePaths = [
53
+ path.join(packageRoot, ".agents", "pm", "extensions", EXTENSION_NAME, "runtime.js"),
54
+ path.join(packageRoot, "packages", PACKAGE_NAME, "extensions", EXTENSION_NAME, "runtime.js"),
55
+ ];
56
+ for (const modulePath of modulePaths) {
57
+ attempted.push(modulePath);
58
+ if (!existsSync(modulePath)) {
59
+ continue;
60
+ }
61
+ try {
62
+ return await import(pathToFileURL(modulePath).href) as PackageRuntimeModule;
63
+ } catch (error: unknown) {
64
+ if (isMissingRuntimeModuleError(error, modulePath)) {
65
+ continue;
66
+ }
67
+ throw error;
68
+ }
69
+ }
70
+ }
71
+
72
+ const localRuntimePath = path.join(CURRENT_EXTENSION_ROOT, "runtime.js");
73
+ attempted.push(localRuntimePath);
74
+ if (existsSync(localRuntimePath)) {
75
+ try {
76
+ return await import(pathToFileURL(localRuntimePath).href) as PackageRuntimeModule;
77
+ } catch (error: unknown) {
78
+ if (!isMissingRuntimeModuleError(error, localRuntimePath)) {
79
+ throw error;
80
+ }
81
+ }
82
+ }
83
+
84
+ throw new Error(
85
+ `Unable to resolve packaged ${DIAGNOSTIC_NAME} extension runtime module. ` +
86
+ `Tried: ${attempted.join(", ")}. Ensure the installed extension includes runtime.js or PM_CLI_PACKAGE_ROOT points to an installed pm package root.`,
87
+ );
88
+ }