@claudetree/cli 0.4.2 → 0.4.3

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 (59) hide show
  1. package/dist/commands/init.test.d.ts +2 -0
  2. package/dist/commands/init.test.d.ts.map +1 -0
  3. package/dist/commands/init.test.js +94 -0
  4. package/dist/commands/init.test.js.map +1 -0
  5. package/dist/commands/list.test.d.ts +2 -0
  6. package/dist/commands/list.test.d.ts.map +1 -0
  7. package/dist/commands/list.test.js +106 -0
  8. package/dist/commands/list.test.js.map +1 -0
  9. package/dist/commands/start/buildPrompt.d.ts +29 -0
  10. package/dist/commands/start/buildPrompt.d.ts.map +1 -0
  11. package/dist/commands/start/buildPrompt.js +142 -0
  12. package/dist/commands/start/buildPrompt.js.map +1 -0
  13. package/dist/commands/start/buildPrompt.test.d.ts +2 -0
  14. package/dist/commands/start/buildPrompt.test.d.ts.map +1 -0
  15. package/dist/commands/start/buildPrompt.test.js +182 -0
  16. package/dist/commands/start/buildPrompt.test.js.map +1 -0
  17. package/dist/commands/start/createWorktree.d.ts +20 -0
  18. package/dist/commands/start/createWorktree.d.ts.map +1 -0
  19. package/dist/commands/start/createWorktree.js +35 -0
  20. package/dist/commands/start/createWorktree.js.map +1 -0
  21. package/dist/commands/start/createWorktree.test.d.ts +2 -0
  22. package/dist/commands/start/createWorktree.test.d.ts.map +1 -0
  23. package/dist/commands/start/createWorktree.test.js +81 -0
  24. package/dist/commands/start/createWorktree.test.js.map +1 -0
  25. package/dist/commands/start/index.d.ts +4 -0
  26. package/dist/commands/start/index.d.ts.map +1 -0
  27. package/dist/commands/start/index.js +4 -0
  28. package/dist/commands/start/index.js.map +1 -0
  29. package/dist/commands/start/parseIssueInput.d.ts +21 -0
  30. package/dist/commands/start/parseIssueInput.d.ts.map +1 -0
  31. package/dist/commands/start/parseIssueInput.js +78 -0
  32. package/dist/commands/start/parseIssueInput.js.map +1 -0
  33. package/dist/commands/start/parseIssueInput.test.d.ts +2 -0
  34. package/dist/commands/start/parseIssueInput.test.d.ts.map +1 -0
  35. package/dist/commands/start/parseIssueInput.test.js +118 -0
  36. package/dist/commands/start/parseIssueInput.test.js.map +1 -0
  37. package/dist/commands/start.d.ts.map +1 -1
  38. package/dist/commands/start.js +141 -280
  39. package/dist/commands/start.js.map +1 -1
  40. package/dist/commands/start.test.d.ts +2 -0
  41. package/dist/commands/start.test.d.ts.map +1 -0
  42. package/dist/commands/start.test.js +260 -0
  43. package/dist/commands/start.test.js.map +1 -0
  44. package/dist/commands/status.test.d.ts +2 -0
  45. package/dist/commands/status.test.d.ts.map +1 -0
  46. package/dist/commands/status.test.js +172 -0
  47. package/dist/commands/status.test.js.map +1 -0
  48. package/dist/commands/stop.test.d.ts +2 -0
  49. package/dist/commands/stop.test.d.ts.map +1 -0
  50. package/dist/commands/stop.test.js +152 -0
  51. package/dist/commands/stop.test.js.map +1 -0
  52. package/dist/commands/web.d.ts.map +1 -1
  53. package/dist/commands/web.js +95 -1
  54. package/dist/commands/web.js.map +1 -1
  55. package/dist/commands/web.test.d.ts +2 -0
  56. package/dist/commands/web.test.d.ts.map +1 -0
  57. package/dist/commands/web.test.js +133 -0
  58. package/dist/commands/web.test.js.map +1 -0
  59. package/package.json +8 -5
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=init.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.test.d.ts","sourceRoot":"","sources":["../../src/commands/init.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,94 @@
1
+ import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
2
+ import { mkdtemp, rm, readFile, access } from 'node:fs/promises';
3
+ import { tmpdir } from 'node:os';
4
+ import { join } from 'node:path';
5
+ import { initCommand } from './init.js';
6
+ describe('initCommand', () => {
7
+ let testDir;
8
+ let originalCwd;
9
+ let originalExit;
10
+ let consoleLogSpy;
11
+ let consoleErrorSpy;
12
+ beforeEach(async () => {
13
+ testDir = await mkdtemp(join(tmpdir(), 'claudetree-init-test-'));
14
+ originalCwd = process.cwd();
15
+ process.chdir(testDir);
16
+ originalExit = process.exit;
17
+ process.exit = vi.fn();
18
+ consoleLogSpy = vi.spyOn(console, 'log').mockImplementation(() => { });
19
+ consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => { });
20
+ });
21
+ afterEach(async () => {
22
+ process.chdir(originalCwd);
23
+ process.exit = originalExit;
24
+ consoleLogSpy.mockRestore();
25
+ consoleErrorSpy.mockRestore();
26
+ await rm(testDir, { recursive: true, force: true });
27
+ });
28
+ describe('basic initialization', () => {
29
+ it('should create .claudetree directory with config.json', async () => {
30
+ await initCommand.parseAsync(['node', 'test']);
31
+ const configPath = join(testDir, '.claudetree', 'config.json');
32
+ await expect(access(configPath)).resolves.toBeUndefined();
33
+ const config = JSON.parse(await readFile(configPath, 'utf-8'));
34
+ expect(config.version).toBe('0.1.0');
35
+ expect(config.worktreeDir).toBe('.worktrees');
36
+ });
37
+ it('should create worktree directory', async () => {
38
+ await initCommand.parseAsync(['node', 'test']);
39
+ const worktreePath = join(testDir, '.worktrees');
40
+ await expect(access(worktreePath)).resolves.toBeUndefined();
41
+ });
42
+ it('should create templates directory with default templates', async () => {
43
+ await initCommand.parseAsync(['node', 'test']);
44
+ const templatesPath = join(testDir, '.claudetree', 'templates');
45
+ await expect(access(templatesPath)).resolves.toBeUndefined();
46
+ });
47
+ it('should output success message', async () => {
48
+ await initCommand.parseAsync(['node', 'test']);
49
+ expect(consoleLogSpy).toHaveBeenCalledWith(expect.stringContaining('Initialized claudetree'));
50
+ });
51
+ });
52
+ describe('with --worktree-dir option', () => {
53
+ it('should use custom worktree directory', async () => {
54
+ await initCommand.parseAsync(['node', 'test', '-d', 'custom-worktrees']);
55
+ const configPath = join(testDir, '.claudetree', 'config.json');
56
+ const config = JSON.parse(await readFile(configPath, 'utf-8'));
57
+ expect(config.worktreeDir).toBe('custom-worktrees');
58
+ const customWorktreePath = join(testDir, 'custom-worktrees');
59
+ await expect(access(customWorktreePath)).resolves.toBeUndefined();
60
+ });
61
+ });
62
+ describe('with --slack option', () => {
63
+ it('should add slack webhook to config', async () => {
64
+ await initCommand.parseAsync([
65
+ 'node',
66
+ 'test',
67
+ '--slack',
68
+ 'https://hooks.slack.com/services/xxx',
69
+ ]);
70
+ const configPath = join(testDir, '.claudetree', 'config.json');
71
+ const config = JSON.parse(await readFile(configPath, 'utf-8'));
72
+ expect(config.slack?.webhookUrl).toBe('https://hooks.slack.com/services/xxx');
73
+ });
74
+ });
75
+ describe('when already initialized', () => {
76
+ it('should error without --force flag', async () => {
77
+ // Initialize first time
78
+ await initCommand.parseAsync(['node', 'test']);
79
+ consoleErrorSpy.mockClear();
80
+ // Try to initialize again
81
+ await initCommand.parseAsync(['node', 'test']);
82
+ expect(consoleErrorSpy).toHaveBeenCalledWith(expect.stringContaining('already initialized'));
83
+ expect(process.exit).toHaveBeenCalledWith(1);
84
+ });
85
+ it('should reinitialize with --force flag', async () => {
86
+ // Initialize first time
87
+ await initCommand.parseAsync(['node', 'test']);
88
+ // Reinitialize with force
89
+ await initCommand.parseAsync(['node', 'test', '--force']);
90
+ expect(consoleLogSpy).toHaveBeenCalledWith(expect.stringContaining('Initialized claudetree'));
91
+ });
92
+ });
93
+ });
94
+ //# sourceMappingURL=init.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.test.js","sourceRoot":"","sources":["../../src/commands/init.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=list.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.test.d.ts","sourceRoot":"","sources":["../../src/commands/list.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,106 @@
1
+ import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
2
+ import { listCommand } from './list.js';
3
+ // Mock GitWorktreeAdapter
4
+ vi.mock('@claudetree/core', () => ({
5
+ GitWorktreeAdapter: vi.fn().mockImplementation(() => ({
6
+ list: vi.fn(),
7
+ })),
8
+ }));
9
+ import { GitWorktreeAdapter } from '@claudetree/core';
10
+ describe('listCommand', () => {
11
+ let originalExit;
12
+ let consoleLogSpy;
13
+ let consoleErrorSpy;
14
+ let mockList;
15
+ beforeEach(() => {
16
+ originalExit = process.exit;
17
+ process.exit = vi.fn();
18
+ consoleLogSpy = vi.spyOn(console, 'log').mockImplementation(() => { });
19
+ consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => { });
20
+ mockList = vi.fn();
21
+ vi.mocked(GitWorktreeAdapter).mockImplementation(() => ({
22
+ list: mockList,
23
+ }));
24
+ });
25
+ afterEach(() => {
26
+ process.exit = originalExit;
27
+ consoleLogSpy.mockRestore();
28
+ consoleErrorSpy.mockRestore();
29
+ vi.clearAllMocks();
30
+ });
31
+ describe('when no worktrees exist', () => {
32
+ it('should display "No worktrees found" message', async () => {
33
+ mockList.mockResolvedValue([]);
34
+ await listCommand.parseAsync(['node', 'test']);
35
+ expect(consoleLogSpy).toHaveBeenCalledWith('No worktrees found.');
36
+ });
37
+ });
38
+ describe('when worktrees exist', () => {
39
+ const mockWorktrees = [
40
+ {
41
+ path: '/path/to/main',
42
+ branch: 'main',
43
+ commit: 'abc123def456',
44
+ isMainWorktree: true,
45
+ },
46
+ {
47
+ path: '/path/to/feature',
48
+ branch: 'feature-branch',
49
+ commit: 'def456abc789',
50
+ isMainWorktree: false,
51
+ },
52
+ ];
53
+ it('should display worktrees with their details', async () => {
54
+ mockList.mockResolvedValue(mockWorktrees);
55
+ await listCommand.parseAsync(['node', 'test']);
56
+ expect(consoleLogSpy).toHaveBeenCalledWith('Worktrees:\n');
57
+ expect(consoleLogSpy).toHaveBeenCalledWith(' main (main)');
58
+ expect(consoleLogSpy).toHaveBeenCalledWith(' feature-branch');
59
+ expect(consoleLogSpy).toHaveBeenCalledWith(' Path: /path/to/main');
60
+ expect(consoleLogSpy).toHaveBeenCalledWith(' Path: /path/to/feature');
61
+ expect(consoleLogSpy).toHaveBeenCalledWith(' Commit: abc123de');
62
+ expect(consoleLogSpy).toHaveBeenCalledWith(' Commit: def456ab');
63
+ });
64
+ it('should handle detached HEAD state', async () => {
65
+ mockList.mockResolvedValue([
66
+ {
67
+ path: '/path/to/detached',
68
+ branch: null,
69
+ commit: '123456789',
70
+ isMainWorktree: false,
71
+ },
72
+ ]);
73
+ await listCommand.parseAsync(['node', 'test']);
74
+ expect(consoleLogSpy).toHaveBeenCalledWith(' (detached)');
75
+ });
76
+ });
77
+ describe('with --json option', () => {
78
+ it('should output worktrees as JSON', async () => {
79
+ const mockWorktrees = [
80
+ {
81
+ path: '/path/to/main',
82
+ branch: 'main',
83
+ commit: 'abc123def456',
84
+ isMainWorktree: true,
85
+ },
86
+ ];
87
+ mockList.mockResolvedValue(mockWorktrees);
88
+ await listCommand.parseAsync(['node', 'test', '--json']);
89
+ expect(consoleLogSpy).toHaveBeenCalledWith(JSON.stringify(mockWorktrees, null, 2));
90
+ });
91
+ });
92
+ describe('when git command fails', () => {
93
+ it('should display error and exit with code 1', async () => {
94
+ mockList.mockRejectedValue(new Error('Git not available'));
95
+ await listCommand.parseAsync(['node', 'test']);
96
+ expect(consoleErrorSpy).toHaveBeenCalledWith('Error: Git not available');
97
+ expect(process.exit).toHaveBeenCalledWith(1);
98
+ });
99
+ });
100
+ describe('alias', () => {
101
+ it('should have "ls" as an alias', () => {
102
+ expect(listCommand.alias()).toBe('ls');
103
+ });
104
+ });
105
+ });
106
+ //# sourceMappingURL=list.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.test.js","sourceRoot":"","sources":["../../src/commands/list.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ import type { Issue, SessionTemplate, TDDConfig } from '@claudetree/shared';
2
+ export interface BuildPromptOptions {
3
+ issueNumber: number | null;
4
+ issueData: Issue | null;
5
+ branchName: string;
6
+ taskDescription: string | null;
7
+ tddEnabled: boolean;
8
+ template?: SessionTemplate | null;
9
+ customPrompt?: string;
10
+ }
11
+ export interface BuildSystemPromptOptions {
12
+ tddEnabled: boolean;
13
+ tddConfig?: TDDConfig;
14
+ skill?: string;
15
+ template?: SessionTemplate | null;
16
+ }
17
+ /**
18
+ * Format duration in milliseconds to human readable string
19
+ */
20
+ export declare function formatDuration(ms: number): string;
21
+ /**
22
+ * Build the prompt for Claude session
23
+ */
24
+ export declare function buildPrompt(options: BuildPromptOptions): string;
25
+ /**
26
+ * Build system prompt based on mode and skill
27
+ */
28
+ export declare function buildSystemPrompt(options: BuildSystemPromptOptions): string | undefined;
29
+ //# sourceMappingURL=buildPrompt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buildPrompt.d.ts","sourceRoot":"","sources":["../../../src/commands/start/buildPrompt.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAE5E,MAAM,WAAW,kBAAkB;IACjC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,SAAS,EAAE,KAAK,GAAG,IAAI,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,UAAU,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,EAAE,eAAe,GAAG,IAAI,CAAC;IAClC,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,wBAAwB;IACvC,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,eAAe,GAAG,IAAI,CAAC;CACnC;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAQjD;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,MAAM,CAqC/D;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,wBAAwB,GAAG,MAAM,GAAG,SAAS,CA0FvF"}
@@ -0,0 +1,142 @@
1
+ /**
2
+ * Format duration in milliseconds to human readable string
3
+ */
4
+ export function formatDuration(ms) {
5
+ const seconds = Math.floor(ms / 1000);
6
+ const minutes = Math.floor(seconds / 60);
7
+ const hours = Math.floor(minutes / 60);
8
+ if (hours > 0)
9
+ return `${hours}h ${minutes % 60}m`;
10
+ if (minutes > 0)
11
+ return `${minutes}m ${seconds % 60}s`;
12
+ return `${seconds}s`;
13
+ }
14
+ /**
15
+ * Build the prompt for Claude session
16
+ */
17
+ export function buildPrompt(options) {
18
+ const { issueNumber, issueData, branchName, taskDescription, tddEnabled, template, customPrompt } = options;
19
+ // Custom prompt takes precedence
20
+ if (customPrompt) {
21
+ return customPrompt;
22
+ }
23
+ let prompt;
24
+ if (issueData) {
25
+ prompt = `You are working on Issue #${issueNumber}: "${issueData.title}"
26
+
27
+ Issue Description:
28
+ ${issueData.body || 'No description provided.'}
29
+
30
+ IMPORTANT: Do NOT just analyze or suggest. Actually IMPLEMENT the solution.
31
+ ${tddEnabled ? '\nStart with TDD - write a failing test first!' : ''}`;
32
+ }
33
+ else if (issueNumber) {
34
+ prompt = `Working on issue #${issueNumber}. ${tddEnabled ? 'Start with TDD - write a failing test first!' : 'Implement the solution.'}`;
35
+ }
36
+ else if (taskDescription) {
37
+ prompt = `Your task: ${taskDescription}
38
+
39
+ IMPORTANT: Do NOT just analyze or suggest. Actually IMPLEMENT the solution.
40
+ ${tddEnabled ? '\nStart with TDD - write a failing test first!' : ''}`;
41
+ }
42
+ else {
43
+ prompt = `Working on ${branchName}. ${tddEnabled ? 'Start with TDD - write a failing test first!' : 'Implement any required changes.'}`;
44
+ }
45
+ // Apply template prefix/suffix
46
+ if (template) {
47
+ const prefix = template.promptPrefix ? `${template.promptPrefix}\n\n` : '';
48
+ const suffix = template.promptSuffix ? `\n\n${template.promptSuffix}` : '';
49
+ prompt = `${prefix}${prompt}${suffix}`;
50
+ }
51
+ return prompt;
52
+ }
53
+ /**
54
+ * Build system prompt based on mode and skill
55
+ */
56
+ export function buildSystemPrompt(options) {
57
+ const { tddEnabled, tddConfig, skill, template } = options;
58
+ // Template system prompt takes precedence
59
+ if (template?.systemPrompt) {
60
+ return template.systemPrompt;
61
+ }
62
+ if (tddEnabled && tddConfig) {
63
+ return `You are in TDD (Test-Driven Development) mode. Follow this STRICT workflow:
64
+
65
+ ## TDD Cycle (Repeat until done)
66
+
67
+ ### 1. RED Phase - Write Failing Test
68
+ - Write ONE failing test that describes the expected behavior
69
+ - Run the test to confirm it fails
70
+ - Commit: "test: add test for <feature>"
71
+
72
+ ### 2. GREEN Phase - Minimal Implementation
73
+ - Write the MINIMUM code to make the test pass
74
+ - Run tests to confirm they pass
75
+ - Commit: "feat: implement <feature>"
76
+
77
+ ### 3. REFACTOR Phase (Optional)
78
+ - Clean up code while keeping tests green
79
+ - Commit: "refactor: improve <description>"
80
+
81
+ ## Rules
82
+ - NEVER write implementation before tests
83
+ - ONE test at a time
84
+ - Run tests after EVERY change
85
+ - Stop when all requirements are met
86
+
87
+ ## Validation Gates (Must Pass Before PR)
88
+ ${tddConfig.gates.map(g => `- ${g.name}: \`${g.command}\` ${g.required ? '(REQUIRED)' : '(optional)'}`).join('\n')}
89
+
90
+ ## Time Limits
91
+ - Total: ${formatDuration(tddConfig.timeout)}
92
+ - Idle: ${formatDuration(tddConfig.idleTimeout)}
93
+
94
+ When done, create a PR to the develop branch.`;
95
+ }
96
+ if (skill === 'review') {
97
+ return 'Review code thoroughly for security, quality, and best practices.';
98
+ }
99
+ if (skill === 'docs') {
100
+ return `You are a documentation specialist. Generate comprehensive documentation.
101
+
102
+ ## Documentation Workflow
103
+
104
+ ### 1. Analysis Phase
105
+ - Read package.json for project metadata
106
+ - Scan src/ directory structure
107
+ - Identify exported APIs and types
108
+ - Note configuration files
109
+
110
+ ### 2. README Generation
111
+ Structure your README with:
112
+ - Project title and badges
113
+ - Description and features
114
+ - Installation instructions
115
+ - Quick start example
116
+ - API reference (if applicable)
117
+ - Configuration options
118
+ - Contributing guidelines
119
+
120
+ ### 3. API Documentation
121
+ For each public module:
122
+ - Purpose and usage
123
+ - Function signatures with types
124
+ - Parameter descriptions
125
+ - Return value descriptions
126
+ - Code examples
127
+
128
+ ### 4. Output
129
+ - Create/update README.md
130
+ - Create docs/ folder for detailed docs if needed
131
+ - Use Markdown formatting
132
+ - Include table of contents for long docs
133
+
134
+ ## Rules
135
+ - Be concise but complete
136
+ - Use code blocks with proper language tags
137
+ - Include real, working examples
138
+ - Document edge cases and error handling`;
139
+ }
140
+ return undefined;
141
+ }
142
+ //# sourceMappingURL=buildPrompt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buildPrompt.js","sourceRoot":"","sources":["../../../src/commands/start/buildPrompt.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=buildPrompt.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buildPrompt.test.d.ts","sourceRoot":"","sources":["../../../src/commands/start/buildPrompt.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,182 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { buildPrompt, buildSystemPrompt, formatDuration } from './buildPrompt.js';
3
+ describe('buildPrompt', () => {
4
+ describe('with issue data', () => {
5
+ it('should build prompt from issue data', () => {
6
+ const issueData = {
7
+ number: 42,
8
+ title: 'Add feature X',
9
+ body: 'We need to implement feature X',
10
+ labels: ['enhancement'],
11
+ state: 'open',
12
+ url: 'https://github.com/owner/repo/issues/42',
13
+ };
14
+ const result = buildPrompt({
15
+ issueNumber: 42,
16
+ issueData,
17
+ branchName: 'issue-42-add-feature-x',
18
+ taskDescription: null,
19
+ tddEnabled: false,
20
+ });
21
+ expect(result).toContain('Issue #42');
22
+ expect(result).toContain('Add feature X');
23
+ expect(result).toContain('We need to implement feature X');
24
+ expect(result).toContain('IMPLEMENT the solution');
25
+ });
26
+ it('should add TDD instruction when enabled', () => {
27
+ const issueData = {
28
+ number: 42,
29
+ title: 'Add feature X',
30
+ body: 'Implement feature',
31
+ labels: [],
32
+ state: 'open',
33
+ url: '',
34
+ };
35
+ const result = buildPrompt({
36
+ issueNumber: 42,
37
+ issueData,
38
+ branchName: 'issue-42',
39
+ taskDescription: null,
40
+ tddEnabled: true,
41
+ });
42
+ expect(result).toContain('TDD');
43
+ expect(result).toContain('failing test');
44
+ });
45
+ });
46
+ describe('with issue number only', () => {
47
+ it('should build simple prompt with issue number', () => {
48
+ const result = buildPrompt({
49
+ issueNumber: 42,
50
+ issueData: null,
51
+ branchName: 'issue-42',
52
+ taskDescription: null,
53
+ tddEnabled: false,
54
+ });
55
+ expect(result).toContain('#42');
56
+ expect(result).toContain('Implement');
57
+ });
58
+ });
59
+ describe('with task description', () => {
60
+ it('should build prompt from task description', () => {
61
+ const result = buildPrompt({
62
+ issueNumber: null,
63
+ issueData: null,
64
+ branchName: 'task-add-auth',
65
+ taskDescription: 'add user authentication',
66
+ tddEnabled: false,
67
+ });
68
+ expect(result).toContain('add user authentication');
69
+ expect(result).toContain('IMPLEMENT');
70
+ });
71
+ });
72
+ describe('with template', () => {
73
+ it('should apply template prefix and suffix', () => {
74
+ const template = {
75
+ name: 'bugfix',
76
+ description: 'Bug fix template',
77
+ promptPrefix: 'DEBUG MODE:',
78
+ promptSuffix: 'Run tests after fix.',
79
+ };
80
+ const result = buildPrompt({
81
+ issueNumber: 1,
82
+ issueData: null,
83
+ branchName: 'issue-1',
84
+ taskDescription: null,
85
+ tddEnabled: false,
86
+ template,
87
+ });
88
+ expect(result).toMatch(/^DEBUG MODE:/);
89
+ expect(result).toMatch(/Run tests after fix\.$/);
90
+ });
91
+ });
92
+ describe('with custom prompt', () => {
93
+ it('should use custom prompt when provided', () => {
94
+ const result = buildPrompt({
95
+ issueNumber: 42,
96
+ issueData: null,
97
+ branchName: 'issue-42',
98
+ taskDescription: null,
99
+ tddEnabled: false,
100
+ customPrompt: 'Custom instruction here',
101
+ });
102
+ expect(result).toBe('Custom instruction here');
103
+ });
104
+ });
105
+ });
106
+ describe('buildSystemPrompt', () => {
107
+ describe('TDD mode', () => {
108
+ it('should build TDD system prompt with gates', () => {
109
+ const tddConfig = {
110
+ timeout: 7200000, // 2h
111
+ idleTimeout: 600000, // 10m
112
+ maxIterations: 10,
113
+ maxRetries: 3,
114
+ gates: [
115
+ { name: 'test', command: 'pnpm test', required: true },
116
+ { name: 'type', command: 'tsc --noEmit', required: true },
117
+ ],
118
+ };
119
+ const result = buildSystemPrompt({
120
+ tddEnabled: true,
121
+ tddConfig,
122
+ });
123
+ expect(result).toContain('TDD');
124
+ expect(result).toContain('RED Phase');
125
+ expect(result).toContain('GREEN Phase');
126
+ expect(result).toContain('REFACTOR');
127
+ expect(result).toContain('pnpm test');
128
+ expect(result).toContain('tsc --noEmit');
129
+ });
130
+ });
131
+ describe('review skill', () => {
132
+ it('should build review system prompt', () => {
133
+ const result = buildSystemPrompt({
134
+ tddEnabled: false,
135
+ skill: 'review',
136
+ });
137
+ expect(result).toContain('Review');
138
+ expect(result).toContain('security');
139
+ });
140
+ });
141
+ describe('docs skill', () => {
142
+ it('should build docs system prompt', () => {
143
+ const result = buildSystemPrompt({
144
+ tddEnabled: false,
145
+ skill: 'docs',
146
+ });
147
+ expect(result).toContain('documentation');
148
+ expect(result).toContain('README');
149
+ });
150
+ });
151
+ describe('template system prompt', () => {
152
+ it('should use template system prompt when provided', () => {
153
+ const template = {
154
+ name: 'custom',
155
+ description: 'Custom template',
156
+ systemPrompt: 'Custom system instructions',
157
+ };
158
+ const result = buildSystemPrompt({
159
+ tddEnabled: false,
160
+ template,
161
+ });
162
+ expect(result).toBe('Custom system instructions');
163
+ });
164
+ });
165
+ });
166
+ describe('formatDuration', () => {
167
+ it('should format seconds', () => {
168
+ expect(formatDuration(5000)).toBe('5s');
169
+ expect(formatDuration(45000)).toBe('45s');
170
+ });
171
+ it('should format minutes and seconds', () => {
172
+ expect(formatDuration(60000)).toBe('1m 0s');
173
+ expect(formatDuration(90000)).toBe('1m 30s');
174
+ expect(formatDuration(125000)).toBe('2m 5s');
175
+ });
176
+ it('should format hours and minutes', () => {
177
+ expect(formatDuration(3600000)).toBe('1h 0m');
178
+ expect(formatDuration(5400000)).toBe('1h 30m');
179
+ expect(formatDuration(7320000)).toBe('2h 2m');
180
+ });
181
+ });
182
+ //# sourceMappingURL=buildPrompt.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buildPrompt.test.js","sourceRoot":"","sources":["../../../src/commands/start/buildPrompt.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ export interface WorktreeInfo {
2
+ id: string;
3
+ path: string;
4
+ branch: string;
5
+ }
6
+ export interface CreateWorktreeOptions {
7
+ cwd: string;
8
+ worktreeDir: string;
9
+ branchName: string;
10
+ issueNumber?: number;
11
+ }
12
+ export interface CreateWorktreeResult {
13
+ worktree: WorktreeInfo;
14
+ isExisting: boolean;
15
+ }
16
+ /**
17
+ * Create a new worktree or find existing one
18
+ */
19
+ export declare function createOrFindWorktree(options: CreateWorktreeOptions): Promise<CreateWorktreeResult>;
20
+ //# sourceMappingURL=createWorktree.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createWorktree.d.ts","sourceRoot":"","sources":["../../../src/commands/start/createWorktree.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,qBAAqB;IACpC,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,YAAY,CAAC;IACvB,UAAU,EAAE,OAAO,CAAC;CACrB;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,oBAAoB,CAAC,CAkC/B"}