@claudetree/cli 0.4.2 → 0.4.4

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 (65) hide show
  1. package/dist/commands/chain.d.ts +3 -0
  2. package/dist/commands/chain.d.ts.map +1 -0
  3. package/dist/commands/chain.js +284 -0
  4. package/dist/commands/chain.js.map +1 -0
  5. package/dist/commands/init.test.d.ts +2 -0
  6. package/dist/commands/init.test.d.ts.map +1 -0
  7. package/dist/commands/init.test.js +94 -0
  8. package/dist/commands/init.test.js.map +1 -0
  9. package/dist/commands/list.test.d.ts +2 -0
  10. package/dist/commands/list.test.d.ts.map +1 -0
  11. package/dist/commands/list.test.js +106 -0
  12. package/dist/commands/list.test.js.map +1 -0
  13. package/dist/commands/start/buildPrompt.d.ts +29 -0
  14. package/dist/commands/start/buildPrompt.d.ts.map +1 -0
  15. package/dist/commands/start/buildPrompt.js +142 -0
  16. package/dist/commands/start/buildPrompt.js.map +1 -0
  17. package/dist/commands/start/buildPrompt.test.d.ts +2 -0
  18. package/dist/commands/start/buildPrompt.test.d.ts.map +1 -0
  19. package/dist/commands/start/buildPrompt.test.js +182 -0
  20. package/dist/commands/start/buildPrompt.test.js.map +1 -0
  21. package/dist/commands/start/createWorktree.d.ts +21 -0
  22. package/dist/commands/start/createWorktree.d.ts.map +1 -0
  23. package/dist/commands/start/createWorktree.js +36 -0
  24. package/dist/commands/start/createWorktree.js.map +1 -0
  25. package/dist/commands/start/createWorktree.test.d.ts +2 -0
  26. package/dist/commands/start/createWorktree.test.d.ts.map +1 -0
  27. package/dist/commands/start/createWorktree.test.js +81 -0
  28. package/dist/commands/start/createWorktree.test.js.map +1 -0
  29. package/dist/commands/start/index.d.ts +4 -0
  30. package/dist/commands/start/index.d.ts.map +1 -0
  31. package/dist/commands/start/index.js +4 -0
  32. package/dist/commands/start/index.js.map +1 -0
  33. package/dist/commands/start/parseIssueInput.d.ts +21 -0
  34. package/dist/commands/start/parseIssueInput.d.ts.map +1 -0
  35. package/dist/commands/start/parseIssueInput.js +78 -0
  36. package/dist/commands/start/parseIssueInput.js.map +1 -0
  37. package/dist/commands/start/parseIssueInput.test.d.ts +2 -0
  38. package/dist/commands/start/parseIssueInput.test.d.ts.map +1 -0
  39. package/dist/commands/start/parseIssueInput.test.js +118 -0
  40. package/dist/commands/start/parseIssueInput.test.js.map +1 -0
  41. package/dist/commands/start.d.ts.map +1 -1
  42. package/dist/commands/start.js +144 -280
  43. package/dist/commands/start.js.map +1 -1
  44. package/dist/commands/start.test.d.ts +2 -0
  45. package/dist/commands/start.test.d.ts.map +1 -0
  46. package/dist/commands/start.test.js +260 -0
  47. package/dist/commands/start.test.js.map +1 -0
  48. package/dist/commands/status.test.d.ts +2 -0
  49. package/dist/commands/status.test.d.ts.map +1 -0
  50. package/dist/commands/status.test.js +172 -0
  51. package/dist/commands/status.test.js.map +1 -0
  52. package/dist/commands/stop.test.d.ts +2 -0
  53. package/dist/commands/stop.test.d.ts.map +1 -0
  54. package/dist/commands/stop.test.js +152 -0
  55. package/dist/commands/stop.test.js.map +1 -0
  56. package/dist/commands/web.d.ts.map +1 -1
  57. package/dist/commands/web.js +95 -1
  58. package/dist/commands/web.js.map +1 -1
  59. package/dist/commands/web.test.d.ts +2 -0
  60. package/dist/commands/web.test.d.ts.map +1 -0
  61. package/dist/commands/web.test.js +133 -0
  62. package/dist/commands/web.test.js.map +1 -0
  63. package/dist/index.js +2 -0
  64. package/dist/index.js.map +1 -1
  65. package/package.json +8 -5
@@ -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,21 @@
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
+ baseBranch?: string;
12
+ }
13
+ export interface CreateWorktreeResult {
14
+ worktree: WorktreeInfo;
15
+ isExisting: boolean;
16
+ }
17
+ /**
18
+ * Create a new worktree or find existing one
19
+ */
20
+ export declare function createOrFindWorktree(options: CreateWorktreeOptions): Promise<CreateWorktreeResult>;
21
+ //# 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;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;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,CAmC/B"}
@@ -0,0 +1,36 @@
1
+ import { join } from 'node:path';
2
+ import { randomUUID } from 'node:crypto';
3
+ import { GitWorktreeAdapter } from '@claudetree/core';
4
+ /**
5
+ * Create a new worktree or find existing one
6
+ */
7
+ export async function createOrFindWorktree(options) {
8
+ const { cwd, worktreeDir, branchName, issueNumber, baseBranch } = options;
9
+ const worktreePath = join(cwd, worktreeDir, branchName);
10
+ const gitAdapter = new GitWorktreeAdapter(cwd);
11
+ // Check for existing worktree
12
+ const existingWorktrees = await gitAdapter.list();
13
+ const existingWorktree = existingWorktrees.find((wt) => wt.branch === branchName || wt.path.endsWith(branchName));
14
+ if (existingWorktree) {
15
+ return {
16
+ worktree: {
17
+ id: randomUUID(),
18
+ path: existingWorktree.path,
19
+ branch: existingWorktree.branch,
20
+ },
21
+ isExisting: true,
22
+ };
23
+ }
24
+ // Create new worktree with optional base branch
25
+ const worktree = await gitAdapter.create({
26
+ path: worktreePath,
27
+ branch: branchName,
28
+ issueNumber,
29
+ baseBranch,
30
+ });
31
+ return {
32
+ worktree,
33
+ isExisting: false,
34
+ };
35
+ }
36
+ //# sourceMappingURL=createWorktree.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createWorktree.js","sourceRoot":"","sources":["../../../src/commands/start/createWorktree.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAqBtD;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,OAA8B;IAE9B,MAAM,EAAE,GAAG,EAAE,WAAW,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC;IAE1E,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,EAAE,WAAW,EAAE,UAAU,CAAC,CAAC;IACxD,MAAM,UAAU,GAAG,IAAI,kBAAkB,CAAC,GAAG,CAAC,CAAC;IAE/C,8BAA8B;IAC9B,MAAM,iBAAiB,GAAG,MAAM,UAAU,CAAC,IAAI,EAAE,CAAC;IAClD,MAAM,gBAAgB,GAAG,iBAAiB,CAAC,IAAI,CAC7C,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,MAAM,KAAK,UAAU,IAAI,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,CACjE,CAAC;IAEF,IAAI,gBAAgB,EAAE,CAAC;QACrB,OAAO;YACL,QAAQ,EAAE;gBACR,EAAE,EAAE,UAAU,EAAE;gBAChB,IAAI,EAAE,gBAAgB,CAAC,IAAI;gBAC3B,MAAM,EAAE,gBAAgB,CAAC,MAAM;aAChC;YACD,UAAU,EAAE,IAAI;SACjB,CAAC;IACJ,CAAC;IAED,gDAAgD;IAChD,MAAM,QAAQ,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC;QACvC,IAAI,EAAE,YAAY;QAClB,MAAM,EAAE,UAAU;QAClB,WAAW;QACX,UAAU;KACX,CAAC,CAAC;IAEH,OAAO;QACL,QAAQ;QACR,UAAU,EAAE,KAAK;KAClB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=createWorktree.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createWorktree.test.d.ts","sourceRoot":"","sources":["../../../src/commands/start/createWorktree.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,81 @@
1
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
2
+ import { createOrFindWorktree } from './createWorktree.js';
3
+ import { GitWorktreeAdapter } from '@claudetree/core';
4
+ // Mock GitWorktreeAdapter
5
+ vi.mock('@claudetree/core', async () => {
6
+ const actual = await vi.importActual('@claudetree/core');
7
+ return {
8
+ ...actual,
9
+ GitWorktreeAdapter: vi.fn().mockImplementation(() => ({
10
+ list: vi.fn().mockResolvedValue([
11
+ { path: '/worktrees/existing-branch', branch: 'existing-branch' },
12
+ ]),
13
+ create: vi.fn().mockImplementation(async (opts) => ({
14
+ id: 'mock-uuid-123',
15
+ path: opts.path,
16
+ branch: opts.branch,
17
+ })),
18
+ })),
19
+ };
20
+ });
21
+ describe('createOrFindWorktree', () => {
22
+ beforeEach(() => {
23
+ vi.clearAllMocks();
24
+ });
25
+ describe('existing worktree', () => {
26
+ it('should return existing worktree when branch already exists', async () => {
27
+ const result = await createOrFindWorktree({
28
+ cwd: '/project',
29
+ worktreeDir: '.worktrees',
30
+ branchName: 'existing-branch',
31
+ });
32
+ expect(result.isExisting).toBe(true);
33
+ expect(result.worktree.branch).toBe('existing-branch');
34
+ expect(result.worktree.path).toBe('/worktrees/existing-branch');
35
+ });
36
+ it('should match by path ending with branch name', async () => {
37
+ const result = await createOrFindWorktree({
38
+ cwd: '/project',
39
+ worktreeDir: '.worktrees',
40
+ branchName: 'existing-branch',
41
+ });
42
+ expect(result.isExisting).toBe(true);
43
+ });
44
+ });
45
+ describe('new worktree', () => {
46
+ it('should create new worktree when branch does not exist', async () => {
47
+ const result = await createOrFindWorktree({
48
+ cwd: '/project',
49
+ worktreeDir: '.worktrees',
50
+ branchName: 'new-branch',
51
+ });
52
+ expect(result.isExisting).toBe(false);
53
+ expect(result.worktree.branch).toBe('new-branch');
54
+ expect(result.worktree.path).toBe('/project/.worktrees/new-branch');
55
+ });
56
+ it('should pass issueNumber to create', async () => {
57
+ const result = await createOrFindWorktree({
58
+ cwd: '/project',
59
+ worktreeDir: '.worktrees',
60
+ branchName: 'issue-42-feature',
61
+ issueNumber: 42,
62
+ });
63
+ expect(result.isExisting).toBe(false);
64
+ expect(result.worktree.branch).toBe('issue-42-feature');
65
+ });
66
+ });
67
+ describe('error handling', () => {
68
+ it('should throw error when create fails', async () => {
69
+ vi.mocked(GitWorktreeAdapter).mockImplementationOnce(() => ({
70
+ list: vi.fn().mockResolvedValue([]),
71
+ create: vi.fn().mockRejectedValue(new Error('Git error: branch already exists')),
72
+ }));
73
+ await expect(createOrFindWorktree({
74
+ cwd: '/project',
75
+ worktreeDir: '.worktrees',
76
+ branchName: 'conflict-branch',
77
+ })).rejects.toThrow('Git error');
78
+ });
79
+ });
80
+ });
81
+ //# sourceMappingURL=createWorktree.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createWorktree.test.js","sourceRoot":"","sources":["../../../src/commands/start/createWorktree.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export { parseIssueInput, type ParsedIssueInput, type ParseIssueOptions } from './parseIssueInput.js';
2
+ export { createOrFindWorktree, type WorktreeInfo, type CreateWorktreeOptions, type CreateWorktreeResult } from './createWorktree.js';
3
+ export { buildPrompt, buildSystemPrompt, formatDuration, type BuildPromptOptions, type BuildSystemPromptOptions } from './buildPrompt.js';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/start/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,KAAK,gBAAgB,EAAE,KAAK,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACtG,OAAO,EAAE,oBAAoB,EAAE,KAAK,YAAY,EAAE,KAAK,qBAAqB,EAAE,KAAK,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AACrI,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,cAAc,EAAE,KAAK,kBAAkB,EAAE,KAAK,wBAAwB,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,4 @@
1
+ export { parseIssueInput } from './parseIssueInput.js';
2
+ export { createOrFindWorktree } from './createWorktree.js';
3
+ export { buildPrompt, buildSystemPrompt, formatDuration } from './buildPrompt.js';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/start/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAiD,MAAM,sBAAsB,CAAC;AACtG,OAAO,EAAE,oBAAoB,EAA4E,MAAM,qBAAqB,CAAC;AACrI,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,cAAc,EAA0D,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,21 @@
1
+ import type { Issue } from '@claudetree/shared';
2
+ export interface ParsedIssueInput {
3
+ issueNumber: number | null;
4
+ issueData: Issue | null;
5
+ branchName: string;
6
+ taskDescription: string | null;
7
+ }
8
+ export interface ParseIssueOptions {
9
+ token?: string;
10
+ branch?: string;
11
+ githubConfig?: {
12
+ owner: string;
13
+ repo: string;
14
+ };
15
+ }
16
+ /**
17
+ * Parse issue input from CLI argument
18
+ * Handles: GitHub URLs, issue numbers, natural language tasks
19
+ */
20
+ export declare function parseIssueInput(input: string, options: ParseIssueOptions): Promise<ParsedIssueInput>;
21
+ //# sourceMappingURL=parseIssueInput.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parseIssueInput.d.ts","sourceRoot":"","sources":["../../../src/commands/start/parseIssueInput.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAEhD,MAAM,WAAW,gBAAgB;IAC/B,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;CAChC;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE;QACb,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;CACH;AAeD;;;GAGG;AACH,wBAAsB,eAAe,CACnC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,iBAAiB,GACzB,OAAO,CAAC,gBAAgB,CAAC,CAwE3B"}
@@ -0,0 +1,78 @@
1
+ import { GitHubAdapter } from '@claudetree/core';
2
+ /**
3
+ * Sanitize natural language input to a valid branch name
4
+ */
5
+ function sanitizeBranchName(input) {
6
+ return input
7
+ .toLowerCase()
8
+ .replace(/[^a-z0-9가-힣\s-]/g, '') // Allow Korean characters
9
+ .replace(/\s+/g, '-')
10
+ .replace(/-+/g, '-')
11
+ .replace(/^-|-$/g, '')
12
+ .slice(0, 50); // Max length
13
+ }
14
+ /**
15
+ * Parse issue input from CLI argument
16
+ * Handles: GitHub URLs, issue numbers, natural language tasks
17
+ */
18
+ export async function parseIssueInput(input, options) {
19
+ const { token, branch: customBranch, githubConfig } = options;
20
+ // Case 1: GitHub URL
21
+ if (input.includes('github.com')) {
22
+ if (!token) {
23
+ throw new Error('GitHub token required for URL. Set GITHUB_TOKEN or use --token.');
24
+ }
25
+ const ghAdapter = new GitHubAdapter(token);
26
+ const parsed = ghAdapter.parseIssueUrl(input);
27
+ if (!parsed) {
28
+ throw new Error('Invalid GitHub URL format.');
29
+ }
30
+ const issueData = await ghAdapter.getIssue(parsed.owner, parsed.repo, parsed.number);
31
+ const branchName = customBranch ?? ghAdapter.generateBranchName(issueData.number, issueData.title);
32
+ return {
33
+ issueNumber: issueData.number,
34
+ issueData,
35
+ branchName,
36
+ taskDescription: null,
37
+ };
38
+ }
39
+ // Case 2: Issue number
40
+ const parsedNumber = parseInt(input, 10);
41
+ const isNumber = !isNaN(parsedNumber);
42
+ if (isNumber) {
43
+ // Try to fetch issue data if we have GitHub config
44
+ if (token && githubConfig) {
45
+ const ghAdapter = new GitHubAdapter(token);
46
+ try {
47
+ const issueData = await ghAdapter.getIssue(githubConfig.owner, githubConfig.repo, parsedNumber);
48
+ const branchName = customBranch ?? ghAdapter.generateBranchName(issueData.number, issueData.title);
49
+ return {
50
+ issueNumber: issueData.number,
51
+ issueData,
52
+ branchName,
53
+ taskDescription: null,
54
+ };
55
+ }
56
+ catch {
57
+ // API failed, fallback to simple branch name
58
+ }
59
+ }
60
+ // Fallback: use issue number without API data
61
+ return {
62
+ issueNumber: parsedNumber,
63
+ issueData: null,
64
+ branchName: customBranch ?? `issue-${parsedNumber}`,
65
+ taskDescription: null,
66
+ };
67
+ }
68
+ // Case 3: Natural language task
69
+ const taskDescription = input;
70
+ const branchName = customBranch ?? `task-${sanitizeBranchName(input)}`;
71
+ return {
72
+ issueNumber: null,
73
+ issueData: null,
74
+ branchName,
75
+ taskDescription,
76
+ };
77
+ }
78
+ //# sourceMappingURL=parseIssueInput.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parseIssueInput.js","sourceRoot":"","sources":["../../../src/commands/start/parseIssueInput.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=parseIssueInput.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parseIssueInput.test.d.ts","sourceRoot":"","sources":["../../../src/commands/start/parseIssueInput.test.ts"],"names":[],"mappings":""}