@unbrained/pm-cli 2026.5.1 → 2026.5.3-5

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 (265) hide show
  1. package/AGENTS.md +8 -1
  2. package/CHANGELOG.md +73 -4
  3. package/CONTRIBUTING.md +11 -5
  4. package/PRD.md +17 -1
  5. package/README.md +55 -1099
  6. package/SECURITY.md +6 -11
  7. package/dist/cli/bootstrap-args.d.ts +18 -0
  8. package/dist/cli/bootstrap-args.js +242 -0
  9. package/dist/cli/bootstrap-args.js.map +1 -0
  10. package/dist/cli/commander-usage.d.ts +17 -0
  11. package/dist/cli/commander-usage.js +178 -0
  12. package/dist/cli/commander-usage.js.map +1 -0
  13. package/dist/cli/commands/activity.d.ts +10 -0
  14. package/dist/cli/commands/activity.js +14 -10
  15. package/dist/cli/commands/activity.js.map +1 -1
  16. package/dist/cli/commands/aggregate.js.map +1 -1
  17. package/dist/cli/commands/append.js.map +1 -1
  18. package/dist/cli/commands/calendar.js +19 -34
  19. package/dist/cli/commands/calendar.js.map +1 -1
  20. package/dist/cli/commands/claim.js.map +1 -1
  21. package/dist/cli/commands/close.js.map +1 -1
  22. package/dist/cli/commands/comments-audit.js.map +1 -1
  23. package/dist/cli/commands/comments.js +1 -9
  24. package/dist/cli/commands/comments.js.map +1 -1
  25. package/dist/cli/commands/completion.js.map +1 -1
  26. package/dist/cli/commands/config.d.ts +21 -3
  27. package/dist/cli/commands/config.js +118 -2
  28. package/dist/cli/commands/config.js.map +1 -1
  29. package/dist/cli/commands/context.d.ts +90 -1
  30. package/dist/cli/commands/context.js +496 -12
  31. package/dist/cli/commands/context.js.map +1 -1
  32. package/dist/cli/commands/contracts.js.map +1 -1
  33. package/dist/cli/commands/create.js +2 -2
  34. package/dist/cli/commands/create.js.map +1 -1
  35. package/dist/cli/commands/dedupe-audit.js +2 -11
  36. package/dist/cli/commands/dedupe-audit.js.map +1 -1
  37. package/dist/cli/commands/delete.js.map +1 -1
  38. package/dist/cli/commands/deps.js.map +1 -1
  39. package/dist/cli/commands/docs.js.map +1 -1
  40. package/dist/cli/commands/extension.js.map +1 -1
  41. package/dist/cli/commands/files.js +14 -2
  42. package/dist/cli/commands/files.js.map +1 -1
  43. package/dist/cli/commands/gc.js.map +1 -1
  44. package/dist/cli/commands/get.js.map +1 -1
  45. package/dist/cli/commands/health.js +16 -12
  46. package/dist/cli/commands/health.js.map +1 -1
  47. package/dist/cli/commands/history.js +1 -9
  48. package/dist/cli/commands/history.js.map +1 -1
  49. package/dist/cli/commands/index.js.map +1 -1
  50. package/dist/cli/commands/init.js.map +1 -1
  51. package/dist/cli/commands/learnings.js +1 -9
  52. package/dist/cli/commands/learnings.js.map +1 -1
  53. package/dist/cli/commands/list.d.ts +1 -0
  54. package/dist/cli/commands/list.js +13 -31
  55. package/dist/cli/commands/list.js.map +1 -1
  56. package/dist/cli/commands/normalize.js +14 -23
  57. package/dist/cli/commands/normalize.js.map +1 -1
  58. package/dist/cli/commands/notes.js +1 -9
  59. package/dist/cli/commands/notes.js.map +1 -1
  60. package/dist/cli/commands/reindex.js +2 -7
  61. package/dist/cli/commands/reindex.js.map +1 -1
  62. package/dist/cli/commands/restore.js.map +1 -1
  63. package/dist/cli/commands/search.js +4 -35
  64. package/dist/cli/commands/search.js.map +1 -1
  65. package/dist/cli/commands/stats.js.map +1 -1
  66. package/dist/cli/commands/templates.js.map +1 -1
  67. package/dist/cli/commands/test-all.js.map +1 -1
  68. package/dist/cli/commands/test-runs.js +1 -11
  69. package/dist/cli/commands/test-runs.js.map +1 -1
  70. package/dist/cli/commands/test.js.map +1 -1
  71. package/dist/cli/commands/update-many.js +1 -6
  72. package/dist/cli/commands/update-many.js.map +1 -1
  73. package/dist/cli/commands/update.js +2 -2
  74. package/dist/cli/commands/update.js.map +1 -1
  75. package/dist/cli/commands/validate.js +23 -18
  76. package/dist/cli/commands/validate.js.map +1 -1
  77. package/dist/cli/error-guidance.d.ts +13 -0
  78. package/dist/cli/error-guidance.js +56 -6
  79. package/dist/cli/error-guidance.js.map +1 -1
  80. package/dist/cli/extension-command-help.d.ts +48 -0
  81. package/dist/cli/extension-command-help.js +389 -0
  82. package/dist/cli/extension-command-help.js.map +1 -0
  83. package/dist/cli/extension-command-options.js.map +1 -1
  84. package/dist/cli/help-content.js +9 -3
  85. package/dist/cli/help-content.js.map +1 -1
  86. package/dist/cli/help-json-payload.d.ts +25 -0
  87. package/dist/cli/help-json-payload.js +265 -0
  88. package/dist/cli/help-json-payload.js.map +1 -0
  89. package/dist/cli/main.js +1000 -4456
  90. package/dist/cli/main.js.map +1 -1
  91. package/dist/cli/migration-gates.d.ts +22 -0
  92. package/dist/cli/migration-gates.js +146 -0
  93. package/dist/cli/migration-gates.js.map +1 -0
  94. package/dist/cli/register-list-query.d.ts +2 -0
  95. package/dist/cli/register-list-query.js +317 -0
  96. package/dist/cli/register-list-query.js.map +1 -0
  97. package/dist/cli/register-mutation.d.ts +2 -0
  98. package/dist/cli/register-mutation.js +795 -0
  99. package/dist/cli/register-mutation.js.map +1 -0
  100. package/dist/cli/register-operations.d.ts +2 -0
  101. package/dist/cli/register-operations.js +610 -0
  102. package/dist/cli/register-operations.js.map +1 -0
  103. package/dist/cli/register-setup.d.ts +2 -0
  104. package/dist/cli/register-setup.js +334 -0
  105. package/dist/cli/register-setup.js.map +1 -0
  106. package/dist/cli/registration-helpers.d.ts +53 -0
  107. package/dist/cli/registration-helpers.js +669 -0
  108. package/dist/cli/registration-helpers.js.map +1 -0
  109. package/dist/cli/shared-parsers.d.ts +6 -0
  110. package/dist/cli/shared-parsers.js +40 -0
  111. package/dist/cli/shared-parsers.js.map +1 -0
  112. package/dist/cli.d.ts +1 -1
  113. package/dist/cli.js +3 -1
  114. package/dist/cli.js.map +1 -1
  115. package/dist/core/extensions/extension-types.d.ts +605 -0
  116. package/dist/core/extensions/extension-types.js +22 -0
  117. package/dist/core/extensions/extension-types.js.map +1 -0
  118. package/dist/core/extensions/index.js.map +1 -1
  119. package/dist/core/extensions/item-fields.js.map +1 -1
  120. package/dist/core/extensions/loader.d.ts +2 -586
  121. package/dist/core/extensions/loader.js +3 -21
  122. package/dist/core/extensions/loader.js.map +1 -1
  123. package/dist/core/extensions/runtime-registrations.js.map +1 -1
  124. package/dist/core/fs/fs-utils.js.map +1 -1
  125. package/dist/core/fs/index.js.map +1 -1
  126. package/dist/core/history/history-stream-policy.js.map +1 -1
  127. package/dist/core/history/history.js.map +1 -1
  128. package/dist/core/history/index.js.map +1 -1
  129. package/dist/core/item/id.js.map +1 -1
  130. package/dist/core/item/index.js.map +1 -1
  131. package/dist/core/item/item-format.js.map +1 -1
  132. package/dist/core/item/parent-reference-policy.js.map +1 -1
  133. package/dist/core/item/parse.js +6 -0
  134. package/dist/core/item/parse.js.map +1 -1
  135. package/dist/core/item/sprint-release-format.js.map +1 -1
  136. package/dist/core/item/status.js.map +1 -1
  137. package/dist/core/item/type-registry.js.map +1 -1
  138. package/dist/core/lock/index.js.map +1 -1
  139. package/dist/core/lock/lock.js +1 -6
  140. package/dist/core/lock/lock.js.map +1 -1
  141. package/dist/core/output/command-aware.js.map +1 -1
  142. package/dist/core/output/output.js.map +1 -1
  143. package/dist/core/schema/runtime-field-filters.js.map +1 -1
  144. package/dist/core/schema/runtime-field-values.js.map +1 -1
  145. package/dist/core/schema/runtime-schema.js.map +1 -1
  146. package/dist/core/search/cache.js +1 -7
  147. package/dist/core/search/cache.js.map +1 -1
  148. package/dist/core/search/embedding-batches.js +4 -0
  149. package/dist/core/search/embedding-batches.js.map +1 -1
  150. package/dist/core/search/http-client.d.ts +29 -0
  151. package/dist/core/search/http-client.js +64 -0
  152. package/dist/core/search/http-client.js.map +1 -0
  153. package/dist/core/search/providers.d.ts +3 -13
  154. package/dist/core/search/providers.js +19 -88
  155. package/dist/core/search/providers.js.map +1 -1
  156. package/dist/core/search/semantic-defaults.js +2 -7
  157. package/dist/core/search/semantic-defaults.js.map +1 -1
  158. package/dist/core/search/vector-stores.d.ts +4 -13
  159. package/dist/core/search/vector-stores.js +40 -93
  160. package/dist/core/search/vector-stores.js.map +1 -1
  161. package/dist/core/sentry/helpers.d.ts +27 -0
  162. package/dist/core/sentry/helpers.js +171 -0
  163. package/dist/core/sentry/helpers.js.map +1 -0
  164. package/dist/core/sentry/instrument.d.ts +25 -0
  165. package/dist/core/sentry/instrument.js +204 -0
  166. package/dist/core/sentry/instrument.js.map +1 -0
  167. package/dist/core/shared/command-types.js.map +1 -1
  168. package/dist/core/shared/conflict-markers.js.map +1 -1
  169. package/dist/core/shared/constants.d.ts +3 -0
  170. package/dist/core/shared/constants.js +58 -1
  171. package/dist/core/shared/constants.js.map +1 -1
  172. package/dist/core/shared/errors.js.map +1 -1
  173. package/dist/core/shared/index.d.ts +1 -0
  174. package/dist/core/shared/index.js +1 -0
  175. package/dist/core/shared/index.js.map +1 -1
  176. package/dist/core/shared/primitives.d.ts +13 -0
  177. package/dist/core/shared/primitives.js +33 -0
  178. package/dist/core/shared/primitives.js.map +1 -0
  179. package/dist/core/shared/serialization.js.map +1 -1
  180. package/dist/core/shared/text-normalization.js.map +1 -1
  181. package/dist/core/shared/time.js.map +1 -1
  182. package/dist/core/store/front-matter-cache.d.ts +6 -0
  183. package/dist/core/store/front-matter-cache.js +150 -0
  184. package/dist/core/store/front-matter-cache.js.map +1 -0
  185. package/dist/core/store/index.js.map +1 -1
  186. package/dist/core/store/item-format-migration.js.map +1 -1
  187. package/dist/core/store/item-store.js +46 -36
  188. package/dist/core/store/item-store.js.map +1 -1
  189. package/dist/core/store/paths.js.map +1 -1
  190. package/dist/core/store/settings.js +36 -0
  191. package/dist/core/store/settings.js.map +1 -1
  192. package/dist/core/telemetry/consent.js.map +1 -1
  193. package/dist/core/telemetry/observability.d.ts +24 -0
  194. package/dist/core/telemetry/observability.js +185 -0
  195. package/dist/core/telemetry/observability.js.map +1 -0
  196. package/dist/core/telemetry/runtime.d.ts +29 -3
  197. package/dist/core/telemetry/runtime.js +337 -25
  198. package/dist/core/telemetry/runtime.js.map +1 -1
  199. package/dist/core/test/background-runs.js.map +1 -1
  200. package/dist/core/test/item-test-run-tracking.js.map +1 -1
  201. package/dist/sdk/cli-contracts.js +28 -0
  202. package/dist/sdk/cli-contracts.js.map +1 -1
  203. package/dist/sdk/index.d.ts +1 -1
  204. package/dist/sdk/index.js.map +1 -1
  205. package/dist/types/index.js.map +1 -1
  206. package/dist/types.d.ts +21 -0
  207. package/dist/types.js +11 -0
  208. package/dist/types.js.map +1 -1
  209. package/docs/AGENT_GUIDE.md +125 -0
  210. package/docs/ARCHITECTURE.md +201 -478
  211. package/docs/COMMANDS.md +209 -0
  212. package/docs/CONFIGURATION.md +146 -0
  213. package/docs/EXTENSIONS.md +146 -645
  214. package/docs/QUICKSTART.md +108 -0
  215. package/docs/README.md +70 -0
  216. package/docs/RELEASING.md +92 -50
  217. package/docs/SDK.md +127 -68
  218. package/docs/TESTING.md +125 -0
  219. package/docs/examples/starter-extension/README.md +39 -25
  220. package/package.json +24 -11
  221. package/dist/command-types.d.ts +0 -1
  222. package/dist/command-types.js +0 -2
  223. package/dist/command-types.js.map +0 -1
  224. package/dist/constants.d.ts +0 -1
  225. package/dist/constants.js +0 -2
  226. package/dist/constants.js.map +0 -1
  227. package/dist/errors.d.ts +0 -1
  228. package/dist/errors.js +0 -2
  229. package/dist/errors.js.map +0 -1
  230. package/dist/fs-utils.d.ts +0 -1
  231. package/dist/fs-utils.js +0 -2
  232. package/dist/fs-utils.js.map +0 -1
  233. package/dist/history.d.ts +0 -1
  234. package/dist/history.js +0 -2
  235. package/dist/history.js.map +0 -1
  236. package/dist/id.d.ts +0 -1
  237. package/dist/id.js +0 -2
  238. package/dist/id.js.map +0 -1
  239. package/dist/item-format.d.ts +0 -1
  240. package/dist/item-format.js +0 -2
  241. package/dist/item-format.js.map +0 -1
  242. package/dist/item-store.d.ts +0 -1
  243. package/dist/item-store.js +0 -2
  244. package/dist/item-store.js.map +0 -1
  245. package/dist/lock.d.ts +0 -1
  246. package/dist/lock.js +0 -2
  247. package/dist/lock.js.map +0 -1
  248. package/dist/output.d.ts +0 -1
  249. package/dist/output.js +0 -2
  250. package/dist/output.js.map +0 -1
  251. package/dist/parse.d.ts +0 -1
  252. package/dist/parse.js +0 -2
  253. package/dist/parse.js.map +0 -1
  254. package/dist/paths.d.ts +0 -1
  255. package/dist/paths.js +0 -2
  256. package/dist/paths.js.map +0 -1
  257. package/dist/serialization.d.ts +0 -1
  258. package/dist/serialization.js +0 -2
  259. package/dist/serialization.js.map +0 -1
  260. package/dist/settings.d.ts +0 -1
  261. package/dist/settings.js +0 -2
  262. package/dist/settings.js.map +0 -1
  263. package/dist/time.d.ts +0 -1
  264. package/dist/time.js +0 -2
  265. package/dist/time.js.map +0 -1
package/README.md CHANGED
@@ -5,87 +5,22 @@
5
5
  [![Node >=20](https://img.shields.io/node/v/%40unbrained%2Fpm-cli)](https://nodejs.org)
6
6
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
7
7
 
8
- `pm` is a git-native project management CLI for humans and coding agents. It stores items as TOON (`.toon`) by default with full first-class JSON-front-matter Markdown (`.md`) support, keeps append-only JSONL history, and supports safe collaboration.
8
+ `pm` is a git-native project management CLI for humans and coding agents. It stores work items in reviewable repository files, records every mutation in append-only history, and defaults to sparse TOON output so agents can spend fewer tokens while still getting deterministic data.
9
9
 
10
- ## Highlights
10
+ ## Start Here
11
11
 
12
- - Git-native items that stay reviewable in diffs
13
- - Safe multi-agent workflows with claims, locks, and restore
14
- - Deterministic output with TOON by default and `--json` when needed
15
- - Layered command help: compact default (`Intent` + one example) and deep explainability via `--explain`
16
- - Machine-readable help payloads via `pm <command> --help --json` (also `pm help <command> --json`)
17
- - Structured diagnostics with machine-readable JSON error envelopes when `--json` is active
18
- - Dedicated machine contract surface via `pm contracts` (`--action`, `--command`, `--schema-only`, `--runtime-only`, `--active-only`)
19
- - Sparse TOON default output that omits null/undefined/empty fields for token-efficient agent workflows
20
- - Agent-friendly calendar views (`pm calendar` / `pm cal`) with markdown default output
21
- - Agent-first context snapshot command (`pm context` / `pm ctx`) for critical work + agenda triage
22
- - Reusable create templates (`pm templates save/list/show` + `pm create --template`)
23
- - First-class dual item storage formats: TOON (`.toon`) and JSON-front-matter Markdown (`.md`)
24
- - Compact TOON documents that are easier to review in terminal and GitHub web UI
25
- - Automatic item format migration when `item-format` config changes
26
- - Deterministic canonical normalization and atomic writes for parallel git/worktree workflows
27
- - Warning-first/strict validation policies for sprint/release and parent references
28
- - Additive history diff/verify diagnostics (`pm history --diff --verify`)
29
- - Linked path hygiene for files/docs (`--add-glob`, `--migrate`, `--validate-paths`, `--audit`)
30
- - Dependency topology inspection via `pm deps --format tree|graph`
31
- - Deterministic `--tag` completion suggestions from tracked item metadata
32
- - Additive large-list controls via projection (`--compact` / `--fields`), configurable sorting (`--sort` + `--order`), pagination (`--offset`), and opt-in JSON streaming (`--stream` with `--json`)
33
- - Governance-focused corpus analysis commands: `pm aggregate` default grouped counts and `pm dedupe-audit` duplicate clustering
34
- - Standalone `pm validate` command for metadata, resolution, lifecycle, linked-file, linked-command reference, and history-drift audits
35
- - Opt-in non-interactive progress output for long-running operations (`pm test`, `pm test-all`, `pm reindex` with `--progress`)
36
- - Managed background linked-test orchestration (`pm test --run --background`, `pm test-all --background`, and `pm test-runs` lifecycle controls; bare `pm test-runs` defaults to list output)
37
- - Linked-test context preflight and auto-remediation controls (`pm test`/`pm test-all` with `--check-context` and `--auto-pm-context`)
38
- - Safer cache cleanup controls via `pm gc --dry-run` and scoped cleanup with `--scope index|embeddings|runtime`
39
- - Pager-safe help output in automation (help requests auto-disable paging on non-TTY stdout, with explicit global `--no-pager` override)
40
- - Settings-gated item-level test result tracking (`pm config ... test-result-tracking --policy enabled|disabled`)
41
- - Optional search and extension support for more advanced setups
12
+ | Need | Read |
13
+ |------|------|
14
+ | Install and create the first item | [Quickstart](docs/QUICKSTART.md) |
15
+ | Agent workflow and token-minimal loops | [Agent Guide](docs/AGENT_GUIDE.md) |
16
+ | Command families and examples | [Command Reference](docs/COMMANDS.md) |
17
+ | Settings, storage, search, and output | [Configuration](docs/CONFIGURATION.md) |
18
+ | Safe test execution and linked tests | [Testing](docs/TESTING.md) |
19
+ | Extension authoring | [Extensions](docs/EXTENSIONS.md) and [SDK](docs/SDK.md) |
20
+ | Maintainer release process (daily auto-release + local parity) | [Releasing](docs/RELEASING.md) |
21
+ | Contributor internals | [Architecture](docs/ARCHITECTURE.md) |
42
22
 
43
- ## Unified Command Contracts
44
-
45
- `pm` now centralizes command/action contract metadata in `src/sdk/cli-contracts.ts` and uses it across:
46
-
47
- - CLI option normalization in `src/cli/main.ts`
48
- - Shell completion generation in `src/cli/commands/completion.ts`
49
- - Pi wrapper tool actions, JSON Schema, and arg mapping in `.pi/extensions/pm-cli/index.ts`
50
-
51
- Compatibility policy for command contracts:
52
-
53
- - Existing commands/flags and aliases remain valid.
54
- - Pi tool schema now uses strict action-scoped branches (schema v4); callers should send only action-relevant fields.
55
- - `--json` remains machine-contract stable; search projection defaults are command-specific (`pm search` defaults to compact rows unless `--full` is requested).
56
- - `pm contracts --json` is the canonical runtime contract introspection surface for agents, including active extension command/action metadata.
57
- - Contract payloads include runtime action availability metadata (`action_availability`) and optional runtime-filtered views (`--runtime-only`, `--active-only`) so automation can avoid non-invocable actions.
58
- - `pm contracts --command <name>` scopes output to the selected command for lower-noise machine payloads; omit `--command` for the full contract corpus.
59
- - `pm contracts` supports lightweight projection modes for automation pipelines: `--flags-only` (command flag surface) and `--availability-only` (runtime invocability metadata); the projection flags are mutually exclusive.
60
- - When `--action` is provided without `--command`, `pm contracts --flags-only` now scopes `command_flags` to the action-mapped command surface (for example `test-runs-list` resolves to `test-runs`).
61
- - Contract payloads include canonical flag + alias metadata (`command_flags` plus `commander_aliases`) so machine clients can expose accepted hyphen/underscore variants deterministically.
62
- - `pm completion` scripts are generated from the same normalized command-contract registry used by parser/contracts, keeping runtime, contract, and completion parity aligned.
63
- - `pm completion` now defaults to lazy tag expansion through runtime `pm completion-tags` lookup in generated scripts; pass `--eager-tags` to embed static tags in the script (legacy eager mode).
64
-
65
- ## Item Storage Formats
66
-
67
- - Default item format is TOON (`.toon`) using root-object field storage (`id`, `title`, ..., `body`).
68
- - JSON front matter + markdown body (`.md`) is a fully supported alternative format.
69
- - `front_matter` is an internal TypeScript field name (`ItemDocument.front_matter`) for item metadata; TOON files store the same metadata as top-level keys, not YAML front matter.
70
- - History files always remain JSONL (`history/<id>.jsonl`).
71
- - Set project item storage format with:
72
-
73
- ```bash
74
- pm config project set item-format --format toon
75
- # or
76
- pm config project set item-format --format json_markdown
77
- ```
78
-
79
- Changing `item-format` automatically migrates item files to the configured format.
80
-
81
- ## Parallel Git and Worktree Robustness
82
-
83
- - TOON and JSON/Markdown are equally supported item formats; teams can choose either format per repository.
84
- - Canonical normalization (stable field ordering and deterministic serialization) reduces diff churn and helps keep merges predictable.
85
- - Item writes are atomic (temp file + rename), which prevents partial writes and corruption during concurrent local operations.
86
- - Item history remains append-only JSONL with before/after hashes, so changes are auditable and recoverable with `pm history` and `pm restore`.
87
- - When both `.toon` and `.md` exist for one item ID, configured `item_format` is the source of truth and automatic migration removes split-format drift.
88
- - Concurrent edits to the exact same content can still require normal git conflict resolution; the storage model is designed to avoid silent data loss and make reconciliation explicit.
23
+ Full documentation starts at [docs/README.md](docs/README.md).
89
24
 
90
25
  ## Install
91
26
 
@@ -97,1060 +32,81 @@ pm --version
97
32
  pm --help
98
33
  ```
99
34
 
100
- For project-local use:
35
+ Project-local invocation also works:
101
36
 
102
37
  ```bash
103
38
  npx @unbrained/pm-cli --help
104
39
  ```
105
40
 
106
- ## Quick Start
41
+ ## 60 Second Example
107
42
 
108
43
  ```bash
109
44
  pm init
110
45
 
111
46
  pm create \
112
- --title "Fix Windows restore failure after stale lock cleanup" \
113
- --description "Restore can fail on Windows when a stale lock is cleaned up during retry." \
47
+ --title "Fix stale lock restore failure" \
48
+ --description "Restore should retry cleanly after stale lock cleanup." \
114
49
  --type Issue \
115
50
  --status open \
116
51
  --priority 1 \
117
- --tags "windows,locks,restore,release" \
118
- --body "Users can reproduce this on Windows after an interrupted restore. Add retry logging and verify restore succeeds after stale lock cleanup." \
119
- --deadline +3d \
120
- --estimate 180 \
121
- --acceptance-criteria "Restore succeeds after stale lock cleanup on Windows and regression coverage is added." \
122
- --definition-of-ready "Owner, reproduction steps, and affected files are identified." \
123
- --order 7 \
124
- --goal "Release readiness" \
125
- --objective "Stabilize restore under lock contention" \
126
- --value "Reduces failed recovery workflows during real incidents" \
127
- --impact "Fewer blocked releases and clearer operator recovery steps" \
128
- --outcome "Restore completes reliably after stale lock cleanup" \
129
- --why-now "The bug affects recovery flows and can block release work." \
130
- --author "alex-maintainer" \
131
- --message "Create restore failure issue with full metadata" \
132
- --assignee "alex-maintainer" \
133
- --parent "pm-release" \
134
- --reviewer "sam-reviewer" \
135
- --risk high \
136
- --confidence medium \
137
- --sprint "2026-W11" \
138
- --release "v2026.3" \
139
- --blocked-by "pm-locks" \
140
- --blocked-reason "Need the lock cleanup refactor merged first" \
141
- --unblock-note "Rebase once the lock cleanup patch lands" \
142
- --reporter "qa-bot" \
143
- --severity high \
144
- --environment "windows-11 node-25 npm-global-install" \
145
- --repro-steps "1) Interrupt restore after lock creation 2) Retry restore 3) Observe stale-lock cleanup fail on Windows" \
146
- --resolution "Add a retry after stale-lock cleanup and log the recovery path" \
147
- --expected-result "Restore retries cleanly and completes after stale-lock cleanup." \
148
- --actual-result "Restore exits with a lock error after cleanup on Windows." \
149
- --affected-version "2026.3.9" \
150
- --fixed-version "2026.3.10" \
151
- --component "core/locks" \
152
- --regression true \
153
- --customer-impact "Maintainers can be blocked from recovering work during release prep." \
154
- --dep "id=pm-locks,kind=blocks,author=alex-maintainer,created_at=now" \
155
- --comment "author=alex-maintainer,created_at=now,text=Initial triage confirms the Windows-only stale-lock recovery failure." \
156
- --note "author=alex-maintainer,created_at=now,text=Investigate lock cleanup timing in the restore retry path." \
157
- --learning "author=alex-maintainer,created_at=now,text=Windows file-handle timing needs a retry window after stale-lock cleanup." \
158
- --file "path=src/core/lock/lock-store.ts,scope=project,note=likely stale-lock retry fix" \
159
- --test "command=node scripts/run-tests.mjs test -- tests/integration/cli.integration.spec.ts,scope=project,timeout_seconds=900,note=restore lock regression coverage" \
160
- --doc "path=docs/ARCHITECTURE.md,scope=project,note=lock and restore design context"
52
+ --tags "restore,locks" \
53
+ --ac "Restore succeeds after stale lock cleanup and has regression coverage." \
54
+ --create-mode progressive
161
55
 
162
56
  pm list-open --limit 10
163
57
  pm claim <item-id>
58
+ pm update <item-id> --status in_progress --message "Start implementation"
59
+ pm files <item-id> --add path=src/core/lock/lock.ts,scope=project
60
+ pm test <item-id> --add command="node scripts/run-tests.mjs test -- tests/unit/lock.spec.ts",scope=project,timeout_seconds=240
61
+ pm test <item-id> --run --progress
62
+ pm close <item-id> "Fixed stale lock retry path; linked test passed."
63
+ pm release <item-id>
164
64
  ```
165
65
 
166
- From there, use `pm update`, `pm comments`, `pm notes`, `pm learnings`, `pm files`, `pm docs`, `pm test`, `pm search`, and `pm close` as work progresses.
167
-
168
- Claim behavior note:
169
-
170
- - `pm claim <ID>` can take over non-terminal items even when currently assigned to someone else.
171
- - Use `--force` for claim/release only when overriding terminal-state or lock conflicts.
172
- - For non-owner release handoffs that only clear assignee metadata, prefer `pm release <ID> --allow-audit-release --author <you>` before `--force`.
173
- - For ownership-conflict mutations, `--force` is intended for coordinated PM audits, lead-maintainer metadata corrections, or explicit ownership handoff cleanup.
174
- - `pm get <ID> --json` now includes `claim_state` with current assignee plus latest claim/release history context.
175
- - `pm get <ID> --json` returns body at top-level key `body` (not `item.body`) alongside `item`, `linked`, and `claim_state`.
176
-
177
- Create policy mode note:
66
+ ## Agent Loop
178
67
 
179
- - `pm create` defaults to strict required-option enforcement.
180
- - Use `--create-mode progressive` for staged governance triage when you need to defer non-critical metadata/linkage fields without placeholder `none` entries.
68
+ Use `pm context` first, then search before creating anything:
181
69
 
182
70
  ```bash
183
- pm create --title "Triage seed" --description "Capture scope first, enrich later" --type Task --create-mode progressive
71
+ pm context --limit 10
72
+ pm search "keywords for the requested work" --limit 10
73
+ pm list-open --limit 20
74
+ pm list-in-progress --limit 20
184
75
  ```
185
76
 
186
- ## Reusable Create Templates
77
+ If no relevant item exists, create a parent lineage before child work, claim the child item, link changed files/docs/tests, and leave evidence comments before closing. The full workflow is in the [Agent Guide](docs/AGENT_GUIDE.md).
187
78
 
188
- Use templates to save recurring create metadata (including repeatable seeds) and apply them with explicit override precedence:
79
+ ## Release Automation
189
80
 
190
- Template names are positional arguments (`pm templates save <name>` / `pm templates show <name>`); `--name` is not a valid flag.
81
+ - Daily release preparation runs in `.github/workflows/auto-release.yml`.
82
+ - Tag-driven publishing remains in `.github/workflows/release.yml`.
83
+ - Local parity commands:
84
+ - `pnpm release:pipeline:dry-run`
85
+ - `pnpm release:pipeline -- --telemetry-mode required`
191
86
 
192
- ```bash
193
- pm templates save release-issue \
194
- --type Issue \
195
- --status open \
196
- --priority 1 \
197
- --tags "release,incident" \
198
- --dep "id=pm-release,kind=related,created_at=now" \
199
- --file "path=src/cli/main.ts,scope=project"
87
+ ## Core Model
200
88
 
201
- pm templates list
202
- pm templates show release-issue --json
89
+ - Items live under `.agents/pm/` as TOON by default, with JSON-front-matter markdown also supported.
90
+ - History lives in `.agents/pm/history/<id>.jsonl` and is append-only.
91
+ - Statuses are `draft`, `open`, `in_progress`, `blocked`, `closed`, and `canceled`.
92
+ - Built-in types include `Epic`, `Feature`, `Task`, `Chore`, `Issue`, `Decision`, `Event`, `Reminder`, `Milestone`, and `Meeting`.
93
+ - Output defaults to sparse TOON. Use `--json` for strict parsing.
94
+ - `pm contracts` is the machine-readable command and schema contract surface for agents.
203
95
 
204
- # Explicit flags override template defaults deterministically.
205
- pm create \
206
- --title "Follow-up issue" \
207
- --description "Investigate release incident follow-up." \
208
- --type Issue \
209
- --template release-issue \
210
- --status blocked
211
- ```
212
-
213
- ## Semantic Search Defaults (Ollama)
214
-
215
- `pm search` now auto-enables semantic-capable defaults on hosts where local Ollama is installed, without requiring manual semantic provider/vector configuration in `settings.json`.
216
-
217
- - Auto-defaults only apply when semantic settings are otherwise unset (no explicit `settings.search.provider`, `settings.vector_store.adapter`, `providers.*`, or `vector_store.*` semantic config).
218
- - Resolved defaults are:
219
- - embedding provider: Ollama (`http://localhost:11434`)
220
- - embedding model: `PM_OLLAMA_MODEL` (if set), otherwise first model from `ollama list` (preferring names containing `embed`/`embedding`), otherwise `qwen3-embedding:0.6b`
221
- - vector store: local LanceDB path `.agents/pm/search/lancedb/`
222
- - Explicit user/project configuration always takes precedence over auto-defaults.
223
- - If implicit auto-defaulted semantic execution fails at runtime, `pm search` falls back to keyword mode to avoid breaking existing users.
224
- - Implicit hybrid auto-default execution now uses bounded semantic timeouts and adds deterministic fallback warnings (for example `search_implicit_semantic_fallback:timeout:using_keyword_mode`) when switching to keyword mode.
225
- - For strict low-latency loops, use `--mode keyword` explicitly.
226
- - Disable this behavior with `PM_DISABLE_OLLAMA_AUTO_DEFAULTS=1`.
227
-
228
- To (re)build semantic artifacts explicitly:
229
-
230
- ```bash
231
- pm reindex --mode hybrid
232
- ```
233
-
234
- ## Search Projection Modes
96
+ ## Tracker References
235
97
 
236
- `pm search` now supports explicit projection controls and defaults to compact rows in both TOON and JSON output modes:
237
-
238
- - default projection: compact (`id`, `title`, `status`, `type`, `priority`, `updated_at`, `score`, `matched_fields`)
239
- - `--full`: return full hit rows (including nested `item` payload)
240
- - `--fields <csv>`: return only specific fields (for example `--fields id,title,score,item.updated_at`)
241
- - projection flags are mutually exclusive (`--compact`, `--full`, `--fields`)
242
-
243
- Unquoted multi-word queries are accepted directly:
244
-
245
- ```bash
246
- pm search performance mobile gpu --limit 5
247
- ```
248
-
249
- ## Hierarchical List Filtering
250
-
251
- All list-family commands now support parent-scoped filtering:
252
-
253
- ```bash
254
- pm list-open --parent pm-epic01 --limit 20
255
- pm list-in-progress --parent pm-feature02 --json
256
- ```
257
-
258
- ## List Projection and Sorting
259
-
260
- List-family commands support explicit projection and deterministic sort controls:
261
-
262
- ```bash
263
- # Compact default projection fields for list rows
264
- pm list-open --compact --limit 20
265
-
266
- # Custom projected fields
267
- pm list-all --fields id,title,parent,type --limit 50
268
-
269
- # Configurable sort field + order
270
- pm list-open --sort deadline --order asc --limit 20
271
- pm list-open --sort priority --order desc --limit 20
272
- ```
273
-
274
- Projection flags are mutually exclusive for list-family commands (`--compact`, `--fields`, `--include-body` remains additive for body projection).
275
-
276
- ## Ownership-Safe Metadata Updates and Bulk Mutation
277
-
278
- Governance workflows now include explicit non-owner metadata mutation and bulk update planning surfaces:
279
-
280
- - `pm update --allow-audit-update` allows non-owner metadata updates without broad `--force` semantics.
281
- - `--allow-audit-update` is intentionally scoped: lifecycle/ownership/linkage mutations remain disallowed in this mode (for example assignee/parent and other lifecycle-governing fields).
282
- - `pm update --allow-audit-dep-update` enables non-owner append-only dependency additions via `--dep` without broad `--force` semantics.
283
- - `--allow-audit-update` and `--allow-audit-dep-update` are mutually exclusive by design.
284
- - `pm update-many` provides native bulk mutation with deterministic filter targeting, dry-run planning, optional checkpoint capture, and rollback.
285
- - `pm update-many` supports linked-array payload parity with `pm update` (repeatable `--dep/--comment/--note/--learning/--file/--test/--doc/--reminder/--event` plus `--clear-*`, `--replace-deps`, and `--replace-tests`).
286
- - `pm update-many --rollback <checkpoint-id>` restores every item in a prior checkpoint (ownership-safe restore path included).
287
- - `pm normalize` provides deterministic lifecycle metadata hygiene with default dry-run planning and explicit `--apply` mode.
288
- - `pm normalize` reuses list-style filter targeting (`--filter-status`, `--filter-type`, `--filter-tag`, assignee/parent/sprint/release, `--limit`, `--offset`) and supports ownership-safe apply controls (`--allow-audit-update`, `--force`).
289
-
290
- ```bash
291
- # Ownership-safe metadata audit update (non-owner, metadata-only scope)
292
- pm update pm-a1b2 --description "Clarified acceptance boundaries" --allow-audit-update --author audit-maintainer
293
-
294
- # Ownership-safe dependency-only audit update (append-only --dep)
295
- pm update pm-a1b2 --dep "id=pm-epic01,kind=related,author=audit-maintainer,created_at=now" --allow-audit-dep-update --author audit-maintainer
296
-
297
- # Bulk apply mode with deterministic targeting
298
- pm update-many --filter-status open --filter-tag governance --status in_progress --author maintainer --message "Governance sweep"
299
-
300
- # Bulk linked-test replacement across matched items (single transaction per item)
301
- pm update-many --filter-tag wave:7 --replace-tests --test "command=node scripts/run-tests.mjs test -- tests/core/history.spec.ts,scope=project,timeout_seconds=240" --message "Normalize linked test assertions"
302
-
303
- # Dry-run planning mode (no mutations)
304
- pm update-many --filter-status in_progress --priority 1 --deadline +2d --dry-run --json
305
-
306
- # Roll back a previously captured checkpoint
307
- pm update-many --rollback 20260406T102455Z-7xq9 --author maintainer --message "Rollback governance batch"
308
-
309
- # Preview lifecycle metadata normalization plans (default mode is dry-run)
310
- pm normalize --filter-status in_progress --dry-run --json
311
-
312
- # Apply lifecycle metadata normalization with audit-safe ownership controls
313
- pm normalize --filter-tag governance --apply --allow-audit-update --author maintainer --message "Normalize lifecycle metadata"
314
- ```
315
-
316
- ## Duplicate and Decomposition Audits
317
-
318
- Governance workflows now have dedicated audit commands:
319
-
320
- ```bash
321
- # Group child counts by parent/type for decomposition checks
322
- pm aggregate --group-by parent,type --status open --json
323
-
324
- # Include rows that do not have a parent when grouping by parent
325
- pm aggregate --group-by parent,type --include-unparented --json
326
-
327
- # Group by operational triage dimensions
328
- pm aggregate --group-by type,status --json
329
-
330
- # Detect likely duplicates by exact title, fuzzy title, or parent-scoped title collisions
331
- pm dedupe-audit --mode title_exact --limit 25 --json
332
- pm dedupe-audit --mode title_fuzzy --threshold 0.75 --limit 25 --json
333
- pm dedupe-audit --mode parent_scope --limit 25 --json
334
- ```
335
-
336
- `pm aggregate --group-by` supports `parent,type,priority,status,assignee,tags,sprint,release`.
337
-
338
- ## GC Safety Controls
339
-
340
- `pm gc` now supports no-side-effect previews and targeted cleanup scopes:
341
-
342
- ```bash
343
- # Preview what would be removed (no deletes)
344
- pm gc --dry-run --json
345
-
346
- # Clean only index + embeddings cache artifacts
347
- pm gc --scope index,embeddings --json
348
-
349
- # Repeatable scope flags are also supported
350
- pm gc --scope runtime --scope embeddings --json
351
- ```
98
+ This documentation refresh is tracked through `pm`:
352
99
 
353
- `pm gc` output now includes `dry_run`, resolved `scope`, and `guidance` fields. When search artifacts are removed, guidance includes reindex recommendations.
100
+ - [pm-3042](.agents/pm/epics/pm-3042.toon) - documentation overhaul epic
101
+ - [pm-r9gu](.agents/pm/features/pm-r9gu.toon) - documentation structure feature
102
+ - [pm-1sb2](.agents/pm/tasks/pm-1sb2.toon) - README and public docs rewrite task
354
103
 
355
- ## Health Drift, Integrity, and Vectorization Checks
356
-
357
- `pm health` includes deterministic checks for item/history integrity and semantic vector freshness:
358
-
359
- - `directories`
360
- - distinguishes required tracker directories from optional built-in item-type directories
361
- - reports `missing_required` and `missing_optional` separately in check details
362
- - treats missing optional built-in type directories (`events`, `reminders`, `milestones`, `meetings`) as informational by default
363
- - supports `--strict-directories` to treat missing optional directories as health warnings/failures
364
- - supports `--strict-exit` (alias `--fail-on-warn`) to return non-zero exit (`1`) when health warnings are present (`ok=false`)
365
- - `integrity`
366
- - scans item and history files for merge-conflict markers (`<<<<<<<`, `=======`, `>>>>>>>`)
367
- - reports invalid item parses and invalid JSONL lines in history streams with deterministic warning codes
368
- - `history_drift`
369
- - scans current items and compares each canonical item hash against the latest history `after_hash`
370
- - reports missing history streams, unreadable/corrupt history streams, and hash mismatches
371
- - `vectorization`
372
- - compares current item `updated_at` values against a local vectorization ledger at `search/vectorization-status.json`
373
- - identifies stale/missing vector entries and (by default) performs targeted semantic refresh for stale item IDs when semantic runtime is available
374
- - avoids forcing a full rebuild (`pm reindex`) for routine health checks
375
- - supports explicit refresh policy controls:
376
- - `--check-only` / `--no-refresh` for read-only diagnostics
377
- - `--refresh-vectors` to force refresh intent explicitly
378
-
379
- The vectorization ledger is also refreshed during `pm reindex --mode semantic|hybrid` to keep health diagnostics aligned with the latest indexed corpus.
380
-
381
- ## Standalone Validation Checks
382
-
383
- `pm validate` provides a dedicated audit surface for project metadata quality and integrity checks:
384
-
385
- - Runs all validation checks by default (`metadata`, `resolution`, `lifecycle`, `files`, `command_references`, `history_drift`).
386
- - Runs linked-command PM reference checks by default (`command_references`) to catch stale `pm-<id>` references before execution-time failures.
387
- - Supports scoped checks with `--check-metadata`, `--check-resolution`, `--check-lifecycle`, `--check-stale-blockers`, `--check-files`, `--check-command-references`, and `--check-history-drift`.
388
- - `--check-metadata` supports `--metadata-profile core|strict|custom` for deterministic required-field policy selection.
389
- - `--metadata-profile custom` reads `settings.validation.metadata_required_fields`; if the configured list is empty, validation falls back to core requirements and emits `validate_metadata_custom_profile_missing_required_fields:0`.
390
- - `--check-lifecycle` audits active-item governance drift for terminal-parent lineage and closure-like metadata on non-terminal items.
391
- - `--check-stale-blockers` adds optional blocker-consistency diagnostics to lifecycle checks, surfacing stale `blocked_by`/`blocked_reason` patterns without enabling those heuristics by default.
392
- - Lifecycle-check details include effective closure/stale pattern lists and deterministic per-field pattern sources (`default` vs `settings`).
393
- - `--check-files` supports `--scan-mode default|tracked-all|tracked-all-strict`; tracked modes use git-tracked candidates when available.
394
- - `tracked-all` excludes PM internals by default for higher-signal orphaned results; pass `--include-pm-internals` for full internal-audit scans.
395
- - `tracked-all-strict` forces full tracked coverage (including PM internals) and bypasses internal exclusion filtering.
396
- - `tracked-all-strict` emits explicit strict-coverage visibility fields in file-check details (`strict_mode_forces_pm_internals`, `strict_mode_forces_pm_internals_notice`) and warning `validate_files_tracked_all_strict_forces_pm_internals` when internals were force-enabled.
397
- - File-check details report filtered candidate counts (`candidate_total`, `candidate_scanned`) plus raw pre-filter counts (`candidate_total_raw`, `candidate_scanned_raw`), `pm_internal_excluded_count`, and structured `excluded_by_reason` summaries when paths are filtered.
398
- - Command-reference details report referenced PM IDs and stale-reference rows; stale rows emit `validate_command_references_stale_pm_ids:<count>` warnings.
399
- - Resolution-check details now include default remediation hint templates (`pm update <id> ...`) for missing `resolution`/`expected_result`/`actual_result` fields.
400
- - `--strict-exit` (alias `--fail-on-warn`) returns non-zero exit (`1`) when validation warnings are present (`ok=false`).
401
- - Returns deterministic TOON/JSON output suitable for review or automation pipelines.
402
- - Output writers treat broken pipes (`EPIPE`) as expected shell behavior: stdout `EPIPE` exits successfully (for pipeline-friendly reads) while stderr `EPIPE` remains non-zero.
403
-
404
- ## Missing History Stream Policy
405
-
406
- `settings.history.missing_stream` controls behavior when an item's `history/<id>.jsonl` stream is missing:
407
-
408
- - `auto_create` (default)
409
- - missing streams for existing items are created automatically before history-touching command paths continue
410
- - `strict_error`
411
- - history-touching command paths fail with a deterministic error instead of creating missing streams
412
-
413
- Configure policy with:
414
-
415
- ```bash
416
- pm config project set history-missing-stream-policy --policy auto_create
417
- pm config project set history-missing-stream-policy --policy strict_error
418
- pm config project get history-missing-stream-policy --json
419
- ```
420
-
421
- Policy enforcement applies to `pm history`, `pm activity`, `pm stats`, `pm health`, restore, and existing-item mutation paths.
422
-
423
- ## Sprint/Release Format Policy
424
-
425
- `settings.validation.sprint_release_format` controls `--sprint` and `--release` validation behavior during `pm create` and `pm update`:
426
-
427
- - `warn` (default)
428
- - accepts non-conforming values and emits deterministic warnings (`validation_warning:sprint_format:<value>` / `validation_warning:release_format:<value>`)
429
- - `strict_error`
430
- - rejects non-conforming values with a deterministic usage error
431
-
432
- Accepted format for conforming values: 1-64 characters matching `[A-Za-z0-9][A-Za-z0-9._/-]*` (no spaces).
433
-
434
- Configure policy with:
435
-
436
- ```bash
437
- pm config project set sprint-release-format-policy --policy warn
438
- pm config project set sprint-release-format-policy --policy strict_error
439
- pm config project get sprint-release-format-policy --json
440
- ```
441
-
442
- ## Parent Reference Validation Policy
443
-
444
- `settings.validation.parent_reference` controls how `--parent` behaves during `pm create` and `pm update` when the referenced parent item does not exist:
445
-
446
- - `warn` (default)
447
- - keeps backward-compatible behavior and emits `validation_warning:parent_reference_missing:<id>`
448
- - `strict_error`
449
- - rejects missing parent references with a deterministic usage error
450
-
451
- Configure policy with:
452
-
453
- ```bash
454
- pm config project set parent-reference-policy --policy warn
455
- pm config project set parent-reference-policy --policy strict_error
456
- pm config project get parent-reference-policy --json
457
- ```
458
-
459
- ## Metadata Validation Profile Policy
460
-
461
- `settings.validation.metadata_profile` controls default required-field behavior for `pm validate --check-metadata`:
462
-
463
- - `core` (default)
464
- - requires baseline governance fields (`author`, `acceptance_criteria`, `estimated_minutes`, `close_reason` for closed items)
465
- - `strict`
466
- - extends core checks with additional governance fields (`reviewer`, `risk`, `confidence`, `sprint`, `release`)
467
- - `custom`
468
- - uses `settings.validation.metadata_required_fields` as the required field set (falls back to core + warning when empty)
469
-
470
- Configure policy with:
471
-
472
- ```bash
473
- pm config project set metadata-validation-profile --policy core
474
- pm config project set metadata-validation-profile --policy strict
475
- pm config project set metadata-validation-profile --policy custom
476
- pm config project get metadata-validation-profile --json
477
- ```
478
-
479
- Configure custom required fields with:
480
-
481
- ```bash
482
- pm config project set metadata-required-fields --criterion sprint --criterion release
483
- pm config project set metadata-required-fields --clear-criteria
484
- pm config project get metadata-required-fields --json
485
- ```
486
-
487
- ## Lifecycle Validation Pattern Policy
488
-
489
- `settings.validation.lifecycle_*_patterns` controls default substring heuristics used by `pm validate --check-lifecycle` and optional stale blocker diagnostics (`--check-stale-blockers`):
490
-
491
- - `settings.validation.lifecycle_stale_blocker_reason_patterns`
492
- - stale blocker reason substrings matched when stale blocker checks are enabled
493
- - `settings.validation.lifecycle_closure_like_blocked_reason_patterns`
494
- - closure-like `blocked_reason` substrings flagged on active items
495
- - `settings.validation.lifecycle_closure_like_resolution_patterns`
496
- - closure-like `resolution` substrings flagged on active items
497
- - `settings.validation.lifecycle_closure_like_actual_result_patterns`
498
- - closure-like `actual_result` substrings flagged on active items
499
-
500
- Configure lifecycle patterns with:
501
-
502
- ```bash
503
- pm config project set lifecycle-stale-blocker-reason-patterns --criterion "no active blocker"
504
- pm config project set lifecycle-closure-like-blocked-reason-patterns --criterion "work is closed"
505
- pm config project set lifecycle-closure-like-resolution-patterns --criterion "closed with implementation evidence"
506
- pm config project set lifecycle-closure-like-actual-result-patterns --criterion "work completed"
507
- pm config project set lifecycle-closure-like-resolution-patterns --clear-criteria
508
- pm config project get lifecycle-stale-blocker-reason-patterns --json
509
- ```
510
-
511
- ## Test Result Tracking Policy
512
-
513
- `settings.testing.record_results_to_items` controls whether `pm test --run` / `pm test-all` append bounded `test_runs` summaries to item front matter:
514
-
515
- - `disabled` (default)
516
- - test execution output is returned in command results only
517
- - `enabled`
518
- - successful/failed runs append deterministic item-level `test_runs` summary entries (bounded history retention)
519
-
520
- Configure policy with:
521
-
522
- ```bash
523
- pm config project set test-result-tracking --policy enabled
524
- pm config project set test-result-tracking --policy disabled
525
- pm config project get test-result-tracking --json
526
- ```
527
-
528
- ## Telemetry Tracking Policy and First-Run Consent
529
-
530
- `settings.telemetry.enabled` controls whether command telemetry is exported to the configured ingestion endpoint.
531
-
532
- - default: `enabled`
533
- - opt-out: `disabled`
534
- - first-run prompt:
535
- - interactive TTY only
536
- - skipped for non-interactive/CI and JSON-oriented automation paths
537
- - persisted in global settings
538
-
539
- Configure policy with:
540
-
541
- ```bash
542
- pm config global set telemetry-tracking --policy enabled
543
- pm config global set telemetry-tracking --policy disabled
544
- pm config global get telemetry-tracking --json
545
- ```
546
-
547
- ### Telemetry payload version and source context
548
-
549
- Command lifecycle telemetry now includes additive payload metadata for segmentation:
550
-
551
- - `pm_version` - CLI version resolved at runtime.
552
- - `source_context` - privacy-safe source bucket (`user`, `automation`, `test`, `dogfood`, `audit_smoke`).
553
- - `source_context_source` - classification provenance (`inferred` or `env_override`).
554
-
555
- Default inference classifies non-interactive/CI/json runs as `automation`, test runtimes as `test`, and interactive sessions as `user`.
556
-
557
- For explicit dogfood/audit attribution, override source context with:
558
-
559
- ```bash
560
- PM_TELEMETRY_SOURCE_CONTEXT=dogfood pm list-open
561
- PM_TELEMETRY_SOURCE_CONTEXT=audit_smoke pm context --limit 10
562
- ```
563
-
564
- ### Optional local OTEL trace export
565
-
566
- `pm` can additionally emit one OTLP trace span per command to a local (or custom) collector endpoint:
567
-
568
- - `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://127.0.0.1:4318/v1/traces`
569
- - or `OTEL_EXPORTER_OTLP_ENDPOINT=http://127.0.0.1:4318` (auto-appends `/v1/traces`)
570
- - optional service name override: `OTEL_SERVICE_NAME=pm-cli`
571
- - disable this OTEL side-channel explicitly with `PM_TELEMETRY_OTEL_DISABLED=1`
572
-
573
- Example:
574
-
575
- ```bash
576
- OTEL_EXPORTER_OTLP_ENDPOINT=http://127.0.0.1:4318 OTEL_SERVICE_NAME=pm-cli node dist/cli.js list-open
577
- ```
578
-
579
- ## Config Discovery and Snapshot Export
580
-
581
- `pm config` also supports read-only key discovery and one-shot snapshot export for integration workflows:
582
-
583
- ```bash
584
- pm config project list --json
585
- pm config project export --json
586
- ```
587
-
588
- - `list` returns key metadata (`key`, aliases, value kind, applicable set flags, summary) plus current resolved values.
589
- - `export` returns the resolved config value object in one payload for deterministic machine consumption.
590
-
591
- ## History Diff and Verify
592
-
593
- `pm history` now supports additive diagnostics:
594
-
595
- ```bash
596
- # Include changed-field summaries derived from RFC6902 patches
597
- pm history pm-a1b2 --diff
598
-
599
- # Verify before/after hash replay chain and current item hash alignment
600
- pm history pm-a1b2 --verify --json
601
- ```
602
-
603
- `pm restore` also supports history-only recovery when an item file is missing or deleted but its history stream still exists.
604
-
605
- ## Activity Timeline Filters and Streaming
606
-
607
- `pm activity` now supports deterministic timeline slicing plus JSON line streaming for downstream automation:
608
-
609
- - Filters: `--id`, `--op`, `--author`, `--from`, `--to`, `--limit`
610
- - Time bounds accept ISO/date/relative inputs (`--from -7d --to now`, etc.)
611
- - `--stream` is JSON-only and emits line-delimited payloads (`rows`, `ndjson`, `jsonl`)
612
- - boolean-style stream enablement is accepted (`--stream`, `--stream true`, `--stream 1`)
613
-
614
- ```bash
615
- pm activity --id pm-a1b2 --op update --author codex-agent --from -7d --to now --limit 100
616
- pm activity --json --stream rows --from -1d --limit 200
617
- ```
618
-
619
- ## Deadline and Date Inputs
620
-
621
- - Date/time inputs used by `--deadline`, `--deadline-before`, `--deadline-after`, calendar `--date/--from/--to`, reminders, and events accept:
622
- - ISO timestamps
623
- - Flexible date strings (for example `2026-03-31T13-59`, `20260331`, `20260331T135900Z`)
624
- - Relative offsets (`+6h`, `+1d`, `+2w`, `+6m`)
625
- - Accepted values are normalized to canonical ISO timestamps for deterministic storage and filtering.
626
- - Parse failures now report the precise field context (for example `event.end`, `reminder.at`, `--from`, `deadline-before`) for faster remediation.
627
- - Compound relative expressions such as `+3d+1h` are rejected; use a single relative token (`+3d`) or an ISO/date string.
628
-
629
- ## Status Values
630
-
631
- - Canonical status values are: `draft`, `open`, `in_progress`, `blocked`, `closed`, `canceled`.
632
- - Status input flags also accept `in-progress` as an alias for `in_progress` (`pm create`, `pm update`, `pm calendar`, and `pm test-all`).
633
- - Persisted item data and command output remain canonical (`in_progress`) for deterministic storage and filtering.
634
- - `pm update --close-reason <text>` sets `close_reason` explicitly; `pm update --unset close-reason` clears it.
635
- - When `pm update --status` reopens an item from `closed` to a non-terminal status, stale `close_reason` is auto-cleared unless `--close-reason` is explicitly provided in that update call.
636
-
637
- Task lifecycle aliases provide discoverable one-step workflows:
638
-
639
- - `pm start-task <id>`: claim + move to `in_progress`
640
- - `pm pause-task <id>`: move to `open` + release claim
641
- - `pm close-task <id> "<reason>"`: close + release claim metadata
642
-
643
- These aliases preserve canonical mutation history entries and accept standard mutation controls (`--author`, `--message`, `--force`; `close-task` also accepts `--validate-close`).
644
-
645
- ## Resilient Entry Input Formats
646
-
647
- Entry-style flags (`--add`, `--remove`, and repeatable create/update seed flags like `--comment`, `--file`, `--test`, `--doc`, `--reminder`, `--event`, `--type-option`) now accept three deterministic forms:
648
-
649
- - CSV key/value: `key=value,key2=value2`
650
- - Markdown-style key/value: `key: value` (single line, bullets, or multiline blocks)
651
- - Stdin token: pass `-` and pipe payload into the command
652
-
653
- Examples:
654
-
655
- ```bash
656
- # Files/docs/tests add supports markdown-style key:value
657
- pm files pm-a1b2 --add "path: src/cli/main.ts,scope: project,note: cli wiring"
658
- pm docs pm-a1b2 --add $'- path: README.md\n- scope: project\n- note: docs sync'
659
- pm test pm-a1b2 --add $'command: node scripts/run-tests.mjs test\nscope: project\ntimeout_seconds: 240'
660
-
661
- # Linked-path hygiene for files/docs (bulk migrate + optional validation/audit)
662
- pm files pm-a1b2 --add-glob "src/**/*.ts"
663
- pm docs pm-a1b2 --add-glob "pattern=docs/**/*.md,scope=project,note=docs sweep"
664
- pm files pm-a1b2 --migrate "from=src/old/,to=src/new/" --validate-paths --audit
665
- pm docs pm-a1b2 --migrate "from=docs/legacy/,to=docs/current/" --validate-paths --audit
666
- pm files pm-a1b2 --add "path=src/new/entry.ts,scope=project" --append-stable
667
-
668
- # Discover file paths mentioned in item text before adding them as links
669
- pm files discover pm-a1b2
670
- pm files discover pm-a1b2 --apply --note "discovered from item text"
671
-
672
- # Comments can be added positionally or with --add
673
- pm comments pm-a1b2 "captured from shorthand positional text"
674
- pm comments pm-a1b2 --add "text: captured from markdown formatter"
675
- pm comments pm-a1b2 --add "handoff note from alternate author" --author "alex-maintainer" --force
676
- pm comments pm-a1b2 --add "audit note from governance review" --author "audit-maintainer" --allow-audit-comment
677
-
678
- # Notes and learnings support the same positional/--add shorthand
679
- pm notes pm-a1b2 "implementation context captured from shorthand positional text"
680
- pm notes pm-a1b2 --add "text: parser fallback rationale"
681
- pm notes pm-a1b2 --add "audit note from governance review" --author "audit-maintainer" --allow-audit-comment
682
- pm learnings pm-a1b2 --add "text: always run linked tests through the sandbox runner"
683
- pm learnings pm-a1b2 --add "audit learning from governance review" --author "audit-maintainer" --allow-audit-comment
684
-
685
- # CSV-like key fragments remain plain text unless text is explicit
686
- pm comments pm-a1b2 --add "text=hello,scope:project" # plain-text fallback
687
- pm comments pm-a1b2 --add 'text="hello,scope:project"' # explicit structured text field
688
- pm notes pm-a1b2 --add "text: hello,scope:project" # markdown structured form
689
-
690
- # Pipe markdown payload via stdin with "-"
691
- printf '%s\n' 'path: docs/ARCHITECTURE.md' 'scope: project' 'note: piped update' | pm files pm-a1b2 --add -
692
- printf '%s\n' 'text: evidence from piped stdin' | pm comments pm-a1b2 --add -
693
- printf '%s\n' 'text: implementation note from piped stdin' | pm notes pm-a1b2 --add -
694
- printf '%s\n' 'text: learning captured from piped stdin' | pm learnings pm-a1b2 --add -
695
- printf '%s\n' 'at: +1d' 'text: reminder from piped stdin' | pm update pm-a1b2 --reminder -
696
- printf '%s\n' 'Backfilled body from stdin token' | pm update pm-a1b2 --body -
697
- pm update pm-a1b2 --dep "id=pm-b3c4,kind=blocks,author=alex-maintainer,created_at=now"
698
- pm update pm-a1b2 --dep-remove "pm-b3c4"
699
- pm update pm-a1b2 --replace-deps --dep "id=pm-c7d8,kind=related,author=alex-maintainer,created_at=now"
700
- pm update pm-a1b2 --clear-deps
701
- pm deps pm-a1b2 --format tree
702
- pm deps pm-a1b2 --format graph --json
703
-
704
- # Bulk governance snapshots for latest comments across matching items
705
- pm comments-audit --status in_progress --parent pm-epic01 --tag governance --latest 1 --limit 20 --json
706
-
707
- # Full-history export rows for NDJSON-friendly downstream processing
708
- pm comments-audit --status in_progress --sprint sprint-12 --release v0.2 --priority 1 --full-history --limit 20 --json
709
-
710
- # Summary-only item rows (no comment rows) for scoped inventory checks
711
- pm comments-audit --status in_progress --latest 0 --limit-items 20 --json
712
- ```
713
-
714
- `pm comments-audit --latest` and `--full-history` are intentionally mutually exclusive. `--latest 0` is valid and returns deterministic summary rows with `export.row_count = 0`. `--limit` is an alias for `--limit-items` (both remain supported). All modes now include additive top-level `summary` metrics (`totals`, coverage ratio/percent, and `by_type` breakdown) without changing existing `items`/`filters`/`export` payloads.
715
-
716
- Use explicit clear flags for repeatable fields (`--clear-files`, `--clear-comments`, `--clear-docs`, etc.) and `--unset <field>` for scalar clears.
717
-
718
- For `pm create` log-seed flags, `--comment` accepts plain-text shorthand (`--comment "triage note"`) in addition to structured forms. Structured `--comment`/`--note`/`--learning` payloads accept only `author`, `created_at`, and `text` keys. Ambiguous unquoted payloads that introduce extra parsed keys (for example `text=hello,scope:project`) are rejected to prevent silent text truncation. Use quoted text (`text="hello,scope:project"`), markdown-style key/value input, or stdin token `-` for punctuation-heavy text.
719
-
720
- ## Linked Artifact and Test Policy
721
-
722
- - Use dedicated linked-artifact commands for file/doc mutations:
723
- - `pm files <ID> --add/--add-glob/--remove`
724
- - `pm docs <ID> --add/--add-glob/--remove`
725
- - Use `pm update <ID> --body <value>` to replace an item's body content (including empty-string backfills); use `pm append <ID> --body <value>` for additive narrative updates.
726
- - Dependency links on existing items are now mutated through `pm update` (`--dep` to add entries, `--clear-deps` to clear all, `--replace-deps` for one-shot atomic replacement, and `--dep-remove`/`--dep_remove` to remove selectors).
727
- - Use `pm deps <ID> --format tree|graph` for deterministic read-only dependency visualization.
728
- - `pm update` supports transactional linked mutations in one lock/history operation via repeatable `--comment`, `--note`, `--learning`, `--file`, `--test`, and `--doc` flags.
729
- - Dedicated commands (`pm comments|notes|learnings|files|test|docs`) remain available for focused single-surface edits.
730
- - `pm test <ID> --add` intentionally enforces sandbox-safe, runnable command entries. Every new linked test must include `command=...`; optional `path=...` is metadata-only context.
731
- - `pm create --test` follows the same policy: `command=...` is required, optional `path=...` can annotate command scope.
732
- - Linked test entries also support optional per-entry runtime directives/assertions plus context override metadata: `env_set=KEY=VALUE;KEY2=VALUE2`, `env_clear=KEY1;KEY2`, `shared_host_safe=true|false`, `pm_context_mode=schema|tracker|auto`, `assert_stdout_contains=...`, `assert_stdout_regex=...`, `assert_stderr_contains=...`, `assert_stderr_regex=...`, `assert_stdout_min_lines=<int>`, `assert_json_field_equals=path=value`, `assert_json_field_gte=path=<number>`.
733
- - `pm test <ID> --run` / `pm test-all` execute in temporary sandbox roots but seed project/global `settings.json` and `extensions/` directories from source roots so extension-defined type behavior matches direct workspace commands.
734
- - `pm test <ID> --run` / `pm test-all` support additive run-level runtime controls: repeatable `--env-set KEY=VALUE`, repeatable `--env-clear NAME`, `--shared-host-safe` (ephemeral/shared-host-friendly defaults such as `PORT=0` when unset), `--pm-context schema|tracker|auto`, `--override-linked-pm-context` (force run-level context over per-test `pm_context_mode`), `--check-context`, `--auto-pm-context`, `--fail-on-context-mismatch`, `--fail-on-skipped`, `--fail-on-empty-test-run`, and `--require-assertions-for-pm`.
735
- - `pm test-all` supports blast-radius pagination with `--limit` and `--offset` before linked-test execution.
736
- - `pm test <ID> --run --background` and `pm test-all --background` start managed background runs and return run metadata immediately.
737
- - `pm test-runs` (no subcommand) defaults to `list` output; `pm test-runs list|status|logs|stop|resume` provides explicit background lifecycle management, log tailing, health snapshots, and stop/resume controls.
738
- - Background run dedupe prevents parallel duplicate execution when an equivalent active run fingerprint already exists.
739
- - Background run metadata resolves `requested_by` deterministically through: explicit author -> `PM_AUTHOR` -> settings `author_default` -> `USER`/`LOGNAME`/`USERNAME` -> OS username (`whoami`) -> `unknown`.
740
- - Linked-test `run_results` include `execution_context` metadata (context mode, PM roots, item counts, mismatch signal, extension seeding state, PM tracker-read classification, `requested_pm_context_mode`, and `auto_pm_context_applied`) so PM-command parity is explicit in machine-readable output.
741
- - With `--check-context`, run warnings include a `context_preflight:...` summary (`checked_pm_commands`, `tracker_read_commands`, `mismatches`, `auto_remediated`) for deterministic diagnostics before/around linked execution.
742
- - In default `--pm-context schema` mode, PM tracker-read linked commands (for example `list*`, `get`, `search`, `stats`, `test-all`) fail on dataset mismatch by default; use `--pm-context auto` for automatic tracker-read routing or `--pm-context tracker` for full tracker-mode execution.
743
- - If run-level `--pm-context tracker` is set but a linked test entry pins `pm_context_mode=schema`, mismatch diagnostics explicitly call out per-test override precedence and recommend either changing/removing per-test metadata or passing `--override-linked-pm-context` to force run-level precedence.
744
- - `pm test <ID> --run` and `pm test-all` emit heartbeat/progress lines to stderr in interactive terminals during long-running linked commands, and support explicit non-interactive progress output via `--progress`.
745
- - Linked test timeout handling uses deterministic process termination (including force-kill fallback) and reports explicit timeout/maxBuffer diagnostics in `run_results`.
746
- - Failed linked test `run_results` now include `failure_category` (for example `infra_collision` vs `assertion_failure`) and `pm test-all` totals include aggregated `failure_categories` counts for triage.
747
- - `pm test <ID> --run` now returns dependency-failed exit code (`5`) when any linked test run result fails (matching `pm test-all` failure gating behavior).
748
- - `pm list` / `pm list-*` return front-matter rows by default; `pm list` and `pm list-all` also accept `--status <value>` for status-specific filtering without switching subcommands. Pass `--compact` or `--fields <csv>` for projection control, `--sort <field> --order <asc|desc>` for deterministic ordering, `--include-body` when body projection is needed, `--offset <n>` for pagination, and `--stream` (with `--json`) for newline-delimited item streaming.
749
-
750
- ## Terminal Compatibility
751
-
752
- `pm` is intentionally terminal-neutral so it works in native shells, IDE-integrated terminals, and emulated PTY backends:
753
-
754
- - Output is plain deterministic TOON/JSON/markdown text (no required terminal-specific OSC/ANSI control protocol).
755
- - Error exits preserve deterministic exit-code mapping while using graceful `process.exitCode` behavior.
756
- - Help invocations suppress pager hangs in non-interactive contexts by auto-disabling paging when stdout is not a TTY; use global `--no-pager` for explicit suppression in any context.
757
- - Stdin token entry (`-`) requires piped stdin when invoked from an interactive TTY.
758
- - `pm beads import --file -` follows the same stdin guard: if stdin is interactive TTY, `pm` returns usage guidance instead of waiting for EOF.
759
- - Linked test execution uses shell-compatible spawn orchestration instead of buffered one-shot capture, reducing silent long-run behavior in IDE-integrated terminals.
760
- - During interactive runs, linked tests print periodic stderr heartbeat lines (`[pm test] linked-test ... running`) until completion.
761
- - Timeout paths attempt graceful termination first, then deterministic force-kill fallback for stubborn subprocess trees.
762
- - For manual EOF in interactive sessions:
763
- - Unix/macOS terminals: `Ctrl+D`
764
- - Windows terminals: `Ctrl+Z` then `Enter`
765
-
766
- Example piped Beads import (after installing the bundled extension once per scope):
767
-
768
- ```bash
769
- pm extension --install --project beads
770
- cat issues.jsonl | pm beads import --file -
771
- ```
772
-
773
- ## Custom Item Types and Type Options
774
-
775
- `pm` supports project/global custom item types through `settings.json` and extension registrations. When no custom configuration exists, built-in types keep their default behavior.
776
- Current built-ins are: `Epic`, `Feature`, `Task`, `Chore`, `Issue`, `Event`, `Reminder`, `Milestone`, and `Meeting`.
777
-
778
- ### Configure custom types in `settings.json`
779
-
780
- ```json
781
- {
782
- "item_types": {
783
- "definitions": [
784
- {
785
- "name": "Asset",
786
- "folder": "assets",
787
- "aliases": ["assets", "3d-asset"],
788
- "required_create_fields": ["title", "description", "status", "priority", "message"],
789
- "required_create_repeatables": [],
790
- "command_option_policies": [
791
- { "command": "create", "option": "severity", "enabled": false },
792
- { "command": "create", "option": "reporter", "enabled": false },
793
- { "command": "create", "option": "goal", "visible": false },
794
- { "command": "update", "option": "message", "required": true }
795
- ],
796
- "options": [
797
- {
798
- "key": "category",
799
- "values": ["Map", "Character", "Prop", "VFX"],
800
- "required": true,
801
- "aliases": ["asset_category"],
802
- "description": "High-level asset classification"
803
- },
804
- {
805
- "key": "pipeline",
806
- "values": ["Blockout", "Modeling", "Rigging", "Texturing", "Done"]
807
- }
808
- ]
809
- }
810
- ]
811
- }
812
- }
813
- ```
814
-
815
- ### Use custom types on create/update
816
-
817
- ```bash
818
- pm create \
819
- --title "Forest world map" \
820
- --description "Primary world navigation mesh and terrain art" \
821
- --type Asset \
822
- --status open \
823
- --priority 1 \
824
- --message "Track world map asset" \
825
- --type-option category=Map \
826
- --type-option pipeline=Modeling
827
-
828
- pm update pm-a1b2 --type-option category=Character --type-option pipeline=Rigging
829
- ```
830
-
831
- `--type-option` accepts `key=value`, `key:value`, and `key=<name>,value=<value>` formats (including markdown-style lines), can read stdin via `-`, and can be cleared with `--clear-type-options`.
832
-
833
- `command_option_policies` lets each type mark create/update options as:
834
-
835
- - `required: true|false` (mandatory or optional)
836
- - `enabled: true|false` (accepted or rejected at runtime)
837
- - `visible: true|false` (shown or hidden in policy-aware help guidance)
838
-
839
- ### Improved required `--type` guidance
840
-
841
- When `--type` is missing, usage output now includes:
842
-
843
- - why `--type` is required
844
- - allowed values from the active runtime type registry
845
- - concrete `pm create` examples (including custom-type usage)
846
- - deterministic aggregation when multiple required create flags and required `--type-option` keys are missing for the selected type (single response, stable flag ordering)
847
- - a type-specific "next valid example" command in structured error guidance to accelerate one-shot fixes
848
-
849
- For `pm create --help` and `pm update --help`, add `--type <value>` to render type-aware policy details (required/disabled/hidden option lists) and type-option schema details (required marker, allowed values, aliases, description) from active settings/extensions.
850
-
851
- ## Help and Error Guidance
852
-
853
- `pm` now treats command guidance as a first-class UX surface:
854
-
855
- - Default help is compact and token-efficient (`Intent` + one high-signal example).
856
- - Add `--explain` to any `--help` invocation to render deeper rationale, multiple examples, and tips.
857
- - `pm help` and `pm help <command>` are success paths (exit code `0`) for known command paths; unavailable-command help requests emit explicit `unknown command '<name>'` guidance and return usage exit (`2`).
858
- - `pm <command> --help --json` and `pm help <command> --json` emit deterministic machine-readable help payloads.
859
- - Usage/runtime errors use one canonical guidance model:
860
- - text mode: structured sections (`What happened`, `What is required`, `Why`, `Examples`, optional `Next steps`)
861
- - `--json` mode: machine-readable envelope (`type`, `code`, `title`, `detail`, `required`, `exit_code`, optional `why/examples/next_steps`)
862
-
863
- Text-mode example:
864
-
865
- ```text
866
- Error: Missing required option --type <value>
867
-
868
- What happened:
869
- Commander rejected the command because --type <value> was not provided.
870
-
871
- What is required:
872
- Pass --type <value> with a valid value before running the command.
873
- ```
874
-
875
- JSON-mode example (`--json`):
876
-
877
- ```json
878
- {
879
- "type": "urn:pm-cli:error:missing_required_option",
880
- "code": "missing_required_option",
881
- "title": "Missing required option --type <value>",
882
- "detail": "Commander rejected the command because --type <value> was not provided.",
883
- "required": "Pass --type <value> with a valid value before running the command.",
884
- "exit_code": 2
885
- }
886
- ```
887
-
888
- ## Sparse TOON Default Output
889
-
890
- For default TOON output, command results are rendered directly from the command payload with recursive compaction:
891
-
892
- - omit `null` and `undefined`
893
- - omit empty arrays and empty objects
894
- - preserve meaningful falsy values (`0`, `false`, non-empty strings)
895
-
896
- JSON output remains contract-stable and command-contract driven; `pm search` uses compact projection by default unless overridden with `--full` or `--fields`.
897
-
898
- ## SDK and Full Override Extensions
899
-
900
- `pm` now ships a stable SDK entrypoint at `@unbrained/pm-cli/sdk` for extension authors.
901
-
902
- ```ts
903
- import { defineExtension, type ExtensionApi } from "@unbrained/pm-cli/sdk";
904
-
905
- export default defineExtension({
906
- activate(api: ExtensionApi) {
907
- api.registerCommand({
908
- name: "list-open",
909
- run: async (context) => ({ overridden: true, command: context.command }),
910
- });
911
- },
912
- });
913
- ```
914
-
915
- Extension runtime behavior is extension-first by default:
916
-
917
- - Extension command handlers can replace core command execution at dispatch time.
918
- - Parser overrides (`registerParser`) can rewrite command args/options/global context before dispatch.
919
- - Preflight overrides (`registerPreflight`) can intercept mutation gate decisions and migration flow.
920
- - Service overrides (`registerService`) can replace output/error/help rendering and selected internal runtime services.
921
- - Command-result overrides and renderer overrides still run with deterministic precedence (last registration wins).
922
- - `beforeCommand` and `afterCommand` hooks receive command args/options/global snapshots and final command result/error state.
923
- - `registerItemFields(...)` definitions now participate in create/update defaulting and validation.
924
- - `registerSearchProvider(...)` + `settings.search.provider` and `registerVectorStoreAdapter(...)` + `settings.vector_store.adapter` are now live runtime selectors for `pm search` / `pm reindex`.
925
- - `registerCommand(...)` definitions can optionally declare action/intent/examples/failure hints/arguments/flags metadata, which is surfaced in dynamic `--help` text, `--help --json` payloads, and `pm contracts`.
926
-
927
- Use `--no-extensions` to force core-only behavior for a single invocation.
928
-
929
- ## Extension Lifecycle Manager (`pm extension`)
930
-
931
- Use `pm extension` to install, adopt, inspect, manage, activate, deactivate, and remove custom extensions in project or global scope.
932
-
933
- Lifecycle actions (exactly one per call):
934
-
935
- - `--init` (alias: `--scaffold`)
936
- - `--install`
937
- - `--uninstall`
938
- - `--explore`
939
- - `--manage`
940
- - `--doctor`
941
- - `--adopt`
942
- - `--adopt-all`
943
- - `--activate`
944
- - `--deactivate`
945
-
946
- Scope selectors:
947
-
948
- - `--project` (default)
949
- - `--local` (alias of `--project`)
950
- - `--global`
951
-
952
- Install source selectors:
953
-
954
- - local extension directory path (for example `.agents/pm/extensions/my-ext`)
955
- - GitHub URL (for example `https://github.com/owner/repo/tree/main/path/to/ext`)
956
- - GitHub shorthand URL form (for example `github.com/owner/repo/path`)
957
- - explicit GitHub shorthand flag form `--gh owner/repo/path` (alias: `--github`)
958
- - optional Git ref override with `--ref <branch|tag|sha>`
959
-
960
- Requested source equivalence examples:
961
-
962
- ```bash
963
- # Scaffold a starter extension project (manifest + entrypoint + README)
964
- pm extension --init ./my-extension
965
- pm extension scaffold ./my-extension
966
-
967
- # Bundled managed aliases shipped with pm-cli (not auto-installed)
968
- pm extension --install --project beads
969
- pm extension --install --project todos
970
-
971
- # Equivalent explicit local bundled paths
972
- pm extension --install --project .agents/pm/extensions/beads
973
- pm extension --install --project .agents/pm/extensions/todos
974
-
975
- # Custom extension roots in repo
976
- pm extension --install --project https://github.com/unbraind/pm-cli/tree/main/.custom/pm-extensions/my-ext
977
- pm extension --install --project github.com/unbraind/pm-cli/.custom/pm-extensions/my-ext
978
- pm extension --install --project --gh unbraind/pm-cli/.custom/pm-extensions/my-ext
979
-
980
- # Single-extension repo or extension at repository root
981
- pm extension --install --project https://github.com/unbraind/pm-cli
982
- pm extension --install --project github.com/unbraind/pm-cli
983
- pm extension --install --project --gh unbraind/pm-cli
984
- ```
985
-
986
- Canonical public shorthand examples in this repository use `unbraind/pm-cli`. For private repositories, ensure your git credentials can access the source before using `--gh` or `github.com/...` selectors.
987
-
988
- Activation and health behavior:
989
-
990
- - `pm extension --init`/`--scaffold` creates an idempotent starter extension scaffold (manifest, entrypoint, README) and reports deterministic next steps.
991
- - Install auto-activates the extension in selected scope settings.
992
- - Deactivate/activate toggle `extensions.disabled[]`/`extensions.enabled[]` in settings.
993
- - `pm extension --explore` lists discovered extensions and compatibility/runtime status fields (`active` compatibility alias, `enabled`, `runtime_active`, `activation_status`).
994
- - `pm extension --adopt` records an existing unmanaged extension into managed state (local or GitHub provenance metadata) without reinstalling extension files.
995
- - `pm extension --adopt-all` bulk-adopts all unmanaged extensions in the selected scope without reinstalling files.
996
- - `pm extension --manage` refreshes GitHub-managed update metadata, persists it to scope-local `.managed-extensions.json`, and includes explicit per-extension `update_check_status`/`update_check_reason` fields (`checked`, `failed`, `skipped_unmanaged`, `skipped_non_github`, `not_checked`) plus triage status totals/remediation hints and update-health coverage diagnostics (`update_health_coverage`, `warning_codes`). `--runtime-probe` opt-in runs doctor-equivalent runtime activation checks for manage output parity. `--fix-managed-state` can adopt unmanaged extensions before update checks.
997
- - `pm extension --doctor` (or `pm extension doctor`) provides consolidated extension diagnostics with normalized warning codes, canonical load roots, active-vs-loaded consistency diagnostics, update-health coverage signals, remediation hints, optional strict exit gating (`--strict-exit`, alias `--fail-on-warn`), machine-usable blocking indicators (`blocking_failure_count`, `has_blocking_failures`), and optional deep output via `--detail deep`. `--trace` (deep mode) includes actionable registration traces and expected-schema hints for activation failures. `--fix-managed-state` can adopt unmanaged extensions before diagnostics.
998
- - Doctor load diagnostics include targeted guidance codes for common local setup failures: `extension_load_failed_sdk_dependency_missing` (missing `@unbrained/pm-cli` dependency) and `extension_load_failed_module_mode_mismatch` (ESM entry without `"type": "module"` or `.mjs` mode alignment).
999
- - Subcommand invocation forms (`pm extension manage ...`, `pm extension doctor ...`) honor the same action flags (`--runtime-probe`, `--detail`, `--trace`, etc.) as top-level action-flag forms.
1000
- - `pm health` includes managed extension state diagnostics plus a condensed extension triage block for quick load/activation/migration issue triage across project/global roots, including `extension_update_health_partial_coverage` only when unmanaged loaded extensions are action-required for update-check coverage.
1001
- - Unknown manifest capabilities emit `extension_capability_unknown` diagnostics with inline allowed-capability lists, nearest-match suggestions, and legacy alias guidance (`migration`/`validation` -> `schema`). Health/doctor payloads include machine-readable capability contract metadata (`details.capability_contract`) and parsed guidance entries (`details.capability_guidance`).
1002
- - Legacy extension command definitions using `handler` remain compatible and map to `run`, with deterministic warning `extension_command_definition_legacy_handler_alias` for migration visibility.
1003
-
1004
- Use `pm extension --help` for compact guidance or `pm extension --help --explain` for expanded examples/tips.
1005
-
1006
- ## Calendar, Reminders, and Events
1007
-
1008
- `pm` supports persistent reminder metadata, one-off and recurring scheduled events, and a dedicated calendar surface for deadline/reminder/event planning.
1009
-
1010
- ### Reminder fields on items
1011
-
1012
- - `pm create` and `pm update` accept repeatable `--reminder` flags.
1013
- - Reminder value format: `at=<iso|date|relative>,text=<text>`.
1014
- - Use `--clear-reminders` to clear reminders on create/update.
1015
-
1016
- Examples:
1017
-
1018
- ```bash
1019
- pm create \
1020
- --title "Prepare release notes" \
1021
- --description "Draft and review release notes for vnext." \
1022
- --create-mode progressive \
1023
- --type Task \
1024
- --status open \
1025
- --priority 1 \
1026
- --tags "release,docs" \
1027
- --body "" \
1028
- --deadline +2d \
1029
- --reminder "at=+1d,text=Start first draft" \
1030
- --reminder "at=+36h,text=Send review draft" \
1031
- --estimate 45 \
1032
- --acceptance-criteria "Release notes merged and linked." \
1033
- --author "maintainer-agent" \
1034
- --message "Create release notes task with reminders"
1035
-
1036
- pm update pm-a1b2 --reminder "at=+4h,text=Follow up with reviewer"
1037
- pm update pm-a1b2 --clear-reminders
1038
- ```
1039
-
1040
- ### Event fields on items
1041
-
1042
- - `pm create` and `pm update` accept repeatable `--event` flags.
1043
- - Event value format supports:
1044
- - `start=<iso|date|relative>` (required)
1045
- - `end=<iso|date|relative>` (optional, must be after `start`)
1046
- - `title=<text>`, `description=<text>`, `location=<text>`, `timezone=<iana-or-label>`, `all_day=<true|false|1|0|yes|no>`
1047
- - Recurrence metadata (optional, RFC-lite):
1048
- - `recur_freq=<daily|weekly|monthly|yearly>`
1049
- - `recur_interval=<int>=1+`
1050
- - `recur_count=<int>=1+`
1051
- - `recur_until=<iso|date|relative>`
1052
- - `recur_by_weekday=<mon|tue|wed|thu|fri|sat|sun>` (pipe-delimited)
1053
- - `recur_by_month_day=<1..31>` (pipe-delimited)
1054
- - `recur_exdates=<iso|date|relative>` (pipe-delimited)
1055
- - Use `--clear-events` to clear all events in create/update flows.
1056
-
1057
- Examples:
1058
-
1059
- ```bash
1060
- pm create \
1061
- --title "Run release planning" \
1062
- --description "Set recurring planning sync plus a one-off launch checkpoint." \
1063
- --create-mode progressive \
1064
- --type Task \
1065
- --status open \
1066
- --priority 1 \
1067
- --tags "release,calendar" \
1068
- --body "" \
1069
- --deadline +7d \
1070
- --event "start=2026-04-03T15:00:00.000Z,title=Launch checkpoint,location=War room" \
1071
- --event "start=2026-04-01T09:00:00.000Z,title=Weekly planning,recur_freq=weekly,recur_by_weekday=wed,recur_interval=1" \
1072
- --estimate 30 \
1073
- --acceptance-criteria "Calendar schedule is captured in item metadata." \
1074
- --author "maintainer-agent" \
1075
- --message "Create calendar-rich planning task"
1076
-
1077
- pm update pm-a1b2 --event "start=+2d,title=Retro,recur_freq=monthly,recur_by_month_day=15"
1078
- pm update pm-a1b2 --clear-events
1079
- ```
1080
-
1081
- ### Calendar command (`pm calendar` / `pm cal`)
1082
-
1083
- - Views: `agenda` (default), `day`, `week`, `month`
1084
- - Default output for calendar is markdown (command-specific override)
1085
- - Explicit output override: `--format markdown|toon|json` or global `--json`
1086
- - JSON summary includes deterministic aggregate breakdowns: `by_kind`, `by_type`, `by_status`, and `recurring_events`.
1087
- - Markdown event lines include richer deterministic metadata for agent parsing (item type, event title, recurrence marker/rule, end-time, timezone, location, and description when present).
1088
- - Event source controls:
1089
- - `--include deadlines|reminders|events|all` (comma or pipe-delimited when passing multiple values)
1090
- - default source set is `all`
1091
- - Recurrence expansion controls:
1092
- - `--recurrence-lookahead-days <n>`
1093
- - `--recurrence-lookback-days <n>`
1094
- - `--occurrence-limit <n>` (per recurring event; `>= 1`)
1095
- - Past toggles and range controls:
1096
- - `--past` includes past events in bounded views
1097
- - `--full-period` keeps day/week/month windows anchored to full period boundaries (without now-clipping)
1098
- - `--from` / `--to` supported on `agenda` (accept `today` as a day-start alias)
1099
- - `--date` anchors day/week/month calculations (accepts `today` as a day-start alias)
1100
- - Shared filters: `--type`, `--tag`, `--priority`, `--status`, `--assignee`, `--assignee-filter assigned|unassigned`, `--sprint`, `--release`, `--limit`
1101
-
1102
- Examples:
1103
-
1104
- ```bash
1105
- pm calendar
1106
- pm calendar --view day --date today --past
1107
- pm cal --view week --date +2d --past
1108
- pm calendar --view week --date 2026-04-06 --full-period --include deadlines,events
1109
- pm calendar --view agenda --from 2026-04-01T00:00:00.000Z --to 2026-04-08T00:00:00.000Z --assignee alex
1110
- pm calendar --view agenda --include events --recurrence-lookahead-days 30 --occurrence-limit 50
1111
- pm calendar --view month --tag release --format json
1112
- ```
1113
-
1114
- ## Context Snapshot (`pm context` / `pm ctx`)
1115
-
1116
- `pm context` provides a token-efficient project-state snapshot optimized for quickly deciding the next work item.
1117
-
1118
- - Default output is TOON (sparse and agent-friendly), with explicit `--format markdown|toon|json` and global `--json`.
1119
- - Focus sections prioritize active work (`in_progress`, then `open`) using deterministic ranking:
1120
- - status
1121
- - priority (`0..4`, lower is higher priority)
1122
- - explicit `order` (when present)
1123
- - deadline proximity
1124
- - recency/id tie-breakers
1125
- - Output is split into:
1126
- - high-level focus (`Epic`, `Feature`)
1127
- - low-level focus (`Task`, `Issue`, `Chore`, `Event`, `Reminder`, `Milestone`, `Meeting`, etc.)
1128
- - Agenda context is included from deadlines, reminders, and scheduled events in an agenda window.
1129
- - If there are no open or in-progress items, `pm context` automatically includes a blocked-work fallback section.
1130
- - Shared filters: `--type`, `--tag`, `--priority`, `--assignee`, `--sprint`, `--release`, `--limit`.
1131
- - Agenda window controls: `--date`, `--from`, `--to`, `--past`.
1132
-
1133
- Examples:
1134
-
1135
- ```bash
1136
- pm context
1137
- pm ctx --limit 5
1138
- pm context --assignee alex --priority 1 --limit 10
1139
- pm context --from +0d --to +7d --format markdown
1140
- pm context --date 2026-04-01T00:00:00.000Z --past --json
1141
- ```
104
+ Docs should link to relevant `pm` items, and `pm` items should link back to changed docs through `pm docs`.
1142
105
 
1143
- ## Documentation
106
+ ## Privacy Boundary
1144
107
 
1145
- - [Architecture](docs/ARCHITECTURE.md)
1146
- - [SDK Guide](docs/SDK.md)
1147
- - [Telemetry and GDPR Operations](docs/TELEMETRY.md)
1148
- - [Remote Telemetry Stack Runbook](docs/operations/REMOTE_TELEMETRY_STACK.md)
1149
- - [Extensions](docs/EXTENSIONS.md)
1150
- - [Contributing](CONTRIBUTING.md)
1151
- - [Security Policy](SECURITY.md)
1152
- - [Changelog](CHANGELOG.md)
108
+ Private production operations material is local-only, gitignored, and intentionally not linked from public documentation or packaged release files. Keep public docs focused on user-facing CLI behavior and safe contribution workflows.
1153
109
 
1154
110
  ## License
1155
111
 
1156
- MIT. See [LICENSE](LICENSE).
112
+ [MIT](LICENSE)