beth-copilot 1.0.18 → 2.0.0

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 (429) hide show
  1. package/CHANGELOG.md +79 -28
  2. package/README.md +127 -298
  3. package/assets/beth-questioning.png +0 -0
  4. package/assets/yellowstone-beth.png +0 -0
  5. package/bin/cli.js +124 -715
  6. package/dist/__tests__/inject-skills.test.d.ts +9 -0
  7. package/dist/__tests__/inject-skills.test.d.ts.map +1 -0
  8. package/dist/__tests__/inject-skills.test.js +143 -0
  9. package/dist/__tests__/inject-skills.test.js.map +1 -0
  10. package/dist/__tests__/skills/disambiguation.test.d.ts +10 -0
  11. package/dist/__tests__/skills/disambiguation.test.d.ts.map +1 -0
  12. package/dist/__tests__/skills/disambiguation.test.js +192 -0
  13. package/dist/__tests__/skills/disambiguation.test.js.map +1 -0
  14. package/dist/__tests__/skills/hook-injection.test.d.ts +11 -0
  15. package/dist/__tests__/skills/hook-injection.test.d.ts.map +1 -0
  16. package/dist/__tests__/skills/hook-injection.test.js +173 -0
  17. package/dist/__tests__/skills/hook-injection.test.js.map +1 -0
  18. package/dist/__tests__/skills/mapping-completeness.test.d.ts +17 -0
  19. package/dist/__tests__/skills/mapping-completeness.test.d.ts.map +1 -0
  20. package/dist/__tests__/skills/mapping-completeness.test.js +281 -0
  21. package/dist/__tests__/skills/mapping-completeness.test.js.map +1 -0
  22. package/dist/__tests__/skills/pipeline-integration.test.d.ts +18 -0
  23. package/dist/__tests__/skills/pipeline-integration.test.d.ts.map +1 -0
  24. package/dist/__tests__/skills/pipeline-integration.test.js +234 -0
  25. package/dist/__tests__/skills/pipeline-integration.test.js.map +1 -0
  26. package/dist/__tests__/skills/skill-routing.test.d.ts +15 -0
  27. package/dist/__tests__/skills/skill-routing.test.d.ts.map +1 -0
  28. package/dist/__tests__/skills/skill-routing.test.js +723 -0
  29. package/dist/__tests__/skills/skill-routing.test.js.map +1 -0
  30. package/dist/__tests__/skills/trigger-coverage.test.d.ts +24 -0
  31. package/dist/__tests__/skills/trigger-coverage.test.d.ts.map +1 -0
  32. package/dist/__tests__/skills/trigger-coverage.test.js +746 -0
  33. package/dist/__tests__/skills/trigger-coverage.test.js.map +1 -0
  34. package/dist/__tests__/smoke.test.d.ts +8 -0
  35. package/dist/__tests__/smoke.test.d.ts.map +1 -0
  36. package/dist/__tests__/smoke.test.js +62 -0
  37. package/dist/__tests__/smoke.test.js.map +1 -0
  38. package/dist/__tests__/verify-skills.test.d.ts +9 -0
  39. package/dist/__tests__/verify-skills.test.d.ts.map +1 -0
  40. package/dist/__tests__/verify-skills.test.js +78 -0
  41. package/dist/__tests__/verify-skills.test.js.map +1 -0
  42. package/dist/cli/commands/beads.e2e.test.d.ts +15 -0
  43. package/dist/cli/commands/beads.e2e.test.d.ts.map +1 -0
  44. package/dist/cli/commands/beads.e2e.test.js +585 -0
  45. package/dist/cli/commands/beads.e2e.test.js.map +1 -0
  46. package/dist/cli/commands/cli-edge-cases.e2e.test.d.ts +32 -0
  47. package/dist/cli/commands/cli-edge-cases.e2e.test.d.ts.map +1 -0
  48. package/dist/cli/commands/cli-edge-cases.e2e.test.js +162 -0
  49. package/dist/cli/commands/cli-edge-cases.e2e.test.js.map +1 -0
  50. package/dist/cli/commands/close.d.ts +54 -0
  51. package/dist/cli/commands/close.d.ts.map +1 -0
  52. package/dist/cli/commands/close.e2e.test.d.ts +11 -0
  53. package/dist/cli/commands/close.e2e.test.d.ts.map +1 -0
  54. package/dist/cli/commands/close.e2e.test.js +71 -0
  55. package/dist/cli/commands/close.e2e.test.js.map +1 -0
  56. package/dist/cli/commands/close.js +95 -0
  57. package/dist/cli/commands/close.js.map +1 -0
  58. package/dist/cli/commands/close.test.d.ts +13 -0
  59. package/dist/cli/commands/close.test.d.ts.map +1 -0
  60. package/dist/cli/commands/close.test.js +254 -0
  61. package/dist/cli/commands/close.test.js.map +1 -0
  62. package/dist/cli/commands/doctor.d.ts +7 -1
  63. package/dist/cli/commands/doctor.d.ts.map +1 -1
  64. package/dist/cli/commands/doctor.e2e.test.js +3 -59
  65. package/dist/cli/commands/doctor.e2e.test.js.map +1 -1
  66. package/dist/cli/commands/doctor.js +38 -18
  67. package/dist/cli/commands/doctor.js.map +1 -1
  68. package/dist/cli/commands/doctor.test.js +32 -25
  69. package/dist/cli/commands/doctor.test.js.map +1 -1
  70. package/dist/cli/commands/framework-isolation.test.d.ts +30 -0
  71. package/dist/cli/commands/framework-isolation.test.d.ts.map +1 -0
  72. package/dist/cli/commands/framework-isolation.test.js +118 -0
  73. package/dist/cli/commands/framework-isolation.test.js.map +1 -0
  74. package/dist/cli/commands/help.e2e.test.js +5 -9
  75. package/dist/cli/commands/help.e2e.test.js.map +1 -1
  76. package/dist/cli/commands/init-logic.e2e.test.d.ts +37 -0
  77. package/dist/cli/commands/init-logic.e2e.test.d.ts.map +1 -0
  78. package/dist/cli/commands/init-logic.e2e.test.js +315 -0
  79. package/dist/cli/commands/init-logic.e2e.test.js.map +1 -0
  80. package/dist/cli/commands/init.test.js +4 -21
  81. package/dist/cli/commands/init.test.js.map +1 -1
  82. package/dist/cli/commands/land.d.ts +130 -0
  83. package/dist/cli/commands/land.d.ts.map +1 -0
  84. package/dist/cli/commands/land.js +592 -0
  85. package/dist/cli/commands/land.js.map +1 -0
  86. package/dist/cli/commands/land.test.d.ts +19 -0
  87. package/dist/cli/commands/land.test.d.ts.map +1 -0
  88. package/dist/cli/commands/land.test.js +567 -0
  89. package/dist/cli/commands/land.test.js.map +1 -0
  90. package/dist/cli/commands/mcp.e2e.test.js +24 -31
  91. package/dist/cli/commands/mcp.e2e.test.js.map +1 -1
  92. package/dist/cli/commands/pipeline.e2e.test.js +28 -31
  93. package/dist/cli/commands/pipeline.e2e.test.js.map +1 -1
  94. package/dist/cli/commands/pre-push-guard.d.ts +74 -0
  95. package/dist/cli/commands/pre-push-guard.d.ts.map +1 -0
  96. package/dist/cli/commands/pre-push-guard.e2e.test.d.ts +24 -0
  97. package/dist/cli/commands/pre-push-guard.e2e.test.d.ts.map +1 -0
  98. package/dist/cli/commands/pre-push-guard.e2e.test.js +171 -0
  99. package/dist/cli/commands/pre-push-guard.e2e.test.js.map +1 -0
  100. package/dist/cli/commands/pre-push-guard.js +212 -0
  101. package/dist/cli/commands/pre-push-guard.js.map +1 -0
  102. package/dist/cli/commands/pre-push-guard.test.d.ts +14 -0
  103. package/dist/cli/commands/pre-push-guard.test.d.ts.map +1 -0
  104. package/dist/cli/commands/pre-push-guard.test.js +314 -0
  105. package/dist/cli/commands/pre-push-guard.test.js.map +1 -0
  106. package/dist/cli/commands/quickstart-expanded.e2e.test.d.ts +23 -0
  107. package/dist/cli/commands/quickstart-expanded.e2e.test.d.ts.map +1 -0
  108. package/dist/cli/commands/quickstart-expanded.e2e.test.js +152 -0
  109. package/dist/cli/commands/quickstart-expanded.e2e.test.js.map +1 -0
  110. package/dist/cli/commands/quickstart.d.ts +0 -1
  111. package/dist/cli/commands/quickstart.d.ts.map +1 -1
  112. package/dist/cli/commands/quickstart.js +9 -83
  113. package/dist/cli/commands/quickstart.js.map +1 -1
  114. package/dist/cli/commands/quickstart.test.js +8 -129
  115. package/dist/cli/commands/quickstart.test.js.map +1 -1
  116. package/dist/cli/commands/update.d.ts +35 -0
  117. package/dist/cli/commands/update.d.ts.map +1 -0
  118. package/dist/cli/commands/update.e2e.test.d.ts +24 -0
  119. package/dist/cli/commands/update.e2e.test.d.ts.map +1 -0
  120. package/dist/cli/commands/update.e2e.test.js +240 -0
  121. package/dist/cli/commands/update.e2e.test.js.map +1 -0
  122. package/dist/cli/commands/update.js +255 -0
  123. package/dist/cli/commands/update.js.map +1 -0
  124. package/dist/core/agents/frontmatter.test.js +1 -1
  125. package/dist/core/agents/frontmatter.test.js.map +1 -1
  126. package/dist/core/agents/handoffs.test.js +1 -1
  127. package/dist/core/agents/handoffs.test.js.map +1 -1
  128. package/dist/core/agents/loader.d.ts +4 -2
  129. package/dist/core/agents/loader.d.ts.map +1 -1
  130. package/dist/core/agents/loader.js +5 -3
  131. package/dist/core/agents/loader.js.map +1 -1
  132. package/dist/core/agents/loader.test.js +42 -4
  133. package/dist/core/agents/loader.test.js.map +1 -1
  134. package/dist/core/agents/suite.test.js +12 -9
  135. package/dist/core/agents/suite.test.js.map +1 -1
  136. package/dist/core/agents/tools.test.js +15 -9
  137. package/dist/core/agents/tools.test.js.map +1 -1
  138. package/dist/core/agents/types.test.js +1 -1
  139. package/dist/core/agents/types.test.js.map +1 -1
  140. package/dist/core/skills/loader.test.js +1 -1
  141. package/dist/core/skills/loader.test.js.map +1 -1
  142. package/dist/index.d.ts +3 -11
  143. package/dist/index.d.ts.map +1 -1
  144. package/dist/index.js +5 -12
  145. package/dist/index.js.map +1 -1
  146. package/dist/lib/pathValidation.d.ts +0 -5
  147. package/dist/lib/pathValidation.d.ts.map +1 -1
  148. package/dist/lib/pathValidation.js +0 -11
  149. package/dist/lib/pathValidation.js.map +1 -1
  150. package/dist/lib/pathValidation.test.js +2 -14
  151. package/dist/lib/pathValidation.test.js.map +1 -1
  152. package/package.json +13 -10
  153. package/sbom.json +1927 -847
  154. package/templates/.github/agents/beth.agent.md +331 -105
  155. package/templates/.github/agents/developer.agent.md +73 -102
  156. package/templates/.github/agents/product-manager.agent.md +24 -68
  157. package/templates/.github/agents/researcher.agent.md +21 -69
  158. package/templates/.github/agents/security-reviewer.agent.md +39 -82
  159. package/templates/.github/agents/tester.agent.md +44 -65
  160. package/templates/.github/agents/ux-designer.agent.md +25 -76
  161. package/templates/.github/copilot-instructions.md +246 -225
  162. package/templates/.github/copilot-mcp-config.json +12 -0
  163. package/templates/.github/dependabot.yml +68 -0
  164. package/templates/.github/hooks/scripts/inject-skills.mjs +139 -0
  165. package/templates/.github/hooks/scripts/verify-skills.mjs +47 -0
  166. package/templates/.github/hooks/skill-enforcement.json +18 -0
  167. package/templates/.github/pull_request_template.md +48 -0
  168. package/templates/.github/skills/framer-components/SKILL.md +0 -0
  169. package/templates/.github/skills/prd/SKILL.md +0 -0
  170. package/templates/.github/skills/security-analysis/SKILL.md +798 -798
  171. package/templates/.github/skills/shadcn-ui/SKILL.md +561 -561
  172. package/templates/.github/skills/vercel-react-best-practices/AGENTS.md +0 -0
  173. package/templates/.github/skills/vercel-react-best-practices/SKILL.md +0 -0
  174. package/templates/.github/skills/vercel-react-best-practices/rules/advanced-event-handler-refs.md +0 -0
  175. package/templates/.github/skills/vercel-react-best-practices/rules/advanced-use-latest.md +0 -0
  176. package/templates/.github/skills/vercel-react-best-practices/rules/async-api-routes.md +0 -0
  177. package/templates/.github/skills/vercel-react-best-practices/rules/async-defer-await.md +0 -0
  178. package/templates/.github/skills/vercel-react-best-practices/rules/async-dependencies.md +0 -0
  179. package/templates/.github/skills/vercel-react-best-practices/rules/async-parallel.md +0 -0
  180. package/templates/.github/skills/vercel-react-best-practices/rules/async-suspense-boundaries.md +0 -0
  181. package/templates/.github/skills/vercel-react-best-practices/rules/bundle-barrel-imports.md +0 -0
  182. package/templates/.github/skills/vercel-react-best-practices/rules/bundle-conditional.md +0 -0
  183. package/templates/.github/skills/vercel-react-best-practices/rules/bundle-defer-third-party.md +0 -0
  184. package/templates/.github/skills/vercel-react-best-practices/rules/bundle-dynamic-imports.md +0 -0
  185. package/templates/.github/skills/vercel-react-best-practices/rules/bundle-preload.md +0 -0
  186. package/templates/.github/skills/vercel-react-best-practices/rules/client-event-listeners.md +0 -0
  187. package/templates/.github/skills/vercel-react-best-practices/rules/client-localstorage-schema.md +0 -0
  188. package/templates/.github/skills/vercel-react-best-practices/rules/client-passive-event-listeners.md +0 -0
  189. package/templates/.github/skills/vercel-react-best-practices/rules/client-swr-dedup.md +0 -0
  190. package/templates/.github/skills/vercel-react-best-practices/rules/js-batch-dom-css.md +0 -0
  191. package/templates/.github/skills/vercel-react-best-practices/rules/js-cache-function-results.md +0 -0
  192. package/templates/.github/skills/vercel-react-best-practices/rules/js-cache-property-access.md +0 -0
  193. package/templates/.github/skills/vercel-react-best-practices/rules/js-cache-storage.md +0 -0
  194. package/templates/.github/skills/vercel-react-best-practices/rules/js-combine-iterations.md +0 -0
  195. package/templates/.github/skills/vercel-react-best-practices/rules/js-early-exit.md +0 -0
  196. package/templates/.github/skills/vercel-react-best-practices/rules/js-hoist-regexp.md +0 -0
  197. package/templates/.github/skills/vercel-react-best-practices/rules/js-index-maps.md +0 -0
  198. package/templates/.github/skills/vercel-react-best-practices/rules/js-length-check-first.md +0 -0
  199. package/templates/.github/skills/vercel-react-best-practices/rules/js-min-max-loop.md +0 -0
  200. package/templates/.github/skills/vercel-react-best-practices/rules/js-set-map-lookups.md +0 -0
  201. package/templates/.github/skills/vercel-react-best-practices/rules/js-tosorted-immutable.md +0 -0
  202. package/templates/.github/skills/vercel-react-best-practices/rules/rendering-activity.md +0 -0
  203. package/templates/.github/skills/vercel-react-best-practices/rules/rendering-animate-svg-wrapper.md +0 -0
  204. package/templates/.github/skills/vercel-react-best-practices/rules/rendering-conditional-render.md +0 -0
  205. package/templates/.github/skills/vercel-react-best-practices/rules/rendering-content-visibility.md +0 -0
  206. package/templates/.github/skills/vercel-react-best-practices/rules/rendering-hoist-jsx.md +0 -0
  207. package/templates/.github/skills/vercel-react-best-practices/rules/rendering-hydration-no-flicker.md +0 -0
  208. package/templates/.github/skills/vercel-react-best-practices/rules/rendering-svg-precision.md +0 -0
  209. package/templates/.github/skills/vercel-react-best-practices/rules/rerender-defer-reads.md +0 -0
  210. package/templates/.github/skills/vercel-react-best-practices/rules/rerender-dependencies.md +0 -0
  211. package/templates/.github/skills/vercel-react-best-practices/rules/rerender-derived-state.md +0 -0
  212. package/templates/.github/skills/vercel-react-best-practices/rules/rerender-functional-setstate.md +0 -0
  213. package/templates/.github/skills/vercel-react-best-practices/rules/rerender-lazy-state-init.md +0 -0
  214. package/templates/.github/skills/vercel-react-best-practices/rules/rerender-memo.md +0 -0
  215. package/templates/.github/skills/vercel-react-best-practices/rules/rerender-simple-expression-in-memo.md +0 -0
  216. package/templates/.github/skills/vercel-react-best-practices/rules/rerender-transitions.md +0 -0
  217. package/templates/.github/skills/vercel-react-best-practices/rules/server-after-nonblocking.md +0 -0
  218. package/templates/.github/skills/vercel-react-best-practices/rules/server-auth-actions.md +0 -0
  219. package/templates/.github/skills/vercel-react-best-practices/rules/server-cache-lru.md +0 -0
  220. package/templates/.github/skills/vercel-react-best-practices/rules/server-cache-react.md +0 -0
  221. package/templates/.github/skills/vercel-react-best-practices/rules/server-dedup-props.md +0 -0
  222. package/templates/.github/skills/vercel-react-best-practices/rules/server-parallel-fetching.md +0 -0
  223. package/templates/.github/skills/vercel-react-best-practices/rules/server-serialization.md +0 -0
  224. package/templates/.github/skills/web-design-guidelines/SKILL.md +0 -0
  225. package/templates/.vscode/settings.json +16 -16
  226. package/templates/AGENTS.md +103 -54
  227. package/templates/Backlog.md +80 -80
  228. package/templates/mcp.json.example +0 -3
  229. package/assets/beth-portrait-small.txt +0 -13
  230. package/assets/beth-portrait.txt +0 -60
  231. package/bin/beth-animation.sh +0 -155
  232. package/bin/lib/animation.js +0 -189
  233. package/bin/lib/pathValidation.js +0 -233
  234. package/bin/lib/pathValidation.test.js +0 -280
  235. package/dist/cli/commands/client-config.d.ts +0 -31
  236. package/dist/cli/commands/client-config.d.ts.map +0 -1
  237. package/dist/cli/commands/client-config.e2e.test.d.ts +0 -15
  238. package/dist/cli/commands/client-config.e2e.test.d.ts.map +0 -1
  239. package/dist/cli/commands/client-config.e2e.test.js +0 -556
  240. package/dist/cli/commands/client-config.e2e.test.js.map +0 -1
  241. package/dist/cli/commands/client-config.js +0 -73
  242. package/dist/cli/commands/client-config.js.map +0 -1
  243. package/dist/cli/commands/client-config.test.d.ts +0 -6
  244. package/dist/cli/commands/client-config.test.d.ts.map +0 -1
  245. package/dist/cli/commands/client-config.test.js +0 -133
  246. package/dist/cli/commands/client-config.test.js.map +0 -1
  247. package/dist/cli/commands/init-quickstart.e2e.test.d.ts +0 -11
  248. package/dist/cli/commands/init-quickstart.e2e.test.d.ts.map +0 -1
  249. package/dist/cli/commands/init-quickstart.e2e.test.js +0 -221
  250. package/dist/cli/commands/init-quickstart.e2e.test.js.map +0 -1
  251. package/dist/core/context.d.ts +0 -171
  252. package/dist/core/context.d.ts.map +0 -1
  253. package/dist/core/context.js +0 -353
  254. package/dist/core/context.js.map +0 -1
  255. package/dist/core/context.test.d.ts +0 -8
  256. package/dist/core/context.test.d.ts.map +0 -1
  257. package/dist/core/context.test.js +0 -253
  258. package/dist/core/context.test.js.map +0 -1
  259. package/dist/core/handoffs.d.ts +0 -151
  260. package/dist/core/handoffs.d.ts.map +0 -1
  261. package/dist/core/handoffs.js +0 -220
  262. package/dist/core/handoffs.js.map +0 -1
  263. package/dist/core/handoffs.test.d.ts +0 -8
  264. package/dist/core/handoffs.test.d.ts.map +0 -1
  265. package/dist/core/handoffs.test.js +0 -231
  266. package/dist/core/handoffs.test.js.map +0 -1
  267. package/dist/core/orchestrator.d.ts +0 -246
  268. package/dist/core/orchestrator.d.ts.map +0 -1
  269. package/dist/core/orchestrator.js +0 -514
  270. package/dist/core/orchestrator.js.map +0 -1
  271. package/dist/core/orchestrator.test.d.ts +0 -8
  272. package/dist/core/orchestrator.test.d.ts.map +0 -1
  273. package/dist/core/orchestrator.test.js +0 -517
  274. package/dist/core/orchestrator.test.js.map +0 -1
  275. package/dist/core/router.d.ts +0 -102
  276. package/dist/core/router.d.ts.map +0 -1
  277. package/dist/core/router.js +0 -178
  278. package/dist/core/router.js.map +0 -1
  279. package/dist/core/router.test.d.ts +0 -8
  280. package/dist/core/router.test.d.ts.map +0 -1
  281. package/dist/core/router.test.js +0 -215
  282. package/dist/core/router.test.js.map +0 -1
  283. package/dist/init.test.js +0 -288
  284. package/dist/providers/azure.d.ts +0 -147
  285. package/dist/providers/azure.d.ts.map +0 -1
  286. package/dist/providers/azure.js +0 -491
  287. package/dist/providers/azure.js.map +0 -1
  288. package/dist/providers/azure.test.d.ts +0 -11
  289. package/dist/providers/azure.test.d.ts.map +0 -1
  290. package/dist/providers/azure.test.js +0 -330
  291. package/dist/providers/azure.test.js.map +0 -1
  292. package/dist/providers/config.d.ts +0 -87
  293. package/dist/providers/config.d.ts.map +0 -1
  294. package/dist/providers/config.js +0 -193
  295. package/dist/providers/config.js.map +0 -1
  296. package/dist/providers/config.test.d.ts +0 -7
  297. package/dist/providers/config.test.d.ts.map +0 -1
  298. package/dist/providers/config.test.js +0 -370
  299. package/dist/providers/config.test.js.map +0 -1
  300. package/dist/providers/index.d.ts +0 -18
  301. package/dist/providers/index.d.ts.map +0 -1
  302. package/dist/providers/index.js +0 -14
  303. package/dist/providers/index.js.map +0 -1
  304. package/dist/providers/interface.d.ts +0 -191
  305. package/dist/providers/interface.d.ts.map +0 -1
  306. package/dist/providers/interface.js +0 -94
  307. package/dist/providers/interface.js.map +0 -1
  308. package/dist/providers/retry.d.ts +0 -128
  309. package/dist/providers/retry.d.ts.map +0 -1
  310. package/dist/providers/retry.js +0 -205
  311. package/dist/providers/retry.js.map +0 -1
  312. package/dist/providers/retry.test.d.ts +0 -7
  313. package/dist/providers/retry.test.d.ts.map +0 -1
  314. package/dist/providers/retry.test.js +0 -439
  315. package/dist/providers/retry.test.js.map +0 -1
  316. package/dist/providers/streaming.d.ts +0 -157
  317. package/dist/providers/streaming.d.ts.map +0 -1
  318. package/dist/providers/streaming.js +0 -233
  319. package/dist/providers/streaming.js.map +0 -1
  320. package/dist/providers/streaming.test.d.ts +0 -7
  321. package/dist/providers/streaming.test.d.ts.map +0 -1
  322. package/dist/providers/streaming.test.js +0 -372
  323. package/dist/providers/streaming.test.js.map +0 -1
  324. package/dist/providers/types.d.ts +0 -209
  325. package/dist/providers/types.d.ts.map +0 -1
  326. package/dist/providers/types.js +0 -53
  327. package/dist/providers/types.js.map +0 -1
  328. package/dist/providers/types.test.d.ts +0 -7
  329. package/dist/providers/types.test.d.ts.map +0 -1
  330. package/dist/providers/types.test.js +0 -141
  331. package/dist/providers/types.test.js.map +0 -1
  332. package/dist/tools/cli/beads.d.ts +0 -27
  333. package/dist/tools/cli/beads.d.ts.map +0 -1
  334. package/dist/tools/cli/beads.js +0 -172
  335. package/dist/tools/cli/beads.js.map +0 -1
  336. package/dist/tools/cli/beads.test.d.ts +0 -8
  337. package/dist/tools/cli/beads.test.d.ts.map +0 -1
  338. package/dist/tools/cli/beads.test.js +0 -264
  339. package/dist/tools/cli/beads.test.js.map +0 -1
  340. package/dist/tools/cli/editFile.d.ts +0 -17
  341. package/dist/tools/cli/editFile.d.ts.map +0 -1
  342. package/dist/tools/cli/editFile.js +0 -125
  343. package/dist/tools/cli/editFile.js.map +0 -1
  344. package/dist/tools/cli/editFile.test.d.ts +0 -8
  345. package/dist/tools/cli/editFile.test.d.ts.map +0 -1
  346. package/dist/tools/cli/editFile.test.js +0 -177
  347. package/dist/tools/cli/editFile.test.js.map +0 -1
  348. package/dist/tools/cli/readFile.d.ts +0 -25
  349. package/dist/tools/cli/readFile.d.ts.map +0 -1
  350. package/dist/tools/cli/readFile.js +0 -118
  351. package/dist/tools/cli/readFile.js.map +0 -1
  352. package/dist/tools/cli/readFile.test.d.ts +0 -8
  353. package/dist/tools/cli/readFile.test.d.ts.map +0 -1
  354. package/dist/tools/cli/readFile.test.js +0 -194
  355. package/dist/tools/cli/readFile.test.js.map +0 -1
  356. package/dist/tools/cli/search.d.ts +0 -16
  357. package/dist/tools/cli/search.d.ts.map +0 -1
  358. package/dist/tools/cli/search.js +0 -261
  359. package/dist/tools/cli/search.js.map +0 -1
  360. package/dist/tools/cli/search.test.d.ts +0 -8
  361. package/dist/tools/cli/search.test.d.ts.map +0 -1
  362. package/dist/tools/cli/search.test.js +0 -172
  363. package/dist/tools/cli/search.test.js.map +0 -1
  364. package/dist/tools/cli/subagent.d.ts +0 -43
  365. package/dist/tools/cli/subagent.d.ts.map +0 -1
  366. package/dist/tools/cli/subagent.js +0 -99
  367. package/dist/tools/cli/subagent.js.map +0 -1
  368. package/dist/tools/cli/subagent.test.d.ts +0 -8
  369. package/dist/tools/cli/subagent.test.d.ts.map +0 -1
  370. package/dist/tools/cli/subagent.test.js +0 -190
  371. package/dist/tools/cli/subagent.test.js.map +0 -1
  372. package/dist/tools/cli/terminal.d.ts +0 -19
  373. package/dist/tools/cli/terminal.d.ts.map +0 -1
  374. package/dist/tools/cli/terminal.js +0 -164
  375. package/dist/tools/cli/terminal.js.map +0 -1
  376. package/dist/tools/cli/terminal.test.d.ts +0 -8
  377. package/dist/tools/cli/terminal.test.d.ts.map +0 -1
  378. package/dist/tools/cli/terminal.test.js +0 -161
  379. package/dist/tools/cli/terminal.test.js.map +0 -1
  380. package/dist/tools/index.d.ts +0 -25
  381. package/dist/tools/index.d.ts.map +0 -1
  382. package/dist/tools/index.js +0 -41
  383. package/dist/tools/index.js.map +0 -1
  384. package/dist/tools/interface.d.ts +0 -64
  385. package/dist/tools/interface.d.ts.map +0 -1
  386. package/dist/tools/interface.js +0 -37
  387. package/dist/tools/interface.js.map +0 -1
  388. package/dist/tools/interface.test.d.ts +0 -7
  389. package/dist/tools/interface.test.d.ts.map +0 -1
  390. package/dist/tools/interface.test.js +0 -179
  391. package/dist/tools/interface.test.js.map +0 -1
  392. package/dist/tools/mcp/bridge.d.ts +0 -48
  393. package/dist/tools/mcp/bridge.d.ts.map +0 -1
  394. package/dist/tools/mcp/bridge.js +0 -128
  395. package/dist/tools/mcp/bridge.js.map +0 -1
  396. package/dist/tools/mcp/bridge.test.d.ts +0 -8
  397. package/dist/tools/mcp/bridge.test.d.ts.map +0 -1
  398. package/dist/tools/mcp/bridge.test.js +0 -300
  399. package/dist/tools/mcp/bridge.test.js.map +0 -1
  400. package/dist/tools/mcp/client.d.ts +0 -135
  401. package/dist/tools/mcp/client.d.ts.map +0 -1
  402. package/dist/tools/mcp/client.js +0 -263
  403. package/dist/tools/mcp/client.js.map +0 -1
  404. package/dist/tools/mcp/client.test.d.ts +0 -8
  405. package/dist/tools/mcp/client.test.d.ts.map +0 -1
  406. package/dist/tools/mcp/client.test.js +0 -390
  407. package/dist/tools/mcp/client.test.js.map +0 -1
  408. package/dist/tools/registry.d.ts +0 -82
  409. package/dist/tools/registry.d.ts.map +0 -1
  410. package/dist/tools/registry.js +0 -99
  411. package/dist/tools/registry.js.map +0 -1
  412. package/dist/tools/registry.test.d.ts +0 -7
  413. package/dist/tools/registry.test.d.ts.map +0 -1
  414. package/dist/tools/registry.test.js +0 -199
  415. package/dist/tools/registry.test.js.map +0 -1
  416. package/dist/tools/suite.test.d.ts +0 -11
  417. package/dist/tools/suite.test.d.ts.map +0 -1
  418. package/dist/tools/suite.test.js +0 -119
  419. package/dist/tools/suite.test.js.map +0 -1
  420. package/dist/tools/types.d.ts +0 -75
  421. package/dist/tools/types.d.ts.map +0 -1
  422. package/dist/tools/types.js +0 -30
  423. package/dist/tools/types.js.map +0 -1
  424. package/dist/tools/types.test.d.ts +0 -7
  425. package/dist/tools/types.test.d.ts.map +0 -1
  426. package/dist/tools/types.test.js +0 -178
  427. package/dist/tools/types.test.js.map +0 -1
  428. package/templates/.vscode/mcp.json +0 -20
  429. package/templates/CLAUDE.md +0 -129
@@ -0,0 +1,723 @@
1
+ /**
2
+ * Skill Routing Tests — Categories 2–10
3
+ *
4
+ * Verifies every skill in the test matrix:
5
+ * 1. Has a valid SKILL.md file on disk (exists and is non-empty)
6
+ * 2. Is mapped to a valid agent from the Beth team
7
+ *
8
+ * These tests validate the structural integrity of the skill system.
9
+ * They do NOT test LLM prompt inference or enforcement mechanisms
10
+ * (hook injection is tested in hook-injection.test.ts).
11
+ *
12
+ * Test plan reference: docs/E2E-SKILL-TESTS.md — Categories 2–10 (tests 10–72)
13
+ */
14
+ import { describe, it, expect } from 'vitest';
15
+ import { join } from 'node:path';
16
+ import { existsSync, readFileSync } from 'node:fs';
17
+ const PROJECT_ROOT = process.cwd();
18
+ const SKILLS_DIR = join(PROJECT_ROOT, '.github/skills');
19
+ const EXTERNAL_SKILLS_DIR = join(process.env.HOME || '~', '.agents/skills');
20
+ // ─── Helpers ───────────────────────────────────────────────────────────────
21
+ function skillExists(test) {
22
+ if (test.external) {
23
+ return existsSync(test.skillPath);
24
+ }
25
+ return existsSync(join(PROJECT_ROOT, test.skillPath));
26
+ }
27
+ function readSkillContent(test) {
28
+ const fullPath = test.external ? test.skillPath : join(PROJECT_ROOT, test.skillPath);
29
+ return readFileSync(fullPath, 'utf8');
30
+ }
31
+ // Valid agents that Beth can route to
32
+ const VALID_AGENTS = [
33
+ 'Beth',
34
+ 'developer',
35
+ 'product-manager',
36
+ 'ux-designer',
37
+ 'security-reviewer',
38
+ 'tester',
39
+ 'researcher',
40
+ ];
41
+ // ─── Category 2: Azure Skills (tests 10–31) ───────────────────────────────
42
+ const AZURE_SKILLS = [
43
+ {
44
+ id: 10,
45
+ skill: 'azure-prepare',
46
+ skillPath: '.github/skills/azure-prepare/SKILL.md',
47
+ agent: 'developer',
48
+ testPrompt: 'Create a new containerized Node.js app and deploy it to Azure Container Apps',
49
+ },
50
+ {
51
+ id: 11,
52
+ skill: 'azure-validate',
53
+ skillPath: '.github/skills/azure-validate/SKILL.md',
54
+ agent: 'developer',
55
+ testPrompt: 'Validate my app\'s deployment readiness and check the Bicep configuration',
56
+ },
57
+ {
58
+ id: 12,
59
+ skill: 'azure-deploy',
60
+ skillPath: '.github/skills/azure-deploy/SKILL.md',
61
+ agent: 'developer',
62
+ testPrompt: 'Run azd up to push the app to production',
63
+ },
64
+ {
65
+ id: 13,
66
+ skill: 'azure-compute',
67
+ skillPath: '.github/skills/azure-compute/SKILL.md',
68
+ agent: 'developer',
69
+ testPrompt: 'Recommend the best VM size for our ML training workload on Azure',
70
+ },
71
+ {
72
+ id: 14,
73
+ skill: 'azure-storage',
74
+ skillPath: '.github/skills/azure-storage/SKILL.md',
75
+ agent: 'developer',
76
+ testPrompt: 'Set up blob storage with lifecycle management for our file upload service',
77
+ },
78
+ {
79
+ id: 15,
80
+ skill: 'azure-ai',
81
+ skillPath: '.github/skills/azure-ai/SKILL.md',
82
+ agent: 'developer',
83
+ testPrompt: 'Configure Azure AI Search with vector search for our product catalog',
84
+ },
85
+ {
86
+ id: 16,
87
+ skill: 'azure-aigateway',
88
+ skillPath: '.github/skills/azure-aigateway/SKILL.md',
89
+ agent: 'developer',
90
+ testPrompt: 'Set up semantic caching and token limits for our Azure OpenAI gateway',
91
+ },
92
+ {
93
+ id: 17,
94
+ skill: 'azure-kusto',
95
+ skillPath: '.github/skills/azure-kusto/SKILL.md',
96
+ agent: 'developer',
97
+ testPrompt: 'Write KQL queries to analyze the IoT telemetry in Azure Data Explorer',
98
+ },
99
+ {
100
+ id: 18,
101
+ skill: 'azure-messaging',
102
+ skillPath: '.github/skills/azure-messaging/SKILL.md',
103
+ agent: 'developer',
104
+ testPrompt: 'Troubleshoot this AMQP connection error with our Event Hub consumer',
105
+ },
106
+ {
107
+ id: 19,
108
+ skill: 'azure-hosted-copilot-sdk',
109
+ skillPath: '.github/skills/azure-hosted-copilot-sdk/SKILL.md',
110
+ agent: 'developer',
111
+ testPrompt: 'Build a copilot app using @github/copilot-sdk and deploy to Azure',
112
+ },
113
+ {
114
+ id: 20,
115
+ skill: 'appinsights-instrumentation',
116
+ skillPath: '.github/skills/appinsights-instrumentation/SKILL.md',
117
+ agent: 'developer',
118
+ testPrompt: 'Instrument our web app with Application Insights telemetry',
119
+ },
120
+ {
121
+ id: 21,
122
+ skill: 'microsoft-foundry',
123
+ skillPath: '.github/skills/microsoft-foundry/SKILL.md',
124
+ agent: 'developer',
125
+ testPrompt: 'Deploy our agent to Microsoft Foundry and run batch evaluation',
126
+ },
127
+ {
128
+ id: 22,
129
+ skill: 'azure-rbac',
130
+ skillPath: '.github/skills/azure-rbac/SKILL.md',
131
+ agent: 'security-reviewer',
132
+ testPrompt: 'Find the least privilege RBAC role for our managed identity to read blobs',
133
+ },
134
+ {
135
+ id: 23,
136
+ skill: 'azure-compliance',
137
+ skillPath: '.github/skills/azure-compliance/SKILL.md',
138
+ agent: 'security-reviewer',
139
+ testPrompt: 'Run a compliance scan and security audit on our Azure subscription',
140
+ },
141
+ {
142
+ id: 24,
143
+ skill: 'entra-app-registration',
144
+ skillPath: '.github/skills/entra-app-registration/SKILL.md',
145
+ agent: 'security-reviewer',
146
+ testPrompt: 'Create an Entra ID app registration with OAuth and MSAL configuration',
147
+ },
148
+ {
149
+ id: 25,
150
+ skill: 'azure-cost-optimization',
151
+ skillPath: '.github/skills/azure-cost-optimization/SKILL.md',
152
+ agent: 'product-manager',
153
+ testPrompt: 'Analyze our Azure spending and find cost optimization opportunities',
154
+ },
155
+ {
156
+ id: 26,
157
+ skill: 'azure-cloud-migrate',
158
+ skillPath: '.github/skills/azure-cloud-migrate/SKILL.md',
159
+ agent: 'product-manager',
160
+ testPrompt: 'Assess migrating our Lambda functions to Azure Functions',
161
+ },
162
+ {
163
+ id: 27,
164
+ skill: 'azure-diagnostics',
165
+ skillPath: '.github/skills/azure-diagnostics/SKILL.md',
166
+ agent: 'tester',
167
+ testPrompt: 'Troubleshoot why our Container App is failing health probes in production',
168
+ },
169
+ {
170
+ id: 28,
171
+ skill: 'azure-resource-lookup',
172
+ skillPath: '.github/skills/azure-resource-lookup/SKILL.md',
173
+ agent: 'Beth',
174
+ testPrompt: 'List all VMs and storage accounts across our Azure subscriptions',
175
+ },
176
+ {
177
+ id: 29,
178
+ skill: 'azure-resource-visualizer',
179
+ skillPath: '.github/skills/azure-resource-visualizer/SKILL.md',
180
+ agent: 'Beth',
181
+ testPrompt: 'Generate a Mermaid architecture diagram of our Azure resource group',
182
+ },
183
+ {
184
+ id: 30,
185
+ skill: 'azure-postgres',
186
+ skillPath: join(EXTERNAL_SKILLS_DIR, 'azure-postgres/SKILL.md'),
187
+ agent: 'developer',
188
+ testPrompt: 'Configure passwordless Entra ID authentication for our Postgres server',
189
+ external: true,
190
+ },
191
+ {
192
+ id: 31,
193
+ skill: 'azure-quotas',
194
+ skillPath: join(EXTERNAL_SKILLS_DIR, 'azure-quotas/SKILL.md'),
195
+ agent: 'developer',
196
+ testPrompt: 'Check our Azure subscription quotas and vCPU limits',
197
+ external: true,
198
+ },
199
+ ];
200
+ // ─── Category 3: Design & Frontend (tests 32–35) ──────────────────────────
201
+ const DESIGN_SKILLS = [
202
+ {
203
+ id: 32,
204
+ skill: 'frontend-design',
205
+ skillPath: '.github/skills/frontend-design/SKILL.md',
206
+ agent: 'developer',
207
+ testPrompt: 'Build a distinctive, production-grade landing page with creative animations',
208
+ },
209
+ {
210
+ id: 33,
211
+ skill: 'brainstorming',
212
+ skillPath: '.github/skills/brainstorming/SKILL.md',
213
+ agent: 'ux-designer',
214
+ testPrompt: 'Let\'s brainstorm approaches for the new onboarding flow',
215
+ },
216
+ {
217
+ id: 34,
218
+ skill: 'document-review',
219
+ skillPath: '.github/skills/document-review/SKILL.md',
220
+ agent: 'ux-designer',
221
+ testPrompt: 'Review and refine this brainstorm document before we proceed to planning',
222
+ },
223
+ {
224
+ id: 35,
225
+ skill: 'every-style-editor',
226
+ skillPath: '.github/skills/every-style-editor/SKILL.md',
227
+ agent: 'product-manager',
228
+ testPrompt: 'Edit this blog post for grammar and style guide compliance',
229
+ },
230
+ ];
231
+ // ─── Category 4: Product & Research (tests 36–39) ─────────────────────────
232
+ const PRODUCT_SKILLS = [
233
+ {
234
+ id: 36,
235
+ skill: 'prd',
236
+ skillPath: '.github/skills/prd/SKILL.md',
237
+ agent: 'product-manager',
238
+ testPrompt: 'Write a product requirements document for the billing dashboard feature',
239
+ },
240
+ {
241
+ id: 37,
242
+ skill: 'web-search',
243
+ skillPath: '.github/skills/web-search/SKILL.md',
244
+ agent: 'researcher',
245
+ testPrompt: 'Research the competitive landscape for AI code assistants',
246
+ },
247
+ {
248
+ id: 38,
249
+ skill: 'proof',
250
+ skillPath: '.github/skills/proof/SKILL.md',
251
+ agent: 'product-manager',
252
+ testPrompt: 'Create a proof document and share it for team review',
253
+ },
254
+ {
255
+ id: 39,
256
+ skill: 'changelog',
257
+ skillPath: '.github/skills/changelog/SKILL.md',
258
+ agent: 'developer',
259
+ testPrompt: 'Generate a changelog from recent commits',
260
+ },
261
+ ];
262
+ // ─── Category 5: Developer Workflow (tests 40–53) ─────────────────────────
263
+ const DEVELOPER_WORKFLOW_SKILLS = [
264
+ {
265
+ id: 40,
266
+ skill: 'create-agent-skills',
267
+ skillPath: '.github/skills/create-agent-skills/SKILL.md',
268
+ agent: 'developer',
269
+ testPrompt: 'Create a new Claude Code skill for database migration workflows',
270
+ },
271
+ {
272
+ id: 41,
273
+ skill: 'git-worktree',
274
+ skillPath: '.github/skills/git-worktree/SKILL.md',
275
+ agent: 'developer',
276
+ testPrompt: 'Create a git worktree for isolated parallel development on the feature branch',
277
+ },
278
+ {
279
+ id: 42,
280
+ skill: 'feature-video',
281
+ skillPath: '.github/skills/feature-video/SKILL.md',
282
+ agent: 'developer',
283
+ testPrompt: 'Record a video walkthrough of the new settings feature for the PR',
284
+ },
285
+ {
286
+ id: 43,
287
+ skill: 'resolve_parallel',
288
+ skillPath: '.github/skills/resolve_parallel/SKILL.md',
289
+ agent: 'developer',
290
+ testPrompt: 'Resolve all code TODOs in the codebase using parallel processing',
291
+ },
292
+ {
293
+ id: 44,
294
+ skill: 'resolve_todo_parallel',
295
+ skillPath: '.github/skills/resolve_todo_parallel/SKILL.md',
296
+ agent: 'developer',
297
+ testPrompt: 'Resolve all pending CLI todos in my todo list',
298
+ },
299
+ {
300
+ id: 45,
301
+ skill: 'resolve-pr-parallel',
302
+ skillPath: '.github/skills/resolve-pr-parallel/SKILL.md',
303
+ agent: 'developer',
304
+ testPrompt: 'Address all PR review comments using parallel processing',
305
+ },
306
+ {
307
+ id: 46,
308
+ skill: 'lfg',
309
+ skillPath: '.github/skills/lfg/SKILL.md',
310
+ agent: 'developer',
311
+ testPrompt: 'Execute the work plan sequentially — let\'s go',
312
+ },
313
+ {
314
+ id: 47,
315
+ skill: 'slfg',
316
+ skillPath: '.github/skills/slfg/SKILL.md',
317
+ agent: 'developer',
318
+ testPrompt: 'Execute the work plan using swarm parallel processing',
319
+ },
320
+ {
321
+ id: 48,
322
+ skill: 'deepen-plan',
323
+ skillPath: '.github/skills/deepen-plan/SKILL.md',
324
+ agent: 'developer',
325
+ testPrompt: 'Enhance this plan with parallel research agents to add depth and best practices',
326
+ },
327
+ {
328
+ id: 49,
329
+ skill: 'agent-browser',
330
+ skillPath: '.github/skills/agent-browser/SKILL.md',
331
+ agent: 'developer',
332
+ testPrompt: 'Browse the staging site and fill out the signup form to test it',
333
+ },
334
+ {
335
+ id: 50,
336
+ skill: 'agent-native-architecture',
337
+ skillPath: '.github/skills/agent-native-architecture/SKILL.md',
338
+ agent: 'developer',
339
+ testPrompt: 'Design an application where agents are first-class citizens with MCP tools',
340
+ },
341
+ {
342
+ id: 51,
343
+ skill: 'rclone',
344
+ skillPath: '.github/skills/rclone/SKILL.md',
345
+ agent: 'developer',
346
+ testPrompt: 'Upload the generated video files to our S3 bucket',
347
+ },
348
+ {
349
+ id: 52,
350
+ skill: 'gemini-imagegen',
351
+ skillPath: '.github/skills/gemini-imagegen/SKILL.md',
352
+ agent: 'developer',
353
+ testPrompt: 'Generate a product mockup image using Gemini for the landing page',
354
+ },
355
+ {
356
+ id: 53,
357
+ skill: 'generate_command',
358
+ skillPath: '.github/skills/generate_command/SKILL.md',
359
+ agent: 'developer',
360
+ testPrompt: 'Generate a shell command to find all TypeScript files with TODO comments',
361
+ },
362
+ ];
363
+ // ─── Category 6: Testing & QA (tests 54–58) ──────────────────────────────
364
+ const TESTING_SKILLS = [
365
+ {
366
+ id: 54,
367
+ skill: 'test-browser',
368
+ skillPath: '.github/skills/test-browser/SKILL.md',
369
+ agent: 'tester',
370
+ testPrompt: 'Run browser tests on pages affected by the current PR',
371
+ },
372
+ {
373
+ id: 55,
374
+ skill: 'test-xcode',
375
+ skillPath: '.github/skills/test-xcode/SKILL.md',
376
+ agent: 'tester',
377
+ testPrompt: 'Run Xcode tests for the iOS module',
378
+ },
379
+ {
380
+ id: 56,
381
+ skill: 'report-bug',
382
+ skillPath: '.github/skills/report-bug/SKILL.md',
383
+ agent: 'tester',
384
+ testPrompt: 'File a bug report for the broken pagination on the search results page',
385
+ },
386
+ {
387
+ id: 57,
388
+ skill: 'reproduce-bug',
389
+ skillPath: '.github/skills/reproduce-bug/SKILL.md',
390
+ agent: 'tester',
391
+ testPrompt: 'Reproduce the intermittent crash reported in issue #42',
392
+ },
393
+ {
394
+ id: 58,
395
+ skill: 'triage',
396
+ skillPath: '.github/skills/triage/SKILL.md',
397
+ agent: 'tester',
398
+ testPrompt: 'Triage the incoming bug reports and prioritize by severity',
399
+ },
400
+ ];
401
+ // ─── Category 7: Orchestration & Swarm (tests 59–62) ─────────────────────
402
+ const ORCHESTRATION_SKILLS = [
403
+ {
404
+ id: 59,
405
+ skill: 'orchestrating-swarms',
406
+ skillPath: '.github/skills/orchestrating-swarms/SKILL.md',
407
+ agent: 'Beth',
408
+ testPrompt: 'Orchestrate a swarm of agents to parallelize the migration work',
409
+ },
410
+ {
411
+ id: 60,
412
+ skill: 'setup',
413
+ skillPath: '.github/skills/setup/SKILL.md',
414
+ agent: 'Beth',
415
+ testPrompt: 'Set up the project structure and initialize the development environment',
416
+ },
417
+ {
418
+ id: 61,
419
+ skill: 'heal-skill',
420
+ skillPath: '.github/skills/heal-skill/SKILL.md',
421
+ agent: 'Beth',
422
+ testPrompt: 'Fix this broken skill that isn\'t loading correctly',
423
+ },
424
+ {
425
+ id: 62,
426
+ skill: 'file-todos',
427
+ skillPath: '.github/skills/file-todos/SKILL.md',
428
+ agent: 'developer',
429
+ testPrompt: 'Scan the codebase and create tasks for all TODO/FIXME comments',
430
+ },
431
+ ];
432
+ // ─── Category 8: CE Workflow Pipeline (tests 63–67) ──────────────────────
433
+ const CE_WORKFLOW_SKILLS = [
434
+ {
435
+ id: 63,
436
+ skill: 'ce:brainstorm',
437
+ skillPath: '.github/skills/ce:brainstorm/SKILL.md',
438
+ agent: 'ux-designer',
439
+ testPrompt: '/ce:brainstorm — explore requirements for the new dashboard',
440
+ },
441
+ {
442
+ id: 64,
443
+ skill: 'ce:plan',
444
+ skillPath: '.github/skills/ce:plan/SKILL.md',
445
+ agent: 'developer',
446
+ testPrompt: '/ce:plan — transform the feature description into a structured project plan',
447
+ },
448
+ {
449
+ id: 65,
450
+ skill: 'ce:work',
451
+ skillPath: '.github/skills/ce:work/SKILL.md',
452
+ agent: 'developer',
453
+ testPrompt: '/ce:work — execute the work plan and finish the feature',
454
+ },
455
+ {
456
+ id: 66,
457
+ skill: 'ce:review',
458
+ skillPath: '.github/skills/ce:review/SKILL.md',
459
+ agent: 'developer',
460
+ testPrompt: '/ce:review — perform exhaustive multi-agent code review',
461
+ },
462
+ {
463
+ id: 67,
464
+ skill: 'ce:compound',
465
+ skillPath: '.github/skills/ce:compound/SKILL.md',
466
+ agent: 'developer',
467
+ testPrompt: '/ce:compound — document what we solved to compound team knowledge',
468
+ },
469
+ ];
470
+ // ─── Category 9: Language-Specific (tests 68–70) ─────────────────────────
471
+ const LANGUAGE_SKILLS = [
472
+ {
473
+ id: 68,
474
+ skill: 'dhh-rails-style',
475
+ skillPath: '.github/skills/dhh-rails-style/SKILL.md',
476
+ agent: 'developer',
477
+ testPrompt: 'Write a Rails controller for user management in DHH\'s 37signals style',
478
+ },
479
+ {
480
+ id: 69,
481
+ skill: 'andrew-kane-gem-writer',
482
+ skillPath: '.github/skills/andrew-kane-gem-writer/SKILL.md',
483
+ agent: 'developer',
484
+ testPrompt: 'Create a Ruby gem for CSV parsing following Andrew Kane\'s patterns',
485
+ },
486
+ {
487
+ id: 70,
488
+ skill: 'dspy-ruby',
489
+ skillPath: '.github/skills/dspy-ruby/SKILL.md',
490
+ agent: 'developer',
491
+ testPrompt: 'Build an LLM module using DSPy.rb signatures for intent classification',
492
+ },
493
+ ];
494
+ // ─── Category 10: Remaining Skills (tests 71–72) ─────────────────────────
495
+ const REMAINING_SKILLS = [
496
+ {
497
+ id: 71,
498
+ skill: 'compound-docs',
499
+ skillPath: '.github/skills/compound-docs/SKILL.md',
500
+ agent: 'developer',
501
+ testPrompt: 'That worked! Document this solution for the team',
502
+ },
503
+ {
504
+ id: 72,
505
+ skill: 'agent-native-audit',
506
+ skillPath: '.github/skills/agent-native-audit/SKILL.md',
507
+ agent: 'security-reviewer',
508
+ testPrompt: 'Audit the agent-native architecture for security and reliability',
509
+ },
510
+ ];
511
+ // ─── All skills combined for cross-cutting tests ──────────────────────────
512
+ const ALL_SKILLS = [
513
+ ...AZURE_SKILLS,
514
+ ...DESIGN_SKILLS,
515
+ ...PRODUCT_SKILLS,
516
+ ...DEVELOPER_WORKFLOW_SKILLS,
517
+ ...TESTING_SKILLS,
518
+ ...ORCHESTRATION_SKILLS,
519
+ ...CE_WORKFLOW_SKILLS,
520
+ ...LANGUAGE_SKILLS,
521
+ ...REMAINING_SKILLS,
522
+ ];
523
+ // ─── Tests ─────────────────────────────────────────────────────────────────
524
+ describe('Category 2: Azure Skills', () => {
525
+ describe.each(AZURE_SKILLS)('Test #$id: $skill → $agent', (test) => {
526
+ if (test.external) {
527
+ it.skipIf(!skillExists(test))('skill file exists (external)', () => {
528
+ expect(skillExists(test)).toBe(true);
529
+ });
530
+ it.skipIf(!skillExists(test))('skill file is non-empty', () => {
531
+ const content = readSkillContent(test);
532
+ expect(content.length).toBeGreaterThan(0);
533
+ });
534
+ }
535
+ else {
536
+ it('skill file exists on disk', () => {
537
+ expect(skillExists(test)).toBe(true);
538
+ });
539
+ it('skill file is non-empty', () => {
540
+ const content = readSkillContent(test);
541
+ expect(content.length).toBeGreaterThan(0);
542
+ });
543
+ }
544
+ it('agent is a valid Beth team member', () => {
545
+ expect(VALID_AGENTS).toContain(test.agent);
546
+ });
547
+ it('test prompt is non-empty', () => {
548
+ expect(test.testPrompt.length).toBeGreaterThan(10);
549
+ });
550
+ });
551
+ });
552
+ describe('Category 3: Design & Frontend', () => {
553
+ describe.each(DESIGN_SKILLS)('Test #$id: $skill → $agent', (test) => {
554
+ it('skill file exists on disk', () => {
555
+ expect(skillExists(test)).toBe(true);
556
+ });
557
+ it('skill file is non-empty', () => {
558
+ const content = readSkillContent(test);
559
+ expect(content.length).toBeGreaterThan(0);
560
+ });
561
+ it('agent is a valid Beth team member', () => {
562
+ expect(VALID_AGENTS).toContain(test.agent);
563
+ });
564
+ });
565
+ });
566
+ describe('Category 4: Product & Research', () => {
567
+ describe.each(PRODUCT_SKILLS)('Test #$id: $skill → $agent', (test) => {
568
+ it('skill file exists on disk', () => {
569
+ expect(skillExists(test)).toBe(true);
570
+ });
571
+ it('skill file is non-empty', () => {
572
+ const content = readSkillContent(test);
573
+ expect(content.length).toBeGreaterThan(0);
574
+ });
575
+ it('agent is a valid Beth team member', () => {
576
+ expect(VALID_AGENTS).toContain(test.agent);
577
+ });
578
+ });
579
+ });
580
+ describe('Category 5: Developer Workflow', () => {
581
+ describe.each(DEVELOPER_WORKFLOW_SKILLS)('Test #$id: $skill → $agent', (test) => {
582
+ it('skill file exists on disk', () => {
583
+ expect(skillExists(test)).toBe(true);
584
+ });
585
+ it('skill file is non-empty', () => {
586
+ const content = readSkillContent(test);
587
+ expect(content.length).toBeGreaterThan(0);
588
+ });
589
+ it('agent is a valid Beth team member', () => {
590
+ expect(VALID_AGENTS).toContain(test.agent);
591
+ });
592
+ });
593
+ });
594
+ describe('Category 6: Testing & QA', () => {
595
+ describe.each(TESTING_SKILLS)('Test #$id: $skill → $agent', (test) => {
596
+ it('skill file exists on disk', () => {
597
+ expect(skillExists(test)).toBe(true);
598
+ });
599
+ it('skill file is non-empty', () => {
600
+ const content = readSkillContent(test);
601
+ expect(content.length).toBeGreaterThan(0);
602
+ });
603
+ it('agent is a valid Beth team member', () => {
604
+ expect(VALID_AGENTS).toContain(test.agent);
605
+ });
606
+ });
607
+ });
608
+ describe('Category 7: Orchestration & Swarm', () => {
609
+ describe.each(ORCHESTRATION_SKILLS)('Test #$id: $skill → $agent', (test) => {
610
+ it('skill file exists on disk', () => {
611
+ expect(skillExists(test)).toBe(true);
612
+ });
613
+ it('skill file is non-empty', () => {
614
+ const content = readSkillContent(test);
615
+ expect(content.length).toBeGreaterThan(0);
616
+ });
617
+ it('agent is a valid Beth team member', () => {
618
+ expect(VALID_AGENTS).toContain(test.agent);
619
+ });
620
+ });
621
+ });
622
+ describe('Category 8: CE Workflow Pipeline', () => {
623
+ describe.each(CE_WORKFLOW_SKILLS)('Test #$id: $skill → $agent', (test) => {
624
+ it('skill file exists on disk', () => {
625
+ expect(skillExists(test)).toBe(true);
626
+ });
627
+ it('skill file is non-empty', () => {
628
+ const content = readSkillContent(test);
629
+ expect(content.length).toBeGreaterThan(0);
630
+ });
631
+ it('agent is a valid Beth team member', () => {
632
+ expect(VALID_AGENTS).toContain(test.agent);
633
+ });
634
+ it('test prompt starts with /ce: (slash command)', () => {
635
+ expect(test.testPrompt).toMatch(/^\/ce:/);
636
+ });
637
+ });
638
+ it('CE pipeline covers all 5 phases: brainstorm → plan → work → review → compound', () => {
639
+ const phases = CE_WORKFLOW_SKILLS.map((s) => s.skill);
640
+ expect(phases).toContain('ce:brainstorm');
641
+ expect(phases).toContain('ce:plan');
642
+ expect(phases).toContain('ce:work');
643
+ expect(phases).toContain('ce:review');
644
+ expect(phases).toContain('ce:compound');
645
+ });
646
+ });
647
+ describe('Category 9: Language-Specific', () => {
648
+ describe.each(LANGUAGE_SKILLS)('Test #$id: $skill → $agent', (test) => {
649
+ it('skill file exists on disk', () => {
650
+ expect(skillExists(test)).toBe(true);
651
+ });
652
+ it('skill file is non-empty', () => {
653
+ const content = readSkillContent(test);
654
+ expect(content.length).toBeGreaterThan(0);
655
+ });
656
+ it('all language skills route to developer', () => {
657
+ expect(test.agent).toBe('developer');
658
+ });
659
+ });
660
+ });
661
+ describe('Category 10: Remaining Skills', () => {
662
+ describe.each(REMAINING_SKILLS)('Test #$id: $skill → $agent', (test) => {
663
+ it('skill file exists on disk', () => {
664
+ expect(skillExists(test)).toBe(true);
665
+ });
666
+ it('skill file is non-empty', () => {
667
+ const content = readSkillContent(test);
668
+ expect(content.length).toBeGreaterThan(0);
669
+ });
670
+ it('agent is a valid Beth team member', () => {
671
+ expect(VALID_AGENTS).toContain(test.agent);
672
+ });
673
+ });
674
+ });
675
+ // ─── Cross-cutting validation ──────────────────────────────────────────────
676
+ describe('Cross-cutting: Test matrix integrity', () => {
677
+ it('all test IDs are unique', () => {
678
+ const ids = ALL_SKILLS.map((t) => t.id);
679
+ const uniqueIds = new Set(ids);
680
+ expect(uniqueIds.size).toBe(ids.length);
681
+ });
682
+ it('test IDs are sequential from 10 to 72 with no gaps', () => {
683
+ const ids = ALL_SKILLS.map((t) => t.id).sort((a, b) => a - b);
684
+ const expectedCount = 72 - 10 + 1;
685
+ expect(ids).toHaveLength(expectedCount);
686
+ for (let i = 0; i < expectedCount; i++) {
687
+ expect(ids[i]).toBe(10 + i);
688
+ }
689
+ });
690
+ it('all agents in the matrix are valid', () => {
691
+ for (const test of ALL_SKILLS) {
692
+ expect(VALID_AGENTS).toContain(test.agent);
693
+ }
694
+ });
695
+ it('no duplicate skill names in the matrix', () => {
696
+ const skills = ALL_SKILLS.map((t) => t.skill);
697
+ // prd appears in both Category 1 (hook) and Category 4 (routing) — allow it
698
+ // web-search also appears twice — same reason
699
+ // Only check within THIS matrix (Categories 2-10)
700
+ const duplicates = skills.filter((s, i) => skills.indexOf(s) !== i);
701
+ expect(duplicates).toHaveLength(0);
702
+ });
703
+ it('every non-external skill has a corresponding directory in .github/skills/', () => {
704
+ for (const test of ALL_SKILLS) {
705
+ if (test.external)
706
+ continue;
707
+ // Extract skill dir name from path
708
+ const match = test.skillPath.match(/\.github\/skills\/([^/]+)\//);
709
+ if (match) {
710
+ const skillDir = join(SKILLS_DIR, match[1]);
711
+ expect(existsSync(skillDir)).toBe(true);
712
+ }
713
+ }
714
+ });
715
+ it('every referenced agent has at least one skill in the matrix', () => {
716
+ const agentsInMatrix = new Set(ALL_SKILLS.map((t) => t.agent));
717
+ for (const agent of agentsInMatrix) {
718
+ const count = ALL_SKILLS.filter((t) => t.agent === agent).length;
719
+ expect(count).toBeGreaterThan(0);
720
+ }
721
+ });
722
+ });
723
+ //# sourceMappingURL=skill-routing.test.js.map