@productbrain/cli 0.1.0-beta.91 → 0.1.0-beta.917

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 (431) hide show
  1. package/dist/__tests__/audit.test.js +5 -0
  2. package/dist/__tests__/audit.test.js.map +1 -1
  3. package/dist/__tests__/authority-domains.test.d.ts +2 -0
  4. package/dist/__tests__/authority-domains.test.d.ts.map +1 -0
  5. package/dist/__tests__/authority-domains.test.js +48 -0
  6. package/dist/__tests__/authority-domains.test.js.map +1 -0
  7. package/dist/__tests__/canonicalRefs.vocab.test.d.ts +2 -0
  8. package/dist/__tests__/canonicalRefs.vocab.test.d.ts.map +1 -0
  9. package/dist/__tests__/canonicalRefs.vocab.test.js +251 -0
  10. package/dist/__tests__/canonicalRefs.vocab.test.js.map +1 -0
  11. package/dist/__tests__/config.test.d.ts +1 -1
  12. package/dist/__tests__/config.test.js +410 -10
  13. package/dist/__tests__/config.test.js.map +1 -1
  14. package/dist/__tests__/constants.test.js +6 -1
  15. package/dist/__tests__/constants.test.js.map +1 -1
  16. package/dist/__tests__/envelope-contract.test.d.ts +15 -0
  17. package/dist/__tests__/envelope-contract.test.d.ts.map +1 -0
  18. package/dist/__tests__/envelope-contract.test.js +152 -0
  19. package/dist/__tests__/envelope-contract.test.js.map +1 -0
  20. package/dist/__tests__/errors.test.js +1 -0
  21. package/dist/__tests__/errors.test.js.map +1 -1
  22. package/dist/__tests__/handshake-augment.test.d.ts +2 -0
  23. package/dist/__tests__/handshake-augment.test.d.ts.map +1 -0
  24. package/dist/__tests__/handshake-augment.test.js +423 -0
  25. package/dist/__tests__/handshake-augment.test.js.map +1 -0
  26. package/dist/__tests__/handshake-dormancy.test.d.ts +2 -0
  27. package/dist/__tests__/handshake-dormancy.test.d.ts.map +1 -0
  28. package/dist/__tests__/handshake-dormancy.test.js +207 -0
  29. package/dist/__tests__/handshake-dormancy.test.js.map +1 -0
  30. package/dist/__tests__/handshake-formatter.test.d.ts +2 -0
  31. package/dist/__tests__/handshake-formatter.test.d.ts.map +1 -0
  32. package/dist/__tests__/handshake-formatter.test.js +67 -0
  33. package/dist/__tests__/handshake-formatter.test.js.map +1 -0
  34. package/dist/__tests__/handshake-preview.test.js +688 -3
  35. package/dist/__tests__/handshake-preview.test.js.map +1 -1
  36. package/dist/__tests__/handshake.e2e.test.d.ts +2 -0
  37. package/dist/__tests__/handshake.e2e.test.d.ts.map +1 -0
  38. package/dist/__tests__/handshake.e2e.test.js +1252 -0
  39. package/dist/__tests__/handshake.e2e.test.js.map +1 -0
  40. package/dist/__tests__/handshake.test.js +611 -2
  41. package/dist/__tests__/handshake.test.js.map +1 -1
  42. package/dist/__tests__/manifest.test.js +118 -1
  43. package/dist/__tests__/manifest.test.js.map +1 -1
  44. package/dist/__tests__/onboarding-path-b.test.js +4 -4
  45. package/dist/__tests__/onboarding-path-b.test.js.map +1 -1
  46. package/dist/__tests__/orient.test.js +135 -8
  47. package/dist/__tests__/orient.test.js.map +1 -1
  48. package/dist/__tests__/perimeter.test.d.ts +2 -0
  49. package/dist/__tests__/perimeter.test.d.ts.map +1 -0
  50. package/dist/__tests__/perimeter.test.js +165 -0
  51. package/dist/__tests__/perimeter.test.js.map +1 -0
  52. package/dist/__tests__/personal-layer.test.d.ts +1 -2
  53. package/dist/__tests__/personal-layer.test.d.ts.map +1 -1
  54. package/dist/__tests__/personal-layer.test.js +12 -48
  55. package/dist/__tests__/personal-layer.test.js.map +1 -1
  56. package/dist/__tests__/profiles.test.js +153 -5
  57. package/dist/__tests__/profiles.test.js.map +1 -1
  58. package/dist/__tests__/promote.test.js +71 -2
  59. package/dist/__tests__/promote.test.js.map +1 -1
  60. package/dist/__tests__/session-state-machine.test.js +45 -1
  61. package/dist/__tests__/session-state-machine.test.js.map +1 -1
  62. package/dist/__tests__/session-switch.test.d.ts +2 -0
  63. package/dist/__tests__/session-switch.test.d.ts.map +1 -0
  64. package/dist/__tests__/session-switch.test.js +129 -0
  65. package/dist/__tests__/session-switch.test.js.map +1 -0
  66. package/dist/__tests__/setup-ingest.test.d.ts +2 -0
  67. package/dist/__tests__/setup-ingest.test.d.ts.map +1 -0
  68. package/dist/__tests__/setup-ingest.test.js +71 -0
  69. package/dist/__tests__/setup-ingest.test.js.map +1 -0
  70. package/dist/__tests__/setup-resolver.test.d.ts +14 -0
  71. package/dist/__tests__/setup-resolver.test.d.ts.map +1 -0
  72. package/dist/__tests__/setup-resolver.test.js +228 -0
  73. package/dist/__tests__/setup-resolver.test.js.map +1 -0
  74. package/dist/__tests__/skill-vocabulary.test.d.ts +21 -0
  75. package/dist/__tests__/skill-vocabulary.test.d.ts.map +1 -0
  76. package/dist/__tests__/skill-vocabulary.test.js +187 -0
  77. package/dist/__tests__/skill-vocabulary.test.js.map +1 -0
  78. package/dist/__tests__/update-check.test.d.ts +2 -0
  79. package/dist/__tests__/update-check.test.d.ts.map +1 -0
  80. package/dist/__tests__/update-check.test.js +56 -0
  81. package/dist/__tests__/update-check.test.js.map +1 -0
  82. package/dist/__tests__/upgrade-runner.test.d.ts +2 -0
  83. package/dist/__tests__/upgrade-runner.test.d.ts.map +1 -0
  84. package/dist/__tests__/upgrade-runner.test.js +42 -0
  85. package/dist/__tests__/upgrade-runner.test.js.map +1 -0
  86. package/dist/__tests__/vocabulary-leak.test.d.ts +39 -0
  87. package/dist/__tests__/vocabulary-leak.test.d.ts.map +1 -0
  88. package/dist/__tests__/vocabulary-leak.test.js +534 -0
  89. package/dist/__tests__/vocabulary-leak.test.js.map +1 -0
  90. package/dist/__tests__/workspace.test.js +32 -12
  91. package/dist/__tests__/workspace.test.js.map +1 -1
  92. package/dist/commands/__tests__/connect-handoff.test.d.ts +11 -0
  93. package/dist/commands/__tests__/connect-handoff.test.d.ts.map +1 -0
  94. package/dist/commands/__tests__/connect-handoff.test.js +111 -0
  95. package/dist/commands/__tests__/connect-handoff.test.js.map +1 -0
  96. package/dist/commands/__tests__/setup-detect-surfaces.test.d.ts +15 -0
  97. package/dist/commands/__tests__/setup-detect-surfaces.test.d.ts.map +1 -0
  98. package/dist/commands/__tests__/setup-detect-surfaces.test.js +149 -0
  99. package/dist/commands/__tests__/setup-detect-surfaces.test.js.map +1 -0
  100. package/dist/commands/__tests__/setup-state.test.d.ts +2 -0
  101. package/dist/commands/__tests__/setup-state.test.d.ts.map +1 -0
  102. package/dist/commands/__tests__/setup-state.test.js +194 -0
  103. package/dist/commands/__tests__/setup-state.test.js.map +1 -0
  104. package/dist/commands/admin/seed.d.ts +46 -2
  105. package/dist/commands/admin/seed.d.ts.map +1 -1
  106. package/dist/commands/admin/seed.js +475 -33
  107. package/dist/commands/admin/seed.js.map +1 -1
  108. package/dist/commands/admin/seed.test.d.ts +5 -0
  109. package/dist/commands/admin/seed.test.d.ts.map +1 -1
  110. package/dist/commands/admin/seed.test.js +67 -2
  111. package/dist/commands/admin/seed.test.js.map +1 -1
  112. package/dist/commands/admin/seedRegistryEntries.generated.d.ts +14 -0
  113. package/dist/commands/admin/seedRegistryEntries.generated.d.ts.map +1 -0
  114. package/dist/commands/admin/seedRegistryEntries.generated.js +117 -0
  115. package/dist/commands/admin/seedRegistryEntries.generated.js.map +1 -0
  116. package/dist/commands/admin/seedRegistryEntries.test.d.ts +11 -0
  117. package/dist/commands/admin/seedRegistryEntries.test.d.ts.map +1 -0
  118. package/dist/commands/admin/seedRegistryEntries.test.js +67 -0
  119. package/dist/commands/admin/seedRegistryEntries.test.js.map +1 -0
  120. package/dist/commands/audit.d.ts.map +1 -1
  121. package/dist/commands/audit.js +30 -3
  122. package/dist/commands/audit.js.map +1 -1
  123. package/dist/commands/authority-domains.d.ts +146 -0
  124. package/dist/commands/authority-domains.d.ts.map +1 -0
  125. package/dist/commands/authority-domains.js +282 -0
  126. package/dist/commands/authority-domains.js.map +1 -0
  127. package/dist/commands/capture.d.ts.map +1 -1
  128. package/dist/commands/capture.js +3 -2
  129. package/dist/commands/capture.js.map +1 -1
  130. package/dist/commands/codex-prep.d.ts +1 -0
  131. package/dist/commands/codex-prep.d.ts.map +1 -1
  132. package/dist/commands/codex-prep.js +10 -7
  133. package/dist/commands/codex-prep.js.map +1 -1
  134. package/dist/commands/connect-config.test.d.ts +2 -0
  135. package/dist/commands/connect-config.test.d.ts.map +1 -0
  136. package/dist/commands/connect-config.test.js +44 -0
  137. package/dist/commands/connect-config.test.js.map +1 -0
  138. package/dist/commands/connect-context.d.ts +45 -0
  139. package/dist/commands/connect-context.d.ts.map +1 -0
  140. package/dist/commands/connect-context.js +64 -0
  141. package/dist/commands/connect-context.js.map +1 -0
  142. package/dist/commands/connect-context.test.d.ts +2 -0
  143. package/dist/commands/connect-context.test.d.ts.map +1 -0
  144. package/dist/commands/connect-context.test.js +110 -0
  145. package/dist/commands/connect-context.test.js.map +1 -0
  146. package/dist/commands/connect-handoff.d.ts +51 -0
  147. package/dist/commands/connect-handoff.d.ts.map +1 -0
  148. package/dist/commands/connect-handoff.js +70 -0
  149. package/dist/commands/connect-handoff.js.map +1 -0
  150. package/dist/commands/connect-integration.test.js +29 -12
  151. package/dist/commands/connect-integration.test.js.map +1 -1
  152. package/dist/commands/connect-screens.d.ts +6 -4
  153. package/dist/commands/connect-screens.d.ts.map +1 -1
  154. package/dist/commands/connect-screens.js +30 -19
  155. package/dist/commands/connect-screens.js.map +1 -1
  156. package/dist/commands/connect.d.ts +21 -6
  157. package/dist/commands/connect.d.ts.map +1 -1
  158. package/dist/commands/connect.js +78 -51
  159. package/dist/commands/connect.js.map +1 -1
  160. package/dist/commands/connect.test.js +64 -1
  161. package/dist/commands/connect.test.js.map +1 -1
  162. package/dist/commands/doctor.d.ts.map +1 -1
  163. package/dist/commands/doctor.js +68 -3
  164. package/dist/commands/doctor.js.map +1 -1
  165. package/dist/commands/doctor.test.js +131 -0
  166. package/dist/commands/doctor.test.js.map +1 -1
  167. package/dist/commands/handshake.d.ts +194 -2
  168. package/dist/commands/handshake.d.ts.map +1 -1
  169. package/dist/commands/handshake.js +1738 -44
  170. package/dist/commands/handshake.js.map +1 -1
  171. package/dist/commands/method.d.ts.map +1 -1
  172. package/dist/commands/method.js +3 -0
  173. package/dist/commands/method.js.map +1 -1
  174. package/dist/commands/migrate-setup.d.ts +18 -0
  175. package/dist/commands/migrate-setup.d.ts.map +1 -0
  176. package/dist/commands/migrate-setup.js +198 -0
  177. package/dist/commands/migrate-setup.js.map +1 -0
  178. package/dist/commands/orient.d.ts +15 -2
  179. package/dist/commands/orient.d.ts.map +1 -1
  180. package/dist/commands/orient.js +86 -4
  181. package/dist/commands/orient.js.map +1 -1
  182. package/dist/commands/profile.d.ts +11 -1
  183. package/dist/commands/profile.d.ts.map +1 -1
  184. package/dist/commands/profile.js +109 -26
  185. package/dist/commands/profile.js.map +1 -1
  186. package/dist/commands/promote.d.ts.map +1 -1
  187. package/dist/commands/promote.js +25 -2
  188. package/dist/commands/promote.js.map +1 -1
  189. package/dist/commands/relate.d.ts.map +1 -1
  190. package/dist/commands/relate.js +13 -0
  191. package/dist/commands/relate.js.map +1 -1
  192. package/dist/commands/session.d.ts.map +1 -1
  193. package/dist/commands/session.js +55 -18
  194. package/dist/commands/session.js.map +1 -1
  195. package/dist/commands/setup-audit.d.ts +59 -0
  196. package/dist/commands/setup-audit.d.ts.map +1 -0
  197. package/dist/commands/setup-audit.js +250 -0
  198. package/dist/commands/setup-audit.js.map +1 -0
  199. package/dist/commands/setup-detect-surfaces.d.ts +38 -0
  200. package/dist/commands/setup-detect-surfaces.d.ts.map +1 -0
  201. package/dist/commands/setup-detect-surfaces.js +76 -0
  202. package/dist/commands/setup-detect-surfaces.js.map +1 -0
  203. package/dist/commands/setup-ingest.d.ts +17 -0
  204. package/dist/commands/setup-ingest.d.ts.map +1 -0
  205. package/dist/commands/setup-ingest.js +226 -0
  206. package/dist/commands/setup-ingest.js.map +1 -0
  207. package/dist/commands/setup-resolver.d.ts +58 -0
  208. package/dist/commands/setup-resolver.d.ts.map +1 -0
  209. package/dist/commands/setup-resolver.js +150 -0
  210. package/dist/commands/setup-resolver.js.map +1 -0
  211. package/dist/commands/setup-state.d.ts +42 -0
  212. package/dist/commands/setup-state.d.ts.map +1 -0
  213. package/dist/commands/setup-state.js +93 -0
  214. package/dist/commands/setup-state.js.map +1 -0
  215. package/dist/commands/setup.d.ts +17 -9
  216. package/dist/commands/setup.d.ts.map +1 -1
  217. package/dist/commands/setup.js +52 -131
  218. package/dist/commands/setup.js.map +1 -1
  219. package/dist/commands/upgrade.d.ts +5 -0
  220. package/dist/commands/upgrade.d.ts.map +1 -0
  221. package/dist/commands/upgrade.js +89 -0
  222. package/dist/commands/upgrade.js.map +1 -0
  223. package/dist/commands/whoami.d.ts +12 -0
  224. package/dist/commands/whoami.d.ts.map +1 -0
  225. package/dist/commands/whoami.js +70 -0
  226. package/dist/commands/whoami.js.map +1 -0
  227. package/dist/commands/whoami.test.d.ts +2 -0
  228. package/dist/commands/whoami.test.d.ts.map +1 -0
  229. package/dist/commands/whoami.test.js +50 -0
  230. package/dist/commands/whoami.test.js.map +1 -0
  231. package/dist/commands/workspace.d.ts +74 -2
  232. package/dist/commands/workspace.d.ts.map +1 -1
  233. package/dist/commands/workspace.js +26 -2
  234. package/dist/commands/workspace.js.map +1 -1
  235. package/dist/formatters/audit.d.ts +6 -0
  236. package/dist/formatters/audit.d.ts.map +1 -1
  237. package/dist/formatters/audit.js.map +1 -1
  238. package/dist/formatters/handshake.d.ts +19 -3
  239. package/dist/formatters/handshake.d.ts.map +1 -1
  240. package/dist/formatters/handshake.js +48 -13
  241. package/dist/formatters/handshake.js.map +1 -1
  242. package/dist/formatters/orient.d.ts +50 -4
  243. package/dist/formatters/orient.d.ts.map +1 -1
  244. package/dist/formatters/orient.js +64 -16
  245. package/dist/formatters/orient.js.map +1 -1
  246. package/dist/formatters/session.js +1 -1
  247. package/dist/formatters/session.js.map +1 -1
  248. package/dist/generators/adapters.js +2 -2
  249. package/dist/generators/boundary-manifest.d.ts +29 -0
  250. package/dist/generators/boundary-manifest.d.ts.map +1 -0
  251. package/dist/generators/boundary-manifest.js +183 -0
  252. package/dist/generators/boundary-manifest.js.map +1 -0
  253. package/dist/generators/boundary-manifest.test.d.ts +2 -0
  254. package/dist/generators/boundary-manifest.test.d.ts.map +1 -0
  255. package/dist/generators/boundary-manifest.test.js +91 -0
  256. package/dist/generators/boundary-manifest.test.js.map +1 -0
  257. package/dist/generators/context-md.js +6 -6
  258. package/dist/generators/context-md.js.map +1 -1
  259. package/dist/generators/manifest.d.ts +78 -0
  260. package/dist/generators/manifest.d.ts.map +1 -1
  261. package/dist/generators/manifest.js +125 -14
  262. package/dist/generators/manifest.js.map +1 -1
  263. package/dist/generators/portable-knowledge.d.ts +6 -12
  264. package/dist/generators/portable-knowledge.d.ts.map +1 -1
  265. package/dist/generators/portable-knowledge.js +2 -19
  266. package/dist/generators/portable-knowledge.js.map +1 -1
  267. package/dist/generators/region-projections.d.ts +18 -0
  268. package/dist/generators/region-projections.d.ts.map +1 -0
  269. package/dist/generators/region-projections.js +49 -0
  270. package/dist/generators/region-projections.js.map +1 -0
  271. package/dist/generators/region-projections.test.d.ts +2 -0
  272. package/dist/generators/region-projections.test.d.ts.map +1 -0
  273. package/dist/generators/region-projections.test.js +63 -0
  274. package/dist/generators/region-projections.test.js.map +1 -0
  275. package/dist/generators/region.d.ts +24 -0
  276. package/dist/generators/region.d.ts.map +1 -0
  277. package/dist/generators/region.js +87 -0
  278. package/dist/generators/region.js.map +1 -0
  279. package/dist/generators/region.test.d.ts +2 -0
  280. package/dist/generators/region.test.d.ts.map +1 -0
  281. package/dist/generators/region.test.js +126 -0
  282. package/dist/generators/region.test.js.map +1 -0
  283. package/dist/generators/surface-profiles.d.ts +1 -2
  284. package/dist/generators/surface-profiles.d.ts.map +1 -1
  285. package/dist/generators/surface-profiles.js.map +1 -1
  286. package/dist/index.js +242 -26
  287. package/dist/index.js.map +1 -1
  288. package/dist/lib/activation.d.ts.map +1 -1
  289. package/dist/lib/activation.js +3 -3
  290. package/dist/lib/activation.js.map +1 -1
  291. package/dist/lib/activation.test.js +3 -3
  292. package/dist/lib/activation.test.js.map +1 -1
  293. package/dist/lib/canonicalRefs.d.ts +141 -0
  294. package/dist/lib/canonicalRefs.d.ts.map +1 -0
  295. package/dist/lib/canonicalRefs.js +150 -0
  296. package/dist/lib/canonicalRefs.js.map +1 -0
  297. package/dist/lib/client.d.ts.map +1 -1
  298. package/dist/lib/client.js +27 -17
  299. package/dist/lib/client.js.map +1 -1
  300. package/dist/lib/config.d.ts +98 -9
  301. package/dist/lib/config.d.ts.map +1 -1
  302. package/dist/lib/config.js +231 -44
  303. package/dist/lib/config.js.map +1 -1
  304. package/dist/lib/connectKeyLabel.d.ts +9 -0
  305. package/dist/lib/connectKeyLabel.d.ts.map +1 -0
  306. package/dist/lib/connectKeyLabel.js +12 -0
  307. package/dist/lib/connectKeyLabel.js.map +1 -0
  308. package/dist/lib/constants.d.ts +2 -0
  309. package/dist/lib/constants.d.ts.map +1 -1
  310. package/dist/lib/constants.js +2 -0
  311. package/dist/lib/constants.js.map +1 -1
  312. package/dist/lib/errors.d.ts +3 -0
  313. package/dist/lib/errors.d.ts.map +1 -1
  314. package/dist/lib/errors.js +3 -0
  315. package/dist/lib/errors.js.map +1 -1
  316. package/dist/lib/normalizeMaterializedFilename.d.ts +28 -0
  317. package/dist/lib/normalizeMaterializedFilename.d.ts.map +1 -0
  318. package/dist/lib/normalizeMaterializedFilename.js +56 -0
  319. package/dist/lib/normalizeMaterializedFilename.js.map +1 -0
  320. package/dist/lib/normalizeMaterializedFilename.test.d.ts +16 -0
  321. package/dist/lib/normalizeMaterializedFilename.test.d.ts.map +1 -0
  322. package/dist/lib/normalizeMaterializedFilename.test.js +90 -0
  323. package/dist/lib/normalizeMaterializedFilename.test.js.map +1 -0
  324. package/dist/lib/onboarding-path-b.d.ts.map +1 -1
  325. package/dist/lib/onboarding-path-b.js +0 -1
  326. package/dist/lib/onboarding-path-b.js.map +1 -1
  327. package/dist/lib/onboarding-shared.d.ts +0 -1
  328. package/dist/lib/onboarding-shared.d.ts.map +1 -1
  329. package/dist/lib/onboarding-shared.js +1 -17
  330. package/dist/lib/onboarding-shared.js.map +1 -1
  331. package/dist/lib/profiles.d.ts +3 -1
  332. package/dist/lib/profiles.d.ts.map +1 -1
  333. package/dist/lib/profiles.js +9 -6
  334. package/dist/lib/profiles.js.map +1 -1
  335. package/dist/lib/session.d.ts +10 -0
  336. package/dist/lib/session.d.ts.map +1 -1
  337. package/dist/lib/session.js +14 -0
  338. package/dist/lib/session.js.map +1 -1
  339. package/dist/lib/update-check.d.ts +20 -0
  340. package/dist/lib/update-check.d.ts.map +1 -1
  341. package/dist/lib/update-check.js +122 -21
  342. package/dist/lib/update-check.js.map +1 -1
  343. package/dist/lib/upgrade-runner.d.ts +21 -0
  344. package/dist/lib/upgrade-runner.d.ts.map +1 -0
  345. package/dist/lib/upgrade-runner.js +109 -0
  346. package/dist/lib/upgrade-runner.js.map +1 -0
  347. package/dist/lib/workspaceVocabCache.d.ts +60 -0
  348. package/dist/lib/workspaceVocabCache.d.ts.map +1 -0
  349. package/dist/lib/workspaceVocabCache.js +98 -0
  350. package/dist/lib/workspaceVocabCache.js.map +1 -0
  351. package/dist/setup/__tests__/coach-traces.test.d.ts +2 -0
  352. package/dist/setup/__tests__/coach-traces.test.d.ts.map +1 -0
  353. package/dist/setup/__tests__/coach-traces.test.js +189 -0
  354. package/dist/setup/__tests__/coach-traces.test.js.map +1 -0
  355. package/dist/setup/__tests__/setup-commands.test.d.ts +2 -0
  356. package/dist/setup/__tests__/setup-commands.test.d.ts.map +1 -0
  357. package/dist/setup/__tests__/setup-commands.test.js +177 -0
  358. package/dist/setup/__tests__/setup-commands.test.js.map +1 -0
  359. package/dist/setup/__tests__/state-machine.test.d.ts +2 -0
  360. package/dist/setup/__tests__/state-machine.test.d.ts.map +1 -0
  361. package/dist/setup/__tests__/state-machine.test.js +341 -0
  362. package/dist/setup/__tests__/state-machine.test.js.map +1 -0
  363. package/dist/setup/detect-surfaces.d.ts +21 -0
  364. package/dist/setup/detect-surfaces.d.ts.map +1 -0
  365. package/dist/setup/detect-surfaces.js +39 -0
  366. package/dist/setup/detect-surfaces.js.map +1 -0
  367. package/dist/setup/manifest-writer.d.ts +17 -0
  368. package/dist/setup/manifest-writer.d.ts.map +1 -0
  369. package/dist/setup/manifest-writer.js +153 -0
  370. package/dist/setup/manifest-writer.js.map +1 -0
  371. package/dist/setup/perimeter.d.ts +72 -0
  372. package/dist/setup/perimeter.d.ts.map +1 -0
  373. package/dist/setup/perimeter.js +128 -0
  374. package/dist/setup/perimeter.js.map +1 -0
  375. package/dist/setup/state-machine.d.ts +67 -0
  376. package/dist/setup/state-machine.d.ts.map +1 -0
  377. package/dist/setup/state-machine.js +124 -0
  378. package/dist/setup/state-machine.js.map +1 -0
  379. package/dist/surfaces/__tests__/adapter.test.d.ts +2 -0
  380. package/dist/surfaces/__tests__/adapter.test.d.ts.map +1 -0
  381. package/dist/surfaces/__tests__/adapter.test.js +90 -0
  382. package/dist/surfaces/__tests__/adapter.test.js.map +1 -0
  383. package/dist/surfaces/__tests__/pb-setup-passthrough.test.d.ts +2 -0
  384. package/dist/surfaces/__tests__/pb-setup-passthrough.test.d.ts.map +1 -0
  385. package/dist/surfaces/__tests__/pb-setup-passthrough.test.js +132 -0
  386. package/dist/surfaces/__tests__/pb-setup-passthrough.test.js.map +1 -0
  387. package/dist/surfaces/__tests__/telemetry.test.d.ts +2 -0
  388. package/dist/surfaces/__tests__/telemetry.test.d.ts.map +1 -0
  389. package/dist/surfaces/__tests__/telemetry.test.js +55 -0
  390. package/dist/surfaces/__tests__/telemetry.test.js.map +1 -0
  391. package/dist/surfaces/adapter.d.ts +70 -0
  392. package/dist/surfaces/adapter.d.ts.map +1 -0
  393. package/dist/surfaces/adapter.js +2 -0
  394. package/dist/surfaces/adapter.js.map +1 -0
  395. package/dist/surfaces/adapters/claude.d.ts +3 -0
  396. package/dist/surfaces/adapters/claude.d.ts.map +1 -0
  397. package/dist/surfaces/adapters/claude.js +67 -0
  398. package/dist/surfaces/adapters/claude.js.map +1 -0
  399. package/dist/surfaces/adapters/codex.d.ts +3 -0
  400. package/dist/surfaces/adapters/codex.d.ts.map +1 -0
  401. package/dist/surfaces/adapters/codex.js +61 -0
  402. package/dist/surfaces/adapters/codex.js.map +1 -0
  403. package/dist/surfaces/adapters/copilot.d.ts +3 -0
  404. package/dist/surfaces/adapters/copilot.d.ts.map +1 -0
  405. package/dist/surfaces/adapters/copilot.js +59 -0
  406. package/dist/surfaces/adapters/copilot.js.map +1 -0
  407. package/dist/surfaces/adapters/cursor.d.ts +3 -0
  408. package/dist/surfaces/adapters/cursor.d.ts.map +1 -0
  409. package/dist/surfaces/adapters/cursor.js +78 -0
  410. package/dist/surfaces/adapters/cursor.js.map +1 -0
  411. package/dist/surfaces/registry.d.ts +58 -2
  412. package/dist/surfaces/registry.d.ts.map +1 -1
  413. package/dist/surfaces/registry.js +82 -7
  414. package/dist/surfaces/registry.js.map +1 -1
  415. package/dist/surfaces/telemetry.d.ts +17 -0
  416. package/dist/surfaces/telemetry.d.ts.map +1 -0
  417. package/dist/surfaces/telemetry.js +31 -0
  418. package/dist/surfaces/telemetry.js.map +1 -0
  419. package/package.json +2 -1
  420. package/dist/__tests__/setup.test.d.ts +0 -2
  421. package/dist/__tests__/setup.test.d.ts.map +0 -1
  422. package/dist/__tests__/setup.test.js +0 -141
  423. package/dist/__tests__/setup.test.js.map +0 -1
  424. package/dist/generators/__tests__/surface-profiles.test.d.ts +0 -2
  425. package/dist/generators/__tests__/surface-profiles.test.d.ts.map +0 -1
  426. package/dist/generators/__tests__/surface-profiles.test.js +0 -89
  427. package/dist/generators/__tests__/surface-profiles.test.js.map +0 -1
  428. package/dist/lib/onboarding-phases.d.ts +0 -9
  429. package/dist/lib/onboarding-phases.d.ts.map +0 -1
  430. package/dist/lib/onboarding-phases.js +0 -120
  431. package/dist/lib/onboarding-phases.js.map +0 -1
@@ -0,0 +1,228 @@
1
+ /**
2
+ * WP-336 E2 — setup-resolver contract tests.
3
+ *
4
+ * Three test groups:
5
+ * 1. getSetupMode() — reads PB_SETUP_MODE env var correctly
6
+ * 2. local mode — resolveSetupAssets returns assets from .productbrain/
7
+ * 3. chain mode — resolveSetupAssets calls kernelCall with the right args
8
+ *
9
+ * Done-when coverage:
10
+ * - WP-336 #3: local mode returns same asset names as what's in .productbrain/
11
+ * - WP-336 #2: chain mode calls kernelCall('setup.getActiveSurface', {...})
12
+ */
13
+ import { beforeEach, afterEach, describe, expect, it, vi } from 'vitest';
14
+ import { join } from 'path';
15
+ // ── VFS (virtual filesystem) ──────────────────────────────────────────────────
16
+ // Declared with vi.hoisted so the mock factory can reference them.
17
+ const { vfs } = vi.hoisted(() => ({
18
+ vfs: {},
19
+ }));
20
+ vi.mock('fs', () => ({
21
+ existsSync: vi.fn((p) => {
22
+ // A path "exists" if it's directly in the VFS (file) or is a directory prefix of any VFS key.
23
+ if (p in vfs)
24
+ return true;
25
+ const prefix = p.endsWith('/') ? p : p + '/';
26
+ return Object.keys(vfs).some((k) => k.startsWith(prefix));
27
+ }),
28
+ readdirSync: vi.fn((p) => {
29
+ // Return the basenames of direct children under <p> (no sub-directories).
30
+ const prefix = p.endsWith('/') ? p : p + '/';
31
+ const keys = Object.keys(vfs).filter((k) => k.startsWith(prefix) && !k.slice(prefix.length).includes('/'));
32
+ return keys.map((k) => k.slice(prefix.length));
33
+ }),
34
+ readFileSync: vi.fn((p, _enc) => {
35
+ if (p in vfs)
36
+ return vfs[p];
37
+ throw Object.assign(new Error(`ENOENT: no such file '${p}'`), { code: 'ENOENT' });
38
+ }),
39
+ }));
40
+ // ── Module under test ─────────────────────────────────────────────────────────
41
+ import { getSetupMode, resolveSetupAssets } from '../commands/setup-resolver.js';
42
+ // ── Helpers ───────────────────────────────────────────────────────────────────
43
+ const MOCK_CWD = '/tmp/resolver-test';
44
+ const PB_DIR = join(MOCK_CWD, '.productbrain');
45
+ const SKILLS_DIR = join(PB_DIR, 'skills');
46
+ const RULES_DIR = join(PB_DIR, 'rules');
47
+ /** Populate VFS with a fake skill file. */
48
+ function seedSkill(name, body) {
49
+ vfs[join(SKILLS_DIR, `${name}.md`)] = body;
50
+ }
51
+ /** Populate VFS with a fake rule file. */
52
+ function seedRule(name, body) {
53
+ vfs[join(RULES_DIR, `${name}.md`)] = body;
54
+ }
55
+ /** No-op kernelCall stub (used when we don't expect it to be called). */
56
+ const noopKernel = vi.fn();
57
+ // ── Tests ─────────────────────────────────────────────────────────────────────
58
+ describe('getSetupMode()', () => {
59
+ const originalEnv = process.env.PB_SETUP_MODE;
60
+ afterEach(() => {
61
+ if (originalEnv === undefined) {
62
+ delete process.env.PB_SETUP_MODE;
63
+ }
64
+ else {
65
+ process.env.PB_SETUP_MODE = originalEnv;
66
+ }
67
+ });
68
+ it('returns "local" when PB_SETUP_MODE is unset', () => {
69
+ delete process.env.PB_SETUP_MODE;
70
+ expect(getSetupMode()).toBe('local');
71
+ });
72
+ it('returns "local" when PB_SETUP_MODE=local', () => {
73
+ process.env.PB_SETUP_MODE = 'local';
74
+ expect(getSetupMode()).toBe('local');
75
+ });
76
+ it('returns "chain" when PB_SETUP_MODE=chain', () => {
77
+ process.env.PB_SETUP_MODE = 'chain';
78
+ expect(getSetupMode()).toBe('chain');
79
+ });
80
+ it('returns "local" for unknown values (fail-open)', () => {
81
+ process.env.PB_SETUP_MODE = 'unknown-value';
82
+ expect(getSetupMode()).toBe('local');
83
+ });
84
+ });
85
+ describe('resolveSetupAssets — local mode', () => {
86
+ beforeEach(() => {
87
+ Object.keys(vfs).forEach((k) => delete vfs[k]);
88
+ // Reset call counts only — do NOT clearAllMocks() as that wipes fs mock implementations
89
+ noopKernel.mockClear();
90
+ });
91
+ it('returns an empty array when .productbrain/ has no skills or rules', async () => {
92
+ // existsSync returns false for all paths (vfs is empty)
93
+ const assets = await resolveSetupAssets('local', noopKernel, MOCK_CWD);
94
+ expect(assets).toEqual([]);
95
+ expect(noopKernel).not.toHaveBeenCalled();
96
+ });
97
+ it('returns skill assets from .productbrain/skills/', async () => {
98
+ seedSkill('triage', '# Triage\nClassify and route work.');
99
+ seedSkill('review', '# Review\nFive-path trace.');
100
+ const assets = await resolveSetupAssets('local', noopKernel, MOCK_CWD);
101
+ const skillAssets = assets.filter((a) => a.assetKind === 'skill');
102
+ const skillNames = skillAssets.map((a) => a.displayName);
103
+ expect(skillNames).toContain('triage');
104
+ expect(skillNames).toContain('review');
105
+ expect(noopKernel).not.toHaveBeenCalled();
106
+ });
107
+ it('returns rule assets from .productbrain/rules/', async () => {
108
+ seedRule('git-workflow', '# Git Workflow\nTwo-track development.');
109
+ const assets = await resolveSetupAssets('local', noopKernel, MOCK_CWD);
110
+ const ruleAssets = assets.filter((a) => a.assetKind === 'rule');
111
+ expect(ruleAssets).toHaveLength(1);
112
+ expect(ruleAssets[0].displayName).toBe('git-workflow');
113
+ expect(ruleAssets[0].assetKind).toBe('rule');
114
+ expect(ruleAssets[0].source).toBe('authored');
115
+ });
116
+ it('strips frontmatter from skill body', async () => {
117
+ seedSkill('commit', '---\nname: commit\ndescription: Commit skill\n---\n# Commit\nVerify and push.');
118
+ const assets = await resolveSetupAssets('local', noopKernel, MOCK_CWD);
119
+ const commitSkill = assets.find((a) => a.displayName === 'commit');
120
+ expect(commitSkill).toBeDefined();
121
+ // Body should not include the frontmatter block
122
+ expect(commitSkill.body).not.toContain('description: Commit skill');
123
+ expect(commitSkill.body).toContain('# Commit');
124
+ });
125
+ it('returns skills + rules together', async () => {
126
+ seedSkill('triage', '# Triage');
127
+ seedRule('git-workflow', '# Git Workflow');
128
+ const assets = await resolveSetupAssets('local', noopKernel, MOCK_CWD);
129
+ const kinds = assets.map((a) => a.assetKind);
130
+ expect(kinds).toContain('skill');
131
+ expect(kinds).toContain('rule');
132
+ });
133
+ it('contract test — local asset displayNames match .productbrain/ file basenames', async () => {
134
+ // WP-336 done-when #3: local mode produces asset names identical to what's in .productbrain/
135
+ const expectedSkills = ['diagnostic-fix', 'handoff', 'preflight'];
136
+ const expectedRules = ['chain-policies', 'git-workflow', 'architecture-boundaries'];
137
+ for (const name of expectedSkills)
138
+ seedSkill(name, `# ${name}`);
139
+ for (const name of expectedRules)
140
+ seedRule(name, `# ${name}`);
141
+ const assets = await resolveSetupAssets('local', noopKernel, MOCK_CWD);
142
+ const assetSkillNames = assets
143
+ .filter((a) => a.assetKind === 'skill')
144
+ .map((a) => a.displayName);
145
+ const assetRuleNames = assets
146
+ .filter((a) => a.assetKind === 'rule')
147
+ .map((a) => a.displayName);
148
+ for (const name of expectedSkills)
149
+ expect(assetSkillNames).toContain(name);
150
+ for (const name of expectedRules)
151
+ expect(assetRuleNames).toContain(name);
152
+ });
153
+ });
154
+ describe('resolveSetupAssets — chain mode', () => {
155
+ beforeEach(() => {
156
+ Object.keys(vfs).forEach((k) => delete vfs[k]);
157
+ // Reset call counts only — do NOT clearAllMocks() as that wipes fs mock implementations
158
+ });
159
+ it('calls kernelCall with "setup.getActiveSurface" (WP-336 done-when #2)', async () => {
160
+ const mockKernel = vi.fn().mockResolvedValue([]);
161
+ await resolveSetupAssets('chain', mockKernel, MOCK_CWD);
162
+ expect(mockKernel).toHaveBeenCalledWith('setup.getActiveSurface', expect.any(Object));
163
+ });
164
+ it('does NOT read from .productbrain/ in chain mode', async () => {
165
+ seedSkill('triage', '# Triage');
166
+ const mockKernel = vi.fn().mockResolvedValue([]);
167
+ // Track readFileSync calls from this point forward
168
+ const { readFileSync } = await import('fs');
169
+ readFileSync.mockClear();
170
+ await resolveSetupAssets('chain', mockKernel, MOCK_CWD);
171
+ // readFileSync should not be called in chain mode (only kernelCall)
172
+ expect(readFileSync).not.toHaveBeenCalled();
173
+ });
174
+ it('maps chain results to SetupAsset shape', async () => {
175
+ const chainResult = [
176
+ {
177
+ assetId: 'SETUP-SKILL-TRIAGE',
178
+ assetKind: 'skill',
179
+ displayName: 'Triage',
180
+ shortDescription: 'Classify and route work.',
181
+ body: '# Triage\nClassify and route.',
182
+ version: 1,
183
+ source: 'seeded',
184
+ },
185
+ {
186
+ assetId: 'SETUP-RULE-GIT',
187
+ assetKind: 'rule',
188
+ displayName: 'Git Workflow',
189
+ shortDescription: 'Two-track development.',
190
+ body: '# Git Workflow',
191
+ version: 1,
192
+ source: 'seeded',
193
+ },
194
+ ];
195
+ const mockKernel = vi.fn().mockResolvedValue(chainResult);
196
+ const assets = await resolveSetupAssets('chain', mockKernel, MOCK_CWD);
197
+ expect(assets).toHaveLength(2);
198
+ const [skill, rule] = assets;
199
+ expect(skill.assetKind).toBe('skill');
200
+ expect(skill.displayName).toBe('Triage');
201
+ expect(skill.body).toContain('# Triage');
202
+ expect(skill.source).toBe('seeded');
203
+ expect(rule.assetKind).toBe('rule');
204
+ expect(rule.displayName).toBe('Git Workflow');
205
+ });
206
+ it('defaults unknown assetKind to "skill"', async () => {
207
+ const chainResult = [
208
+ {
209
+ assetId: 'SETUP-X-UNKNOWN',
210
+ assetKind: 'unknown-future-type',
211
+ displayName: 'Mystery Asset',
212
+ shortDescription: '',
213
+ body: '# Mystery',
214
+ version: 1,
215
+ source: 'seeded',
216
+ },
217
+ ];
218
+ const mockKernel = vi.fn().mockResolvedValue(chainResult);
219
+ const assets = await resolveSetupAssets('chain', mockKernel, MOCK_CWD);
220
+ expect(assets[0].assetKind).toBe('skill');
221
+ });
222
+ it('calls kernelCall with empty args object (gateway injects personId server-side)', async () => {
223
+ const mockKernel = vi.fn().mockResolvedValue([]);
224
+ await resolveSetupAssets('chain', mockKernel, MOCK_CWD);
225
+ expect(mockKernel).toHaveBeenCalledWith('setup.getActiveSurface', {});
226
+ });
227
+ });
228
+ //# sourceMappingURL=setup-resolver.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup-resolver.test.js","sourceRoot":"","sources":["../../src/__tests__/setup-resolver.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Skill vocabulary fixture tests — WP-436 S3.
3
+ *
4
+ * 3 skill files × 3 workspace presets = 9 fixture assertions.
5
+ *
6
+ * Each test renders a tokenized skill file content through replaceVocabTokens
7
+ * with the given workspace preset and asserts:
8
+ * 1. No un-tokenized noun-form "bet" / "Bet" / "bets" / "Bets" remains
9
+ * outside exclusions (code fences, inline code, already-tokenized lines).
10
+ * 2. No raw {{vocab:...}} token survives (resolver is exhaustive).
11
+ * 3. The rendered content contains the expected singular label for the preset.
12
+ *
13
+ * Workspace presets (methodology-neutral):
14
+ * - Shape Up: singular=Bet, plural=Bets, verb_start=shape, verb_complete=ship
15
+ * - Generic: singular=Initiative, plural=Initiatives, verb_start=start, verb_complete=complete
16
+ * - Linear: singular=Issue, plural=Issues, verb_start=begin, verb_complete=archive
17
+ *
18
+ * Chain: WP-436 S3, STD-253, DEC-1021.
19
+ */
20
+ export {};
21
+ //# sourceMappingURL=skill-vocabulary.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill-vocabulary.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/skill-vocabulary.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG"}
@@ -0,0 +1,187 @@
1
+ /**
2
+ * Skill vocabulary fixture tests — WP-436 S3.
3
+ *
4
+ * 3 skill files × 3 workspace presets = 9 fixture assertions.
5
+ *
6
+ * Each test renders a tokenized skill file content through replaceVocabTokens
7
+ * with the given workspace preset and asserts:
8
+ * 1. No un-tokenized noun-form "bet" / "Bet" / "bets" / "Bets" remains
9
+ * outside exclusions (code fences, inline code, already-tokenized lines).
10
+ * 2. No raw {{vocab:...}} token survives (resolver is exhaustive).
11
+ * 3. The rendered content contains the expected singular label for the preset.
12
+ *
13
+ * Workspace presets (methodology-neutral):
14
+ * - Shape Up: singular=Bet, plural=Bets, verb_start=shape, verb_complete=ship
15
+ * - Generic: singular=Initiative, plural=Initiatives, verb_start=start, verb_complete=complete
16
+ * - Linear: singular=Issue, plural=Issues, verb_start=begin, verb_complete=archive
17
+ *
18
+ * Chain: WP-436 S3, STD-253, DEC-1021.
19
+ */
20
+ import { readFileSync } from 'fs';
21
+ import { join } from 'path';
22
+ import { describe, expect, it } from 'vitest';
23
+ import { replaceVocabTokens } from '../lib/canonicalRefs.js';
24
+ // ── Helpers ───────────────────────────────────────────────────────────────────
25
+ const PB_SKILLS_DIR = join(new URL('../../../..', import.meta.url).pathname, '.productbrain', 'skills');
26
+ function readSkill(name) {
27
+ return readFileSync(join(PB_SKILLS_DIR, `${name}.md`), 'utf8');
28
+ }
29
+ // ── Workspace presets ─────────────────────────────────────────────────────────
30
+ const PRESETS = {
31
+ 'Shape Up': {
32
+ collectionLabels: {
33
+ work_package: {
34
+ singular: 'Bet',
35
+ plural: 'Bets',
36
+ verb_start: 'shape',
37
+ verb_complete: 'ship',
38
+ verb_archive: 'archive',
39
+ },
40
+ },
41
+ },
42
+ 'Generic': {
43
+ collectionLabels: {
44
+ work_package: {
45
+ singular: 'Initiative',
46
+ plural: 'Initiatives',
47
+ verb_start: 'start',
48
+ verb_complete: 'complete',
49
+ verb_archive: 'close',
50
+ },
51
+ },
52
+ },
53
+ 'Linear': {
54
+ collectionLabels: {
55
+ work_package: {
56
+ singular: 'Issue',
57
+ plural: 'Issues',
58
+ verb_start: 'begin',
59
+ verb_complete: 'archive',
60
+ verb_archive: 'archive',
61
+ },
62
+ },
63
+ },
64
+ };
65
+ // ── Assertion helpers ─────────────────────────────────────────────────────────
66
+ /**
67
+ * Check that no raw {{vocab:...}} token survives in the rendered output.
68
+ * The resolver should replace ALL tokens.
69
+ */
70
+ function assertNoRawTokens(rendered, description) {
71
+ const rawTokens = rendered.match(/\{\{vocab:[a-z_]+\.[a-z_]+\}\}/g) ?? [];
72
+ expect(rawTokens, `${description}: found raw {{vocab:...}} tokens after render: ${rawTokens.join(', ')}`).toHaveLength(0);
73
+ }
74
+ /**
75
+ * Check that no un-tokenized noun-form "bet" remains in prose (outside code fences and inline code).
76
+ *
77
+ * This replicates the verify-no-noun-bet exclusion logic inline.
78
+ * Note: after render, what we are checking is the OUTPUT — rendered prose that should use
79
+ * the workspace label (e.g. "Bet", "Initiative", "Issue") — NOT the raw token. So we only
80
+ * need to confirm no lowercase "bet"/"bets" remain that are NOT the resolved label.
81
+ *
82
+ * For the Shape Up preset where singular="Bet", the rendered text will contain "Bet" naturally.
83
+ * For Generic/Linear, "Bet" should NOT appear (it was replaced by Initiative/Issue).
84
+ */
85
+ function assertNoUnresolved(rendered, preset, ctx) {
86
+ const singular = ctx.collectionLabels?.work_package?.singular ?? '';
87
+ const plural = ctx.collectionLabels?.work_package?.plural ?? '';
88
+ // If the preset maps to "Bet"/"Bets" (Shape Up), then rendered "Bet" is expected.
89
+ // Otherwise, we check that "bet" / "Bet" doesn't appear in prose outside inline code.
90
+ if (singular === 'Bet') {
91
+ // Shape Up: resolved labels are "Bet"/"Bets" (capital) — those are expected in prose.
92
+ // What MUST NOT appear: LOWERCASE noun-form "bet"/"bets"/possessives — that signals a
93
+ // token-rewrite miss (since resolved labels for this preset are always capital).
94
+ // Strip code fences + inline code first so legitimate `bet-XXX-short-name` etc. don't trip us.
95
+ const strippedForCheck = stripCodeSpans(stripFences(rendered));
96
+ expect(strippedForCheck, `${preset}: lowercase noun-form 'bet'/'bets' in prose = unresolved leak`)
97
+ .not.toMatch(/\bbet(s|'s|s')?\b(?!-)/);
98
+ return;
99
+ }
100
+ // For non-Shape Up presets: no "Bet" (capital) should appear in prose (it was replaced).
101
+ // Strip code fences + inline code before checking.
102
+ const strippedFences = stripFences(rendered);
103
+ const strippedAll = stripCodeSpans(strippedFences);
104
+ // Check for any remaining {{vocab:...}} already handled above.
105
+ // Check that prose noun-form "Bet" is gone (replaced by singular/plural preset label).
106
+ const betMatches = strippedAll.match(/\b[Bb]et(s|'s|s')?\b(?!-)/g) ?? [];
107
+ expect(betMatches, `${preset}: found un-resolved noun-form "bet" in prose: ${betMatches.join(', ')}`).toHaveLength(0);
108
+ }
109
+ function stripFences(text) {
110
+ // Remove code fence blocks (```...``` and ~~~~...~~~~)
111
+ return text.replace(/```[\s\S]*?```/g, ' ').replace(/~{4,}[\s\S]*?~{4,}/g, ' ');
112
+ }
113
+ function stripCodeSpans(text) {
114
+ // Remove inline backtick spans
115
+ return text.replace(/`[^`]+`/g, ' ');
116
+ }
117
+ // ── Fixture: Source file content (tokenized) loaded once ─────────────────────
118
+ const SHAPING_SRC = readSkill('shaping');
119
+ const PHASING_SRC = readSkill('phasing');
120
+ const REVIEW_SRC = readSkill('implementation-review');
121
+ // ── 3×3 tests ─────────────────────────────────────────────────────────────────
122
+ const SKILL_FIXTURES = [
123
+ { name: 'shaping', src: SHAPING_SRC },
124
+ { name: 'phasing', src: PHASING_SRC },
125
+ { name: 'implementation-review', src: REVIEW_SRC },
126
+ ];
127
+ for (const { name: skillName, src } of SKILL_FIXTURES) {
128
+ describe(`skill: ${skillName}`, () => {
129
+ for (const [presetName, ctx] of Object.entries(PRESETS)) {
130
+ it(`renders correctly under preset: ${presetName}`, () => {
131
+ const rendered = replaceVocabTokens(src, ctx);
132
+ const description = `${skillName} × ${presetName}`;
133
+ // 1. No raw {{vocab:...}} tokens survive
134
+ assertNoRawTokens(rendered, description);
135
+ // 2. Resolved content contains the workspace singular label (confirms resolution worked)
136
+ const singular = ctx.collectionLabels?.work_package?.singular ?? '';
137
+ expect(rendered, `${description}: rendered output should contain workspace singular label "${singular}"`).toContain(singular);
138
+ // 3. No un-resolved noun-form "bet" in prose (for non-Shape Up presets)
139
+ assertNoUnresolved(rendered, presetName, ctx);
140
+ });
141
+ }
142
+ });
143
+ }
144
+ // ── Additional: verify source file IS tokenized (has {{vocab:...}} tokens) ───
145
+ describe('source files are tokenized', () => {
146
+ it('shaping.md contains vocab tokens', () => {
147
+ expect(SHAPING_SRC).toContain('{{vocab:work_package.');
148
+ });
149
+ it('phasing.md contains vocab tokens', () => {
150
+ expect(PHASING_SRC).toContain('{{vocab:work_package.');
151
+ });
152
+ it('implementation-review.md contains vocab tokens', () => {
153
+ expect(REVIEW_SRC).toContain('{{vocab:work_package.');
154
+ });
155
+ });
156
+ // ── Additional: verb-form preset assertion ─────────────────────────────────────
157
+ //
158
+ // shaping.md has one verb-form token: {{vocab:work_package.verb_start}} (from "shape a bet")
159
+ // in the YAML triggers block. "ship a bet" was not literal text in any skill — so
160
+ // verb_complete tokens only appear where we explicitly test with a custom fixture.
161
+ describe('verb-form resolution across presets', () => {
162
+ it('Shape Up: verb_start resolves to "shape" (trigger line in shaping.md)', () => {
163
+ const rendered = replaceVocabTokens(SHAPING_SRC, PRESETS['Shape Up']);
164
+ // The trigger line was "- shape a bet" → "- {{vocab:work_package.verb_start}} a {{vocab:work_package.singular}}"
165
+ // After render with Shape Up: "- shape a Bet"
166
+ expect(rendered).toContain('shape a Bet');
167
+ });
168
+ it('Generic: verb_start resolves to "start" (trigger line in shaping.md)', () => {
169
+ const rendered = replaceVocabTokens(SHAPING_SRC, PRESETS['Generic']);
170
+ // After render with Generic: "- start a Initiative"
171
+ expect(rendered).toContain('start a Initiative');
172
+ });
173
+ it('Linear: verb_start resolves to "begin" (trigger line in shaping.md)', () => {
174
+ const rendered = replaceVocabTokens(SHAPING_SRC, PRESETS['Linear']);
175
+ // verb_start="begin" for Linear
176
+ // The "shape a bet" trigger → "begin a Issue"
177
+ expect(rendered).toContain('begin a Issue');
178
+ });
179
+ it('verb_complete inline fixture: each preset resolves correctly', () => {
180
+ // No "ship a bet" literal appeared in skills, so test verb_complete via an inline fixture.
181
+ const fixture = 'To {{vocab:work_package.verb_complete}} a {{vocab:work_package.singular}}, all slices must pass review.';
182
+ expect(replaceVocabTokens(fixture, PRESETS['Shape Up'])).toBe('To ship a Bet, all slices must pass review.');
183
+ expect(replaceVocabTokens(fixture, PRESETS['Generic'])).toBe('To complete a Initiative, all slices must pass review.');
184
+ expect(replaceVocabTokens(fixture, PRESETS['Linear'])).toBe('To archive a Issue, all slices must pass review.');
185
+ });
186
+ });
187
+ //# sourceMappingURL=skill-vocabulary.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill-vocabulary.test.js","sourceRoot":"","sources":["../../src/__tests__/skill-vocabulary.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=update-check.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update-check.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/update-check.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,56 @@
1
+ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
2
+ const files = new Map();
3
+ vi.mock('node:os', () => ({
4
+ homedir: () => '/mock-home',
5
+ }));
6
+ vi.mock('node:fs', async () => ({
7
+ existsSync: (path) => files.has(path),
8
+ readFileSync: (path) => files.get(path) ?? '',
9
+ writeFileSync: (path, body) => { files.set(path, body); },
10
+ mkdirSync: vi.fn(),
11
+ unlinkSync: (path) => { files.delete(path); },
12
+ }));
13
+ import { clearPendingUpgradeCache, isNewer, recordServerLatest, readCachedLatestVersion, writeUpgradePendingSentinel, } from '../lib/update-check.js';
14
+ import { setOutputMode } from '../lib/runner.js';
15
+ describe('update-check', () => {
16
+ const originalEnv = { ...process.env };
17
+ beforeEach(() => {
18
+ files.clear();
19
+ process.env = { ...originalEnv };
20
+ setOutputMode('auto');
21
+ vi.clearAllMocks();
22
+ });
23
+ afterEach(() => {
24
+ process.env = { ...originalEnv };
25
+ setOutputMode('auto');
26
+ vi.restoreAllMocks();
27
+ });
28
+ it('compares prerelease channels by alpha < beta < rc < release', () => {
29
+ expect(isNewer('0.1.0-beta.32', '0.1.0-beta.108')).toBe(true);
30
+ expect(isNewer('0.1.0-beta.5', '0.1.0-rc.1')).toBe(true);
31
+ expect(isNewer('0.1.0-rc.1', '0.1.0-beta.5')).toBe(false);
32
+ expect(isNewer('0.1.0-rc.1', '0.1.0')).toBe(true);
33
+ });
34
+ it('recordServerLatest updates cache silently in JSON mode', () => {
35
+ setOutputMode('json');
36
+ const stderrSpy = vi.spyOn(process.stderr, 'write').mockImplementation(() => true);
37
+ recordServerLatest('0.1.0-beta.109');
38
+ expect(readCachedLatestVersion()).toBe('0.1.0-beta.109');
39
+ expect(stderrSpy).not.toHaveBeenCalled();
40
+ });
41
+ it('PB_NO_VERSION_CHECK disables cache writes and output', () => {
42
+ process.env.PB_NO_VERSION_CHECK = '1';
43
+ const stderrSpy = vi.spyOn(process.stderr, 'write').mockImplementation(() => true);
44
+ recordServerLatest('0.1.0-beta.109');
45
+ expect(readCachedLatestVersion()).toBeNull();
46
+ expect(stderrSpy).not.toHaveBeenCalled();
47
+ });
48
+ it('next startup clears upgrade sentinel and stale update cache', () => {
49
+ recordServerLatest('0.1.0-beta.109');
50
+ expect(readCachedLatestVersion()).toBe('0.1.0-beta.109');
51
+ writeUpgradePendingSentinel();
52
+ clearPendingUpgradeCache();
53
+ expect(readCachedLatestVersion()).toBeNull();
54
+ });
55
+ });
56
+ //# sourceMappingURL=update-check.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update-check.test.js","sourceRoot":"","sources":["../../src/__tests__/update-check.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=upgrade-runner.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upgrade-runner.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/upgrade-runner.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,42 @@
1
+ import { EventEmitter } from 'node:events';
2
+ import { describe, expect, it, vi, beforeEach } from 'vitest';
3
+ const spawnMock = vi.fn();
4
+ vi.mock('node:child_process', () => ({
5
+ spawn: (...args) => spawnMock(...args),
6
+ }));
7
+ vi.mock('../lib/telemetry.js', () => ({
8
+ trackEvent: vi.fn(),
9
+ }));
10
+ vi.mock('../lib/update-check.js', () => ({
11
+ writeUpgradePendingSentinel: vi.fn(),
12
+ }));
13
+ import { CLIError, ErrorCode } from '../lib/errors.js';
14
+ import { buildUpgradeCommand, detectInstallChannel, spawnUpgrade } from '../lib/upgrade-runner.js';
15
+ describe('upgrade-runner', () => {
16
+ beforeEach(() => {
17
+ spawnMock.mockReset();
18
+ });
19
+ it('detects package-manager channels from execPath fixtures', () => {
20
+ expect(detectInstallChannel('/Users/r/.local/share/pnpm/node', {})).toBe('pnpm');
21
+ expect(detectInstallChannel('/opt/yarn/bin/node', {})).toBe('yarn');
22
+ expect(detectInstallChannel('/Users/r/.bun/bin/bun', {})).toBe('bun');
23
+ expect(detectInstallChannel('/opt/homebrew/Cellar/node/25/bin/node', {})).toBe('brew');
24
+ expect(detectInstallChannel('/usr/local/lib/node_modules/npm/bin/node', {})).toBe('npm');
25
+ });
26
+ it('builds beta upgrade commands instead of @latest', () => {
27
+ expect(buildUpgradeCommand('npm').display).toBe('npm install -g @productbrain/cli@beta');
28
+ expect(buildUpgradeCommand('unknown').display).toBe('npm install -g @productbrain/cli@beta');
29
+ expect(buildUpgradeCommand('pnpm').args).toEqual(['add', '-g', '@productbrain/cli@beta']);
30
+ });
31
+ it('throws UPGRADE_FAILED on spawn failure', async () => {
32
+ const child = new EventEmitter();
33
+ child.stdout = new EventEmitter();
34
+ child.stderr = new EventEmitter();
35
+ spawnMock.mockReturnValue(child);
36
+ const promise = spawnUpgrade('npm');
37
+ child.emit('error', Object.assign(new Error('spawn npm ENOENT'), { code: 'ENOENT' }));
38
+ await expect(promise).rejects.toBeInstanceOf(CLIError);
39
+ await expect(promise).rejects.toMatchObject({ code: ErrorCode.UPGRADE_FAILED });
40
+ });
41
+ });
42
+ //# sourceMappingURL=upgrade-runner.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upgrade-runner.test.js","sourceRoot":"","sources":["../../src/__tests__/upgrade-runner.test.ts"],"names":[],"mappings":"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"}