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.
- package/CHANGELOG.md +41 -28
- package/README.md +87 -247
- package/bin/cli.js +158 -358
- package/dist/__tests__/smoke.test.d.ts +8 -0
- package/dist/__tests__/smoke.test.d.ts.map +1 -0
- package/dist/__tests__/smoke.test.js +49 -0
- package/dist/__tests__/smoke.test.js.map +1 -0
- package/dist/cli/commands/beads.e2e.test.d.ts +13 -0
- package/dist/cli/commands/beads.e2e.test.d.ts.map +1 -0
- package/dist/cli/commands/beads.e2e.test.js +526 -0
- package/dist/cli/commands/beads.e2e.test.js.map +1 -0
- package/dist/cli/commands/cli-edge-cases.e2e.test.d.ts +32 -0
- package/dist/cli/commands/cli-edge-cases.e2e.test.d.ts.map +1 -0
- package/dist/cli/commands/cli-edge-cases.e2e.test.js +162 -0
- package/dist/cli/commands/cli-edge-cases.e2e.test.js.map +1 -0
- package/dist/cli/commands/close.d.ts +89 -0
- package/dist/cli/commands/close.d.ts.map +1 -0
- package/dist/cli/commands/close.e2e.test.d.ts +27 -0
- package/dist/cli/commands/close.e2e.test.d.ts.map +1 -0
- package/dist/cli/commands/close.e2e.test.js +252 -0
- package/dist/cli/commands/close.e2e.test.js.map +1 -0
- package/dist/cli/commands/close.js +309 -0
- package/dist/cli/commands/close.js.map +1 -0
- package/dist/cli/commands/close.test.d.ts +15 -0
- package/dist/cli/commands/close.test.d.ts.map +1 -0
- package/dist/cli/commands/close.test.js +634 -0
- package/dist/cli/commands/close.test.js.map +1 -0
- package/dist/cli/commands/doctor.d.ts +23 -0
- package/dist/cli/commands/doctor.d.ts.map +1 -1
- package/dist/cli/commands/doctor.js +93 -0
- package/dist/cli/commands/doctor.js.map +1 -1
- package/dist/cli/commands/doctor.test.js +209 -0
- package/dist/cli/commands/doctor.test.js.map +1 -1
- package/dist/cli/commands/framework-isolation.test.d.ts +30 -0
- package/dist/cli/commands/framework-isolation.test.d.ts.map +1 -0
- package/dist/cli/commands/framework-isolation.test.js +119 -0
- package/dist/cli/commands/framework-isolation.test.js.map +1 -0
- package/dist/cli/commands/help.e2e.test.js +4 -4
- package/dist/cli/commands/help.e2e.test.js.map +1 -1
- package/dist/cli/commands/init-logic.e2e.test.d.ts +37 -0
- package/dist/cli/commands/init-logic.e2e.test.d.ts.map +1 -0
- package/dist/cli/commands/init-logic.e2e.test.js +305 -0
- package/dist/cli/commands/init-logic.e2e.test.js.map +1 -0
- package/dist/cli/commands/land.d.ts +142 -0
- package/dist/cli/commands/land.d.ts.map +1 -0
- package/dist/cli/commands/land.js +647 -0
- package/dist/cli/commands/land.js.map +1 -0
- package/dist/cli/commands/land.test.d.ts +20 -0
- package/dist/cli/commands/land.test.d.ts.map +1 -0
- package/dist/cli/commands/land.test.js +622 -0
- package/dist/cli/commands/land.test.js.map +1 -0
- package/dist/cli/commands/mcp.e2e.test.js +22 -29
- package/dist/cli/commands/mcp.e2e.test.js.map +1 -1
- package/dist/cli/commands/pipeline.e2e.test.js +20 -20
- package/dist/cli/commands/pipeline.e2e.test.js.map +1 -1
- package/dist/cli/commands/pre-push-guard.d.ts +84 -0
- package/dist/cli/commands/pre-push-guard.d.ts.map +1 -0
- package/dist/cli/commands/pre-push-guard.e2e.test.d.ts +24 -0
- package/dist/cli/commands/pre-push-guard.e2e.test.d.ts.map +1 -0
- package/dist/cli/commands/pre-push-guard.e2e.test.js +171 -0
- package/dist/cli/commands/pre-push-guard.e2e.test.js.map +1 -0
- package/dist/cli/commands/pre-push-guard.js +257 -0
- package/dist/cli/commands/pre-push-guard.js.map +1 -0
- package/dist/cli/commands/pre-push-guard.test.d.ts +15 -0
- package/dist/cli/commands/pre-push-guard.test.d.ts.map +1 -0
- package/dist/cli/commands/pre-push-guard.test.js +397 -0
- package/dist/cli/commands/pre-push-guard.test.js.map +1 -0
- package/dist/cli/commands/quickstart-expanded.e2e.test.d.ts +23 -0
- package/dist/cli/commands/quickstart-expanded.e2e.test.d.ts.map +1 -0
- package/dist/cli/commands/quickstart-expanded.e2e.test.js +179 -0
- package/dist/cli/commands/quickstart-expanded.e2e.test.js.map +1 -0
- package/dist/cli/commands/quickstart.d.ts.map +1 -1
- package/dist/cli/commands/quickstart.js +7 -23
- package/dist/cli/commands/quickstart.js.map +1 -1
- package/dist/cli/commands/quickstart.test.js +40 -67
- package/dist/cli/commands/quickstart.test.js.map +1 -1
- package/dist/core/agents/suite.test.js +4 -2
- package/dist/core/agents/suite.test.js.map +1 -1
- package/dist/core/agents/tools.test.js +5 -1
- package/dist/core/agents/tools.test.js.map +1 -1
- package/dist/index.d.ts +3 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -10
- package/dist/index.js.map +1 -1
- package/package.json +15 -9
- package/sbom.json +2011 -819
- package/templates/.github/agents/beth.agent.md +220 -66
- package/templates/.github/agents/developer.agent.md +53 -90
- package/templates/.github/agents/product-manager.agent.md +15 -68
- package/templates/.github/agents/researcher.agent.md +20 -71
- package/templates/.github/agents/security-reviewer.agent.md +29 -81
- package/templates/.github/agents/tester.agent.md +40 -69
- package/templates/.github/agents/ux-designer.agent.md +20 -74
- package/templates/.github/copilot-instructions.md +217 -225
- package/templates/AGENTS.md +108 -20
- package/templates/mcp.json.example +0 -3
- package/dist/cli/commands/client-config.d.ts +0 -31
- package/dist/cli/commands/client-config.d.ts.map +0 -1
- package/dist/cli/commands/client-config.e2e.test.d.ts +0 -15
- package/dist/cli/commands/client-config.e2e.test.d.ts.map +0 -1
- package/dist/cli/commands/client-config.e2e.test.js +0 -556
- package/dist/cli/commands/client-config.e2e.test.js.map +0 -1
- package/dist/cli/commands/client-config.js +0 -73
- package/dist/cli/commands/client-config.js.map +0 -1
- package/dist/cli/commands/client-config.test.d.ts +0 -6
- package/dist/cli/commands/client-config.test.d.ts.map +0 -1
- package/dist/cli/commands/client-config.test.js +0 -133
- package/dist/cli/commands/client-config.test.js.map +0 -1
- package/dist/cli/commands/init-quickstart.e2e.test.d.ts +0 -11
- package/dist/cli/commands/init-quickstart.e2e.test.d.ts.map +0 -1
- package/dist/cli/commands/init-quickstart.e2e.test.js +0 -221
- package/dist/cli/commands/init-quickstart.e2e.test.js.map +0 -1
- package/dist/core/context.d.ts +0 -171
- package/dist/core/context.d.ts.map +0 -1
- package/dist/core/context.js +0 -353
- package/dist/core/context.js.map +0 -1
- package/dist/core/context.test.d.ts +0 -8
- package/dist/core/context.test.d.ts.map +0 -1
- package/dist/core/context.test.js +0 -253
- package/dist/core/context.test.js.map +0 -1
- package/dist/core/handoffs.d.ts +0 -151
- package/dist/core/handoffs.d.ts.map +0 -1
- package/dist/core/handoffs.js +0 -220
- package/dist/core/handoffs.js.map +0 -1
- package/dist/core/handoffs.test.d.ts +0 -8
- package/dist/core/handoffs.test.d.ts.map +0 -1
- package/dist/core/handoffs.test.js +0 -231
- package/dist/core/handoffs.test.js.map +0 -1
- package/dist/core/orchestrator.d.ts +0 -246
- package/dist/core/orchestrator.d.ts.map +0 -1
- package/dist/core/orchestrator.js +0 -514
- package/dist/core/orchestrator.js.map +0 -1
- package/dist/core/orchestrator.test.d.ts +0 -8
- package/dist/core/orchestrator.test.d.ts.map +0 -1
- package/dist/core/orchestrator.test.js +0 -517
- package/dist/core/orchestrator.test.js.map +0 -1
- package/dist/core/router.d.ts +0 -102
- package/dist/core/router.d.ts.map +0 -1
- package/dist/core/router.js +0 -178
- package/dist/core/router.js.map +0 -1
- package/dist/core/router.test.d.ts +0 -8
- package/dist/core/router.test.d.ts.map +0 -1
- package/dist/core/router.test.js +0 -215
- package/dist/core/router.test.js.map +0 -1
- package/dist/init.test.js +0 -288
- package/dist/providers/azure.d.ts +0 -147
- package/dist/providers/azure.d.ts.map +0 -1
- package/dist/providers/azure.js +0 -491
- package/dist/providers/azure.js.map +0 -1
- package/dist/providers/azure.test.d.ts +0 -11
- package/dist/providers/azure.test.d.ts.map +0 -1
- package/dist/providers/azure.test.js +0 -330
- package/dist/providers/azure.test.js.map +0 -1
- package/dist/providers/config.d.ts +0 -87
- package/dist/providers/config.d.ts.map +0 -1
- package/dist/providers/config.js +0 -193
- package/dist/providers/config.js.map +0 -1
- package/dist/providers/config.test.d.ts +0 -7
- package/dist/providers/config.test.d.ts.map +0 -1
- package/dist/providers/config.test.js +0 -370
- package/dist/providers/config.test.js.map +0 -1
- package/dist/providers/index.d.ts +0 -18
- package/dist/providers/index.d.ts.map +0 -1
- package/dist/providers/index.js +0 -14
- package/dist/providers/index.js.map +0 -1
- package/dist/providers/interface.d.ts +0 -191
- package/dist/providers/interface.d.ts.map +0 -1
- package/dist/providers/interface.js +0 -94
- package/dist/providers/interface.js.map +0 -1
- package/dist/providers/retry.d.ts +0 -128
- package/dist/providers/retry.d.ts.map +0 -1
- package/dist/providers/retry.js +0 -205
- package/dist/providers/retry.js.map +0 -1
- package/dist/providers/retry.test.d.ts +0 -7
- package/dist/providers/retry.test.d.ts.map +0 -1
- package/dist/providers/retry.test.js +0 -439
- package/dist/providers/retry.test.js.map +0 -1
- package/dist/providers/streaming.d.ts +0 -157
- package/dist/providers/streaming.d.ts.map +0 -1
- package/dist/providers/streaming.js +0 -233
- package/dist/providers/streaming.js.map +0 -1
- package/dist/providers/streaming.test.d.ts +0 -7
- package/dist/providers/streaming.test.d.ts.map +0 -1
- package/dist/providers/streaming.test.js +0 -372
- package/dist/providers/streaming.test.js.map +0 -1
- package/dist/providers/types.d.ts +0 -209
- package/dist/providers/types.d.ts.map +0 -1
- package/dist/providers/types.js +0 -53
- package/dist/providers/types.js.map +0 -1
- package/dist/providers/types.test.d.ts +0 -7
- package/dist/providers/types.test.d.ts.map +0 -1
- package/dist/providers/types.test.js +0 -141
- package/dist/providers/types.test.js.map +0 -1
- package/dist/tools/cli/beads.d.ts +0 -27
- package/dist/tools/cli/beads.d.ts.map +0 -1
- package/dist/tools/cli/beads.js +0 -172
- package/dist/tools/cli/beads.js.map +0 -1
- package/dist/tools/cli/beads.test.d.ts +0 -8
- package/dist/tools/cli/beads.test.d.ts.map +0 -1
- package/dist/tools/cli/beads.test.js +0 -264
- package/dist/tools/cli/beads.test.js.map +0 -1
- package/dist/tools/cli/editFile.d.ts +0 -17
- package/dist/tools/cli/editFile.d.ts.map +0 -1
- package/dist/tools/cli/editFile.js +0 -125
- package/dist/tools/cli/editFile.js.map +0 -1
- package/dist/tools/cli/editFile.test.d.ts +0 -8
- package/dist/tools/cli/editFile.test.d.ts.map +0 -1
- package/dist/tools/cli/editFile.test.js +0 -177
- package/dist/tools/cli/editFile.test.js.map +0 -1
- package/dist/tools/cli/readFile.d.ts +0 -25
- package/dist/tools/cli/readFile.d.ts.map +0 -1
- package/dist/tools/cli/readFile.js +0 -118
- package/dist/tools/cli/readFile.js.map +0 -1
- package/dist/tools/cli/readFile.test.d.ts +0 -8
- package/dist/tools/cli/readFile.test.d.ts.map +0 -1
- package/dist/tools/cli/readFile.test.js +0 -194
- package/dist/tools/cli/readFile.test.js.map +0 -1
- package/dist/tools/cli/search.d.ts +0 -16
- package/dist/tools/cli/search.d.ts.map +0 -1
- package/dist/tools/cli/search.js +0 -261
- package/dist/tools/cli/search.js.map +0 -1
- package/dist/tools/cli/search.test.d.ts +0 -8
- package/dist/tools/cli/search.test.d.ts.map +0 -1
- package/dist/tools/cli/search.test.js +0 -172
- package/dist/tools/cli/search.test.js.map +0 -1
- package/dist/tools/cli/subagent.d.ts +0 -43
- package/dist/tools/cli/subagent.d.ts.map +0 -1
- package/dist/tools/cli/subagent.js +0 -99
- package/dist/tools/cli/subagent.js.map +0 -1
- package/dist/tools/cli/subagent.test.d.ts +0 -8
- package/dist/tools/cli/subagent.test.d.ts.map +0 -1
- package/dist/tools/cli/subagent.test.js +0 -190
- package/dist/tools/cli/subagent.test.js.map +0 -1
- package/dist/tools/cli/terminal.d.ts +0 -19
- package/dist/tools/cli/terminal.d.ts.map +0 -1
- package/dist/tools/cli/terminal.js +0 -164
- package/dist/tools/cli/terminal.js.map +0 -1
- package/dist/tools/cli/terminal.test.d.ts +0 -8
- package/dist/tools/cli/terminal.test.d.ts.map +0 -1
- package/dist/tools/cli/terminal.test.js +0 -161
- package/dist/tools/cli/terminal.test.js.map +0 -1
- package/dist/tools/index.d.ts +0 -25
- package/dist/tools/index.d.ts.map +0 -1
- package/dist/tools/index.js +0 -41
- package/dist/tools/index.js.map +0 -1
- package/dist/tools/interface.d.ts +0 -64
- package/dist/tools/interface.d.ts.map +0 -1
- package/dist/tools/interface.js +0 -37
- package/dist/tools/interface.js.map +0 -1
- package/dist/tools/interface.test.d.ts +0 -7
- package/dist/tools/interface.test.d.ts.map +0 -1
- package/dist/tools/interface.test.js +0 -179
- package/dist/tools/interface.test.js.map +0 -1
- package/dist/tools/mcp/bridge.d.ts +0 -48
- package/dist/tools/mcp/bridge.d.ts.map +0 -1
- package/dist/tools/mcp/bridge.js +0 -128
- package/dist/tools/mcp/bridge.js.map +0 -1
- package/dist/tools/mcp/bridge.test.d.ts +0 -8
- package/dist/tools/mcp/bridge.test.d.ts.map +0 -1
- package/dist/tools/mcp/bridge.test.js +0 -300
- package/dist/tools/mcp/bridge.test.js.map +0 -1
- package/dist/tools/mcp/client.d.ts +0 -135
- package/dist/tools/mcp/client.d.ts.map +0 -1
- package/dist/tools/mcp/client.js +0 -263
- package/dist/tools/mcp/client.js.map +0 -1
- package/dist/tools/mcp/client.test.d.ts +0 -8
- package/dist/tools/mcp/client.test.d.ts.map +0 -1
- package/dist/tools/mcp/client.test.js +0 -390
- package/dist/tools/mcp/client.test.js.map +0 -1
- package/dist/tools/registry.d.ts +0 -82
- package/dist/tools/registry.d.ts.map +0 -1
- package/dist/tools/registry.js +0 -99
- package/dist/tools/registry.js.map +0 -1
- package/dist/tools/registry.test.d.ts +0 -7
- package/dist/tools/registry.test.d.ts.map +0 -1
- package/dist/tools/registry.test.js +0 -199
- package/dist/tools/registry.test.js.map +0 -1
- package/dist/tools/suite.test.d.ts +0 -11
- package/dist/tools/suite.test.d.ts.map +0 -1
- package/dist/tools/suite.test.js +0 -119
- package/dist/tools/suite.test.js.map +0 -1
- package/dist/tools/types.d.ts +0 -75
- package/dist/tools/types.d.ts.map +0 -1
- package/dist/tools/types.js +0 -30
- package/dist/tools/types.js.map +0 -1
- package/dist/tools/types.test.d.ts +0 -7
- package/dist/tools/types.test.d.ts.map +0 -1
- package/dist/tools/types.test.js +0 -178
- package/dist/tools/types.test.js.map +0 -1
- package/templates/.vscode/mcp.json +0 -20
- 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"}
|