@unbrained/pm-cli 2026.5.18 → 2026.5.27

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (369) hide show
  1. package/CHANGELOG.md +953 -472
  2. package/README.md +4 -11
  3. package/dist/cli/bootstrap-args.d.ts +18 -1
  4. package/dist/cli/bootstrap-args.js +143 -3
  5. package/dist/cli/bootstrap-args.js.map +1 -1
  6. package/dist/cli/commander-usage.js +147 -10
  7. package/dist/cli/commander-usage.js.map +1 -1
  8. package/dist/cli/commands/annotation-command.d.ts +49 -0
  9. package/dist/cli/commands/annotation-command.js +135 -0
  10. package/dist/cli/commands/annotation-command.js.map +1 -0
  11. package/dist/cli/commands/append.js +5 -8
  12. package/dist/cli/commands/append.js.map +1 -1
  13. package/dist/cli/commands/calendar.js +3 -6
  14. package/dist/cli/commands/calendar.js.map +1 -1
  15. package/dist/cli/commands/claim.js +15 -24
  16. package/dist/cli/commands/claim.js.map +1 -1
  17. package/dist/cli/commands/close.js +63 -10
  18. package/dist/cli/commands/close.js.map +1 -1
  19. package/dist/cli/commands/comments.d.ts +5 -0
  20. package/dist/cli/commands/comments.js +27 -117
  21. package/dist/cli/commands/comments.js.map +1 -1
  22. package/dist/cli/commands/completion.d.ts +2 -2
  23. package/dist/cli/commands/completion.js +203 -63
  24. package/dist/cli/commands/completion.js.map +1 -1
  25. package/dist/cli/commands/config.d.ts +1 -1
  26. package/dist/cli/commands/config.js +82 -4
  27. package/dist/cli/commands/config.js.map +1 -1
  28. package/dist/cli/commands/context.js +4 -10
  29. package/dist/cli/commands/context.js.map +1 -1
  30. package/dist/cli/commands/contracts.js +168 -36
  31. package/dist/cli/commands/contracts.js.map +1 -1
  32. package/dist/cli/commands/create.js +53 -313
  33. package/dist/cli/commands/create.js.map +1 -1
  34. package/dist/cli/commands/dedupe-audit.js +7 -4
  35. package/dist/cli/commands/dedupe-audit.js.map +1 -1
  36. package/dist/cli/commands/delete.d.ts +3 -0
  37. package/dist/cli/commands/delete.js +11 -9
  38. package/dist/cli/commands/delete.js.map +1 -1
  39. package/dist/cli/commands/docs.d.ts +2 -12
  40. package/dist/cli/commands/docs.js +8 -316
  41. package/dist/cli/commands/docs.js.map +1 -1
  42. package/dist/cli/commands/event-validation-messages.d.ts +3 -0
  43. package/dist/cli/commands/event-validation-messages.js +44 -0
  44. package/dist/cli/commands/event-validation-messages.js.map +1 -0
  45. package/dist/cli/commands/extension/bundled-catalog.d.ts +14 -0
  46. package/dist/cli/commands/extension/bundled-catalog.js +268 -0
  47. package/dist/cli/commands/extension/bundled-catalog.js.map +1 -0
  48. package/dist/cli/commands/extension/doctor.d.ts +31 -0
  49. package/dist/cli/commands/extension/doctor.js +345 -0
  50. package/dist/cli/commands/extension/doctor.js.map +1 -0
  51. package/dist/cli/commands/extension/install-sources.d.ts +37 -0
  52. package/dist/cli/commands/extension/install-sources.js +384 -0
  53. package/dist/cli/commands/extension/install-sources.js.map +1 -0
  54. package/dist/cli/commands/extension/managed-state.d.ts +48 -0
  55. package/dist/cli/commands/extension/managed-state.js +172 -0
  56. package/dist/cli/commands/extension/managed-state.js.map +1 -0
  57. package/dist/cli/commands/extension/scaffold.d.ts +14 -0
  58. package/dist/cli/commands/extension/scaffold.js +169 -0
  59. package/dist/cli/commands/extension/scaffold.js.map +1 -0
  60. package/dist/cli/commands/extension/shared.d.ts +14 -0
  61. package/dist/cli/commands/extension/shared.js +106 -0
  62. package/dist/cli/commands/extension/shared.js.map +1 -0
  63. package/dist/cli/commands/extension.d.ts +37 -68
  64. package/dist/cli/commands/extension.js +157 -1319
  65. package/dist/cli/commands/extension.js.map +1 -1
  66. package/dist/cli/commands/files.d.ts +1 -12
  67. package/dist/cli/commands/files.js +14 -318
  68. package/dist/cli/commands/files.js.map +1 -1
  69. package/dist/cli/commands/gc.js +17 -4
  70. package/dist/cli/commands/gc.js.map +1 -1
  71. package/dist/cli/commands/get.d.ts +3 -2
  72. package/dist/cli/commands/get.js +52 -9
  73. package/dist/cli/commands/get.js.map +1 -1
  74. package/dist/cli/commands/health.d.ts +10 -0
  75. package/dist/cli/commands/health.js +269 -76
  76. package/dist/cli/commands/health.js.map +1 -1
  77. package/dist/cli/commands/history-redact.d.ts +8 -0
  78. package/dist/cli/commands/history-redact.js +35 -113
  79. package/dist/cli/commands/history-redact.js.map +1 -1
  80. package/dist/cli/commands/history-repair.d.ts +33 -0
  81. package/dist/cli/commands/history-repair.js +172 -0
  82. package/dist/cli/commands/history-repair.js.map +1 -0
  83. package/dist/cli/commands/history.d.ts +4 -4
  84. package/dist/cli/commands/history.js +10 -88
  85. package/dist/cli/commands/history.js.map +1 -1
  86. package/dist/cli/commands/index.d.ts +3 -1
  87. package/dist/cli/commands/index.js +5 -3
  88. package/dist/cli/commands/index.js.map +1 -1
  89. package/dist/cli/commands/init.d.ts +28 -0
  90. package/dist/cli/commands/init.js +23 -2
  91. package/dist/cli/commands/init.js.map +1 -1
  92. package/dist/cli/commands/learnings.js +20 -119
  93. package/dist/cli/commands/learnings.js.map +1 -1
  94. package/dist/cli/commands/legacy-none-tokens.d.ts +3 -0
  95. package/dist/cli/commands/legacy-none-tokens.js +39 -0
  96. package/dist/cli/commands/legacy-none-tokens.js.map +1 -0
  97. package/dist/cli/commands/linked-artifacts.d.ts +96 -0
  98. package/dist/cli/commands/linked-artifacts.js +335 -0
  99. package/dist/cli/commands/linked-artifacts.js.map +1 -0
  100. package/dist/cli/commands/linked-test-entry.d.ts +3 -0
  101. package/dist/cli/commands/linked-test-entry.js +62 -0
  102. package/dist/cli/commands/linked-test-entry.js.map +1 -0
  103. package/dist/cli/commands/linked-test-parsers.d.ts +28 -0
  104. package/dist/cli/commands/linked-test-parsers.js +192 -0
  105. package/dist/cli/commands/linked-test-parsers.js.map +1 -0
  106. package/dist/cli/commands/list.js +49 -24
  107. package/dist/cli/commands/list.js.map +1 -1
  108. package/dist/cli/commands/normalize.js +4 -3
  109. package/dist/cli/commands/normalize.js.map +1 -1
  110. package/dist/cli/commands/notes.js +20 -119
  111. package/dist/cli/commands/notes.js.map +1 -1
  112. package/dist/cli/commands/plan.d.ts +3 -0
  113. package/dist/cli/commands/plan.js +184 -22
  114. package/dist/cli/commands/plan.js.map +1 -1
  115. package/dist/cli/commands/recurrence-parsers.d.ts +26 -0
  116. package/dist/cli/commands/recurrence-parsers.js +98 -0
  117. package/dist/cli/commands/recurrence-parsers.js.map +1 -0
  118. package/dist/cli/commands/restore.js +24 -56
  119. package/dist/cli/commands/restore.js.map +1 -1
  120. package/dist/cli/commands/schema.d.ts +31 -0
  121. package/dist/cli/commands/schema.js +98 -0
  122. package/dist/cli/commands/schema.js.map +1 -0
  123. package/dist/cli/commands/search.js +154 -42
  124. package/dist/cli/commands/search.js.map +1 -1
  125. package/dist/cli/commands/templates.d.ts +4 -0
  126. package/dist/cli/commands/templates.js +89 -17
  127. package/dist/cli/commands/templates.js.map +1 -1
  128. package/dist/cli/commands/test/linked-command-detection.d.ts +37 -0
  129. package/dist/cli/commands/test/linked-command-detection.js +200 -0
  130. package/dist/cli/commands/test/linked-command-detection.js.map +1 -0
  131. package/dist/cli/commands/test-all.js +4 -8
  132. package/dist/cli/commands/test-all.js.map +1 -1
  133. package/dist/cli/commands/test.d.ts +2 -2
  134. package/dist/cli/commands/test.js +12 -357
  135. package/dist/cli/commands/test.js.map +1 -1
  136. package/dist/cli/commands/update-many.js +6 -9
  137. package/dist/cli/commands/update-many.js.map +1 -1
  138. package/dist/cli/commands/update.js +167 -401
  139. package/dist/cli/commands/update.js.map +1 -1
  140. package/dist/cli/commands/validate.d.ts +3 -1
  141. package/dist/cli/commands/validate.js +23 -71
  142. package/dist/cli/commands/validate.js.map +1 -1
  143. package/dist/cli/error-guidance.d.ts +1 -0
  144. package/dist/cli/error-guidance.js +100 -6
  145. package/dist/cli/error-guidance.js.map +1 -1
  146. package/dist/cli/extension-command-help.d.ts +0 -1
  147. package/dist/cli/extension-command-help.js +2 -13
  148. package/dist/cli/extension-command-help.js.map +1 -1
  149. package/dist/cli/extension-command-options.d.ts +1 -0
  150. package/dist/cli/extension-command-options.js +106 -7
  151. package/dist/cli/extension-command-options.js.map +1 -1
  152. package/dist/cli/help-content.d.ts +0 -1
  153. package/dist/cli/help-content.js +13 -9
  154. package/dist/cli/help-content.js.map +1 -1
  155. package/dist/cli/help-json-payload.d.ts +1 -0
  156. package/dist/cli/help-json-payload.js +33 -3
  157. package/dist/cli/help-json-payload.js.map +1 -1
  158. package/dist/cli/main.d.ts +11 -0
  159. package/dist/cli/main.js +109 -55
  160. package/dist/cli/main.js.map +1 -1
  161. package/dist/cli/register-list-query.d.ts +5 -2
  162. package/dist/cli/register-list-query.js +254 -192
  163. package/dist/cli/register-list-query.js.map +1 -1
  164. package/dist/cli/register-mutation.d.ts +1 -1
  165. package/dist/cli/register-mutation.js +247 -64
  166. package/dist/cli/register-mutation.js.map +1 -1
  167. package/dist/cli/register-operations.js +17 -12
  168. package/dist/cli/register-operations.js.map +1 -1
  169. package/dist/cli/register-setup.js +33 -16
  170. package/dist/cli/register-setup.js.map +1 -1
  171. package/dist/cli/registration-helpers.d.ts +0 -2
  172. package/dist/cli/registration-helpers.js +14 -40
  173. package/dist/cli/registration-helpers.js.map +1 -1
  174. package/dist/cli.js +25 -4
  175. package/dist/cli.js.map +1 -1
  176. package/dist/core/config/positional-value.d.ts +44 -0
  177. package/dist/core/config/positional-value.js +109 -0
  178. package/dist/core/config/positional-value.js.map +1 -0
  179. package/dist/core/extensions/extension-capability-aliases.d.ts +14 -0
  180. package/dist/core/extensions/extension-capability-aliases.js +159 -0
  181. package/dist/core/extensions/extension-capability-aliases.js.map +1 -0
  182. package/dist/core/extensions/extension-hook-runtime.d.ts +13 -0
  183. package/dist/core/extensions/extension-hook-runtime.js +414 -0
  184. package/dist/core/extensions/extension-hook-runtime.js.map +1 -0
  185. package/dist/core/extensions/extension-policy.d.ts +69 -0
  186. package/dist/core/extensions/extension-policy.js +481 -0
  187. package/dist/core/extensions/extension-policy.js.map +1 -0
  188. package/dist/core/extensions/extension-registries.d.ts +8 -0
  189. package/dist/core/extensions/extension-registries.js +52 -0
  190. package/dist/core/extensions/extension-registries.js.map +1 -0
  191. package/dist/core/extensions/extension-runtime-helpers.d.ts +6 -0
  192. package/dist/core/extensions/extension-runtime-helpers.js +29 -0
  193. package/dist/core/extensions/extension-runtime-helpers.js.map +1 -0
  194. package/dist/core/extensions/extension-types.d.ts +13 -39
  195. package/dist/core/extensions/extension-types.js +34 -2
  196. package/dist/core/extensions/extension-types.js.map +1 -1
  197. package/dist/core/extensions/index.d.ts +7 -1
  198. package/dist/core/extensions/index.js +11 -14
  199. package/dist/core/extensions/index.js.map +1 -1
  200. package/dist/core/extensions/loader.d.ts +4 -22
  201. package/dist/core/extensions/loader.js +23 -1146
  202. package/dist/core/extensions/loader.js.map +1 -1
  203. package/dist/core/fs/path-utils.d.ts +1 -0
  204. package/dist/core/fs/path-utils.js +12 -0
  205. package/dist/core/fs/path-utils.js.map +1 -0
  206. package/dist/core/history/drift-scan.d.ts +22 -0
  207. package/dist/core/history/drift-scan.js +149 -0
  208. package/dist/core/history/drift-scan.js.map +1 -0
  209. package/dist/core/history/history-rewrite.d.ts +43 -0
  210. package/dist/core/history/history-rewrite.js +48 -0
  211. package/dist/core/history/history-rewrite.js.map +1 -0
  212. package/dist/core/history/history.js +5 -4
  213. package/dist/core/history/history.js.map +1 -1
  214. package/dist/core/history/replay.d.ts +82 -0
  215. package/dist/core/history/replay.js +250 -0
  216. package/dist/core/history/replay.js.map +1 -0
  217. package/dist/core/item/item-format.js +11 -8
  218. package/dist/core/item/item-format.js.map +1 -1
  219. package/dist/core/item/item-record.d.ts +19 -0
  220. package/dist/core/item/item-record.js +24 -0
  221. package/dist/core/item/item-record.js.map +1 -0
  222. package/dist/core/item/item-type-definition.d.ts +52 -0
  223. package/dist/core/item/item-type-definition.js +123 -0
  224. package/dist/core/item/item-type-definition.js.map +1 -0
  225. package/dist/core/item/parse.js +3 -2
  226. package/dist/core/item/parse.js.map +1 -1
  227. package/dist/core/item/priority.d.ts +23 -0
  228. package/dist/core/item/priority.js +55 -0
  229. package/dist/core/item/priority.js.map +1 -0
  230. package/dist/core/item/status.d.ts +14 -1
  231. package/dist/core/item/status.js +22 -2
  232. package/dist/core/item/status.js.map +1 -1
  233. package/dist/core/item/toon-decode.d.ts +19 -0
  234. package/dist/core/item/toon-decode.js +69 -0
  235. package/dist/core/item/toon-decode.js.map +1 -0
  236. package/dist/core/item/type-registry.js +13 -84
  237. package/dist/core/item/type-registry.js.map +1 -1
  238. package/dist/core/output/mutation-projection.d.ts +31 -0
  239. package/dist/core/output/mutation-projection.js +103 -0
  240. package/dist/core/output/mutation-projection.js.map +1 -0
  241. package/dist/core/output/output.d.ts +2 -0
  242. package/dist/core/output/output.js +5 -3
  243. package/dist/core/output/output.js.map +1 -1
  244. package/dist/core/packages/manifest.js +3 -9
  245. package/dist/core/packages/manifest.js.map +1 -1
  246. package/dist/core/schema/item-types-file.d.ts +85 -0
  247. package/dist/core/schema/item-types-file.js +243 -0
  248. package/dist/core/schema/item-types-file.js.map +1 -0
  249. package/dist/core/schema/runtime-schema.d.ts +2 -1
  250. package/dist/core/schema/runtime-schema.js +17 -45
  251. package/dist/core/schema/runtime-schema.js.map +1 -1
  252. package/dist/core/search/semantic-defaults.js +3 -3
  253. package/dist/core/search/semantic-defaults.js.map +1 -1
  254. package/dist/core/search/vector-stores.js +46 -9
  255. package/dist/core/search/vector-stores.js.map +1 -1
  256. package/dist/core/sentry/helpers.d.ts +1 -1
  257. package/dist/core/sentry/helpers.js +20 -3
  258. package/dist/core/sentry/helpers.js.map +1 -1
  259. package/dist/core/shared/author.d.ts +1 -0
  260. package/dist/core/shared/author.js +9 -0
  261. package/dist/core/shared/author.js.map +1 -0
  262. package/dist/core/shared/command-types.d.ts +1 -0
  263. package/dist/core/shared/command-types.js +2 -2
  264. package/dist/core/shared/command-types.js.map +1 -1
  265. package/dist/core/shared/constants.d.ts +10 -1
  266. package/dist/core/shared/constants.js +56 -58
  267. package/dist/core/shared/constants.js.map +1 -1
  268. package/dist/core/shared/lazy-module.d.ts +1 -0
  269. package/dist/core/shared/lazy-module.js +11 -0
  270. package/dist/core/shared/lazy-module.js.map +1 -0
  271. package/dist/core/shared/option-alias-visibility.d.ts +44 -0
  272. package/dist/core/shared/option-alias-visibility.js +76 -0
  273. package/dist/core/shared/option-alias-visibility.js.map +1 -0
  274. package/dist/core/shared/primitives.d.ts +23 -0
  275. package/dist/core/shared/primitives.js +39 -2
  276. package/dist/core/shared/primitives.js.map +1 -1
  277. package/dist/core/shared/text-normalization.d.ts +0 -1
  278. package/dist/core/shared/text-normalization.js +2 -5
  279. package/dist/core/shared/text-normalization.js.map +1 -1
  280. package/dist/core/store/front-matter-cache.d.ts +16 -2
  281. package/dist/core/store/front-matter-cache.js +99 -33
  282. package/dist/core/store/front-matter-cache.js.map +1 -1
  283. package/dist/core/store/item-store.d.ts +2 -0
  284. package/dist/core/store/item-store.js +76 -110
  285. package/dist/core/store/item-store.js.map +1 -1
  286. package/dist/core/store/settings-validator.d.ts +106 -0
  287. package/dist/core/store/settings-validator.js +279 -0
  288. package/dist/core/store/settings-validator.js.map +1 -0
  289. package/dist/core/store/settings.js +6 -343
  290. package/dist/core/store/settings.js.map +1 -1
  291. package/dist/core/telemetry/runtime.js +5 -3
  292. package/dist/core/telemetry/runtime.js.map +1 -1
  293. package/dist/mcp/server.js +138 -39
  294. package/dist/mcp/server.js.map +1 -1
  295. package/dist/sdk/cli-contracts/enum-contracts.d.ts +20 -0
  296. package/dist/sdk/cli-contracts/enum-contracts.js +156 -0
  297. package/dist/sdk/cli-contracts/enum-contracts.js.map +1 -0
  298. package/dist/sdk/cli-contracts/tool-option-contracts.d.ts +14 -0
  299. package/dist/sdk/cli-contracts/tool-option-contracts.js +243 -0
  300. package/dist/sdk/cli-contracts/tool-option-contracts.js.map +1 -0
  301. package/dist/sdk/cli-contracts/tool-parameter-tables.d.ts +11 -0
  302. package/dist/sdk/cli-contracts/tool-parameter-tables.js +901 -0
  303. package/dist/sdk/cli-contracts/tool-parameter-tables.js.map +1 -0
  304. package/dist/sdk/cli-contracts.d.ts +18 -33
  305. package/dist/sdk/cli-contracts.js +96 -1238
  306. package/dist/sdk/cli-contracts.js.map +1 -1
  307. package/dist/sdk/package-import-adapters.d.ts +74 -0
  308. package/dist/sdk/package-import-adapters.js +186 -0
  309. package/dist/sdk/package-import-adapters.js.map +1 -0
  310. package/dist/sdk/package-runtime-options.d.ts +26 -0
  311. package/dist/sdk/package-runtime-options.js +71 -0
  312. package/dist/sdk/package-runtime-options.js.map +1 -0
  313. package/dist/sdk/runtime.d.ts +27 -1
  314. package/dist/sdk/runtime.js +48 -3
  315. package/dist/sdk/runtime.js.map +1 -1
  316. package/dist/types.d.ts +6 -0
  317. package/dist/types.js +10 -2
  318. package/dist/types.js.map +1 -1
  319. package/docs/AGENT_GUIDE.md +13 -11
  320. package/docs/ARCHITECTURE.md +1 -1
  321. package/docs/CLAUDE_CODE_PLUGIN.md +5 -28
  322. package/docs/CODEX_PLUGIN.md +5 -5
  323. package/docs/COMMANDS.md +58 -9
  324. package/docs/CONFIGURATION.md +16 -1
  325. package/docs/EXTENSIONS.md +4 -63
  326. package/docs/RELEASING.md +12 -8
  327. package/docs/SDK.md +11 -2
  328. package/marketplace.json +7 -3
  329. package/package.json +18 -14
  330. package/packages/pm-beads/extensions/beads/index.js +2 -49
  331. package/packages/pm-beads/extensions/beads/index.ts +2 -54
  332. package/packages/pm-beads/extensions/beads/runtime-loader.js +86 -0
  333. package/packages/pm-beads/extensions/beads/runtime-loader.ts +88 -0
  334. package/packages/pm-beads/extensions/beads/runtime.js +26 -115
  335. package/packages/pm-beads/extensions/beads/runtime.ts +33 -132
  336. package/packages/pm-calendar/README.md +3 -1
  337. package/packages/pm-calendar/extensions/calendar/index.js +66 -2
  338. package/packages/pm-calendar/extensions/calendar/index.ts +71 -2
  339. package/packages/pm-calendar/extensions/calendar/runtime.js +1 -0
  340. package/packages/pm-calendar/extensions/calendar/runtime.ts +1 -0
  341. package/packages/pm-governance-audit/extensions/governance-audit/runtime.js +14 -41
  342. package/packages/pm-governance-audit/extensions/governance-audit/runtime.ts +25 -41
  343. package/packages/pm-guide-shell/extensions/guide-shell/runtime.js +10 -50
  344. package/packages/pm-guide-shell/extensions/guide-shell/runtime.ts +17 -50
  345. package/packages/pm-linked-test-adapters/extensions/linked-test-adapters/runtime.js +8 -40
  346. package/packages/pm-linked-test-adapters/extensions/linked-test-adapters/runtime.ts +10 -40
  347. package/packages/pm-search-advanced/README.md +8 -0
  348. package/packages/pm-search-advanced/extensions/search-advanced/index.js +75 -1
  349. package/packages/pm-search-advanced/extensions/search-advanced/index.ts +74 -0
  350. package/packages/pm-search-advanced/extensions/search-advanced/runtime.js +58 -33
  351. package/packages/pm-search-advanced/extensions/search-advanced/runtime.ts +60 -33
  352. package/packages/pm-templates/extensions/templates/runtime.js +11 -202
  353. package/packages/pm-templates/extensions/templates/runtime.ts +38 -230
  354. package/packages/pm-todos/extensions/todos/index.js +3 -50
  355. package/packages/pm-todos/extensions/todos/index.ts +3 -55
  356. package/packages/pm-todos/extensions/todos/runtime-loader.js +86 -0
  357. package/packages/pm-todos/extensions/todos/runtime-loader.ts +88 -0
  358. package/packages/pm-todos/extensions/todos/runtime.js +24 -117
  359. package/packages/pm-todos/extensions/todos/runtime.ts +32 -129
  360. package/plugins/pm-claude/README.md +2 -2
  361. package/plugins/pm-claude/commands/pm-planner.md +1 -15
  362. package/plugins/pm-claude/scripts/pm-mcp-server.mjs +5 -2
  363. package/plugins/pm-claude/skills/pm-planner/SKILL.md +3 -21
  364. package/plugins/pm-codex/scripts/pm-mcp-server.mjs +15 -6
  365. package/plugins/pm-codex/skills/pm-native/SKILL.md +1 -13
  366. package/PRD.md +0 -1734
  367. package/dist/core/output/command-aware.d.ts +0 -1
  368. package/dist/core/output/command-aware.js +0 -397
  369. package/dist/core/output/command-aware.js.map +0 -1
@@ -1,8 +1,9 @@
1
1
 
2
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="5d7fe7a0-57cd-5bd9-ab50-36f6cc73ca5c")}catch(e){}}();
2
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="7b4219a0-215b-5cfa-a437-f979968a70c4")}catch(e){}}();
3
3
  import fs from "node:fs/promises";
4
4
  import path from "node:path";
5
5
  import { toNonEmptyStringOrUndefined } from "../../core/shared/primitives.js";
6
+ import { isPathWithinDirectory } from "../../core/fs/path-utils.js";
6
7
  import { getActiveExtensionRegistrations, runActiveOnReadHooks } from "../../core/extensions/index.js";
7
8
  import { resolveRegisteredSearchProvider, resolveRegisteredVectorStoreAdapter, } from "../../core/extensions/runtime-registrations.js";
8
9
  import { resolveItemTypeRegistry } from "../../core/item/type-registry.js";
@@ -13,7 +14,8 @@ import { executeVectorQuery, resolveVectorStores, } from "../../core/search/vect
13
14
  import { buildEventCorpus, buildPlanFlatCorpus, buildReminderCorpus } from "../../core/search/corpus.js";
14
15
  import { pathExists } from "../../core/fs/fs-utils.js";
15
16
  import { parseItemDocument } from "../../core/item/item-format.js";
16
- import { normalizeStatusInput } from "../../core/item/status.js";
17
+ import { toItemRecord } from "../../core/item/item-record.js";
18
+ import { isTerminalStatus } from "../../core/item/status.js";
17
19
  import { collectRuntimeFilterValues, matchesRuntimeFilters } from "../../core/schema/runtime-field-filters.js";
18
20
  import { resolveRuntimeFieldRegistry, resolveRuntimeStatusRegistry, } from "../../core/schema/runtime-schema.js";
19
21
  import { EXIT_CODE } from "../../core/shared/constants.js";
@@ -34,15 +36,68 @@ const DEFAULT_COMPACT_SEARCH_FIELDS = [
34
36
  "score",
35
37
  "matched_fields",
36
38
  ];
39
+ const SEARCH_HIT_FIELD_KEYS = new Set(["score", "matched_fields"]);
40
+ const SEARCH_ITEM_FIELD_KEYS = new Set([
41
+ "id",
42
+ "title",
43
+ "description",
44
+ "type",
45
+ "status",
46
+ "priority",
47
+ "tags",
48
+ "created_at",
49
+ "updated_at",
50
+ "deadline",
51
+ "assignee",
52
+ "author",
53
+ "estimated_minutes",
54
+ "acceptance_criteria",
55
+ "dependencies",
56
+ "comments",
57
+ "notes",
58
+ "learnings",
59
+ "reminders",
60
+ "events",
61
+ "files",
62
+ "tests",
63
+ "docs",
64
+ "close_reason",
65
+ "parent",
66
+ "reviewer",
67
+ "risk",
68
+ "confidence",
69
+ "sprint",
70
+ "release",
71
+ "blocked_by",
72
+ "blocked_reason",
73
+ "reporter",
74
+ "severity",
75
+ "environment",
76
+ "repro_steps",
77
+ "resolution",
78
+ "expected_result",
79
+ "actual_result",
80
+ "affected_version",
81
+ "fixed_version",
82
+ "component",
83
+ "regression",
84
+ "customer_impact",
85
+ "definition_of_ready",
86
+ "order",
87
+ "rank",
88
+ "goal",
89
+ "objective",
90
+ "value",
91
+ "impact",
92
+ "outcome",
93
+ "why_now",
94
+ "plan",
95
+ ]);
37
96
  const LONG_QUERY_TOKEN_THRESHOLD = 2;
38
97
  const LONG_QUERY_TITLE_EXACT_BONUS = 120;
39
98
  const LONG_QUERY_PHRASE_MULTIPLIER = 6;
40
99
  const IMPLICIT_HYBRID_EMBEDDING_TIMEOUT_MS = 8_000;
41
100
  const IMPLICIT_HYBRID_VECTOR_TIMEOUT_MS = 8_000;
42
- function isTerminal(status, statusRegistry) {
43
- const normalized = normalizeStatusInput(status, statusRegistry) ?? status;
44
- return statusRegistry.terminal_statuses.has(normalized);
45
- }
46
101
  function classifyImplicitSemanticFallbackReason(error) {
47
102
  const message = (error instanceof Error ? error.message : String(error)).toLowerCase();
48
103
  if (message.includes("timed out") || message.includes("timeout")) {
@@ -67,9 +122,16 @@ function buildImplicitSemanticFallbackWarning(error) {
67
122
  }
68
123
  return "search_implicit_semantic_fallback:error:using_keyword_mode";
69
124
  }
70
- function parseMode(raw, context) {
125
+ // Explicit --semantic/--hybrid searches must never hard-fail an agent when the
126
+ // embedding/vector backend is unreachable or unconfigured: degrade to keyword
127
+ // search and surface a machine-readable warning instead of an unknown_error.
128
+ function buildExplicitSemanticFallbackWarning(requestedMode, error) {
129
+ const reason = classifyImplicitSemanticFallbackReason(error);
130
+ return `search_${requestedMode}_fallback:${reason}:using_keyword_mode`;
131
+ }
132
+ function parseMode(raw, _context) {
71
133
  if (raw === undefined) {
72
- return context.hasProvider && context.hasVectorStore ? "hybrid" : "keyword";
134
+ return "keyword";
73
135
  }
74
136
  const normalized = raw.trim().toLowerCase();
75
137
  if (normalized !== "keyword" && normalized !== "semantic" && normalized !== "hybrid") {
@@ -141,6 +203,26 @@ function parseProjectionConfig(options) {
141
203
  fields: [],
142
204
  };
143
205
  }
206
+ function validateSearchProjectionFields(projection, runtimeFieldRegistry) {
207
+ if (projection.mode !== "fields") {
208
+ return;
209
+ }
210
+ const runtimeKeys = new Set(runtimeFieldRegistry.definitions.flatMap((field) => [field.key, field.metadata_key]));
211
+ const unknown = projection.fields.filter((field) => {
212
+ const normalized = field.trim();
213
+ const itemKey = normalized.startsWith("item.") ? normalized.slice("item.".length) : normalized;
214
+ return !SEARCH_HIT_FIELD_KEYS.has(normalized) && !SEARCH_ITEM_FIELD_KEYS.has(itemKey) && !runtimeKeys.has(itemKey);
215
+ });
216
+ if (unknown.length > 0) {
217
+ throw new PmCliError(`Unknown search --fields value(s): ${unknown.join(", ")}`, EXIT_CODE.USAGE, {
218
+ examples: [
219
+ "pm search <query> --fields id,title,status,score",
220
+ "pm search <query> --fields id,title,item.description,matched_fields",
221
+ ],
222
+ nextSteps: ["Use item.<field> for explicit item metadata fields, or run pm search --help for projection examples."],
223
+ });
224
+ }
225
+ }
144
226
  function parseTokens(query) {
145
227
  const normalized = normalizeSearchPhrase(query);
146
228
  if (!normalized) {
@@ -148,20 +230,36 @@ function parseTokens(query) {
148
230
  }
149
231
  return normalized.split(/\s+/).filter(Boolean);
150
232
  }
233
+ function stringArray(value) {
234
+ return Array.isArray(value) ? value.filter((entry) => typeof entry === "string") : [];
235
+ }
236
+ function textEntries(value) {
237
+ return Array.isArray(value)
238
+ ? value.filter((entry) => typeof entry === "object" && entry !== null && typeof entry.text === "string")
239
+ : [];
240
+ }
241
+ function dependencyEntries(value) {
242
+ return Array.isArray(value)
243
+ ? value.filter((entry) => typeof entry === "object" &&
244
+ entry !== null &&
245
+ typeof entry.id === "string" &&
246
+ typeof entry.kind === "string")
247
+ : [];
248
+ }
151
249
  function collectExactPhraseFields(document) {
152
250
  const item = document.metadata;
153
251
  return [
154
252
  item.title,
155
253
  item.description,
156
254
  item.status,
157
- item.tags.join(" "),
255
+ stringArray(item.tags).join(" "),
158
256
  document.body,
159
- (item.comments ?? []).map((entry) => entry.text).join(" "),
160
- (item.notes ?? []).map((entry) => entry.text).join(" "),
161
- (item.learnings ?? []).map((entry) => entry.text).join(" "),
257
+ textEntries(item.comments).map((entry) => entry.text).join(" "),
258
+ textEntries(item.notes).map((entry) => entry.text).join(" "),
259
+ textEntries(item.learnings).map((entry) => entry.text).join(" "),
162
260
  buildReminderCorpus(item).join(" "),
163
261
  buildEventCorpus(item).join(" "),
164
- (item.dependencies ?? []).map((entry) => `${entry.id} ${entry.kind}`).join(" "),
262
+ dependencyEntries(item.dependencies).map((entry) => `${entry.id} ${entry.kind}`).join(" "),
165
263
  buildPlanFlatCorpus(item),
166
264
  ];
167
265
  }
@@ -192,7 +290,7 @@ function applyFilters(items, options, typeRegistry, runtimeFieldFilters) {
192
290
  const item = document.metadata;
193
291
  if (typeFilter && item.type !== typeFilter)
194
292
  return false;
195
- if (tagFilter && !item.tags.includes(tagFilter))
293
+ if (tagFilter && !stringArray(item.tags).includes(tagFilter))
196
294
  return false;
197
295
  if (priorityFilter !== undefined && item.priority !== priorityFilter)
198
296
  return false;
@@ -244,13 +342,6 @@ function collectLinkedPaths(item) {
244
342
  }
245
343
  return [...deduped.values()];
246
344
  }
247
- function isPathWithinRoot(root, resolvedPath) {
248
- const relative = path.relative(root, resolvedPath);
249
- if (relative.length === 0) {
250
- return true;
251
- }
252
- return !relative.startsWith("..") && !path.isAbsolute(relative);
253
- }
254
345
  async function resolveContainmentRoot(root) {
255
346
  const resolved = path.resolve(root);
256
347
  try {
@@ -283,7 +374,7 @@ async function loadLinkedCorpus(document, roots) {
283
374
  continue;
284
375
  }
285
376
  const resolved = path.resolve(containmentRoot.resolved, linkedPath.path);
286
- if (!isPathWithinRoot(containmentRoot.resolved, resolved)) {
377
+ if (!isPathWithinDirectory(containmentRoot.resolved, resolved)) {
287
378
  continue;
288
379
  }
289
380
  let linkedRealpath;
@@ -293,7 +384,7 @@ async function loadLinkedCorpus(document, roots) {
293
384
  catch {
294
385
  continue;
295
386
  }
296
- if (!isPathWithinRoot(containmentRoot.realpath, linkedRealpath)) {
387
+ if (!isPathWithinDirectory(containmentRoot.realpath, linkedRealpath)) {
297
388
  continue;
298
389
  }
299
390
  try {
@@ -318,17 +409,17 @@ function scoreDocument(document, tokens, normalizedQuery, linkedCorpus, tuning)
318
409
  const searchableFields = [
319
410
  { name: "title", value: item.title, weight: tuning.title_weight },
320
411
  { name: "description", value: item.description, weight: tuning.description_weight },
321
- { name: "tags", value: item.tags.join(" "), weight: tuning.tags_weight },
322
- { name: "status", value: item.status, weight: tuning.status_weight },
412
+ { name: "tags", value: stringArray(item.tags).join(" "), weight: tuning.tags_weight },
413
+ { name: "status", value: typeof item.status === "string" ? item.status : "", weight: tuning.status_weight },
323
414
  { name: "body", value: document.body, weight: tuning.body_weight },
324
- { name: "comments", value: (item.comments ?? []).map((entry) => entry.text).join(" "), weight: tuning.comments_weight },
325
- { name: "notes", value: (item.notes ?? []).map((entry) => entry.text).join(" "), weight: tuning.notes_weight },
326
- { name: "learnings", value: (item.learnings ?? []).map((entry) => entry.text).join(" "), weight: tuning.learnings_weight },
415
+ { name: "comments", value: textEntries(item.comments).map((entry) => entry.text).join(" "), weight: tuning.comments_weight },
416
+ { name: "notes", value: textEntries(item.notes).map((entry) => entry.text).join(" "), weight: tuning.notes_weight },
417
+ { name: "learnings", value: textEntries(item.learnings).map((entry) => entry.text).join(" "), weight: tuning.learnings_weight },
327
418
  { name: "reminders", value: buildReminderCorpus(item).join(" "), weight: tuning.reminders_weight },
328
419
  { name: "events", value: buildEventCorpus(item).join(" "), weight: tuning.events_weight },
329
420
  {
330
421
  name: "dependencies",
331
- value: (item.dependencies ?? []).map((entry) => `${entry.id} ${entry.kind}`).join(" "),
422
+ value: dependencyEntries(item.dependencies).map((entry) => `${entry.id} ${entry.kind}`).join(" "),
332
423
  weight: tuning.dependencies_weight,
333
424
  },
334
425
  { name: "plan", value: buildPlanFlatCorpus(item), weight: tuning.body_weight },
@@ -381,8 +472,8 @@ function sortHits(items, statusRegistry) {
381
472
  const byScore = b.score - a.score;
382
473
  if (byScore !== 0)
383
474
  return byScore;
384
- const aTerminal = isTerminal(a.item.status, statusRegistry);
385
- const bTerminal = isTerminal(b.item.status, statusRegistry);
475
+ const aTerminal = isTerminalStatus(a.item.status, statusRegistry);
476
+ const bTerminal = isTerminalStatus(b.item.status, statusRegistry);
386
477
  if (aTerminal !== bTerminal) {
387
478
  return aTerminal ? 1 : -1;
388
479
  }
@@ -678,10 +769,14 @@ async function computeSemanticOrHybridHits(context) {
678
769
  }
679
770
  const filteredById = new Map(context.filteredDocuments.map((document) => [document.metadata.id, document]));
680
771
  const { semanticHits, semanticScores } = buildSemanticHits(vectorHits, filteredById);
772
+ const vectorMatchCount = semanticScores.size;
681
773
  if (context.requestedMode === "semantic") {
682
- return semanticHits;
774
+ return { hits: semanticHits, vectorMatchCount };
683
775
  }
684
- return combineHybridHits(filteredById, semanticScores, context.keywordHits, context.hybridSemanticWeight);
776
+ return {
777
+ hits: combineHybridHits(filteredById, semanticScores, context.keywordHits, context.hybridSemanticWeight),
778
+ vectorMatchCount,
779
+ };
685
780
  }
686
781
  async function loadDocuments(pmRoot, itemFormat, typeToFolder, schema) {
687
782
  const readDocumentBody = async (metadata, preferredPath, preferredFormat) => {
@@ -760,11 +855,11 @@ function readSearchFieldValue(hit, field) {
760
855
  if (itemKey.length === 0) {
761
856
  return null;
762
857
  }
763
- const itemRecord = hit.item;
858
+ const itemRecord = toItemRecord(hit.item);
764
859
  return itemRecord[itemKey] ?? null;
765
860
  }
766
861
  const hitRecord = hit;
767
- const itemRecord = hit.item;
862
+ const itemRecord = toItemRecord(hit.item);
768
863
  if (Object.prototype.hasOwnProperty.call(itemRecord, normalized)) {
769
864
  return itemRecord[normalized] ?? null;
770
865
  }
@@ -803,6 +898,7 @@ export async function runSearch(query, options, global) {
803
898
  const settings = runtimeDefaultsResolution.settings;
804
899
  const statusRegistry = resolveRuntimeStatusRegistry(settings.schema);
805
900
  const runtimeFieldRegistry = resolveRuntimeFieldRegistry(settings.schema);
901
+ validateSearchProjectionFields(projection, runtimeFieldRegistry);
806
902
  const runtimeFieldFilters = collectRuntimeFilterValues(options, runtimeFieldRegistry, "search");
807
903
  const typeRegistry = resolveItemTypeRegistry(settings, getActiveExtensionRegistrations());
808
904
  const maxResults = resolveSearchMaxResults(settings);
@@ -873,7 +969,7 @@ export async function runSearch(query, options, global) {
873
969
  if (hits === keywordHits) {
874
970
  const implicitHybridMode = !modeWasExplicit && effectiveMode === "hybrid";
875
971
  const { provider, vectorStore } = requireSemanticDependencies(effectiveMode, providerResolution, vectorResolution, extensionVectorAdapter !== null);
876
- hits = await computeSemanticOrHybridHits({
972
+ const semanticResult = await computeSemanticOrHybridHits({
877
973
  requestedMode: effectiveMode,
878
974
  query,
879
975
  filteredDocuments,
@@ -892,16 +988,32 @@ export async function runSearch(query, options, global) {
892
988
  }
893
989
  : {}),
894
990
  });
991
+ hits = semanticResult.hits;
992
+ // The semantic/hybrid query ran without error, but vector ranking
993
+ // contributed no hits for this query/filter set. Pure semantic mode would
994
+ // otherwise return an empty set, so degrade to the locally computed
995
+ // keyword hits (hybrid already blends them in) and warn so agents do not
996
+ // mistake them for true vector ranking. The reported mode is left
997
+ // unchanged; the warning is the signal.
998
+ if (semanticResult.vectorMatchCount === 0) {
999
+ if (effectiveMode === "semantic") {
1000
+ hits = keywordHits;
1001
+ }
1002
+ warnings.push(`search_${effectiveMode}_degraded:no_vector_matches:results_are_lexical`);
1003
+ }
895
1004
  }
896
1005
  }
897
1006
  catch (error) {
898
- const canFallbackToKeyword = !modeWasExplicit && effectiveMode === "hybrid";
899
- if (!canFallbackToKeyword) {
900
- throw error;
901
- }
1007
+ // Any semantic/hybrid attempt that fails (backend down, timeout, or the
1008
+ // project is not configured for semantic search) degrades to keyword mode
1009
+ // so agents are never blocked. Keyword hits are always computed locally
1010
+ // before this point, so the fallback is guaranteed to succeed.
1011
+ const fallbackWarning = modeWasExplicit
1012
+ ? buildExplicitSemanticFallbackWarning(effectiveMode, error)
1013
+ : buildImplicitSemanticFallbackWarning(error);
902
1014
  effectiveMode = "keyword";
903
1015
  hits = keywordHits;
904
- warnings.push(buildImplicitSemanticFallbackWarning(error));
1016
+ warnings.push(fallbackWarning);
905
1017
  }
906
1018
  }
907
1019
  const thresholded = hits.filter((entry) => entry.score >= scoreThreshold);
@@ -941,4 +1053,4 @@ export async function runSearch(query, options, global) {
941
1053
  };
942
1054
  }
943
1055
  //# sourceMappingURL=search.js.map
944
- //# debugId=5d7fe7a0-57cd-5bd9-ab50-36f6cc73ca5c
1056
+ //# debugId=7b4219a0-215b-5cfa-a437-f979968a70c4