beth-copilot 1.0.18 → 1.1.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 (291) hide show
  1. package/CHANGELOG.md +41 -28
  2. package/README.md +87 -247
  3. package/bin/cli.js +158 -358
  4. package/dist/__tests__/smoke.test.d.ts +8 -0
  5. package/dist/__tests__/smoke.test.d.ts.map +1 -0
  6. package/dist/__tests__/smoke.test.js +49 -0
  7. package/dist/__tests__/smoke.test.js.map +1 -0
  8. package/dist/cli/commands/beads.e2e.test.d.ts +13 -0
  9. package/dist/cli/commands/beads.e2e.test.d.ts.map +1 -0
  10. package/dist/cli/commands/beads.e2e.test.js +526 -0
  11. package/dist/cli/commands/beads.e2e.test.js.map +1 -0
  12. package/dist/cli/commands/cli-edge-cases.e2e.test.d.ts +32 -0
  13. package/dist/cli/commands/cli-edge-cases.e2e.test.d.ts.map +1 -0
  14. package/dist/cli/commands/cli-edge-cases.e2e.test.js +162 -0
  15. package/dist/cli/commands/cli-edge-cases.e2e.test.js.map +1 -0
  16. package/dist/cli/commands/close.d.ts +89 -0
  17. package/dist/cli/commands/close.d.ts.map +1 -0
  18. package/dist/cli/commands/close.e2e.test.d.ts +27 -0
  19. package/dist/cli/commands/close.e2e.test.d.ts.map +1 -0
  20. package/dist/cli/commands/close.e2e.test.js +252 -0
  21. package/dist/cli/commands/close.e2e.test.js.map +1 -0
  22. package/dist/cli/commands/close.js +309 -0
  23. package/dist/cli/commands/close.js.map +1 -0
  24. package/dist/cli/commands/close.test.d.ts +15 -0
  25. package/dist/cli/commands/close.test.d.ts.map +1 -0
  26. package/dist/cli/commands/close.test.js +634 -0
  27. package/dist/cli/commands/close.test.js.map +1 -0
  28. package/dist/cli/commands/doctor.d.ts +23 -0
  29. package/dist/cli/commands/doctor.d.ts.map +1 -1
  30. package/dist/cli/commands/doctor.js +93 -0
  31. package/dist/cli/commands/doctor.js.map +1 -1
  32. package/dist/cli/commands/doctor.test.js +209 -0
  33. package/dist/cli/commands/doctor.test.js.map +1 -1
  34. package/dist/cli/commands/framework-isolation.test.d.ts +30 -0
  35. package/dist/cli/commands/framework-isolation.test.d.ts.map +1 -0
  36. package/dist/cli/commands/framework-isolation.test.js +119 -0
  37. package/dist/cli/commands/framework-isolation.test.js.map +1 -0
  38. package/dist/cli/commands/help.e2e.test.js +4 -4
  39. package/dist/cli/commands/help.e2e.test.js.map +1 -1
  40. package/dist/cli/commands/init-logic.e2e.test.d.ts +37 -0
  41. package/dist/cli/commands/init-logic.e2e.test.d.ts.map +1 -0
  42. package/dist/cli/commands/init-logic.e2e.test.js +305 -0
  43. package/dist/cli/commands/init-logic.e2e.test.js.map +1 -0
  44. package/dist/cli/commands/land.d.ts +142 -0
  45. package/dist/cli/commands/land.d.ts.map +1 -0
  46. package/dist/cli/commands/land.js +647 -0
  47. package/dist/cli/commands/land.js.map +1 -0
  48. package/dist/cli/commands/land.test.d.ts +20 -0
  49. package/dist/cli/commands/land.test.d.ts.map +1 -0
  50. package/dist/cli/commands/land.test.js +622 -0
  51. package/dist/cli/commands/land.test.js.map +1 -0
  52. package/dist/cli/commands/mcp.e2e.test.js +22 -29
  53. package/dist/cli/commands/mcp.e2e.test.js.map +1 -1
  54. package/dist/cli/commands/pipeline.e2e.test.js +20 -20
  55. package/dist/cli/commands/pipeline.e2e.test.js.map +1 -1
  56. package/dist/cli/commands/pre-push-guard.d.ts +84 -0
  57. package/dist/cli/commands/pre-push-guard.d.ts.map +1 -0
  58. package/dist/cli/commands/pre-push-guard.e2e.test.d.ts +24 -0
  59. package/dist/cli/commands/pre-push-guard.e2e.test.d.ts.map +1 -0
  60. package/dist/cli/commands/pre-push-guard.e2e.test.js +171 -0
  61. package/dist/cli/commands/pre-push-guard.e2e.test.js.map +1 -0
  62. package/dist/cli/commands/pre-push-guard.js +257 -0
  63. package/dist/cli/commands/pre-push-guard.js.map +1 -0
  64. package/dist/cli/commands/pre-push-guard.test.d.ts +15 -0
  65. package/dist/cli/commands/pre-push-guard.test.d.ts.map +1 -0
  66. package/dist/cli/commands/pre-push-guard.test.js +397 -0
  67. package/dist/cli/commands/pre-push-guard.test.js.map +1 -0
  68. package/dist/cli/commands/quickstart-expanded.e2e.test.d.ts +23 -0
  69. package/dist/cli/commands/quickstart-expanded.e2e.test.d.ts.map +1 -0
  70. package/dist/cli/commands/quickstart-expanded.e2e.test.js +179 -0
  71. package/dist/cli/commands/quickstart-expanded.e2e.test.js.map +1 -0
  72. package/dist/cli/commands/quickstart.d.ts.map +1 -1
  73. package/dist/cli/commands/quickstart.js +7 -23
  74. package/dist/cli/commands/quickstart.js.map +1 -1
  75. package/dist/cli/commands/quickstart.test.js +40 -67
  76. package/dist/cli/commands/quickstart.test.js.map +1 -1
  77. package/dist/core/agents/suite.test.js +4 -2
  78. package/dist/core/agents/suite.test.js.map +1 -1
  79. package/dist/core/agents/tools.test.js +5 -1
  80. package/dist/core/agents/tools.test.js.map +1 -1
  81. package/dist/index.d.ts +3 -10
  82. package/dist/index.d.ts.map +1 -1
  83. package/dist/index.js +5 -10
  84. package/dist/index.js.map +1 -1
  85. package/package.json +15 -9
  86. package/sbom.json +2011 -819
  87. package/templates/.github/agents/beth.agent.md +220 -66
  88. package/templates/.github/agents/developer.agent.md +53 -90
  89. package/templates/.github/agents/product-manager.agent.md +15 -68
  90. package/templates/.github/agents/researcher.agent.md +20 -71
  91. package/templates/.github/agents/security-reviewer.agent.md +29 -81
  92. package/templates/.github/agents/tester.agent.md +40 -69
  93. package/templates/.github/agents/ux-designer.agent.md +20 -74
  94. package/templates/.github/copilot-instructions.md +217 -225
  95. package/templates/AGENTS.md +108 -20
  96. package/templates/mcp.json.example +0 -3
  97. package/dist/cli/commands/client-config.d.ts +0 -31
  98. package/dist/cli/commands/client-config.d.ts.map +0 -1
  99. package/dist/cli/commands/client-config.e2e.test.d.ts +0 -15
  100. package/dist/cli/commands/client-config.e2e.test.d.ts.map +0 -1
  101. package/dist/cli/commands/client-config.e2e.test.js +0 -556
  102. package/dist/cli/commands/client-config.e2e.test.js.map +0 -1
  103. package/dist/cli/commands/client-config.js +0 -73
  104. package/dist/cli/commands/client-config.js.map +0 -1
  105. package/dist/cli/commands/client-config.test.d.ts +0 -6
  106. package/dist/cli/commands/client-config.test.d.ts.map +0 -1
  107. package/dist/cli/commands/client-config.test.js +0 -133
  108. package/dist/cli/commands/client-config.test.js.map +0 -1
  109. package/dist/cli/commands/init-quickstart.e2e.test.d.ts +0 -11
  110. package/dist/cli/commands/init-quickstart.e2e.test.d.ts.map +0 -1
  111. package/dist/cli/commands/init-quickstart.e2e.test.js +0 -221
  112. package/dist/cli/commands/init-quickstart.e2e.test.js.map +0 -1
  113. package/dist/core/context.d.ts +0 -171
  114. package/dist/core/context.d.ts.map +0 -1
  115. package/dist/core/context.js +0 -353
  116. package/dist/core/context.js.map +0 -1
  117. package/dist/core/context.test.d.ts +0 -8
  118. package/dist/core/context.test.d.ts.map +0 -1
  119. package/dist/core/context.test.js +0 -253
  120. package/dist/core/context.test.js.map +0 -1
  121. package/dist/core/handoffs.d.ts +0 -151
  122. package/dist/core/handoffs.d.ts.map +0 -1
  123. package/dist/core/handoffs.js +0 -220
  124. package/dist/core/handoffs.js.map +0 -1
  125. package/dist/core/handoffs.test.d.ts +0 -8
  126. package/dist/core/handoffs.test.d.ts.map +0 -1
  127. package/dist/core/handoffs.test.js +0 -231
  128. package/dist/core/handoffs.test.js.map +0 -1
  129. package/dist/core/orchestrator.d.ts +0 -246
  130. package/dist/core/orchestrator.d.ts.map +0 -1
  131. package/dist/core/orchestrator.js +0 -514
  132. package/dist/core/orchestrator.js.map +0 -1
  133. package/dist/core/orchestrator.test.d.ts +0 -8
  134. package/dist/core/orchestrator.test.d.ts.map +0 -1
  135. package/dist/core/orchestrator.test.js +0 -517
  136. package/dist/core/orchestrator.test.js.map +0 -1
  137. package/dist/core/router.d.ts +0 -102
  138. package/dist/core/router.d.ts.map +0 -1
  139. package/dist/core/router.js +0 -178
  140. package/dist/core/router.js.map +0 -1
  141. package/dist/core/router.test.d.ts +0 -8
  142. package/dist/core/router.test.d.ts.map +0 -1
  143. package/dist/core/router.test.js +0 -215
  144. package/dist/core/router.test.js.map +0 -1
  145. package/dist/init.test.js +0 -288
  146. package/dist/providers/azure.d.ts +0 -147
  147. package/dist/providers/azure.d.ts.map +0 -1
  148. package/dist/providers/azure.js +0 -491
  149. package/dist/providers/azure.js.map +0 -1
  150. package/dist/providers/azure.test.d.ts +0 -11
  151. package/dist/providers/azure.test.d.ts.map +0 -1
  152. package/dist/providers/azure.test.js +0 -330
  153. package/dist/providers/azure.test.js.map +0 -1
  154. package/dist/providers/config.d.ts +0 -87
  155. package/dist/providers/config.d.ts.map +0 -1
  156. package/dist/providers/config.js +0 -193
  157. package/dist/providers/config.js.map +0 -1
  158. package/dist/providers/config.test.d.ts +0 -7
  159. package/dist/providers/config.test.d.ts.map +0 -1
  160. package/dist/providers/config.test.js +0 -370
  161. package/dist/providers/config.test.js.map +0 -1
  162. package/dist/providers/index.d.ts +0 -18
  163. package/dist/providers/index.d.ts.map +0 -1
  164. package/dist/providers/index.js +0 -14
  165. package/dist/providers/index.js.map +0 -1
  166. package/dist/providers/interface.d.ts +0 -191
  167. package/dist/providers/interface.d.ts.map +0 -1
  168. package/dist/providers/interface.js +0 -94
  169. package/dist/providers/interface.js.map +0 -1
  170. package/dist/providers/retry.d.ts +0 -128
  171. package/dist/providers/retry.d.ts.map +0 -1
  172. package/dist/providers/retry.js +0 -205
  173. package/dist/providers/retry.js.map +0 -1
  174. package/dist/providers/retry.test.d.ts +0 -7
  175. package/dist/providers/retry.test.d.ts.map +0 -1
  176. package/dist/providers/retry.test.js +0 -439
  177. package/dist/providers/retry.test.js.map +0 -1
  178. package/dist/providers/streaming.d.ts +0 -157
  179. package/dist/providers/streaming.d.ts.map +0 -1
  180. package/dist/providers/streaming.js +0 -233
  181. package/dist/providers/streaming.js.map +0 -1
  182. package/dist/providers/streaming.test.d.ts +0 -7
  183. package/dist/providers/streaming.test.d.ts.map +0 -1
  184. package/dist/providers/streaming.test.js +0 -372
  185. package/dist/providers/streaming.test.js.map +0 -1
  186. package/dist/providers/types.d.ts +0 -209
  187. package/dist/providers/types.d.ts.map +0 -1
  188. package/dist/providers/types.js +0 -53
  189. package/dist/providers/types.js.map +0 -1
  190. package/dist/providers/types.test.d.ts +0 -7
  191. package/dist/providers/types.test.d.ts.map +0 -1
  192. package/dist/providers/types.test.js +0 -141
  193. package/dist/providers/types.test.js.map +0 -1
  194. package/dist/tools/cli/beads.d.ts +0 -27
  195. package/dist/tools/cli/beads.d.ts.map +0 -1
  196. package/dist/tools/cli/beads.js +0 -172
  197. package/dist/tools/cli/beads.js.map +0 -1
  198. package/dist/tools/cli/beads.test.d.ts +0 -8
  199. package/dist/tools/cli/beads.test.d.ts.map +0 -1
  200. package/dist/tools/cli/beads.test.js +0 -264
  201. package/dist/tools/cli/beads.test.js.map +0 -1
  202. package/dist/tools/cli/editFile.d.ts +0 -17
  203. package/dist/tools/cli/editFile.d.ts.map +0 -1
  204. package/dist/tools/cli/editFile.js +0 -125
  205. package/dist/tools/cli/editFile.js.map +0 -1
  206. package/dist/tools/cli/editFile.test.d.ts +0 -8
  207. package/dist/tools/cli/editFile.test.d.ts.map +0 -1
  208. package/dist/tools/cli/editFile.test.js +0 -177
  209. package/dist/tools/cli/editFile.test.js.map +0 -1
  210. package/dist/tools/cli/readFile.d.ts +0 -25
  211. package/dist/tools/cli/readFile.d.ts.map +0 -1
  212. package/dist/tools/cli/readFile.js +0 -118
  213. package/dist/tools/cli/readFile.js.map +0 -1
  214. package/dist/tools/cli/readFile.test.d.ts +0 -8
  215. package/dist/tools/cli/readFile.test.d.ts.map +0 -1
  216. package/dist/tools/cli/readFile.test.js +0 -194
  217. package/dist/tools/cli/readFile.test.js.map +0 -1
  218. package/dist/tools/cli/search.d.ts +0 -16
  219. package/dist/tools/cli/search.d.ts.map +0 -1
  220. package/dist/tools/cli/search.js +0 -261
  221. package/dist/tools/cli/search.js.map +0 -1
  222. package/dist/tools/cli/search.test.d.ts +0 -8
  223. package/dist/tools/cli/search.test.d.ts.map +0 -1
  224. package/dist/tools/cli/search.test.js +0 -172
  225. package/dist/tools/cli/search.test.js.map +0 -1
  226. package/dist/tools/cli/subagent.d.ts +0 -43
  227. package/dist/tools/cli/subagent.d.ts.map +0 -1
  228. package/dist/tools/cli/subagent.js +0 -99
  229. package/dist/tools/cli/subagent.js.map +0 -1
  230. package/dist/tools/cli/subagent.test.d.ts +0 -8
  231. package/dist/tools/cli/subagent.test.d.ts.map +0 -1
  232. package/dist/tools/cli/subagent.test.js +0 -190
  233. package/dist/tools/cli/subagent.test.js.map +0 -1
  234. package/dist/tools/cli/terminal.d.ts +0 -19
  235. package/dist/tools/cli/terminal.d.ts.map +0 -1
  236. package/dist/tools/cli/terminal.js +0 -164
  237. package/dist/tools/cli/terminal.js.map +0 -1
  238. package/dist/tools/cli/terminal.test.d.ts +0 -8
  239. package/dist/tools/cli/terminal.test.d.ts.map +0 -1
  240. package/dist/tools/cli/terminal.test.js +0 -161
  241. package/dist/tools/cli/terminal.test.js.map +0 -1
  242. package/dist/tools/index.d.ts +0 -25
  243. package/dist/tools/index.d.ts.map +0 -1
  244. package/dist/tools/index.js +0 -41
  245. package/dist/tools/index.js.map +0 -1
  246. package/dist/tools/interface.d.ts +0 -64
  247. package/dist/tools/interface.d.ts.map +0 -1
  248. package/dist/tools/interface.js +0 -37
  249. package/dist/tools/interface.js.map +0 -1
  250. package/dist/tools/interface.test.d.ts +0 -7
  251. package/dist/tools/interface.test.d.ts.map +0 -1
  252. package/dist/tools/interface.test.js +0 -179
  253. package/dist/tools/interface.test.js.map +0 -1
  254. package/dist/tools/mcp/bridge.d.ts +0 -48
  255. package/dist/tools/mcp/bridge.d.ts.map +0 -1
  256. package/dist/tools/mcp/bridge.js +0 -128
  257. package/dist/tools/mcp/bridge.js.map +0 -1
  258. package/dist/tools/mcp/bridge.test.d.ts +0 -8
  259. package/dist/tools/mcp/bridge.test.d.ts.map +0 -1
  260. package/dist/tools/mcp/bridge.test.js +0 -300
  261. package/dist/tools/mcp/bridge.test.js.map +0 -1
  262. package/dist/tools/mcp/client.d.ts +0 -135
  263. package/dist/tools/mcp/client.d.ts.map +0 -1
  264. package/dist/tools/mcp/client.js +0 -263
  265. package/dist/tools/mcp/client.js.map +0 -1
  266. package/dist/tools/mcp/client.test.d.ts +0 -8
  267. package/dist/tools/mcp/client.test.d.ts.map +0 -1
  268. package/dist/tools/mcp/client.test.js +0 -390
  269. package/dist/tools/mcp/client.test.js.map +0 -1
  270. package/dist/tools/registry.d.ts +0 -82
  271. package/dist/tools/registry.d.ts.map +0 -1
  272. package/dist/tools/registry.js +0 -99
  273. package/dist/tools/registry.js.map +0 -1
  274. package/dist/tools/registry.test.d.ts +0 -7
  275. package/dist/tools/registry.test.d.ts.map +0 -1
  276. package/dist/tools/registry.test.js +0 -199
  277. package/dist/tools/registry.test.js.map +0 -1
  278. package/dist/tools/suite.test.d.ts +0 -11
  279. package/dist/tools/suite.test.d.ts.map +0 -1
  280. package/dist/tools/suite.test.js +0 -119
  281. package/dist/tools/suite.test.js.map +0 -1
  282. package/dist/tools/types.d.ts +0 -75
  283. package/dist/tools/types.d.ts.map +0 -1
  284. package/dist/tools/types.js +0 -30
  285. package/dist/tools/types.js.map +0 -1
  286. package/dist/tools/types.test.d.ts +0 -7
  287. package/dist/tools/types.test.d.ts.map +0 -1
  288. package/dist/tools/types.test.js +0 -178
  289. package/dist/tools/types.test.js.map +0 -1
  290. package/templates/.vscode/mcp.json +0 -20
  291. package/templates/CLAUDE.md +0 -129
package/dist/init.test.js DELETED
@@ -1,288 +0,0 @@
1
- /**
2
- * E2E tests for init command.
3
- * Run with: node --test dist/cli/commands/init.test.js
4
- */
5
- import { describe, it, beforeEach, afterEach } from 'node:test';
6
- import assert from 'node:assert';
7
- import { execSync } from 'child_process';
8
- import { existsSync, mkdirSync, writeFileSync, rmSync, readFileSync, readdirSync } from 'fs';
9
- import { join } from 'path';
10
- import { tmpdir } from 'os';
11
- // Expected files and directories from templates
12
- const EXPECTED_AGENTS = [
13
- 'beth.agent.md',
14
- 'developer.agent.md',
15
- 'product-manager.agent.md',
16
- 'researcher.agent.md',
17
- 'security-reviewer.agent.md',
18
- 'tester.agent.md',
19
- 'ux-designer.agent.md',
20
- ];
21
- const EXPECTED_SKILLS = [
22
- 'framer-components',
23
- 'prd',
24
- 'security-analysis',
25
- 'shadcn-ui',
26
- 'vercel-react-best-practices',
27
- 'web-design-guidelines',
28
- ];
29
- // Path to CLI binary
30
- const CLI_PATH = join(process.cwd(), 'bin', 'cli.js');
31
- /**
32
- * Run the init command in a specified directory.
33
- * Uses --skip-beads to avoid interactive prompts during testing.
34
- */
35
- function runInit(cwd, flags = []) {
36
- // Always include --skip-beads to avoid interactive prompts
37
- const allFlags = ['--skip-beads', ...flags];
38
- const command = `node "${CLI_PATH}" init ${allFlags.join(' ')}`;
39
- try {
40
- const stdout = execSync(command, {
41
- cwd,
42
- encoding: 'utf-8',
43
- env: { ...process.env, NO_COLOR: '1' }, // Disable colors and animations
44
- stdio: ['pipe', 'pipe', 'pipe'],
45
- });
46
- return { stdout, stderr: '', exitCode: 0 };
47
- }
48
- catch (error) {
49
- const execError = error;
50
- return {
51
- stdout: execError.stdout || '',
52
- stderr: execError.stderr || '',
53
- exitCode: execError.status || 1,
54
- };
55
- }
56
- }
57
- describe('init command E2E', () => {
58
- let testDir;
59
- beforeEach(() => {
60
- // Create a temp directory for each test
61
- testDir = join(tmpdir(), `beth-init-test-${Date.now()}-${Math.random().toString(36).slice(2)}`);
62
- mkdirSync(testDir, { recursive: true });
63
- });
64
- afterEach(() => {
65
- // Clean up temp directory
66
- if (existsSync(testDir)) {
67
- rmSync(testDir, { recursive: true, force: true });
68
- }
69
- });
70
- describe('directory structure creation', () => {
71
- it('should create .github/agents directory with all 7 agent files', () => {
72
- runInit(testDir);
73
- const agentsDir = join(testDir, '.github', 'agents');
74
- assert.strictEqual(existsSync(agentsDir), true, '.github/agents directory should exist');
75
- const files = readdirSync(agentsDir).filter(f => f.endsWith('.agent.md')).sort();
76
- assert.deepStrictEqual(files, EXPECTED_AGENTS, 'All 7 agent files should be created');
77
- });
78
- it('should create .github/skills directory with all skill directories', () => {
79
- runInit(testDir);
80
- const skillsDir = join(testDir, '.github', 'skills');
81
- assert.strictEqual(existsSync(skillsDir), true, '.github/skills directory should exist');
82
- const dirs = readdirSync(skillsDir).filter(f => {
83
- return existsSync(join(skillsDir, f, 'SKILL.md')) ||
84
- existsSync(join(skillsDir, f, 'AGENTS.md'));
85
- }).sort();
86
- assert.deepStrictEqual(dirs, EXPECTED_SKILLS, 'All skill directories should be created');
87
- });
88
- it('should create AGENTS.md in project root', () => {
89
- runInit(testDir);
90
- const agentsMd = join(testDir, 'AGENTS.md');
91
- assert.strictEqual(existsSync(agentsMd), true, 'AGENTS.md should exist');
92
- const content = readFileSync(agentsMd, 'utf-8');
93
- assert.ok(content.includes('beads'), 'AGENTS.md should mention beads');
94
- });
95
- it('should create Backlog.md in project root', () => {
96
- runInit(testDir);
97
- const backlogMd = join(testDir, 'Backlog.md');
98
- assert.strictEqual(existsSync(backlogMd), true, 'Backlog.md should exist');
99
- });
100
- it('should create mcp.json.example in project root', () => {
101
- runInit(testDir);
102
- const mcpJson = join(testDir, 'mcp.json.example');
103
- assert.strictEqual(existsSync(mcpJson), true, 'mcp.json.example should exist');
104
- });
105
- it('should create .vscode/settings.json', () => {
106
- runInit(testDir);
107
- const settingsJson = join(testDir, '.vscode', 'settings.json');
108
- assert.strictEqual(existsSync(settingsJson), true, '.vscode/settings.json should exist');
109
- });
110
- it('should create copilot-instructions.md in .github', () => {
111
- runInit(testDir);
112
- const copilotInstructions = join(testDir, '.github', 'copilot-instructions.md');
113
- assert.strictEqual(existsSync(copilotInstructions), true, '.github/copilot-instructions.md should exist');
114
- });
115
- });
116
- describe('--force flag', () => {
117
- it('should overwrite existing files when --force is used', () => {
118
- // Create existing AGENTS.md with different content
119
- const agentsMd = join(testDir, 'AGENTS.md');
120
- writeFileSync(agentsMd, 'ORIGINAL CONTENT');
121
- // Run init without --force
122
- runInit(testDir);
123
- let content = readFileSync(agentsMd, 'utf-8');
124
- assert.strictEqual(content, 'ORIGINAL CONTENT', 'Should not overwrite without --force');
125
- // Run init with --force
126
- runInit(testDir, ['--force']);
127
- content = readFileSync(agentsMd, 'utf-8');
128
- assert.notStrictEqual(content, 'ORIGINAL CONTENT', 'Should overwrite with --force');
129
- assert.ok(content.includes('beads'), 'Content should be from template');
130
- });
131
- it('should overwrite existing agent files with --force', () => {
132
- // Create existing .github/agents directory with modified file
133
- const agentsDir = join(testDir, '.github', 'agents');
134
- mkdirSync(agentsDir, { recursive: true });
135
- const bethAgent = join(agentsDir, 'beth.agent.md');
136
- writeFileSync(bethAgent, 'MODIFIED BETH');
137
- // Run init without --force
138
- runInit(testDir);
139
- let content = readFileSync(bethAgent, 'utf-8');
140
- assert.strictEqual(content, 'MODIFIED BETH', 'Should not overwrite without --force');
141
- // Run init with --force
142
- runInit(testDir, ['--force']);
143
- content = readFileSync(bethAgent, 'utf-8');
144
- assert.notStrictEqual(content, 'MODIFIED BETH', 'Should overwrite with --force');
145
- });
146
- });
147
- describe('--skip-backlog flag', () => {
148
- it('should not create Backlog.md when --skip-backlog is used', () => {
149
- runInit(testDir, ['--skip-backlog']);
150
- const backlogMd = join(testDir, 'Backlog.md');
151
- assert.strictEqual(existsSync(backlogMd), false, 'Backlog.md should not exist');
152
- });
153
- it('should still create other files when --skip-backlog is used', () => {
154
- runInit(testDir, ['--skip-backlog']);
155
- assert.strictEqual(existsSync(join(testDir, 'AGENTS.md')), true, 'AGENTS.md should exist');
156
- assert.strictEqual(existsSync(join(testDir, 'mcp.json.example')), true, 'mcp.json.example should exist');
157
- assert.strictEqual(existsSync(join(testDir, '.github', 'agents')), true, '.github/agents should exist');
158
- });
159
- });
160
- describe('--skip-mcp flag', () => {
161
- it('should not create mcp.json.example when --skip-mcp is used', () => {
162
- runInit(testDir, ['--skip-mcp']);
163
- const mcpJson = join(testDir, 'mcp.json.example');
164
- assert.strictEqual(existsSync(mcpJson), false, 'mcp.json.example should not exist');
165
- });
166
- it('should still create other files when --skip-mcp is used', () => {
167
- runInit(testDir, ['--skip-mcp']);
168
- assert.strictEqual(existsSync(join(testDir, 'AGENTS.md')), true, 'AGENTS.md should exist');
169
- assert.strictEqual(existsSync(join(testDir, 'Backlog.md')), true, 'Backlog.md should exist');
170
- assert.strictEqual(existsSync(join(testDir, '.github', 'agents')), true, '.github/agents should exist');
171
- });
172
- });
173
- describe('--skip-beads flag', () => {
174
- it('should complete without beads check when --skip-beads is used', () => {
175
- const result = runInit(testDir);
176
- // Should complete successfully (exit 0)
177
- assert.strictEqual(result.exitCode, 0, 'Should exit with code 0');
178
- // Should have created files
179
- assert.strictEqual(existsSync(join(testDir, '.github', 'agents')), true, 'Should create agents');
180
- });
181
- it('should show warning about skipping beads', () => {
182
- const result = runInit(testDir);
183
- // Output should mention skipping beads
184
- assert.ok(result.stdout.includes('Skipped beads check') || result.stdout.includes('skip-beads'), 'Should warn about skipping beads');
185
- });
186
- });
187
- describe('existing files handling', () => {
188
- it('should warn about existing files without --force', () => {
189
- // Create existing file
190
- writeFileSync(join(testDir, 'AGENTS.md'), 'EXISTING');
191
- const result = runInit(testDir);
192
- assert.ok(result.stdout.includes('Skipped') || result.stdout.includes('exists'), 'Should mention that file was skipped');
193
- });
194
- it('should not overwrite existing files without --force', () => {
195
- const agentsMd = join(testDir, 'AGENTS.md');
196
- writeFileSync(agentsMd, 'ORIGINAL');
197
- runInit(testDir);
198
- const content = readFileSync(agentsMd, 'utf-8');
199
- assert.strictEqual(content, 'ORIGINAL', 'Should preserve original content');
200
- });
201
- it('should count files correctly when some are skipped', () => {
202
- // Create some existing files
203
- writeFileSync(join(testDir, 'AGENTS.md'), 'EXISTING');
204
- writeFileSync(join(testDir, 'Backlog.md'), 'EXISTING');
205
- const result = runInit(testDir);
206
- // Should have installed some files but not all
207
- assert.ok(result.stdout.includes('Installed'), 'Should report installed files');
208
- });
209
- });
210
- describe('empty directory behavior', () => {
211
- it('should work correctly in an empty directory', () => {
212
- const result = runInit(testDir);
213
- assert.strictEqual(result.exitCode, 0, 'Should exit with code 0');
214
- assert.strictEqual(existsSync(join(testDir, '.github', 'agents')), true, '.github/agents should exist');
215
- assert.strictEqual(existsSync(join(testDir, '.github', 'skills')), true, '.github/skills should exist');
216
- assert.strictEqual(existsSync(join(testDir, 'AGENTS.md')), true, 'AGENTS.md should exist');
217
- });
218
- it('should install all expected files in empty directory', () => {
219
- runInit(testDir);
220
- // Check all expected files exist
221
- const agentsDir = join(testDir, '.github', 'agents');
222
- const agentFiles = readdirSync(agentsDir).filter(f => f.endsWith('.agent.md'));
223
- assert.strictEqual(agentFiles.length, 7, 'Should create 7 agent files');
224
- const skillsDir = join(testDir, '.github', 'skills');
225
- const skillDirs = readdirSync(skillsDir);
226
- assert.strictEqual(skillDirs.length, 6, 'Should create 6 skill directories');
227
- });
228
- });
229
- describe('existing .github folder behavior', () => {
230
- it('should work in directory with existing .github folder', () => {
231
- // Create existing .github folder with some content
232
- const existingGithub = join(testDir, '.github', 'workflows');
233
- mkdirSync(existingGithub, { recursive: true });
234
- writeFileSync(join(existingGithub, 'ci.yml'), 'name: CI');
235
- const result = runInit(testDir);
236
- assert.strictEqual(result.exitCode, 0, 'Should exit with code 0');
237
- // Should preserve existing content
238
- assert.strictEqual(existsSync(join(existingGithub, 'ci.yml')), true, 'Should preserve existing .github/workflows/ci.yml');
239
- // Should add new content
240
- assert.strictEqual(existsSync(join(testDir, '.github', 'agents')), true, 'Should create .github/agents');
241
- });
242
- it('should merge with existing .github/agents folder', () => {
243
- // Create existing agents folder with custom agent
244
- const agentsDir = join(testDir, '.github', 'agents');
245
- mkdirSync(agentsDir, { recursive: true });
246
- writeFileSync(join(agentsDir, 'custom.agent.md'), 'CUSTOM AGENT');
247
- runInit(testDir);
248
- // Should preserve custom agent
249
- assert.strictEqual(existsSync(join(agentsDir, 'custom.agent.md')), true, 'Should preserve custom.agent.md');
250
- // Custom agent content should be unchanged
251
- const customContent = readFileSync(join(agentsDir, 'custom.agent.md'), 'utf-8');
252
- assert.strictEqual(customContent, 'CUSTOM AGENT', 'Custom agent content preserved');
253
- // Should have added Beth agents (they don't exist yet)
254
- assert.strictEqual(existsSync(join(agentsDir, 'beth.agent.md')), true, 'Should create beth.agent.md');
255
- });
256
- });
257
- describe('multiple flag combinations', () => {
258
- it('should handle --skip-backlog and --skip-mcp together', () => {
259
- runInit(testDir, ['--skip-backlog', '--skip-mcp']);
260
- assert.strictEqual(existsSync(join(testDir, 'Backlog.md')), false, 'Backlog.md should not exist');
261
- assert.strictEqual(existsSync(join(testDir, 'mcp.json.example')), false, 'mcp.json.example should not exist');
262
- assert.strictEqual(existsSync(join(testDir, 'AGENTS.md')), true, 'AGENTS.md should exist');
263
- assert.strictEqual(existsSync(join(testDir, '.github', 'agents')), true, '.github/agents should exist');
264
- });
265
- it('should handle --force with skip flags', () => {
266
- // Create existing file
267
- writeFileSync(join(testDir, 'AGENTS.md'), 'ORIGINAL');
268
- runInit(testDir, ['--force', '--skip-backlog', '--skip-mcp']);
269
- // Force should overwrite
270
- const content = readFileSync(join(testDir, 'AGENTS.md'), 'utf-8');
271
- assert.notStrictEqual(content, 'ORIGINAL', 'Should overwrite with --force');
272
- // Skip flags should still work
273
- assert.strictEqual(existsSync(join(testDir, 'Backlog.md')), false, 'Backlog.md should not exist');
274
- assert.strictEqual(existsSync(join(testDir, 'mcp.json.example')), false, 'mcp.json.example should not exist');
275
- });
276
- });
277
- describe('output messages', () => {
278
- it('should report number of installed files', () => {
279
- const result = runInit(testDir);
280
- assert.ok(result.stdout.includes('Installed'), 'Should mention installed files');
281
- assert.ok(/Installed \d+ files/.test(result.stdout), 'Should report file count');
282
- });
283
- it('should show next steps after installation', () => {
284
- const result = runInit(testDir);
285
- assert.ok(result.stdout.includes('Next steps') || result.stdout.includes('VS Code'), 'Should show next steps');
286
- });
287
- });
288
- });
@@ -1,147 +0,0 @@
1
- /**
2
- * Azure OpenAI Provider
3
- *
4
- * LLM provider implementation for Azure OpenAI using the Responses API.
5
- * Uses Entra ID authentication via TokenCredential.
6
- */
7
- import type { ChatMessage, ChatChunk, LLMResponse, LLMConfig } from './types.js';
8
- import { LLMProviderBase, type ChatRequestOptions } from './interface.js';
9
- /**
10
- * Azure OpenAI provider implementation.
11
- *
12
- * Uses the OpenAI SDK's AzureOpenAI client with Entra ID authentication.
13
- * Supports both streaming and non-streaming chat completions with tool calling.
14
- *
15
- * @example
16
- * ```typescript
17
- * import { DefaultAzureCredential } from '@azure/identity';
18
- *
19
- * const provider = new AzureOpenAIProvider({
20
- * provider: 'azure-openai',
21
- * endpoint: 'https://my-resource.openai.azure.com',
22
- * model: 'gpt-4',
23
- * credential: new DefaultAzureCredential(),
24
- * apiVersion: '2025-03-01-preview',
25
- * });
26
- *
27
- * const response = await provider.chat([
28
- * { role: 'user', content: 'Hello!' }
29
- * ]);
30
- * ```
31
- */
32
- export declare class AzureOpenAIProvider extends LLMProviderBase {
33
- /** Azure OpenAI client instance */
34
- private client;
35
- /**
36
- * Create a new Azure OpenAI provider instance.
37
- *
38
- * @param config - Provider configuration with Entra ID credentials
39
- */
40
- constructor(config: LLMConfig);
41
- /**
42
- * Provider identifier.
43
- */
44
- get name(): string;
45
- /**
46
- * Check if the provider is properly configured.
47
- *
48
- * Validates that endpoint, model, and credential are present.
49
- */
50
- get isConfigured(): boolean;
51
- /**
52
- * Send a non-streaming chat completion request.
53
- *
54
- * @param messages - Conversation history
55
- * @param options - Request options (tools, temperature, etc.)
56
- * @returns Complete LLM response with message and usage stats
57
- * @throws {LLMError} On API errors
58
- */
59
- chat(messages: ChatMessage[], options?: ChatRequestOptions): Promise<LLMResponse>;
60
- /**
61
- * Send a streaming chat completion request.
62
- *
63
- * @param messages - Conversation history
64
- * @param options - Request options (tools, temperature, etc.)
65
- * @yields ChatChunk objects with incremental content
66
- * @throws {LLMError} On API errors
67
- */
68
- chatStream(messages: ChatMessage[], options?: ChatRequestOptions): AsyncGenerator<ChatChunk, void, undefined>;
69
- /**
70
- * Estimate token count for messages.
71
- *
72
- * Uses a rough estimation based on character count divided by 4.
73
- * This is an approximation suitable for basic usage tracking and
74
- * context window management.
75
- *
76
- * @param messages - Messages to count tokens for
77
- * @returns Estimated token count
78
- */
79
- countTokens(messages: ChatMessage[]): Promise<number>;
80
- /**
81
- * Map internal ChatMessage format to OpenAI API format.
82
- *
83
- * @param messages - Internal message format
84
- * @returns OpenAI-compatible message array
85
- */
86
- private mapMessages;
87
- /**
88
- * Map internal ToolDefinition format to OpenAI API format.
89
- *
90
- * @param tools - Internal tool definitions
91
- * @returns OpenAI-compatible tool array
92
- */
93
- private mapTools;
94
- /**
95
- * Map OpenAI API response to internal LLMResponse format.
96
- *
97
- * @param response - OpenAI API response
98
- * @returns Internal response format
99
- */
100
- private mapResponse;
101
- /**
102
- * Map tool calls from OpenAI format, filtering out non-function types.
103
- *
104
- * @param toolCalls - OpenAI tool calls array
105
- * @returns Internal tool calls array or undefined
106
- */
107
- private mapToolCalls;
108
- /**
109
- * Map OpenAI streaming chunk to internal ChatChunk format.
110
- *
111
- * @param chunk - OpenAI streaming chunk
112
- * @returns Internal chunk format
113
- */
114
- private mapChunk;
115
- /**
116
- * Map OpenAI finish reason to internal FinishReason type.
117
- *
118
- * @param reason - OpenAI finish reason string
119
- * @returns Internal finish reason or null
120
- */
121
- private mapFinishReason;
122
- /**
123
- * Wrap an error from the OpenAI SDK into an LLMError.
124
- *
125
- * Maps HTTP status codes and error types to appropriate LLMErrorCode values.
126
- *
127
- * @param error - The original error
128
- * @returns Wrapped LLMError
129
- */
130
- private wrapError;
131
- /**
132
- * Extract HTTP status code from various error types.
133
- *
134
- * @param error - Error object to inspect
135
- * @returns HTTP status code or undefined
136
- */
137
- private extractStatusCode;
138
- /**
139
- * Map HTTP status code to LLMErrorCode.
140
- *
141
- * @param statusCode - HTTP status code
142
- * @param error - Original error for additional context
143
- * @returns Appropriate LLMErrorCode
144
- */
145
- private mapStatusToErrorCode;
146
- }
147
- //# sourceMappingURL=azure.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"azure.d.ts","sourceRoot":"","sources":["../../src/providers/azure.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAYH,OAAO,KAAK,EACV,WAAW,EACX,SAAS,EACT,WAAW,EACX,SAAS,EAIV,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,eAAe,EAAE,KAAK,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAkB1E;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,qBAAa,mBAAoB,SAAQ,eAAe;IACtD,mCAAmC;IACnC,OAAO,CAAC,MAAM,CAAc;IAE5B;;;;OAIG;gBACS,MAAM,EAAE,SAAS;IAsB7B;;OAEG;IACH,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED;;;;OAIG;IACH,IAAI,YAAY,IAAI,OAAO,CAM1B;IAMD;;;;;;;OAOG;IACG,IAAI,CACR,QAAQ,EAAE,WAAW,EAAE,EACvB,OAAO,CAAC,EAAE,kBAAkB,GAC3B,OAAO,CAAC,WAAW,CAAC;IAwCvB;;;;;;;OAOG;IACI,UAAU,CACf,QAAQ,EAAE,WAAW,EAAE,EACvB,OAAO,CAAC,EAAE,kBAAkB,GAC3B,cAAc,CAAC,SAAS,EAAE,IAAI,EAAE,SAAS,CAAC;IAwC7C;;;;;;;;;OASG;IACG,WAAW,CAAC,QAAQ,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IAwC3D;;;;;OAKG;IACH,OAAO,CAAC,WAAW;IA+CnB;;;;;OAKG;IACH,OAAO,CAAC,QAAQ;IAiBhB;;;;;OAKG;IACH,OAAO,CAAC,WAAW;IAqBnB;;;;;OAKG;IACH,OAAO,CAAC,YAAY;IAgCpB;;;;;OAKG;IACH,OAAO,CAAC,QAAQ;IAyChB;;;;;OAKG;IACH,OAAO,CAAC,eAAe;IA0BvB;;;;;;;OAOG;IACH,OAAO,CAAC,SAAS;IA4BjB;;;;;OAKG;IACH,OAAO,CAAC,iBAAiB;IAezB;;;;;;OAMG;IACH,OAAO,CAAC,oBAAoB;CA4D7B"}