@unbrained/pm-cli 2026.3.12 → 2026.5.1-2

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 (285) hide show
  1. package/.agents/pm/extensions/.managed-extensions.json +42 -0
  2. package/.agents/pm/extensions/beads/index.js +109 -0
  3. package/.agents/pm/extensions/beads/manifest.json +7 -0
  4. package/{dist/cli/commands/beads.js → .agents/pm/extensions/beads/runtime.js} +31 -21
  5. package/.agents/pm/extensions/beads/runtime.ts +702 -0
  6. package/.agents/pm/extensions/todos/index.js +126 -0
  7. package/.agents/pm/extensions/todos/manifest.json +7 -0
  8. package/{dist/extensions/builtins/todos/import-export.js → .agents/pm/extensions/todos/runtime.js} +39 -29
  9. package/.agents/pm/extensions/todos/runtime.ts +568 -0
  10. package/AGENTS.md +196 -92
  11. package/CHANGELOG.md +404 -0
  12. package/CODE_OF_CONDUCT.md +42 -0
  13. package/CONTRIBUTING.md +144 -0
  14. package/PRD.md +512 -164
  15. package/README.md +1053 -2
  16. package/SECURITY.md +51 -0
  17. package/dist/cli/commands/activity.d.ts +5 -0
  18. package/dist/cli/commands/activity.js +66 -3
  19. package/dist/cli/commands/activity.js.map +1 -1
  20. package/dist/cli/commands/aggregate.d.ts +54 -0
  21. package/dist/cli/commands/aggregate.js +181 -0
  22. package/dist/cli/commands/aggregate.js.map +1 -0
  23. package/dist/cli/commands/append.js +4 -1
  24. package/dist/cli/commands/append.js.map +1 -1
  25. package/dist/cli/commands/calendar.d.ts +109 -0
  26. package/dist/cli/commands/calendar.js +797 -0
  27. package/dist/cli/commands/calendar.js.map +1 -0
  28. package/dist/cli/commands/claim.d.ts +5 -1
  29. package/dist/cli/commands/claim.js +42 -21
  30. package/dist/cli/commands/claim.js.map +1 -1
  31. package/dist/cli/commands/close.d.ts +1 -0
  32. package/dist/cli/commands/close.js +54 -5
  33. package/dist/cli/commands/close.js.map +1 -1
  34. package/dist/cli/commands/comments-audit.d.ts +91 -0
  35. package/dist/cli/commands/comments-audit.js +195 -0
  36. package/dist/cli/commands/comments-audit.js.map +1 -0
  37. package/dist/cli/commands/comments.d.ts +1 -0
  38. package/dist/cli/commands/comments.js +70 -21
  39. package/dist/cli/commands/comments.js.map +1 -1
  40. package/dist/cli/commands/completion.d.ts +10 -4
  41. package/dist/cli/commands/completion.js +1184 -137
  42. package/dist/cli/commands/completion.js.map +1 -1
  43. package/dist/cli/commands/config.d.ts +35 -3
  44. package/dist/cli/commands/config.js +968 -13
  45. package/dist/cli/commands/config.js.map +1 -1
  46. package/dist/cli/commands/context.d.ts +86 -0
  47. package/dist/cli/commands/context.js +299 -0
  48. package/dist/cli/commands/context.js.map +1 -0
  49. package/dist/cli/commands/contracts.d.ts +78 -0
  50. package/dist/cli/commands/contracts.js +920 -0
  51. package/dist/cli/commands/contracts.js.map +1 -0
  52. package/dist/cli/commands/create.d.ts +48 -14
  53. package/dist/cli/commands/create.js +1331 -160
  54. package/dist/cli/commands/create.js.map +1 -1
  55. package/dist/cli/commands/dedupe-audit.d.ts +81 -0
  56. package/dist/cli/commands/dedupe-audit.js +330 -0
  57. package/dist/cli/commands/dedupe-audit.js.map +1 -0
  58. package/dist/cli/commands/deps.d.ts +52 -0
  59. package/dist/cli/commands/deps.js +204 -0
  60. package/dist/cli/commands/deps.js.map +1 -0
  61. package/dist/cli/commands/docs.d.ts +19 -0
  62. package/dist/cli/commands/docs.js +212 -13
  63. package/dist/cli/commands/docs.js.map +1 -1
  64. package/dist/cli/commands/extension.d.ts +122 -0
  65. package/dist/cli/commands/extension.js +1850 -0
  66. package/dist/cli/commands/extension.js.map +1 -0
  67. package/dist/cli/commands/files.d.ts +52 -1
  68. package/dist/cli/commands/files.js +455 -13
  69. package/dist/cli/commands/files.js.map +1 -1
  70. package/dist/cli/commands/gc.d.ts +11 -1
  71. package/dist/cli/commands/gc.js +89 -11
  72. package/dist/cli/commands/gc.js.map +1 -1
  73. package/dist/cli/commands/get.d.ts +13 -0
  74. package/dist/cli/commands/get.js +35 -3
  75. package/dist/cli/commands/get.js.map +1 -1
  76. package/dist/cli/commands/health.d.ts +10 -2
  77. package/dist/cli/commands/health.js +774 -23
  78. package/dist/cli/commands/health.js.map +1 -1
  79. package/dist/cli/commands/history.d.ts +20 -0
  80. package/dist/cli/commands/history.js +152 -6
  81. package/dist/cli/commands/history.js.map +1 -1
  82. package/dist/cli/commands/index.d.ts +16 -3
  83. package/dist/cli/commands/index.js +16 -3
  84. package/dist/cli/commands/index.js.map +1 -1
  85. package/dist/cli/commands/init.d.ts +7 -2
  86. package/dist/cli/commands/init.js +137 -5
  87. package/dist/cli/commands/init.js.map +1 -1
  88. package/dist/cli/commands/learnings.d.ts +17 -0
  89. package/dist/cli/commands/learnings.js +129 -0
  90. package/dist/cli/commands/learnings.js.map +1 -0
  91. package/dist/cli/commands/list.d.ts +29 -1
  92. package/dist/cli/commands/list.js +289 -53
  93. package/dist/cli/commands/list.js.map +1 -1
  94. package/dist/cli/commands/normalize.d.ts +51 -0
  95. package/dist/cli/commands/normalize.js +298 -0
  96. package/dist/cli/commands/normalize.js.map +1 -0
  97. package/dist/cli/commands/notes.d.ts +17 -0
  98. package/dist/cli/commands/notes.js +129 -0
  99. package/dist/cli/commands/notes.js.map +1 -0
  100. package/dist/cli/commands/reindex.d.ts +1 -0
  101. package/dist/cli/commands/reindex.js +208 -32
  102. package/dist/cli/commands/reindex.js.map +1 -1
  103. package/dist/cli/commands/restore.js +164 -30
  104. package/dist/cli/commands/restore.js.map +1 -1
  105. package/dist/cli/commands/search.d.ts +14 -1
  106. package/dist/cli/commands/search.js +475 -81
  107. package/dist/cli/commands/search.js.map +1 -1
  108. package/dist/cli/commands/stats.js +26 -10
  109. package/dist/cli/commands/stats.js.map +1 -1
  110. package/dist/cli/commands/templates.d.ts +26 -0
  111. package/dist/cli/commands/templates.js +179 -0
  112. package/dist/cli/commands/templates.js.map +1 -0
  113. package/dist/cli/commands/test-all.d.ts +19 -1
  114. package/dist/cli/commands/test-all.js +161 -13
  115. package/dist/cli/commands/test-all.js.map +1 -1
  116. package/dist/cli/commands/test-runs.d.ts +63 -0
  117. package/dist/cli/commands/test-runs.js +179 -0
  118. package/dist/cli/commands/test-runs.js.map +1 -0
  119. package/dist/cli/commands/test.d.ts +75 -1
  120. package/dist/cli/commands/test.js +1360 -41
  121. package/dist/cli/commands/test.js.map +1 -1
  122. package/dist/cli/commands/update-many.d.ts +57 -0
  123. package/dist/cli/commands/update-many.js +631 -0
  124. package/dist/cli/commands/update-many.js.map +1 -0
  125. package/dist/cli/commands/update.d.ts +30 -0
  126. package/dist/cli/commands/update.js +1393 -84
  127. package/dist/cli/commands/update.js.map +1 -1
  128. package/dist/cli/commands/validate.d.ts +30 -0
  129. package/dist/cli/commands/validate.js +1151 -0
  130. package/dist/cli/commands/validate.js.map +1 -0
  131. package/dist/cli/error-guidance.d.ts +33 -0
  132. package/dist/cli/error-guidance.js +337 -0
  133. package/dist/cli/error-guidance.js.map +1 -0
  134. package/dist/cli/extension-command-options.d.ts +1 -0
  135. package/dist/cli/extension-command-options.js +92 -0
  136. package/dist/cli/extension-command-options.js.map +1 -1
  137. package/dist/cli/help-content.d.ts +20 -0
  138. package/dist/cli/help-content.js +543 -0
  139. package/dist/cli/help-content.js.map +1 -0
  140. package/dist/cli/main.js +3625 -445
  141. package/dist/cli/main.js.map +1 -1
  142. package/dist/core/extensions/index.d.ts +13 -1
  143. package/dist/core/extensions/index.js +108 -1
  144. package/dist/core/extensions/index.js.map +1 -1
  145. package/dist/core/extensions/item-fields.d.ts +2 -0
  146. package/dist/core/extensions/item-fields.js +79 -0
  147. package/dist/core/extensions/item-fields.js.map +1 -0
  148. package/dist/core/extensions/loader.d.ts +322 -9
  149. package/dist/core/extensions/loader.js +911 -20
  150. package/dist/core/extensions/loader.js.map +1 -1
  151. package/dist/core/extensions/runtime-registrations.d.ts +5 -0
  152. package/dist/core/extensions/runtime-registrations.js +51 -0
  153. package/dist/core/extensions/runtime-registrations.js.map +1 -0
  154. package/dist/core/history/history-stream-policy.d.ts +20 -0
  155. package/dist/core/history/history-stream-policy.js +53 -0
  156. package/dist/core/history/history-stream-policy.js.map +1 -0
  157. package/dist/core/history/history.js +90 -1
  158. package/dist/core/history/history.js.map +1 -1
  159. package/dist/core/item/id.js +4 -1
  160. package/dist/core/item/id.js.map +1 -1
  161. package/dist/core/item/index.d.ts +1 -0
  162. package/dist/core/item/index.js +1 -0
  163. package/dist/core/item/index.js.map +1 -1
  164. package/dist/core/item/item-format.d.ts +11 -5
  165. package/dist/core/item/item-format.js +507 -24
  166. package/dist/core/item/item-format.js.map +1 -1
  167. package/dist/core/item/parent-reference-policy.d.ts +6 -0
  168. package/dist/core/item/parent-reference-policy.js +32 -0
  169. package/dist/core/item/parent-reference-policy.js.map +1 -0
  170. package/dist/core/item/parse.d.ts +5 -0
  171. package/dist/core/item/parse.js +216 -19
  172. package/dist/core/item/parse.js.map +1 -1
  173. package/dist/core/item/sprint-release-format.d.ts +6 -0
  174. package/dist/core/item/sprint-release-format.js +33 -0
  175. package/dist/core/item/sprint-release-format.js.map +1 -0
  176. package/dist/core/item/status.d.ts +3 -0
  177. package/dist/core/item/status.js +24 -0
  178. package/dist/core/item/status.js.map +1 -0
  179. package/dist/core/item/type-registry.d.ts +37 -0
  180. package/dist/core/item/type-registry.js +706 -0
  181. package/dist/core/item/type-registry.js.map +1 -0
  182. package/dist/core/lock/lock.d.ts +1 -1
  183. package/dist/core/lock/lock.js +101 -12
  184. package/dist/core/lock/lock.js.map +1 -1
  185. package/dist/core/output/command-aware.d.ts +1 -0
  186. package/dist/core/output/command-aware.js +394 -0
  187. package/dist/core/output/command-aware.js.map +1 -0
  188. package/dist/core/output/output.d.ts +3 -0
  189. package/dist/core/output/output.js +124 -6
  190. package/dist/core/output/output.js.map +1 -1
  191. package/dist/core/schema/runtime-field-filters.d.ts +3 -0
  192. package/dist/core/schema/runtime-field-filters.js +39 -0
  193. package/dist/core/schema/runtime-field-filters.js.map +1 -0
  194. package/dist/core/schema/runtime-field-values.d.ts +8 -0
  195. package/dist/core/schema/runtime-field-values.js +154 -0
  196. package/dist/core/schema/runtime-field-values.js.map +1 -0
  197. package/dist/core/schema/runtime-schema.d.ts +68 -0
  198. package/dist/core/schema/runtime-schema.js +554 -0
  199. package/dist/core/schema/runtime-schema.js.map +1 -0
  200. package/dist/core/search/cache.d.ts +13 -1
  201. package/dist/core/search/cache.js +123 -14
  202. package/dist/core/search/cache.js.map +1 -1
  203. package/dist/core/search/semantic-defaults.d.ts +6 -0
  204. package/dist/core/search/semantic-defaults.js +120 -0
  205. package/dist/core/search/semantic-defaults.js.map +1 -0
  206. package/dist/core/search/vector-stores.js +3 -1
  207. package/dist/core/search/vector-stores.js.map +1 -1
  208. package/dist/core/shared/command-types.d.ts +2 -0
  209. package/dist/core/shared/conflict-markers.d.ts +7 -0
  210. package/dist/core/shared/conflict-markers.js +27 -0
  211. package/dist/core/shared/conflict-markers.js.map +1 -0
  212. package/dist/core/shared/constants.d.ts +15 -4
  213. package/dist/core/shared/constants.js +141 -1
  214. package/dist/core/shared/constants.js.map +1 -1
  215. package/dist/core/shared/errors.d.ts +10 -1
  216. package/dist/core/shared/errors.js +3 -1
  217. package/dist/core/shared/errors.js.map +1 -1
  218. package/dist/core/shared/text-normalization.d.ts +4 -0
  219. package/dist/core/shared/text-normalization.js +33 -0
  220. package/dist/core/shared/text-normalization.js.map +1 -0
  221. package/dist/core/shared/time.d.ts +1 -2
  222. package/dist/core/shared/time.js +98 -11
  223. package/dist/core/shared/time.js.map +1 -1
  224. package/dist/core/store/index.d.ts +1 -0
  225. package/dist/core/store/index.js +1 -0
  226. package/dist/core/store/index.js.map +1 -1
  227. package/dist/core/store/item-format-migration.d.ts +9 -0
  228. package/dist/core/store/item-format-migration.js +87 -0
  229. package/dist/core/store/item-format-migration.js.map +1 -0
  230. package/dist/core/store/item-store.d.ts +13 -4
  231. package/dist/core/store/item-store.js +238 -51
  232. package/dist/core/store/item-store.js.map +1 -1
  233. package/dist/core/store/paths.d.ts +21 -3
  234. package/dist/core/store/paths.js +59 -4
  235. package/dist/core/store/paths.js.map +1 -1
  236. package/dist/core/store/settings.d.ts +14 -1
  237. package/dist/core/store/settings.js +463 -7
  238. package/dist/core/store/settings.js.map +1 -1
  239. package/dist/core/telemetry/consent.d.ts +2 -0
  240. package/dist/core/telemetry/consent.js +79 -0
  241. package/dist/core/telemetry/consent.js.map +1 -0
  242. package/dist/core/telemetry/runtime.d.ts +38 -0
  243. package/dist/core/telemetry/runtime.js +733 -0
  244. package/dist/core/telemetry/runtime.js.map +1 -0
  245. package/dist/core/test/background-runs.d.ts +117 -0
  246. package/dist/core/test/background-runs.js +760 -0
  247. package/dist/core/test/background-runs.js.map +1 -0
  248. package/dist/core/test/item-test-run-tracking.d.ts +9 -0
  249. package/dist/core/test/item-test-run-tracking.js +50 -0
  250. package/dist/core/test/item-test-run-tracking.js.map +1 -0
  251. package/dist/sdk/cli-contracts.d.ts +92 -0
  252. package/dist/sdk/cli-contracts.js +2357 -0
  253. package/dist/sdk/cli-contracts.js.map +1 -0
  254. package/dist/sdk/index.d.ts +34 -0
  255. package/dist/sdk/index.js +23 -0
  256. package/dist/sdk/index.js.map +1 -0
  257. package/dist/types.d.ts +197 -3
  258. package/dist/types.js +48 -1
  259. package/dist/types.js.map +1 -1
  260. package/docs/ARCHITECTURE.md +368 -39
  261. package/docs/EXTENSIONS.md +454 -49
  262. package/docs/RELEASING.md +70 -19
  263. package/docs/SDK.md +123 -0
  264. package/docs/examples/starter-extension/README.md +48 -0
  265. package/docs/examples/starter-extension/index.js +191 -0
  266. package/docs/examples/starter-extension/manifest.json +17 -0
  267. package/docs/examples/starter-extension/package.json +10 -0
  268. package/package.json +41 -14
  269. package/.pi/extensions/pm-cli/index.ts +0 -778
  270. package/dist/cli/commands/beads.d.ts +0 -16
  271. package/dist/cli/commands/beads.js.map +0 -1
  272. package/dist/cli/commands/install.d.ts +0 -18
  273. package/dist/cli/commands/install.js +0 -87
  274. package/dist/cli/commands/install.js.map +0 -1
  275. package/dist/core/extensions/builtins.d.ts +0 -3
  276. package/dist/core/extensions/builtins.js +0 -47
  277. package/dist/core/extensions/builtins.js.map +0 -1
  278. package/dist/extensions/builtins/beads/index.d.ts +0 -8
  279. package/dist/extensions/builtins/beads/index.js +0 -33
  280. package/dist/extensions/builtins/beads/index.js.map +0 -1
  281. package/dist/extensions/builtins/todos/import-export.d.ts +0 -26
  282. package/dist/extensions/builtins/todos/import-export.js.map +0 -1
  283. package/dist/extensions/builtins/todos/index.d.ts +0 -8
  284. package/dist/extensions/builtins/todos/index.js +0 -38
  285. package/dist/extensions/builtins/todos/index.js.map +0 -1
@@ -10,8 +10,10 @@ This document describes the internal architecture of `pm-cli` for contributors a
10
10
  src/
11
11
  cli/ CLI layer: command registration, option parsing, output rendering
12
12
  core/ Domain logic: storage, locking, history, search, extensions
13
- extensions/ Built-in extension implementations (beads, todos)
13
+ extensions/ Optional extension authoring sources (non-bundled)
14
14
  types/ Shared TypeScript type definitions
15
+ .agents/
16
+ pm/extensions/ Bundled managed extension sources shipped with package (beads, todos)
15
17
  ```
16
18
 
17
19
  ## Source Tree
@@ -24,37 +26,50 @@ src/
24
26
  commands/
25
27
  init.ts pm init
26
28
  create.ts pm create (full schema flag surface)
29
+ templates.ts pm templates save/list/show
27
30
  get.ts pm get
28
- update.ts pm update
31
+ update.ts pm update (including ownership-safe metadata audits via --allow-audit-update and dependency-only audits via --allow-audit-dep-update)
32
+ update-many.ts pm update-many (bulk apply/dry-run/rollback checkpoint workflow)
33
+ normalize.ts pm normalize (lifecycle metadata dry-run planning + optional apply workflow)
29
34
  append.ts pm append
30
- close.ts pm close
35
+ close.ts pm close (includes optional close-time validation mode)
31
36
  delete.ts pm delete
32
37
  claim.ts pm claim / release
33
38
  release.ts (re-exports from claim.ts)
34
- list.ts pm list (active-only: excludes closed/canceled) / list-all / list-* commands
39
+ list.ts pm list (active-only: excludes closed/canceled) / list-all / list-* commands with projection, sorting, offset, and JSON stream controls
40
+ aggregate.ts pm aggregate (default grouped child-count governance queries)
41
+ dedupe-audit.ts pm dedupe-audit (exact/fuzzy/parent-scoped duplicate clustering)
42
+ calendar.ts pm calendar / pm cal (agenda/day/week/month views)
43
+ context.ts pm context / pm ctx (critical work + agenda snapshot)
35
44
  comments.ts pm comments
45
+ notes.ts pm notes
46
+ learnings.ts pm learnings
36
47
  files.ts pm files
37
48
  docs.ts pm docs
38
- test.ts pm test (add/remove/run linked tests)
39
- test-all.ts pm test-all (orchestration)
49
+ deps.ts pm deps (dependency tree/graph projection)
50
+ test.ts pm test (add/remove/run linked tests; optional forced progress visibility)
51
+ test-all.ts pm test-all (orchestration; optional forced progress visibility + pre-run limit/offset pagination)
52
+ test-runs.ts pm test-runs (background run lifecycle: list/status/logs/stop/resume; bare command defaults to list)
40
53
  search.ts pm search (keyword / semantic / hybrid)
41
- reindex.ts pm reindex
54
+ reindex.ts pm reindex (optional forced progress visibility)
42
55
  history.ts pm history
43
- activity.ts pm activity
56
+ activity.ts pm activity (timeline filters + JSON stream mode)
44
57
  restore.ts pm restore
45
58
  stats.ts pm stats
46
59
  health.ts pm health
47
- gc.ts pm gc
60
+ validate.ts pm validate (metadata/resolution/lifecycle/files/command-reference/history drift checks)
61
+ gc.ts pm gc (dry-run and scoped cache cleanup)
62
+ contracts.ts pm contracts (machine-readable contracts/schema surface)
48
63
  config.ts pm config
49
- install.ts pm install pi
50
- completion.ts pm completion
51
- beads.ts pm beads (subcommand router to built-in extension)
64
+ extension.ts pm extension lifecycle manager (install/uninstall/explore/manage/activate/deactivate)
65
+ completion.ts pm completion (lazy/eager tag completion modes)
66
+ beads.ts Beads import runtime used by bundled managed extension
67
+ todos.ts Todos import/export runtime used by bundled managed extension
52
68
  index.ts barrel re-export
53
69
  extension-command-options.ts Loose option parser for dynamic extension commands
54
70
  core/
55
71
  extensions/
56
72
  loader.ts Extension manifest discovery, load, activate
57
- builtins.ts Built-in extension registrations
58
73
  index.ts barrel
59
74
  fs/
60
75
  fs-utils.ts Atomic write, path existence, mkdirp
@@ -66,6 +81,8 @@ src/
66
81
  id.ts ID generation (cryptographic random base36) and normalization
67
82
  item-format.ts Item front-matter serializer (canonical key order, determinism)
68
83
  parse.ts Markdown item file parser (JSON front-matter + body)
84
+ parent-reference-policy.ts Parent-reference policy normalization + warning/strict validation helpers
85
+ type-registry.ts Runtime item-type registry (built-ins + settings + extensions)
69
86
  index.ts barrel
70
87
  lock/
71
88
  lock.ts Exclusive lock acquire/release with TTL and stale detection
@@ -77,12 +94,19 @@ src/
77
94
  embedding-batches.ts Deterministic batch embedding generation with retry
78
95
  providers.ts OpenAI / Ollama embedding provider abstraction
79
96
  vector-stores.ts Qdrant / LanceDB vector store abstraction
97
+ test/
98
+ background-runs.ts Background linked-test run registry/worker lifecycle + dedupe
99
+ item-test-run-tracking.ts Settings-gated bounded item `test_runs` summary persistence
100
+ telemetry/
101
+ consent.ts First-run telemetry consent prompt + non-interactive guardrails
102
+ runtime.ts Telemetry event capture, redaction, queueing, and exporter retry flow
80
103
  shared/
81
104
  command-types.ts GlobalOptions, shared command type definitions
82
105
  constants.ts Exit codes, required directory names
83
- errors.ts PmCliError with exit code
106
+ conflict-markers.ts Merge-conflict marker detection helpers
107
+ errors.ts PmCliError with exit code + optional guidance context
84
108
  serialization.ts Deterministic JSON serialization (stable key order)
85
- time.ts ISO timestamp helpers, relative deadline parsing
109
+ time.ts ISO/date parsing helpers, relative offsets, and field-attributed parse diagnostics
86
110
  index.ts barrel
87
111
  store/
88
112
  item-store.ts File-backed item CRUD with lock/atomic write contract
@@ -91,36 +115,74 @@ src/
91
115
  index.ts barrel
92
116
  types/
93
117
  index.ts ItemFrontMatter, ItemType, ItemStatus, Dependency, etc.
94
- extensions/
95
- builtins/
96
- beads/
97
- index.ts Beads JSONL import extension
98
- todos/
99
- index.ts todos extension activate()
100
- import-export.ts todos import/export logic
118
+ sdk/
119
+ cli-contracts.ts Canonical command/action contracts + JSON Schema exports
120
+ index.ts Public SDK exports
101
121
  command-types.ts (re-export shim)
102
122
  constants.ts (re-export shim)
103
123
  errors.ts (re-export shim)
104
124
  ... (other re-export shims for backward compat)
125
+ .agents/
126
+ pm/
127
+ extensions/
128
+ beads/
129
+ manifest.json Bundled managed beads extension manifest
130
+ index.js Registers `beads import` command and loads runtime from dist
131
+ todos/
132
+ manifest.json Bundled managed todos extension manifest
133
+ index.js Registers `todos import` / `todos export` and loads runtime from dist
105
134
  ```
106
135
 
136
+ ## Command Contract Registry
137
+
138
+ Command/action contract metadata is centralized in `src/sdk/cli-contracts.ts`.
139
+
140
+ The same registry drives:
141
+
142
+ - commander option normalization in `src/cli/main.ts`
143
+ - shell completion flag/command surfaces in `src/cli/commands/completion.ts`
144
+ - Pi wrapper action enum, tool `inputSchema`, and CLI arg mapping in `.pi/extensions/pm-cli/index.ts`
145
+ - runtime `pm contracts` payload generation for action/command/schema introspection
146
+ - runtime schema augmentation for active extension commands/actions (including extension source metadata and extension-defined flag surfaces)
147
+ - additive command surfaces such as `templates-*` actions, extension lifecycle actions (`extension-install`, `extension-uninstall`, `extension-explore`, `extension-manage`, `extension-doctor`, `extension-adopt`, `extension-adopt-all`, `extension-activate`, `extension-deactivate`), `history --diff/--verify`, files/docs path hygiene flags (`--add-glob`, `--migrate`, `--append-stable`, `--validate-paths`, `--audit`), validate governance/file drift flags (`--check-lifecycle`, `--check-stale-blockers`, `--scan-mode`, `--include-pm-internals`), list projection/sort controls (`--compact`, `--fields`, `--sort`, `--order`), `aggregate`/`dedupe-audit` action surfaces, comments-audit governance filters/export controls (`--parent`, `--tag`, `--sprint`, `--release`, `--priority`, `--latest`, `--full-history`, `--limit` alias), lifecycle aliases (`start-task`, `pause-task`, `close-task`), bulk mutation (`update-many`), lifecycle metadata normalization (`normalize`), and ownership-safe audit update controls (`update --allow-audit-update`, `update --allow-audit-dep-update`), health vector refresh controls (`--check-only`, `--no-refresh`, `--refresh-vectors`), contracts projections (`--flags-only`, `--availability-only`), completion mode controls (`--eager-tags` + lazy `completion-tags` path), calendar period control (`--full-period`), activity filtering/stream controls (`--id`, `--op`, `--author`, `--from`, `--to`, `--stream`), global pager suppression (`--no-pager`), `create --create-mode`, `comments --allow-audit-comment`, `release --allow-audit-release`, `test-all --limit/--offset`, run-level PM-context override (`--override-linked-pm-context`), linked-test preflight/remediation controls (`--check-context`, `--auto-pm-context`), `gc --dry-run/--scope`, `update --replace-deps`, richer `deps` traversal controls, and `contracts` create-required metadata projections
148
+
149
+ This keeps human CLI UX and machine-facing contracts aligned while preserving additive evolution; new projection flags such as `--command`, `--flags-only`, and `--availability-only` provide lower-noise machine payloads without replacing the full default contract corpus.
150
+
151
+ Contract projection behavior also keeps action filters deterministic: when `pm contracts --flags-only` is called with `--action` and no `--command`, the emitted `command_flags` rows are scoped to commands that implement the selected action(s).
152
+
107
153
  ## Item Storage
108
154
 
109
- Each item is stored as a Markdown file:
155
+ Each item is stored as a format-configured document file:
110
156
 
111
157
  ```
112
158
  .agents/pm/
113
- <type-plural>/<id>.md e.g. tasks/pm-a1b2.md
159
+ <type-folder>/<id>.toon default item storage (TOON root-object fields)
160
+ <type-folder>/<id>.md fully supported JSON metadata object + markdown body
114
161
  history/<id>.jsonl append-only RFC6902 patch log
115
162
  locks/<id>.lock exclusive lock metadata (JSON)
116
163
  settings.json project configuration
117
164
  index/manifest.json keyword index cache (optional, rebuildable)
118
165
  search/embeddings.jsonl keyword corpus records (optional, rebuildable)
166
+ search/vectorization-status.json semantic vector freshness ledger (optional, rebuildable)
119
167
  extensions/ project-local extensions
168
+ extensions/.managed-extensions.json scope-local extension manager state (optional, lifecycle-managed)
120
169
  ```
121
170
 
122
171
  ### Item File Format
123
172
 
173
+ Default TOON item document:
174
+
175
+ ```toon
176
+ id: pm-a1b2
177
+ title: ...
178
+ # ...
179
+ body: |
180
+ Optional markdown body here.
181
+ ```
182
+
183
+ Alternative markdown item document:
184
+
185
+ ```md
124
186
  ```
125
187
  {
126
188
  "id": "pm-a1b2",
@@ -131,24 +193,178 @@ Each item is stored as a Markdown file:
131
193
  Optional markdown body here.
132
194
  ```
133
195
 
134
- Fields are serialized in canonical key order (defined in `item-format.ts`).
196
+ Fields are normalized and serialized in canonical key order (defined in `item-format.ts`) before hashing/history patch generation, regardless of on-disk item format.
197
+
198
+ `front_matter` is the internal object key used by the TypeScript document model; TOON files store identical metadata as top-level keys (no YAML front matter layer).
199
+
200
+ Type resolution is centralized in the runtime type registry:
201
+
202
+ - built-in types (`Epic`, `Feature`, `Task`, `Chore`, `Issue`, `Event`, `Reminder`, `Milestone`, `Meeting`)
203
+ - `settings.item_types.definitions`
204
+ - extension `registerItemTypes(...)` registrations
205
+
206
+ The registry is used by create/update validation, list/search/calendar type filters, completion scripts, and store path routing.
207
+
208
+ Type definitions can additionally provide `command_option_policies` entries (`create`/`update`) to mark options as required, disabled, or hidden in policy-aware help guidance while preserving default behavior when unset.
209
+
210
+ Scheduling metadata is persisted directly in item metadata:
211
+
212
+ - `reminders?: Array<{ at: ISO timestamp; text: string }>`
213
+ - reminders are normalized and sorted deterministically by `at` then `text`
214
+ - `events?: Array<{ start_at: ISO timestamp; end_at?: ISO timestamp; title?: string; description?: string; location?: string; timezone?: string; all_day?: boolean; recurrence?: RecurrenceRule }>`
215
+ - recurrence supports `freq`, `interval`, `count`, `until`, `by_weekday`, `by_month_day`, and `exdates`
216
+ - event and recurrence arrays are normalized/sorted deterministically for stable serialization
217
+ - `pm create` and `pm update` support repeatable `--reminder` and `--event` values with explicit clear flags (`--clear-reminders`, `--clear-events`)
218
+
219
+ ### Parallel Git/Worktree Safety
220
+
221
+ `pm` storage is designed for high-concurrency git workflows (branches, worktrees, and multi-host collaboration):
222
+
223
+ 1. **First-class dual formats** — `.toon` and `.md` are both supported for item storage.
224
+ 2. **Single format of record per repo** — `settings.item_format` defines the canonical extension; migration removes alternate-extension drift.
225
+ 3. **Deterministic canonicalization** — normalized fields and stable ordering reduce diff noise and improve merge predictability.
226
+ 4. **Atomic writes** — item files are replaced via temp + `rename`, preventing torn writes.
227
+ 5. **Append-only history** — `history/<id>.jsonl` records RFC6902 patches with before/after hashes for auditability and restore.
228
+
229
+ If concurrent edits modify the same semantic fields on separate branches, git can still surface textual conflicts. In those cases, the deterministic canonical model plus append-only history is intended to make reconciliation explicit and loss-resistant rather than silent.
135
230
 
136
231
  ## Mutation Contract
137
232
 
138
233
  Every item mutation follows this sequence:
139
234
 
140
235
  1. **Acquire lock** — exclusive open on `locks/<id>.lock`; reject if stale and no `--force`
141
- 2. **Read current item** — parse front-matter + body
142
- 3. **Compute `before_hash`**SHA-256 of canonical `{ front_matter, body }` JSON
143
- 4. **Apply mutation**in-memory model update
144
- 5. **Update `updated_at`**every mutation must change this timestamp
145
- 6. **Compute patch + `after_hash`** — RFC6902 diff; SHA-256 of new canonical state
146
- 7. **Atomic write** write to temp file; `rename` to target (single syscall, OS-atomic)
147
- 8. **Append history line** — JSONL append to `history/<id>.jsonl`
148
- 9. **Release lock** — unlink lock file
236
+ 2. **Read current item** — parse configured-format item (`.toon` or `.md`) into canonical `{ front_matter, body }`
237
+ 3. **Enforce history stream policy** for existing-item mutations, apply `settings.history.missing_stream` (`auto_create` or `strict_error`) before mutation writes
238
+ 4. **Compute `before_hash`**SHA-256 of canonical `{ front_matter, body }` JSON
239
+ 5. **Apply mutation**in-memory model update
240
+ 6. **Update `updated_at`** — every mutation must change this timestamp
241
+ 7. **Compute patch + `after_hash`** RFC6902 diff; SHA-256 of new canonical state
242
+ 8. **Atomic write** — write configured-format item file via temp + `rename` (single syscall, OS-atomic)
243
+ 9. **Append history line** — JSONL append to `history/<id>.jsonl`
244
+ 10. **Release lock** — unlink lock file
149
245
 
150
246
  If step 7 or 8 fails, the item file is rolled back (if write succeeded) before returning failure.
151
247
 
248
+ When `update --type` changes an item's resolved type folder, mutation logic performs a safe file move to the target folder and rolls back on failure.
249
+ `pm update` now supports transactional linked/log collection mutations (`--comment`, `--note`, `--learning`, `--file`, `--test`, `--doc`) so metadata and linked surfaces can be updated under one lock/history entry. Dedicated commands (`pm comments|notes|learnings|files|test|docs`) remain available for focused single-surface operations.
250
+
251
+ ### Additive Diagnostics and Path Hygiene
252
+
253
+ - `pm history --diff` adds field-level patch summaries without changing base history output.
254
+ - `pm history --verify` validates stream hash-chain replay and current-item hash alignment.
255
+ - `pm close --validate-close [warn|strict]` adds optional close-time resolution-field validation without changing default close semantics.
256
+ - `pm files` and `pm docs` support additive linked-path hygiene options:
257
+ - `--add-glob <pattern>` for deterministic batch expansion into linked entries
258
+ - `--migrate from=<old>,to=<new>` for bulk prefix migration
259
+ - `--append-stable` on `pm files` to append/dedupe without full-array resorting
260
+ - `--validate-paths` for resolved path-existence checks
261
+ - `--audit` for cross-item linked-path usage inspection
262
+ - `pm files --list` for explicit non-mutating linked-file listing
263
+ - `pm files discover <ID>` scans item text fields for existing project/global file paths, reports addable vs already linked candidates, and only writes missing links when `--apply` is supplied
264
+ - `pm comments|notes|learnings --allow-audit-comment` enables append-only audit log entries on items assigned to other owners without broad ownership override semantics.
265
+ - `pm release --allow-audit-release` enables non-owner release handoffs that only clear assignee metadata without broad ownership override semantics.
266
+ - `pm comments-audit` now emits additive top-level governance `summary` metrics (`totals`, coverage ratio/percent, and `by_type`) across latest and full-history export modes while preserving existing item/export payloads; `--limit` is available as an alias for legacy `--limit-items`.
267
+ - `pm test-runs` now defaults bare command execution to list output, aligning CLI behavior with explicit `pm test-runs list`.
268
+ - `pm create --create-mode strict|progressive` keeps strict mode as default while enabling staged progressive creation for governance triage workflows.
269
+ - Strict create-mode missing-required guidance now includes direct remediation hints (`--create-mode progressive`, and scheduling-type `--schedule-preset lightweight` guidance for `Reminder`/`Meeting`/`Event`).
270
+ - Time/date parse errors are field-attributed (for example `event.end`, `reminder.at`, `--from`, `deadline-before`) with explicit guidance when unsupported compound relative expressions (for example `+3d+1h`) are provided.
271
+ - `pm create` log-seed repeatables (`--comment`, `--note`, `--learning`) now enforce explicit key boundaries (`author`, `created_at`, `text`) and reject parsed extra keys with usage guidance so unquoted key:value-like comma continuations cannot silently truncate seeded narrative text.
272
+ - `pm deps --format tree|graph --max-depth <n> --collapse none|repeated --summary` provides read-only dependency traversal from stored front matter, with deterministic ordering, cycle markers, missing-node reporting, and governance-friendly bounded projections.
273
+ - `pm update --replace-deps` enables one-shot atomic dependency replacement without separate clear/add mutations.
274
+ - `pm update --allow-audit-update` provides ownership-safe non-owner metadata mutation mode with explicit lifecycle/ownership guardrails.
275
+ - `pm update --allow-audit-dep-update` provides ownership-safe non-owner append-only dependency additions (`--dep`) without broad force semantics.
276
+ - `pm update-many` adds native bulk mutation orchestration with deterministic filter targeting, dry-run planning, checkpoint capture, and rollback-by-checkpoint-id flow; apply payload parity now includes linked-array mutation flags (`--dep/--comment/--note/--learning/--file/--test/--doc/--reminder/--event`), explicit `--clear-*` controls, and atomic `--replace-deps`/`--replace-tests` semantics while dry-run planning reports linked-array mutation intent per item.
277
+ - Lifecycle aliases (`pm start-task`, `pm pause-task`, `pm close-task`) compose claim/update/close/release primitives into discoverable single commands while preserving canonical history entries.
278
+ - `pm get` now returns `claim_state` metadata (active assignee plus latest claim/release history context) for ownership-aware automation.
279
+ - `pm get --json` payload shape is deterministic: `{ item, body, linked, claim_state }`, with body intentionally top-level for single-item diff/merge workflows.
280
+ - `pm list` / `pm list-*` support additive projection (`--compact`, `--fields`, `--include-body`), configurable sorting (`--sort`, `--order`), `--offset` pagination, and JSON-only `--stream` line-delimited output for large datasets.
281
+ - `pm aggregate` provides grouped count projections (default `--group-by parent,type`; supported dimensions: `parent,type,priority,status,assignee,tags,sprint,release`; `--count` accepted for explicit parity) for governance decomposition and triage checks.
282
+ - `pm gc` now supports no-side-effect previews (`--dry-run`) and scoped cleanup (`--scope index|embeddings|runtime`) with output guidance for reindex follow-up when search artifacts are removed.
283
+ - `pm dedupe-audit` provides exact-title, fuzzy-title, and parent-scoped duplicate cluster detection with machine-readable merge suggestions.
284
+ - `pm validate` runs standalone repository checks (`metadata`, `resolution`, `lifecycle`, `files`, `command_references`, `history_drift`), supports metadata policy selection via `--metadata-profile core|strict|custom`, supports lifecycle-governance drift targeting via `--check-lifecycle` plus optional stale-blocker heuristics via `--check-stale-blockers`, reads lifecycle pattern lists from `settings.validation.lifecycle_*_patterns` (tunable through config criteria-list keys), reports deterministic pattern-source metadata (`default|settings`) and effective pattern arrays in lifecycle check details, supports file candidate selection via `--scan-mode default|tracked-all|tracked-all-strict`, supports additive internal-audit coverage with `--include-pm-internals`, and returns deterministic filtered + raw file scan metrics, structured `excluded_by_reason` summaries, plus stale PM-id command-reference diagnostics.
285
+
286
+ ## Calendar Pipeline
287
+
288
+ `pm calendar` (`pm cal`) is a read-only projection command that derives scheduling events from existing item metadata.
289
+
290
+ Pipeline:
291
+
292
+ 1. Resolve PM root and load settings.
293
+ 2. Read all item front matter records.
294
+ 3. Apply deterministic item filters (`type`, `tag`, `priority`, `status`, `assignee`, `sprint`, `release`).
295
+ 4. Expand each item into calendar events:
296
+ - deadline event (if `deadline` is set)
297
+ - reminder events (for each `reminders[]` entry)
298
+ - one-off scheduled events (`events[]` entries without recurrence)
299
+ - recurring event occurrences (`events[].recurrence`) expanded inside a bounded recurrence window
300
+ 5. Apply source controls and recurrence bounds:
301
+ - `--include deadlines|reminders|events|all`
302
+ - `--recurrence-lookahead-days`, `--recurrence-lookback-days`
303
+ - `--occurrence-limit` (cap per recurring event expansion)
304
+ 6. Apply view windows:
305
+ - `agenda` (default, optional `--from`/`--to`)
306
+ - `day`, `week`, `month` (anchored by `--date`)
307
+ - `--past` toggles lower-bound behavior for bounded views
308
+ - `--full-period` (day/week/month only) keeps full anchored-period lower bounds instead of now-clipping
309
+ 7. Sort events deterministically by timestamp, priority, item id, event kind, event title, then reminder text.
310
+ 8. Bucket events by UTC date and compute summary counts (`events`, `items`, `deadlines`, `reminders`, `scheduled`) plus deterministic aggregate breakdowns (`by_kind`, `by_type`, `by_status`, `recurring_events`).
311
+ 9. Render markdown event rows with deterministic detail tokens (item type, recurrence markers/rules, end-time derivation, timezone/location metadata, and description context when present).
312
+
313
+ Output behavior is command-specific: `pm calendar` defaults to markdown for agent/human readability while keeping explicit `--format`/`--json` overrides. Calendar range payloads include `period_start`/`period_end` and `full_period` metadata for deterministic downstream interpretation. Global TOON defaults for other commands are unchanged.
314
+
315
+ ## Context Pipeline
316
+
317
+ `pm context` (`pm ctx`) is a read-only context-assembly command that combines prioritized active work with agenda/reminder visibility.
318
+
319
+ Pipeline:
320
+
321
+ 1. Run `list` logic with non-terminal filtering and optional shared filters (`type`, `tag`, `priority`, `parent`, `assignee`, `sprint`, `release`).
322
+ 2. Rank candidate items deterministically by status (`in_progress` before `open`), then priority, explicit `order`, deadline proximity, recency, and id tie-break.
323
+ 3. Split ranked active items into:
324
+ - high-level focus (`Epic`, `Feature`)
325
+ - low-level focus (all other item types, including calendar-native built-ins such as `Event`, `Reminder`, `Milestone`, and `Meeting`)
326
+ 4. If active focus is empty, project top blocked items into a blocked fallback section.
327
+ 5. Run `calendar` logic in agenda mode with shared filters and context window controls (`--date`, `--from`, `--to`, `--past`).
328
+ 6. Filter agenda projection to non-terminal items and summarize deadlines/reminders/events counts.
329
+ 7. Return deterministic context payload (`output_default`, `window`, `filters`, `summary`, focus sections, and agenda section) with TOON default output and optional `--format`/`--json` overrides.
330
+
331
+ ## Activity Pipeline
332
+
333
+ `pm activity` is a read-only history projection command for timeline inspection and automation export.
334
+
335
+ Pipeline:
336
+
337
+ 1. Resolve PM root and enumerate history stream files.
338
+ 2. Parse history records in deterministic timestamp order.
339
+ 3. Apply optional filters (`--id`, `--op`, `--author`, `--from`, `--to`) before row materialization.
340
+ 4. Validate time-window bounds (`--from <= --to`) and return usage errors deterministically on invalid windows.
341
+ 5. Apply `--limit` to bounded result sets.
342
+ 6. Render either:
343
+ - standard payload `{ activity, count, limit, filters }`, or
344
+ - JSON stream mode (`--json --stream [rows|ndjson|jsonl]`) with deterministic `meta` then `entry` records.
345
+
346
+ ## Terminal and Process I/O Compatibility
347
+
348
+ `pm-cli` keeps runtime behavior terminal-neutral so commands behave consistently across native shells, IDE-integrated terminals, and emulated PTY backends:
349
+
350
+ 1. **Plain deterministic output** — core output paths emit TOON/JSON/markdown text with stable key ordering and no required custom terminal control protocol.
351
+ 2. **Sparse TOON fallback output** — default TOON output renders command payloads directly and recursively omits `null`/`undefined`/empty arrays/empty objects to reduce token overhead while preserving meaningful scalar values.
352
+ 3. **Fail-fast stdin semantics** — stdin token readers reject interactive TTY stdin for piped-only flows (`-`) and provide explicit EOF guidance instead of waiting indefinitely.
353
+ 4. **Graceful error exits** — CLI error handling preserves canonical exit codes using graceful `process.exitCode` semantics to reduce output truncation risk under buffered writes.
354
+ 5. **Broken-pipe-safe output writes** — stream error handlers treat `EPIPE` as expected pipeline behavior: stdout writes preserve successful exits (pipeline-friendly readers) while stderr `EPIPE` remains non-zero, and both suppress unhandled stack traces.
355
+ 6. **Linked test runtime hardening** — linked test subprocess execution uses shell-compatible spawn orchestration, closes child stdin immediately, applies deterministic runtime environment defaults, supports additive run-level/per-test env directives (`--env-set`, `--env-clear`, `--shared-host-safe`, plus linked metadata `env_set`/`env_clear`/`shared_host_safe`), supports additive PM-context controls (`--pm-context schema|tracker|auto`, `--override-linked-pm-context`, `--check-context`, `--auto-pm-context`, linked metadata `pm_context_mode=schema|tracker|auto`, `--fail-on-context-mismatch`, `--fail-on-skipped`, `--fail-on-empty-test-run`, `--require-assertions-for-pm`), enforces default schema-mode mismatch failures for PM tracker-read linked commands, emits mismatch guidance that explicitly calls out per-test `pm_context_mode` overrides when they supersede run-level context mode (unless explicitly overridden), can emit deterministic `context_preflight` warning summaries when requested, evaluates optional linked-test assertions (stdout/stderr contains/regex, min-lines, JSON equals/gte), detects high-confidence empty-selection runner signals when `--fail-on-empty-test-run` is enabled, emits per-run `execution_context` metadata for PM-command parity diagnostics (including tracker-read classification, `requested_pm_context_mode`, and `auto_pm_context_applied`), emits interactive stderr heartbeat progress for long runs (with explicit non-interactive `--progress`), supports managed background execution (`--background`) with `pm test-runs` lifecycle controls and duplicate-run fingerprints plus hardened `requested_by` fallback attribution, supports pre-run blast-radius pagination in `pm test-all` via `--offset`/`--limit`, enforces timeout/maxBuffer diagnostics with force-kill fallback plus structured failure categorization (`infra_collision`, `assertion_failure`, `empty_run`, etc.), and maps `pm test --run` linked failures to dependency-failed exit code (`5`) for CI-safe gating parity with `pm test-all`.
356
+
357
+ ## Help and Error Guidance Pipeline
358
+
359
+ Help and error UX is centralized to reduce per-command drift:
360
+
361
+ 1. `src/cli/help-content.ts` defines command-path help bundles (`why`, `examples`, optional `tips`) and attaches compact help by default (`Intent` + one example) with deep help enabled via `--explain`.
362
+ 2. `src/cli/main.ts` performs bootstrap routing for help paths so `pm help`/`pm help <command>` are deterministic success flows, non-interactive help routes suppress pager blocking (auto-disable when stdout is not TTY), global `--no-pager` provides explicit pager suppression, and `--help --json` emits machine-readable help payloads.
363
+ 3. Dynamic extension command descriptors (intent/action/examples/failure hints/arguments/flags) are merged into runtime help surfaces when available, with graceful fallback for legacy extensions that only register command handlers/flags.
364
+ 4. `src/cli/error-guidance.ts` defines canonical guidance descriptors and renders either structured text sections or machine-readable JSON envelopes (`type`, `code`, `title`, `detail`, `required`, `exit_code`, optional remediation fields), with `PmCliError.context` overrides for precise runtime guidance.
365
+ 5. `src/cli/main.ts` routes commander usage failures and `PmCliError` failures through these renderers, emitting JSON diagnostics when `--json` is active.
366
+ 6. Commander native stderr writes are suppressed so the CLI emits a single high-signal guidance payload per failure path.
367
+
152
368
  ## History and Restore
153
369
 
154
370
  Each history entry is a JSONL line:
@@ -169,28 +385,89 @@ Each history entry is a JSONL line:
169
385
 
170
386
  ## Extension System
171
387
 
172
- Extensions are Node.js modules with an `activate(api)` export:
388
+ Extensions are Node.js modules with an `activate(api)` export. For package consumers, extension types and helpers are exported through `@unbrained/pm-cli/sdk`.
173
389
 
174
390
  ```ts
175
391
  export function activate(api: ExtensionApi): void {
176
- api.registerCommand({ name: "my command", run: async (args, opts, global) => { ... } });
177
- api.hooks.beforeCommand((ctx) => { ... });
392
+ api.registerCommand({
393
+ name: "my command",
394
+ action: "my-command",
395
+ intent: "Short command intent shown in runtime help/contracts.",
396
+ examples: ["pm my command --limit 5"],
397
+ run: async (context) => ({ ok: true, command: context.command }),
398
+ });
399
+ api.hooks.beforeCommand((ctx) => { /* ... */ });
178
400
  }
179
401
  ```
180
402
 
181
403
  Load order: **core built-ins → global (`~/.pm-cli/extensions/`) → project (`.agents/pm/extensions/`)**.
182
404
 
183
- Project-local extensions override global by default. See [EXTENSIONS.md](./EXTENSIONS.md) for the full API reference.
405
+ Project-local extensions override global by default. Runtime dispatch is extension-first: if an extension registers a command handler for an existing core command path, the extension handler executes instead of the core action. Command result overrides and renderer overrides are still evaluated after dispatch with deterministic "last registration wins" precedence.
406
+
407
+ Lifecycle manager command architecture:
408
+
409
+ - `src/cli/commands/extension.ts` implements `pm extension` actions (`install`, `uninstall`, `explore`, `manage`, `doctor`, `adopt`, `adopt-all`, `activate`, `deactivate`) with deterministic validation, mutually-exclusive action routing, doctor-only strict warning exit controls (`--strict-exit`, alias `--fail-on-warn`), optional doctor trace payloads (`--trace` with `--detail deep`), manage runtime parity probes (`--runtime-probe`), optional managed-state remediation (`--fix-managed-state`), and explicit extension state semantics (`active` compatibility alias + `enabled`/`runtime_active`/`activation_status`).
410
+ - Install sources support local directories, GitHub HTTPS URLs, `github.com/<owner>/<repo>[/path]`, and forced shorthand via `--gh/--github`.
411
+ - Scope-local managed state is persisted at `<extensions-root>/.managed-extensions.json` for deterministic source metadata, install/update timestamps, and update-check status.
412
+ - `--manage` executes GitHub remote checks (`git ls-remote`) for managed GitHub entries, updates managed-state metadata, and emits deterministic per-extension `update_check_status`/`update_check_reason` fields plus `details.triage` status totals/remediation hints. With `--runtime-probe`, manage performs doctor-like runtime activation probes and annotates runtime probe execution metadata.
413
+ - `--adopt-all` bulk-adopts unmanaged scope extensions into managed-state metadata without reinstalling files.
414
+ - Health diagnostics include managed extension summaries/warnings for both project and global extension roots and a condensed `details.triage` surface for load/activation/migration triage, including update-coverage parity warning codes (`extension_update_health_partial_coverage`) when unmanaged extensions are action-required, capability guidance metadata, and machine-readable capability contract metadata for unknown manifest capabilities.
415
+
416
+ Extension Host V2 adds three additional override planes:
417
+
418
+ 1. **Parser overrides** (`registerParser`) run before command dispatch and can normalize/replace `args`, `options`, and `global` command context.
419
+ 2. **Preflight overrides** (`registerPreflight`) run before mutation gates and can control whether item-format write gates, pre-mutation format sync, extension migrations, and mandatory-migration write blocking are enforced.
420
+ 3. **Service overrides** (`registerService`) expose deterministic replacement points for output/error/help formatting plus internal lock/history/item-store operations.
421
+
422
+ Runtime registration wiring now includes:
423
+
424
+ - `registerFlags(...)` deterministic shape validation (`long`/`short` presence plus typed metadata) before dynamic help registration.
425
+ - `registerCommand({ ... })` optional metadata (`action`, `description`, `intent`, `examples`, `failure_hints`, `arguments`, `flags`) is validated and stored for runtime help/contracts introspection.
426
+ - `registerItemFields(...)` defaults/validation on create and update write paths.
427
+ - `registerItemTypes(...)` deterministic schema validation for required type/policy/option fields before type-registry merge.
428
+ - `registerMigration(...)` mandatory migration execution + write gating in command preflight.
429
+ - `registerMigration(...)` activation-time validation for typed migration metadata (`id`, `description`, `status`, `mandatory`, `run`) when provided.
430
+ - `registerParser(...)` command-scoped parser override registry with deterministic last-wins behavior.
431
+ - `registerPreflight(...)` preAction decision override registry for mutation gate and migration orchestration.
432
+ - `registerService(...)` service override registry for output/error/help/lock/history/item-store runtime hooks.
433
+ - `registerSearchProvider(...)` selected by `settings.search.provider` for live `pm search` execution.
434
+ - `registerVectorStoreAdapter(...)` selected by `settings.vector_store.adapter` for live `pm search` query and `pm reindex` upsert execution.
435
+
436
+ See [EXTENSIONS.md](./EXTENSIONS.md) for the full API reference.
184
437
 
185
438
  ## Search Architecture
186
439
 
187
440
  - **Keyword mode** (always available): multi-factor lexical scoring with configurable field weights
188
- - **Semantic mode** (requires provider + vector store config): embedding-based vector similarity
189
- - **Hybrid mode** (default when semantic available): blended lexical + semantic ranking
441
+ - **Semantic mode** (requires embedding + vector query capability): embedding-based vector similarity
442
+ - **Hybrid mode** (default when semantic capability is available): blended lexical + semantic ranking
190
443
 
191
444
  Providers: OpenAI-compatible, Ollama
192
445
  Vector stores: Qdrant, LanceDB
193
446
 
447
+ Runtime semantic defaults:
448
+
449
+ - When semantic settings are otherwise unset and local Ollama is installed, search/reindex runtime resolves built-in semantic defaults (Ollama provider + local LanceDB path) so semantic-capable behavior is available out of the box.
450
+ - Auto-default model resolution order: `PM_OLLAMA_MODEL` env override, then `ollama list` discovery (prefers embedding-like model names), then deterministic fallback `qwen3-embedding:0.6b`.
451
+ - Explicit semantic settings always win over auto-defaults (`settings.search.provider`, `settings.vector_store.adapter`, `providers.*`, `vector_store.*`).
452
+ - For implicit default-mode search, auto-default semantic execution failures degrade to keyword mode to preserve compatibility for existing users.
453
+ - Auto-defaults can be disabled with `PM_DISABLE_OLLAMA_AUTO_DEFAULTS=1`.
454
+
455
+ Health-time integrity and semantic/vector diagnostics:
456
+
457
+ - `pm health` runs a `directories` check that separates required tracker directories from optional built-in type directories and supports `--strict-directories` for stricter warning semantics plus `--strict-exit`/`--fail-on-warn` for non-zero exit gating when warnings are present.
458
+ - `pm health` runs an `integrity` check that scans item/history files for merge-conflict markers and parse/JSONL anomalies.
459
+ - `pm health` now runs a `history_drift` check that compares each current item's canonical hash to the latest history `after_hash`.
460
+ - `pm health` also runs a `vectorization` check that compares current item `updated_at` values to `search/vectorization-status.json`.
461
+ - When stale IDs are detected and semantic runtime is available, `pm health` defaults to targeted semantic refresh for stale IDs only (not a full reindex), while `--check-only`/`--no-refresh` keep diagnostics read-only and `--refresh-vectors` makes refresh intent explicit.
462
+ - `pm reindex --mode semantic|hybrid` rewrites the vectorization-status ledger for the full indexed corpus, keeping health diagnostics and index state aligned.
463
+
464
+ Extension runtime can supply equivalents for both sides of semantic execution:
465
+
466
+ - Search provider selection: `settings.search.provider` -> `registerSearchProvider(...)`.
467
+ - Vector adapter selection: `settings.vector_store.adapter` -> `registerVectorStoreAdapter(...)`.
468
+
469
+ If an extension provider/adapter fails and built-in provider/vector settings are configured, runtime falls back to built-in semantic components and records deterministic warnings.
470
+
194
471
  ### Keyword Scoring
195
472
 
196
473
  Each item is scored across: `title` (8×), `description` (5×), `tags` (6×), `status` (2×), `body` (1×), `comments`/`notes`/`learnings` (1× each), `dependencies` (3×). Exact title token matches add a bonus (10×).
@@ -205,14 +482,66 @@ Weights are configurable via `settings.json` under `search.tuning`.
205
482
  |-----|-------------|
206
483
  | `id_prefix` | Prefix for generated IDs (default `pm-`) |
207
484
  | `author_default` | Default author for mutations |
485
+ | `item_format` | Item storage format: `toon` (default) or `json_markdown` |
208
486
  | `locks.ttl_seconds` | Lock TTL (default 1800) |
209
487
  | `output.default_format` | `toon` or `json` |
488
+ | `history.missing_stream` | Missing history-stream policy: `auto_create` (default) or `strict_error` |
489
+ | `validation.sprint_release_format` | Sprint/release format policy: `warn` (default) or `strict_error` |
490
+ | `validation.parent_reference` | Parent-reference policy for create/update: `warn` (default) or `strict_error` |
491
+ | `testing.record_results_to_items` | Item-level test summary persistence toggle: `false` (default) / `true` |
492
+ | `telemetry.enabled` | Telemetry export toggle: `true` (default) / `false` |
493
+ | `telemetry.capture_level` | Runtime capture profile (`redacted` default, `max`, `minimal`) |
494
+ | `telemetry.endpoint` | Remote telemetry ingestion endpoint URL |
495
+ | `telemetry.installation_id` | Pseudonymous global installation identifier |
496
+ | `telemetry.retention_days` | Telemetry retention window (days) used for local queue pruning during flush and remote worker cleanup |
497
+ | `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT` / `OTEL_EXPORTER_OTLP_ENDPOINT` (env) | Optional local OTLP trace export target for command spans |
498
+ | `item_types.definitions[]` | Custom type names, aliases, folders, required fields/repeatables, `--type-option` definitions, and `command_option_policies` (`required`/`enabled`/`visible`) |
210
499
  | `search.*` | Search provider and tuning settings |
211
500
  | `providers.openai` / `providers.ollama` | Embedding provider config |
212
501
  | `vector_store.qdrant` / `vector_store.lancedb` | Vector store config |
213
502
 
214
503
  Precedence: CLI flags > env vars (`PM_PATH`, `PM_AUTHOR`, etc.) > `settings.json` > hard defaults.
215
504
 
505
+ For repositories created before `item_format` existed, the first mutating item command auto-selects the current default format and runs pre-mutation item-file migration. Explicit `pm config ... item-format --format ...` selections remain supported; once selected or changed, item files are automatically migrated to the configured format, and when both `.md` and `.toon` exist for an item, the configured format is the source of truth.
506
+
507
+ History stream policy can be configured via `pm config ... history-missing-stream-policy --policy ...`. In `auto_create`, required missing streams for existing item IDs are created before history-touching command paths continue; in `strict_error`, those command paths fail fast. Restore also supports history-only recovery when an item file is missing/deleted but the stream exists.
508
+
509
+ Validation policies can be configured via:
510
+
511
+ - `pm config ... sprint-release-format-policy --policy warn|strict_error`
512
+ - `pm config ... parent-reference-policy --policy warn|strict_error`
513
+ - `pm config ... test-result-tracking --policy enabled|disabled`
514
+ - `pm config ... telemetry-tracking --policy enabled|disabled`
515
+ - `pm config ... list|export` for key discovery and one-shot resolved snapshot export
516
+
517
+ Under `warn`, create/update continue and return deterministic validation warnings; under `strict_error`, invalid values are rejected with usage errors.
518
+
519
+ ## Telemetry Pipeline
520
+
521
+ Command lifecycle telemetry is integrated as an additive runtime path:
522
+
523
+ - `src/cli/main.ts`
524
+ - initializes first-run consent behavior
525
+ - starts telemetry capture during pre-action bootstrap
526
+ - finalizes telemetry with command outcome in post-action and error paths
527
+ - `src/core/telemetry/consent.ts`
528
+ - interactive first-run consent prompt
529
+ - deterministic skip behavior for non-interactive/CI/json contexts
530
+ - `src/core/telemetry/runtime.ts`
531
+ - sanitizes args/options/result summaries
532
+ - emits `command_start` + `command_finish` events with additive `pm_version` and `source_context` metadata
533
+ - spools local JSONL queue entries under global runtime storage
534
+ - exports batched events to `settings.telemetry.endpoint` with retry/backoff
535
+ - optionally exports command spans to OTLP (`OTEL_EXPORTER_OTLP_TRACES_ENDPOINT` or `OTEL_EXPORTER_OTLP_ENDPOINT`)
536
+ - supports explicit source-context overrides via `PM_TELEMETRY_SOURCE_CONTEXT` (`user|automation|test|dogfood|audit_smoke`)
537
+
538
+ Design constraints:
539
+
540
+ - telemetry failures never block command execution
541
+ - sensitive fields are redacted before transport
542
+ - pseudonymous identifiers are used for host/path metadata
543
+ - source-context classification uses coarse categories only (no raw session/operator identifiers)
544
+
216
545
  ## Exit Codes
217
546
 
218
547
  | Code | Meaning |