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
|
@@ -0,0 +1,397 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pre-Push Guard Tests
|
|
3
|
+
*
|
|
4
|
+
* Tests branch discipline enforcement:
|
|
5
|
+
* - Push ref parsing from Git stdin
|
|
6
|
+
* - Branch name extraction from refs
|
|
7
|
+
* - Protected branch detection
|
|
8
|
+
* - Epic branch convention validation
|
|
9
|
+
* - Release branch recognition
|
|
10
|
+
* - Guard logic: errors vs warnings
|
|
11
|
+
* - Hook script generation
|
|
12
|
+
* - Beads in-progress issue detection
|
|
13
|
+
*/
|
|
14
|
+
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
15
|
+
import * as child_process from 'child_process';
|
|
16
|
+
// Mock child_process before importing the module under test
|
|
17
|
+
vi.mock('child_process', () => ({
|
|
18
|
+
execFileSync: vi.fn(),
|
|
19
|
+
}));
|
|
20
|
+
import { parsePushRefs, extractBranchName, isProtectedBranch, isEpicBranch, isReleaseBranch, isRecognizedBranch, runGuard, getInProgressIssues, generateHookScript, BETH_GUARD_BEGIN, BETH_GUARD_END, } from './pre-push-guard.js';
|
|
21
|
+
const mockedExecFileSync = vi.mocked(child_process.execFileSync);
|
|
22
|
+
beforeEach(() => {
|
|
23
|
+
vi.clearAllMocks();
|
|
24
|
+
});
|
|
25
|
+
// ─── parsePushRefs ─────────────────────────────────────────────────────────────
|
|
26
|
+
describe('parsePushRefs', () => {
|
|
27
|
+
it('parses a single push ref line', () => {
|
|
28
|
+
const stdin = 'refs/heads/epic/beth-abc 1234567 refs/heads/epic/beth-abc 0000000';
|
|
29
|
+
const refs = parsePushRefs(stdin);
|
|
30
|
+
expect(refs).toHaveLength(1);
|
|
31
|
+
expect(refs[0]).toEqual({
|
|
32
|
+
localRef: 'refs/heads/epic/beth-abc',
|
|
33
|
+
localSha: '1234567',
|
|
34
|
+
remoteRef: 'refs/heads/epic/beth-abc',
|
|
35
|
+
remoteSha: '0000000',
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
it('parses multiple push ref lines', () => {
|
|
39
|
+
const stdin = [
|
|
40
|
+
'refs/heads/epic/beth-abc 1111111 refs/heads/epic/beth-abc 0000000',
|
|
41
|
+
'refs/heads/epic/beth-def 2222222 refs/heads/epic/beth-def 0000000',
|
|
42
|
+
].join('\n');
|
|
43
|
+
const refs = parsePushRefs(stdin);
|
|
44
|
+
expect(refs).toHaveLength(2);
|
|
45
|
+
expect(refs[0].localRef).toBe('refs/heads/epic/beth-abc');
|
|
46
|
+
expect(refs[1].localRef).toBe('refs/heads/epic/beth-def');
|
|
47
|
+
});
|
|
48
|
+
it('handles empty stdin', () => {
|
|
49
|
+
expect(parsePushRefs('')).toHaveLength(0);
|
|
50
|
+
expect(parsePushRefs(' ')).toHaveLength(0);
|
|
51
|
+
expect(parsePushRefs('\n')).toHaveLength(0);
|
|
52
|
+
});
|
|
53
|
+
it('handles trailing newlines', () => {
|
|
54
|
+
const stdin = 'refs/heads/epic/beth-abc 1234567 refs/heads/epic/beth-abc 0000000\n\n';
|
|
55
|
+
const refs = parsePushRefs(stdin);
|
|
56
|
+
expect(refs).toHaveLength(1);
|
|
57
|
+
});
|
|
58
|
+
it('handles partial lines gracefully', () => {
|
|
59
|
+
const stdin = 'refs/heads/main';
|
|
60
|
+
const refs = parsePushRefs(stdin);
|
|
61
|
+
expect(refs).toHaveLength(1);
|
|
62
|
+
expect(refs[0].localRef).toBe('refs/heads/main');
|
|
63
|
+
expect(refs[0].localSha).toBe('');
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
// ─── extractBranchName ─────────────────────────────────────────────────────────
|
|
67
|
+
describe('extractBranchName', () => {
|
|
68
|
+
it('strips refs/heads/ prefix', () => {
|
|
69
|
+
expect(extractBranchName('refs/heads/main')).toBe('main');
|
|
70
|
+
expect(extractBranchName('refs/heads/epic/beth-abc')).toBe('epic/beth-abc');
|
|
71
|
+
});
|
|
72
|
+
it('returns ref as-is when no prefix', () => {
|
|
73
|
+
expect(extractBranchName('main')).toBe('main');
|
|
74
|
+
expect(extractBranchName('epic/beth-abc')).toBe('epic/beth-abc');
|
|
75
|
+
});
|
|
76
|
+
it('handles refs/tags (not stripped)', () => {
|
|
77
|
+
expect(extractBranchName('refs/tags/v1.0.0')).toBe('refs/tags/v1.0.0');
|
|
78
|
+
});
|
|
79
|
+
it('handles empty string', () => {
|
|
80
|
+
expect(extractBranchName('')).toBe('');
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
// ─── isProtectedBranch ─────────────────────────────────────────────────────────
|
|
84
|
+
describe('isProtectedBranch', () => {
|
|
85
|
+
it('identifies main as protected', () => {
|
|
86
|
+
expect(isProtectedBranch('main')).toBe(true);
|
|
87
|
+
});
|
|
88
|
+
it('identifies master as protected', () => {
|
|
89
|
+
expect(isProtectedBranch('master')).toBe(true);
|
|
90
|
+
});
|
|
91
|
+
it('rejects epic branches', () => {
|
|
92
|
+
expect(isProtectedBranch('epic/beth-abc')).toBe(false);
|
|
93
|
+
});
|
|
94
|
+
it('rejects release branches', () => {
|
|
95
|
+
expect(isProtectedBranch('release/v1.0.0')).toBe(false);
|
|
96
|
+
});
|
|
97
|
+
it('rejects random branches', () => {
|
|
98
|
+
expect(isProtectedBranch('feature/foo')).toBe(false);
|
|
99
|
+
expect(isProtectedBranch('')).toBe(false);
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
// ─── isEpicBranch ──────────────────────────────────────────────────────────────
|
|
103
|
+
describe('isEpicBranch', () => {
|
|
104
|
+
it('accepts valid epic branches', () => {
|
|
105
|
+
expect(isEpicBranch('epic/beth-abc')).toBe(true);
|
|
106
|
+
expect(isEpicBranch('epic/beth-abc123')).toBe(true);
|
|
107
|
+
expect(isEpicBranch('epic/hq-xyz')).toBe(true);
|
|
108
|
+
expect(isEpicBranch('epic/beth-bdh')).toBe(true);
|
|
109
|
+
});
|
|
110
|
+
it('rejects branches without epic/ prefix', () => {
|
|
111
|
+
expect(isEpicBranch('beth-abc')).toBe(false);
|
|
112
|
+
expect(isEpicBranch('feature/beth-abc')).toBe(false);
|
|
113
|
+
});
|
|
114
|
+
it('rejects branches with uppercase', () => {
|
|
115
|
+
expect(isEpicBranch('epic/BETH-abc')).toBe(false);
|
|
116
|
+
expect(isEpicBranch('epic/Beth-Abc')).toBe(false);
|
|
117
|
+
});
|
|
118
|
+
it('rejects branches without rig-hash format', () => {
|
|
119
|
+
expect(isEpicBranch('epic/justwords')).toBe(false);
|
|
120
|
+
expect(isEpicBranch('epic/')).toBe(false);
|
|
121
|
+
expect(isEpicBranch('epic/a-')).toBe(false);
|
|
122
|
+
});
|
|
123
|
+
it('rejects branches with special characters', () => {
|
|
124
|
+
expect(isEpicBranch('epic/beth-abc; rm -rf /')).toBe(false);
|
|
125
|
+
expect(isEpicBranch('epic/beth-abc$(whoami)')).toBe(false);
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
// ─── isReleaseBranch ───────────────────────────────────────────────────────────
|
|
129
|
+
describe('isReleaseBranch', () => {
|
|
130
|
+
it('accepts release branches with v prefix', () => {
|
|
131
|
+
expect(isReleaseBranch('release/v1.0.0')).toBe(true);
|
|
132
|
+
expect(isReleaseBranch('release/v2')).toBe(true);
|
|
133
|
+
expect(isReleaseBranch('release/v1.0.15')).toBe(true);
|
|
134
|
+
});
|
|
135
|
+
it('accepts release branches without v prefix', () => {
|
|
136
|
+
expect(isReleaseBranch('release/1.0.0')).toBe(true);
|
|
137
|
+
expect(isReleaseBranch('release/2')).toBe(true);
|
|
138
|
+
});
|
|
139
|
+
it('rejects non-release branches', () => {
|
|
140
|
+
expect(isReleaseBranch('main')).toBe(false);
|
|
141
|
+
expect(isReleaseBranch('epic/beth-abc')).toBe(false);
|
|
142
|
+
expect(isReleaseBranch('release/')).toBe(false);
|
|
143
|
+
expect(isReleaseBranch('release/abc')).toBe(false);
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
// ─── isRecognizedBranch ────────────────────────────────────────────────────────
|
|
147
|
+
describe('isRecognizedBranch', () => {
|
|
148
|
+
it('recognizes epic branches', () => {
|
|
149
|
+
expect(isRecognizedBranch('epic/beth-abc')).toBe(true);
|
|
150
|
+
});
|
|
151
|
+
it('recognizes release branches', () => {
|
|
152
|
+
expect(isRecognizedBranch('release/v1.0.0')).toBe(true);
|
|
153
|
+
});
|
|
154
|
+
it('recognizes protected branches', () => {
|
|
155
|
+
expect(isRecognizedBranch('main')).toBe(true);
|
|
156
|
+
expect(isRecognizedBranch('master')).toBe(true);
|
|
157
|
+
});
|
|
158
|
+
it('rejects unrecognized branches', () => {
|
|
159
|
+
expect(isRecognizedBranch('feature/foo')).toBe(false);
|
|
160
|
+
expect(isRecognizedBranch('bugfix/bar')).toBe(false);
|
|
161
|
+
expect(isRecognizedBranch('dev')).toBe(false);
|
|
162
|
+
expect(isRecognizedBranch('')).toBe(false);
|
|
163
|
+
});
|
|
164
|
+
});
|
|
165
|
+
// ─── getInProgressIssues ───────────────────────────────────────────────────────
|
|
166
|
+
describe('getInProgressIssues', () => {
|
|
167
|
+
it('returns in-progress issues from bd list', () => {
|
|
168
|
+
mockedExecFileSync.mockReturnValueOnce(JSON.stringify([
|
|
169
|
+
{ id: 'beth-abc', title: 'Task A', status: 'in_progress' },
|
|
170
|
+
{ id: 'beth-def', title: 'Task B', status: 'open' },
|
|
171
|
+
{ id: 'beth-ghi', title: 'Task C', status: 'in_progress' },
|
|
172
|
+
]));
|
|
173
|
+
const result = getInProgressIssues();
|
|
174
|
+
expect(result).toHaveLength(2);
|
|
175
|
+
expect(result[0]).toEqual({ id: 'beth-abc', title: 'Task A' });
|
|
176
|
+
expect(result[1]).toEqual({ id: 'beth-ghi', title: 'Task C' });
|
|
177
|
+
});
|
|
178
|
+
it('returns empty array when no in-progress issues', () => {
|
|
179
|
+
mockedExecFileSync.mockReturnValueOnce(JSON.stringify([
|
|
180
|
+
{ id: 'beth-abc', title: 'Task A', status: 'open' },
|
|
181
|
+
{ id: 'beth-def', title: 'Task B', status: 'closed' },
|
|
182
|
+
]));
|
|
183
|
+
expect(getInProgressIssues()).toHaveLength(0);
|
|
184
|
+
});
|
|
185
|
+
it('returns empty array when bd is unavailable', () => {
|
|
186
|
+
mockedExecFileSync.mockImplementationOnce(() => {
|
|
187
|
+
throw new Error('bd not found');
|
|
188
|
+
});
|
|
189
|
+
expect(getInProgressIssues()).toHaveLength(0);
|
|
190
|
+
});
|
|
191
|
+
it('returns empty array on invalid JSON', () => {
|
|
192
|
+
mockedExecFileSync.mockReturnValueOnce('not json');
|
|
193
|
+
expect(getInProgressIssues()).toHaveLength(0);
|
|
194
|
+
});
|
|
195
|
+
it('returns empty array when bd returns non-array', () => {
|
|
196
|
+
mockedExecFileSync.mockReturnValueOnce(JSON.stringify({ error: 'nope' }));
|
|
197
|
+
expect(getInProgressIssues()).toHaveLength(0);
|
|
198
|
+
});
|
|
199
|
+
it('filters out items missing required fields', () => {
|
|
200
|
+
mockedExecFileSync.mockReturnValueOnce(JSON.stringify([
|
|
201
|
+
{ id: 'beth-abc', status: 'in_progress' }, // missing title
|
|
202
|
+
{ title: 'Task B', status: 'in_progress' }, // missing id
|
|
203
|
+
{ id: 'beth-ccc', title: 'Task C', status: 'in_progress' }, // valid
|
|
204
|
+
]));
|
|
205
|
+
const result = getInProgressIssues();
|
|
206
|
+
expect(result).toHaveLength(1);
|
|
207
|
+
expect(result[0].id).toBe('beth-ccc');
|
|
208
|
+
});
|
|
209
|
+
});
|
|
210
|
+
// ─── runGuard ──────────────────────────────────────────────────────────────────
|
|
211
|
+
describe('runGuard', () => {
|
|
212
|
+
describe('protected branch blocking', () => {
|
|
213
|
+
it('blocks push when current branch is main', () => {
|
|
214
|
+
const result = runGuard('main', undefined, false);
|
|
215
|
+
expect(result.allowed).toBe(false);
|
|
216
|
+
expect(result.errors).toHaveLength(1);
|
|
217
|
+
expect(result.errors[0]).toContain('main');
|
|
218
|
+
expect(result.errors[0]).toContain('blocked');
|
|
219
|
+
});
|
|
220
|
+
it('blocks push when current branch is master', () => {
|
|
221
|
+
const result = runGuard('master', undefined, false);
|
|
222
|
+
expect(result.allowed).toBe(false);
|
|
223
|
+
expect(result.errors[0]).toContain('master');
|
|
224
|
+
});
|
|
225
|
+
it('blocks push when remote ref targets main', () => {
|
|
226
|
+
const refs = [
|
|
227
|
+
{
|
|
228
|
+
localRef: 'refs/heads/feature/x',
|
|
229
|
+
localSha: '111',
|
|
230
|
+
remoteRef: 'refs/heads/main',
|
|
231
|
+
remoteSha: '000',
|
|
232
|
+
},
|
|
233
|
+
];
|
|
234
|
+
const result = runGuard('feature/x', refs, false);
|
|
235
|
+
expect(result.allowed).toBe(false);
|
|
236
|
+
expect(result.errors[0]).toContain("'main'");
|
|
237
|
+
});
|
|
238
|
+
it('blocks push when remote ref targets master', () => {
|
|
239
|
+
const refs = [
|
|
240
|
+
{
|
|
241
|
+
localRef: 'refs/heads/feature/x',
|
|
242
|
+
localSha: '111',
|
|
243
|
+
remoteRef: 'refs/heads/master',
|
|
244
|
+
remoteSha: '000',
|
|
245
|
+
},
|
|
246
|
+
];
|
|
247
|
+
const result = runGuard('feature/x', refs, false);
|
|
248
|
+
expect(result.allowed).toBe(false);
|
|
249
|
+
});
|
|
250
|
+
it('deduplicates error when both current branch and ref target main', () => {
|
|
251
|
+
const refs = [
|
|
252
|
+
{
|
|
253
|
+
localRef: 'refs/heads/main',
|
|
254
|
+
localSha: '111',
|
|
255
|
+
remoteRef: 'refs/heads/main',
|
|
256
|
+
remoteSha: '000',
|
|
257
|
+
},
|
|
258
|
+
];
|
|
259
|
+
const result = runGuard('main', refs, false);
|
|
260
|
+
expect(result.allowed).toBe(false);
|
|
261
|
+
// Should have error about remote ref + error about pushing from main
|
|
262
|
+
// The current-branch check deduplicates if the branch name is already in errors
|
|
263
|
+
expect(result.errors.length).toBeGreaterThanOrEqual(1);
|
|
264
|
+
});
|
|
265
|
+
});
|
|
266
|
+
describe('branch convention warnings', () => {
|
|
267
|
+
it('does not warn on epic branches', () => {
|
|
268
|
+
const result = runGuard('epic/beth-abc', undefined, false);
|
|
269
|
+
expect(result.allowed).toBe(true);
|
|
270
|
+
expect(result.warnings).toHaveLength(0);
|
|
271
|
+
});
|
|
272
|
+
it('does not warn on release branches', () => {
|
|
273
|
+
const result = runGuard('release/v1.0.0', undefined, false);
|
|
274
|
+
expect(result.allowed).toBe(true);
|
|
275
|
+
expect(result.warnings).toHaveLength(0);
|
|
276
|
+
});
|
|
277
|
+
it('warns on unrecognized branch names', () => {
|
|
278
|
+
const result = runGuard('feature/random', undefined, false);
|
|
279
|
+
expect(result.allowed).toBe(true);
|
|
280
|
+
expect(result.warnings).toHaveLength(1);
|
|
281
|
+
expect(result.warnings[0]).toContain('feature/random');
|
|
282
|
+
expect(result.warnings[0]).toContain('epic/<id>');
|
|
283
|
+
});
|
|
284
|
+
it('warns on branches like dev or staging', () => {
|
|
285
|
+
const result = runGuard('dev', undefined, false);
|
|
286
|
+
expect(result.allowed).toBe(true);
|
|
287
|
+
expect(result.warnings[0]).toContain('dev');
|
|
288
|
+
});
|
|
289
|
+
it('handles null currentBranch (detached HEAD)', () => {
|
|
290
|
+
const result = runGuard(null, undefined, false);
|
|
291
|
+
expect(result.allowed).toBe(true);
|
|
292
|
+
expect(result.warnings).toHaveLength(0);
|
|
293
|
+
expect(result.errors).toHaveLength(0);
|
|
294
|
+
});
|
|
295
|
+
});
|
|
296
|
+
describe('beads in-progress check', () => {
|
|
297
|
+
it('warns when there are in-progress issues', () => {
|
|
298
|
+
mockedExecFileSync.mockReturnValueOnce(JSON.stringify([
|
|
299
|
+
{ id: 'beth-abc', title: 'Unfinished work', status: 'in_progress' },
|
|
300
|
+
]));
|
|
301
|
+
const result = runGuard('epic/beth-abc', undefined, true);
|
|
302
|
+
expect(result.allowed).toBe(true); // warning only, not blocking
|
|
303
|
+
expect(result.warnings.length).toBeGreaterThan(0);
|
|
304
|
+
expect(result.warnings.some((w) => w.includes('in_progress'))).toBe(true);
|
|
305
|
+
});
|
|
306
|
+
it('no warning when no in-progress issues', () => {
|
|
307
|
+
mockedExecFileSync.mockReturnValueOnce(JSON.stringify([
|
|
308
|
+
{ id: 'beth-abc', title: 'Done', status: 'closed' },
|
|
309
|
+
]));
|
|
310
|
+
const result = runGuard('epic/beth-abc', undefined, true);
|
|
311
|
+
expect(result.warnings).toHaveLength(0);
|
|
312
|
+
});
|
|
313
|
+
it('skips beads check when checkBeads is false', () => {
|
|
314
|
+
const result = runGuard('epic/beth-abc', undefined, false);
|
|
315
|
+
expect(result.warnings).toHaveLength(0);
|
|
316
|
+
expect(mockedExecFileSync).not.toHaveBeenCalled();
|
|
317
|
+
});
|
|
318
|
+
it('does not block on beads errors', () => {
|
|
319
|
+
mockedExecFileSync.mockImplementationOnce(() => {
|
|
320
|
+
throw new Error('bd timeout');
|
|
321
|
+
});
|
|
322
|
+
const result = runGuard('epic/beth-abc', undefined, true);
|
|
323
|
+
expect(result.allowed).toBe(true);
|
|
324
|
+
});
|
|
325
|
+
});
|
|
326
|
+
describe('happy path', () => {
|
|
327
|
+
it('allows push from epic branch to epic remote', () => {
|
|
328
|
+
const refs = [
|
|
329
|
+
{
|
|
330
|
+
localRef: 'refs/heads/epic/beth-abc',
|
|
331
|
+
localSha: '111',
|
|
332
|
+
remoteRef: 'refs/heads/epic/beth-abc',
|
|
333
|
+
remoteSha: '000',
|
|
334
|
+
},
|
|
335
|
+
];
|
|
336
|
+
const result = runGuard('epic/beth-abc', refs, false);
|
|
337
|
+
expect(result.allowed).toBe(true);
|
|
338
|
+
expect(result.errors).toHaveLength(0);
|
|
339
|
+
expect(result.warnings).toHaveLength(0);
|
|
340
|
+
});
|
|
341
|
+
it('allows push from release branch', () => {
|
|
342
|
+
const refs = [
|
|
343
|
+
{
|
|
344
|
+
localRef: 'refs/heads/release/v1.0.15',
|
|
345
|
+
localSha: '111',
|
|
346
|
+
remoteRef: 'refs/heads/release/v1.0.15',
|
|
347
|
+
remoteSha: '000',
|
|
348
|
+
},
|
|
349
|
+
];
|
|
350
|
+
const result = runGuard('release/v1.0.15', refs, false);
|
|
351
|
+
expect(result.allowed).toBe(true);
|
|
352
|
+
});
|
|
353
|
+
it('allows push with no refs (branch deletion)', () => {
|
|
354
|
+
const result = runGuard('epic/beth-abc', [], false);
|
|
355
|
+
expect(result.allowed).toBe(true);
|
|
356
|
+
});
|
|
357
|
+
});
|
|
358
|
+
});
|
|
359
|
+
// ─── generateHookScript ────────────────────────────────────────────────────────
|
|
360
|
+
describe('generateHookScript', () => {
|
|
361
|
+
it('contains begin and end markers', () => {
|
|
362
|
+
const script = generateHookScript();
|
|
363
|
+
expect(script).toContain(BETH_GUARD_BEGIN);
|
|
364
|
+
expect(script).toContain(BETH_GUARD_END);
|
|
365
|
+
});
|
|
366
|
+
it('contains bypass check', () => {
|
|
367
|
+
const script = generateHookScript();
|
|
368
|
+
expect(script).toContain('BETH_SKIP_PUSH_GUARD');
|
|
369
|
+
});
|
|
370
|
+
it('blocks main and master', () => {
|
|
371
|
+
const script = generateHookScript();
|
|
372
|
+
expect(script).toContain('main|master');
|
|
373
|
+
});
|
|
374
|
+
it('checks for epic branch pattern', () => {
|
|
375
|
+
const script = generateHookScript();
|
|
376
|
+
expect(script).toContain('epic/*');
|
|
377
|
+
});
|
|
378
|
+
it('checks for release branch pattern', () => {
|
|
379
|
+
const script = generateHookScript();
|
|
380
|
+
expect(script).toContain('release/*');
|
|
381
|
+
});
|
|
382
|
+
it('outputs to stderr', () => {
|
|
383
|
+
const script = generateHookScript();
|
|
384
|
+
// All echo statements should go to stderr (>&2)
|
|
385
|
+
const echoLines = script
|
|
386
|
+
.split('\n')
|
|
387
|
+
.filter((line) => line.trim().startsWith('echo '));
|
|
388
|
+
for (const line of echoLines) {
|
|
389
|
+
expect(line).toContain('>&2');
|
|
390
|
+
}
|
|
391
|
+
});
|
|
392
|
+
it('exits 1 when blocked', () => {
|
|
393
|
+
const script = generateHookScript();
|
|
394
|
+
expect(script).toContain('exit 1');
|
|
395
|
+
});
|
|
396
|
+
});
|
|
397
|
+
//# sourceMappingURL=pre-push-guard.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pre-push-guard.test.js","sourceRoot":"","sources":["../../../src/cli/commands/pre-push-guard.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Expanded tests for quickstart command.
|
|
3
|
+
*
|
|
4
|
+
* beth-ywg.3: quickstart only had 13 tests, many conditional. This adds
|
|
5
|
+
* non-conditional tests for output format, error paths, and edge cases.
|
|
6
|
+
*
|
|
7
|
+
* Repro steps:
|
|
8
|
+
* 1. Build: npm run build
|
|
9
|
+
* 2. Run: npx vitest run src/cli/commands/quickstart-expanded.e2e.test.ts
|
|
10
|
+
*
|
|
11
|
+
* Test cases (non-conditional — no beads dependency):
|
|
12
|
+
* - Empty directory → exit 1, clear error about missing Beth
|
|
13
|
+
* - Beth initialized but no skills → still runs doctor, reports warning
|
|
14
|
+
* - Output contains "Quick Start Guide" heading or equivalent guidance
|
|
15
|
+
* - Output mentions @Beth for starting sessions
|
|
16
|
+
* - Exit code is numeric in all scenarios (no crashes)
|
|
17
|
+
* - --verbose flag is accepted and produces more output
|
|
18
|
+
* - Non-existent flag → graceful handling
|
|
19
|
+
*
|
|
20
|
+
* Expected outcomes documented inline per test case.
|
|
21
|
+
*/
|
|
22
|
+
export {};
|
|
23
|
+
//# sourceMappingURL=quickstart-expanded.e2e.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quickstart-expanded.e2e.test.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/quickstart-expanded.e2e.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG"}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Expanded tests for quickstart command.
|
|
3
|
+
*
|
|
4
|
+
* beth-ywg.3: quickstart only had 13 tests, many conditional. This adds
|
|
5
|
+
* non-conditional tests for output format, error paths, and edge cases.
|
|
6
|
+
*
|
|
7
|
+
* Repro steps:
|
|
8
|
+
* 1. Build: npm run build
|
|
9
|
+
* 2. Run: npx vitest run src/cli/commands/quickstart-expanded.e2e.test.ts
|
|
10
|
+
*
|
|
11
|
+
* Test cases (non-conditional — no beads dependency):
|
|
12
|
+
* - Empty directory → exit 1, clear error about missing Beth
|
|
13
|
+
* - Beth initialized but no skills → still runs doctor, reports warning
|
|
14
|
+
* - Output contains "Quick Start Guide" heading or equivalent guidance
|
|
15
|
+
* - Output mentions @Beth for starting sessions
|
|
16
|
+
* - Exit code is numeric in all scenarios (no crashes)
|
|
17
|
+
* - --verbose flag is accepted and produces more output
|
|
18
|
+
* - Non-existent flag → graceful handling
|
|
19
|
+
*
|
|
20
|
+
* Expected outcomes documented inline per test case.
|
|
21
|
+
*/
|
|
22
|
+
import { describe, it, beforeEach, afterEach } from 'node:test';
|
|
23
|
+
import assert from 'node:assert';
|
|
24
|
+
import { spawnSync } from 'child_process';
|
|
25
|
+
import { chmodSync, existsSync, mkdirSync, rmSync, writeFileSync } from 'fs';
|
|
26
|
+
import { delimiter, join, resolve } from 'path';
|
|
27
|
+
import { tmpdir } from 'os';
|
|
28
|
+
const CLI_PATH = resolve(join(import.meta.dirname, '..', '..', '..', 'bin', 'cli.js'));
|
|
29
|
+
function createMockBeadsCli(binDir) {
|
|
30
|
+
const cliPath = join(binDir, 'bd');
|
|
31
|
+
const script = `#!/bin/sh
|
|
32
|
+
set -eu
|
|
33
|
+
|
|
34
|
+
command_name="\${1:-}"
|
|
35
|
+
|
|
36
|
+
case "$command_name" in
|
|
37
|
+
--version)
|
|
38
|
+
echo "bd 0.0.0-test"
|
|
39
|
+
exit 0
|
|
40
|
+
;;
|
|
41
|
+
init)
|
|
42
|
+
mkdir -p .beads
|
|
43
|
+
printf '{"version":"1.0"}' > .beads/config.json
|
|
44
|
+
exit 0
|
|
45
|
+
;;
|
|
46
|
+
*)
|
|
47
|
+
echo "mock bd: unsupported command $command_name" >&2
|
|
48
|
+
exit 0
|
|
49
|
+
;;
|
|
50
|
+
esac
|
|
51
|
+
`;
|
|
52
|
+
writeFileSync(cliPath, script);
|
|
53
|
+
chmodSync(cliPath, 0o755);
|
|
54
|
+
}
|
|
55
|
+
function runQuickstart(cwd, mockBinDir, args = []) {
|
|
56
|
+
const result = spawnSync('node', [CLI_PATH, 'quickstart', ...args], {
|
|
57
|
+
cwd,
|
|
58
|
+
encoding: 'utf-8',
|
|
59
|
+
env: {
|
|
60
|
+
...process.env,
|
|
61
|
+
NO_COLOR: '1',
|
|
62
|
+
FORCE_COLOR: '0',
|
|
63
|
+
PATH: `${mockBinDir}${delimiter}${process.env.PATH ?? ''}`,
|
|
64
|
+
},
|
|
65
|
+
timeout: 30000,
|
|
66
|
+
});
|
|
67
|
+
return {
|
|
68
|
+
stdout: result.stdout || '',
|
|
69
|
+
stderr: result.stderr || '',
|
|
70
|
+
code: result.status ?? 1,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
function createMinimalBethProject(dir) {
|
|
74
|
+
const agentsDir = join(dir, '.github', 'agents');
|
|
75
|
+
mkdirSync(agentsDir, { recursive: true });
|
|
76
|
+
writeFileSync(join(agentsDir, 'beth.agent.md'), '---\nname: Beth\ndescription: Test\nmodel: gpt-4\ntools:\n - readFile\n---\n# Beth\n');
|
|
77
|
+
}
|
|
78
|
+
function createFullBethProject(dir) {
|
|
79
|
+
createMinimalBethProject(dir);
|
|
80
|
+
// Add skills directory
|
|
81
|
+
const skillDir = join(dir, '.github', 'skills', 'test-skill');
|
|
82
|
+
mkdirSync(skillDir, { recursive: true });
|
|
83
|
+
writeFileSync(join(skillDir, 'SKILL.md'), '# Test Skill\nTest content');
|
|
84
|
+
}
|
|
85
|
+
describe('quickstart expanded E2E tests', () => {
|
|
86
|
+
let testDir;
|
|
87
|
+
let mockBinDir;
|
|
88
|
+
beforeEach(() => {
|
|
89
|
+
testDir = join(tmpdir(), `beth-qs-expanded-${Date.now()}-${Math.random().toString(36).slice(2)}`);
|
|
90
|
+
mkdirSync(testDir, { recursive: true });
|
|
91
|
+
mockBinDir = join(testDir, 'mock-bin');
|
|
92
|
+
mkdirSync(mockBinDir, { recursive: true });
|
|
93
|
+
createMockBeadsCli(mockBinDir);
|
|
94
|
+
});
|
|
95
|
+
afterEach(() => {
|
|
96
|
+
if (existsSync(testDir)) {
|
|
97
|
+
rmSync(testDir, { recursive: true, force: true });
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
describe('empty directory (Beth not initialized)', () => {
|
|
101
|
+
// Expected: exit 1, clear error about Beth not being set up
|
|
102
|
+
it('should exit 1 in an empty directory', () => {
|
|
103
|
+
const result = runQuickstart(testDir, mockBinDir);
|
|
104
|
+
assert.strictEqual(result.code, 1, 'Should exit 1 when Beth is not initialized');
|
|
105
|
+
});
|
|
106
|
+
it('should tell user to run init first', () => {
|
|
107
|
+
const result = runQuickstart(testDir, mockBinDir);
|
|
108
|
+
const combined = result.stdout + result.stderr;
|
|
109
|
+
assert.ok(combined.includes('init') || combined.includes('not initialized'), 'Should suggest running init');
|
|
110
|
+
});
|
|
111
|
+
it('should not crash with unhandled exception', () => {
|
|
112
|
+
const result = runQuickstart(testDir, mockBinDir);
|
|
113
|
+
assert.ok(!result.stderr.includes('TypeError') && !result.stderr.includes('ReferenceError'), 'Should not have unhandled JS errors');
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
describe('Beth initialized without skills', () => {
|
|
117
|
+
// Expected: quickstart proceeds past Beth check, may warn about missing skills
|
|
118
|
+
it('should detect Beth is initialized even without skills', () => {
|
|
119
|
+
createMinimalBethProject(testDir);
|
|
120
|
+
const result = runQuickstart(testDir, mockBinDir);
|
|
121
|
+
const combined = result.stdout + result.stderr;
|
|
122
|
+
assert.ok(combined.includes('initialized') || combined.includes('✓') || combined.includes('Beth'), 'Should acknowledge Beth is present');
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
describe('Beth fully initialized', () => {
|
|
126
|
+
it('should proceed past Beth initialization check', () => {
|
|
127
|
+
createFullBethProject(testDir);
|
|
128
|
+
const result = runQuickstart(testDir, mockBinDir);
|
|
129
|
+
const combined = result.stdout + result.stderr;
|
|
130
|
+
// Should get past the "not initialized" gate
|
|
131
|
+
assert.ok(!combined.includes('not initialized') || combined.includes('✓'), 'Should not show "not initialized" error');
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
describe('output format and content', () => {
|
|
135
|
+
it('should produce non-empty stdout', () => {
|
|
136
|
+
createFullBethProject(testDir);
|
|
137
|
+
const result = runQuickstart(testDir, mockBinDir);
|
|
138
|
+
assert.ok(result.stdout.length > 0 || result.stderr.length > 0, 'Should produce some output');
|
|
139
|
+
});
|
|
140
|
+
it('should mention @Beth or VS Code in guidance', () => {
|
|
141
|
+
createFullBethProject(testDir);
|
|
142
|
+
const result = runQuickstart(testDir, mockBinDir);
|
|
143
|
+
const combined = result.stdout + result.stderr;
|
|
144
|
+
assert.ok(combined.includes('@Beth') || combined.includes('VS Code') || combined.includes('Copilot'), 'Should include actionable guidance mentioning @Beth or VS Code');
|
|
145
|
+
});
|
|
146
|
+
});
|
|
147
|
+
describe('--verbose flag', () => {
|
|
148
|
+
it('should accept --verbose without error', () => {
|
|
149
|
+
createFullBethProject(testDir);
|
|
150
|
+
const result = runQuickstart(testDir, mockBinDir, ['--verbose']);
|
|
151
|
+
// Should not reject the flag
|
|
152
|
+
assert.ok(!result.stderr.includes('Unknown flag'), '--verbose should be accepted');
|
|
153
|
+
});
|
|
154
|
+
it('should produce equal or more output with --verbose', () => {
|
|
155
|
+
createFullBethProject(testDir);
|
|
156
|
+
const normal = runQuickstart(testDir, mockBinDir);
|
|
157
|
+
const verbose = runQuickstart(testDir, mockBinDir, ['--verbose']);
|
|
158
|
+
assert.ok(verbose.stdout.length >= normal.stdout.length || verbose.stderr.length >= normal.stderr.length, '--verbose should produce at least as much output');
|
|
159
|
+
});
|
|
160
|
+
});
|
|
161
|
+
describe('resilience', () => {
|
|
162
|
+
it('should handle directory with no permissions gracefully', () => {
|
|
163
|
+
// Create a directory structure that exists but has weird contents
|
|
164
|
+
createMinimalBethProject(testDir);
|
|
165
|
+
// Write a corrupt agent file
|
|
166
|
+
writeFileSync(join(testDir, '.github', 'agents', 'broken.agent.md'), 'this is not valid frontmatter at all {{{');
|
|
167
|
+
const result = runQuickstart(testDir, mockBinDir);
|
|
168
|
+
// Should not crash — may warn or fail gracefully
|
|
169
|
+
assert.ok(typeof result.code === 'number', 'Should exit with a numeric code, not crash');
|
|
170
|
+
});
|
|
171
|
+
it('should handle very deep nested directories', () => {
|
|
172
|
+
const deepDir = join(testDir, 'a', 'b', 'c', 'd', 'e');
|
|
173
|
+
mkdirSync(deepDir, { recursive: true });
|
|
174
|
+
const result = runQuickstart(deepDir, mockBinDir);
|
|
175
|
+
assert.strictEqual(result.code, 1, 'Should exit 1 (no Beth project in deep dir)');
|
|
176
|
+
});
|
|
177
|
+
});
|
|
178
|
+
});
|
|
179
|
+
//# sourceMappingURL=quickstart-expanded.e2e.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quickstart-expanded.e2e.test.js","sourceRoot":"","sources":["../../../src/cli/commands/quickstart-expanded.e2e.test.ts"],"names":[],"mappings":"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"}
|