@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.
- package/dist/commands/chain.d.ts +3 -0
- package/dist/commands/chain.d.ts.map +1 -0
- package/dist/commands/chain.js +284 -0
- package/dist/commands/chain.js.map +1 -0
- package/dist/commands/init.test.d.ts +2 -0
- package/dist/commands/init.test.d.ts.map +1 -0
- package/dist/commands/init.test.js +94 -0
- package/dist/commands/init.test.js.map +1 -0
- package/dist/commands/list.test.d.ts +2 -0
- package/dist/commands/list.test.d.ts.map +1 -0
- package/dist/commands/list.test.js +106 -0
- package/dist/commands/list.test.js.map +1 -0
- package/dist/commands/start/buildPrompt.d.ts +29 -0
- package/dist/commands/start/buildPrompt.d.ts.map +1 -0
- package/dist/commands/start/buildPrompt.js +142 -0
- package/dist/commands/start/buildPrompt.js.map +1 -0
- package/dist/commands/start/buildPrompt.test.d.ts +2 -0
- package/dist/commands/start/buildPrompt.test.d.ts.map +1 -0
- package/dist/commands/start/buildPrompt.test.js +182 -0
- package/dist/commands/start/buildPrompt.test.js.map +1 -0
- package/dist/commands/start/createWorktree.d.ts +21 -0
- package/dist/commands/start/createWorktree.d.ts.map +1 -0
- package/dist/commands/start/createWorktree.js +36 -0
- package/dist/commands/start/createWorktree.js.map +1 -0
- package/dist/commands/start/createWorktree.test.d.ts +2 -0
- package/dist/commands/start/createWorktree.test.d.ts.map +1 -0
- package/dist/commands/start/createWorktree.test.js +81 -0
- package/dist/commands/start/createWorktree.test.js.map +1 -0
- package/dist/commands/start/index.d.ts +4 -0
- package/dist/commands/start/index.d.ts.map +1 -0
- package/dist/commands/start/index.js +4 -0
- package/dist/commands/start/index.js.map +1 -0
- package/dist/commands/start/parseIssueInput.d.ts +21 -0
- package/dist/commands/start/parseIssueInput.d.ts.map +1 -0
- package/dist/commands/start/parseIssueInput.js +78 -0
- package/dist/commands/start/parseIssueInput.js.map +1 -0
- package/dist/commands/start/parseIssueInput.test.d.ts +2 -0
- package/dist/commands/start/parseIssueInput.test.d.ts.map +1 -0
- package/dist/commands/start/parseIssueInput.test.js +118 -0
- package/dist/commands/start/parseIssueInput.test.js.map +1 -0
- package/dist/commands/start.d.ts.map +1 -1
- package/dist/commands/start.js +144 -280
- package/dist/commands/start.js.map +1 -1
- package/dist/commands/start.test.d.ts +2 -0
- package/dist/commands/start.test.d.ts.map +1 -0
- package/dist/commands/start.test.js +260 -0
- package/dist/commands/start.test.js.map +1 -0
- package/dist/commands/status.test.d.ts +2 -0
- package/dist/commands/status.test.d.ts.map +1 -0
- package/dist/commands/status.test.js +172 -0
- package/dist/commands/status.test.js.map +1 -0
- package/dist/commands/stop.test.d.ts +2 -0
- package/dist/commands/stop.test.d.ts.map +1 -0
- package/dist/commands/stop.test.js +152 -0
- package/dist/commands/stop.test.js.map +1 -0
- package/dist/commands/web.d.ts.map +1 -1
- package/dist/commands/web.js +95 -1
- package/dist/commands/web.js.map +1 -1
- package/dist/commands/web.test.d.ts +2 -0
- package/dist/commands/web.test.d.ts.map +1 -0
- package/dist/commands/web.test.js +133 -0
- package/dist/commands/web.test.js.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/package.json +8 -5
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
|
|
2
|
+
import { mkdtemp, rm, mkdir } from 'node:fs/promises';
|
|
3
|
+
import { tmpdir } from 'node:os';
|
|
4
|
+
import { join } from 'node:path';
|
|
5
|
+
// Create mock functions
|
|
6
|
+
const mockFindAll = vi.fn();
|
|
7
|
+
const mockSave = vi.fn();
|
|
8
|
+
// Mock FileSessionRepository
|
|
9
|
+
vi.mock('@claudetree/core', () => ({
|
|
10
|
+
FileSessionRepository: vi.fn().mockImplementation(() => ({
|
|
11
|
+
findAll: mockFindAll,
|
|
12
|
+
save: mockSave,
|
|
13
|
+
})),
|
|
14
|
+
}));
|
|
15
|
+
// Import after mock
|
|
16
|
+
import { stopCommand } from './stop.js';
|
|
17
|
+
describe('stopCommand', () => {
|
|
18
|
+
let testDir;
|
|
19
|
+
let originalCwd;
|
|
20
|
+
let originalExit;
|
|
21
|
+
let consoleLogSpy;
|
|
22
|
+
let consoleErrorSpy;
|
|
23
|
+
const createMockSession = (overrides = {}) => ({
|
|
24
|
+
id: 'test-session-id-123',
|
|
25
|
+
worktreeId: 'worktree-id-456',
|
|
26
|
+
claudeSessionId: null,
|
|
27
|
+
status: 'running',
|
|
28
|
+
issueNumber: 42,
|
|
29
|
+
prompt: 'Fix the bug',
|
|
30
|
+
createdAt: new Date('2024-01-15'),
|
|
31
|
+
updatedAt: new Date('2024-01-15'),
|
|
32
|
+
processId: null,
|
|
33
|
+
osProcessId: null,
|
|
34
|
+
lastHeartbeat: null,
|
|
35
|
+
errorCount: 0,
|
|
36
|
+
worktreePath: '/path/to/worktree',
|
|
37
|
+
usage: null,
|
|
38
|
+
progress: null,
|
|
39
|
+
...overrides,
|
|
40
|
+
});
|
|
41
|
+
beforeEach(async () => {
|
|
42
|
+
testDir = await mkdtemp(join(tmpdir(), 'claudetree-stop-test-'));
|
|
43
|
+
originalCwd = process.cwd();
|
|
44
|
+
process.chdir(testDir);
|
|
45
|
+
originalExit = process.exit;
|
|
46
|
+
process.exit = vi.fn();
|
|
47
|
+
consoleLogSpy = vi.spyOn(console, 'log').mockImplementation(() => { });
|
|
48
|
+
consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => { });
|
|
49
|
+
mockFindAll.mockReset();
|
|
50
|
+
mockSave.mockReset();
|
|
51
|
+
});
|
|
52
|
+
afterEach(async () => {
|
|
53
|
+
process.chdir(originalCwd);
|
|
54
|
+
process.exit = originalExit;
|
|
55
|
+
consoleLogSpy.mockRestore();
|
|
56
|
+
consoleErrorSpy.mockRestore();
|
|
57
|
+
vi.clearAllMocks();
|
|
58
|
+
await rm(testDir, { recursive: true, force: true });
|
|
59
|
+
});
|
|
60
|
+
describe('when not initialized', () => {
|
|
61
|
+
it('should display error and exit with code 1', async () => {
|
|
62
|
+
const exitError = new Error('process.exit called');
|
|
63
|
+
process.exit.mockImplementation(() => {
|
|
64
|
+
throw exitError;
|
|
65
|
+
});
|
|
66
|
+
await expect(stopCommand.parseAsync(['node', 'test'])).rejects.toThrow('process.exit called');
|
|
67
|
+
expect(consoleErrorSpy).toHaveBeenCalledWith('Error: claudetree not initialized. Run "claudetree init" first.');
|
|
68
|
+
expect(process.exit).toHaveBeenCalledWith(1);
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
describe('when initialized', () => {
|
|
72
|
+
beforeEach(async () => {
|
|
73
|
+
await mkdir(join(testDir, '.claudetree'), { recursive: true });
|
|
74
|
+
});
|
|
75
|
+
describe('when no sessions exist', () => {
|
|
76
|
+
it('should display "No active sessions" message', async () => {
|
|
77
|
+
mockFindAll.mockResolvedValue([]);
|
|
78
|
+
await stopCommand.parseAsync(['node', 'test']);
|
|
79
|
+
expect(consoleLogSpy).toHaveBeenCalledWith('No active sessions.');
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
describe('with session-id argument', () => {
|
|
83
|
+
it('should stop matching session by ID prefix', async () => {
|
|
84
|
+
const session = createMockSession({ id: 'test-session-abc123' });
|
|
85
|
+
mockFindAll.mockResolvedValue([session]);
|
|
86
|
+
mockSave.mockResolvedValue(undefined);
|
|
87
|
+
await stopCommand.parseAsync(['node', 'test', 'test-ses']);
|
|
88
|
+
expect(mockSave).toHaveBeenCalledWith(expect.objectContaining({
|
|
89
|
+
id: 'test-session-abc123',
|
|
90
|
+
status: 'completed',
|
|
91
|
+
}));
|
|
92
|
+
expect(consoleLogSpy).toHaveBeenCalledWith(expect.stringContaining('Stopping session: test-ses'));
|
|
93
|
+
expect(consoleLogSpy).toHaveBeenCalledWith(expect.stringContaining('Stopped 1 session(s)'));
|
|
94
|
+
});
|
|
95
|
+
it('should error when no matching session found', async () => {
|
|
96
|
+
const session = createMockSession({ id: 'test-session-abc123' });
|
|
97
|
+
mockFindAll.mockResolvedValue([session]);
|
|
98
|
+
const exitError = new Error('process.exit called');
|
|
99
|
+
process.exit.mockImplementation(() => {
|
|
100
|
+
throw exitError;
|
|
101
|
+
});
|
|
102
|
+
await expect(stopCommand.parseAsync(['node', 'test', 'nonexistent'])).rejects.toThrow('process.exit called');
|
|
103
|
+
expect(consoleErrorSpy).toHaveBeenCalledWith('No session found matching: nonexistent');
|
|
104
|
+
expect(process.exit).toHaveBeenCalledWith(1);
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
describe('with --all option', () => {
|
|
108
|
+
it('should stop all sessions', async () => {
|
|
109
|
+
const sessions = [
|
|
110
|
+
createMockSession({ id: 'session-1' }),
|
|
111
|
+
createMockSession({ id: 'session-2' }),
|
|
112
|
+
createMockSession({ id: 'session-3' }),
|
|
113
|
+
];
|
|
114
|
+
mockFindAll.mockResolvedValue(sessions);
|
|
115
|
+
mockSave.mockResolvedValue(undefined);
|
|
116
|
+
await stopCommand.parseAsync(['node', 'test', '--all']);
|
|
117
|
+
expect(mockSave).toHaveBeenCalledTimes(3);
|
|
118
|
+
expect(consoleLogSpy).toHaveBeenCalledWith(expect.stringContaining('Stopped 3 session(s)'));
|
|
119
|
+
});
|
|
120
|
+
});
|
|
121
|
+
describe('session status update', () => {
|
|
122
|
+
it('should update session status to completed', async () => {
|
|
123
|
+
const session = createMockSession({
|
|
124
|
+
id: 'test-session',
|
|
125
|
+
status: 'running',
|
|
126
|
+
});
|
|
127
|
+
mockFindAll.mockResolvedValue([session]);
|
|
128
|
+
mockSave.mockResolvedValue(undefined);
|
|
129
|
+
await stopCommand.parseAsync(['node', 'test', 'test']);
|
|
130
|
+
expect(mockSave).toHaveBeenCalledWith(expect.objectContaining({
|
|
131
|
+
status: 'completed',
|
|
132
|
+
}));
|
|
133
|
+
});
|
|
134
|
+
it('should update the updatedAt timestamp', async () => {
|
|
135
|
+
const originalDate = new Date('2024-01-01');
|
|
136
|
+
const session = createMockSession({
|
|
137
|
+
id: 'test-session',
|
|
138
|
+
updatedAt: originalDate,
|
|
139
|
+
});
|
|
140
|
+
mockFindAll.mockResolvedValue([session]);
|
|
141
|
+
mockSave.mockResolvedValue(undefined);
|
|
142
|
+
await stopCommand.parseAsync(['node', 'test', 'test']);
|
|
143
|
+
expect(mockSave).toHaveBeenCalledWith(expect.objectContaining({
|
|
144
|
+
updatedAt: expect.any(Date),
|
|
145
|
+
}));
|
|
146
|
+
const savedSession = mockSave.mock.calls[0][0];
|
|
147
|
+
expect(savedSession.updatedAt.getTime()).toBeGreaterThan(originalDate.getTime());
|
|
148
|
+
});
|
|
149
|
+
});
|
|
150
|
+
});
|
|
151
|
+
});
|
|
152
|
+
//# sourceMappingURL=stop.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stop.test.js","sourceRoot":"","sources":["../../src/commands/stop.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"web.d.ts","sourceRoot":"","sources":["../../src/commands/web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"web.d.ts","sourceRoot":"","sources":["../../src/commands/web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAcpC,eAAO,MAAM,UAAU,SA8JnB,CAAC"}
|
package/dist/commands/web.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
2
|
import { join } from 'node:path';
|
|
3
|
-
import { access } from 'node:fs/promises';
|
|
3
|
+
import { access, readFile } from 'node:fs/promises';
|
|
4
4
|
import { spawn } from 'node:child_process';
|
|
5
|
+
import { watch } from 'node:fs';
|
|
5
6
|
import { WebSocketBroadcaster } from '@claudetree/core';
|
|
6
7
|
const CONFIG_DIR = '.claudetree';
|
|
7
8
|
export const webCommand = new Command('web')
|
|
@@ -24,6 +25,91 @@ export const webCommand = new Command('web')
|
|
|
24
25
|
// Start WebSocket server
|
|
25
26
|
const wss = new WebSocketBroadcaster(wsPort);
|
|
26
27
|
console.log(` WebSocket: ws://localhost:${wsPort}`);
|
|
28
|
+
// Watch sessions.json for changes and broadcast updates
|
|
29
|
+
const sessionsPath = join(configDir, 'sessions.json');
|
|
30
|
+
const eventsDir = join(configDir, 'events');
|
|
31
|
+
let lastSessionsContent = '';
|
|
32
|
+
let sessionFileWatcher = null;
|
|
33
|
+
let eventsWatcher = null;
|
|
34
|
+
let debounceTimer = null;
|
|
35
|
+
let eventsDebounceTimer = null;
|
|
36
|
+
// Track last event count per session for incremental updates
|
|
37
|
+
const lastEventCounts = new Map();
|
|
38
|
+
const broadcastSessionUpdate = async () => {
|
|
39
|
+
try {
|
|
40
|
+
const content = await readFile(sessionsPath, 'utf-8');
|
|
41
|
+
if (content !== lastSessionsContent) {
|
|
42
|
+
lastSessionsContent = content;
|
|
43
|
+
const sessions = JSON.parse(content);
|
|
44
|
+
wss.broadcast({
|
|
45
|
+
type: 'session:updated',
|
|
46
|
+
payload: { sessions },
|
|
47
|
+
timestamp: new Date(),
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
// File might not exist yet or be temporarily unavailable
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
// Broadcast new events only (incremental)
|
|
56
|
+
const broadcastNewEvents = async (sessionId) => {
|
|
57
|
+
try {
|
|
58
|
+
const eventPath = join(eventsDir, `${sessionId}.json`);
|
|
59
|
+
const content = await readFile(eventPath, 'utf-8');
|
|
60
|
+
const events = JSON.parse(content);
|
|
61
|
+
const lastCount = lastEventCounts.get(sessionId) || 0;
|
|
62
|
+
if (events.length > lastCount) {
|
|
63
|
+
const newEvents = events.slice(lastCount);
|
|
64
|
+
lastEventCounts.set(sessionId, events.length);
|
|
65
|
+
// Broadcast each new event for live streaming effect
|
|
66
|
+
for (const event of newEvents) {
|
|
67
|
+
wss.broadcast({
|
|
68
|
+
type: 'event:created',
|
|
69
|
+
payload: { sessionId, event },
|
|
70
|
+
timestamp: new Date(),
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
// Events file might not exist yet
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
// Initial read
|
|
80
|
+
await broadcastSessionUpdate();
|
|
81
|
+
// Watch sessions.json for changes
|
|
82
|
+
try {
|
|
83
|
+
sessionFileWatcher = watch(sessionsPath, { persistent: true }, () => {
|
|
84
|
+
if (debounceTimer)
|
|
85
|
+
clearTimeout(debounceTimer);
|
|
86
|
+
debounceTimer = setTimeout(broadcastSessionUpdate, 100);
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
sessionFileWatcher = watch(configDir, { persistent: true }, (_, filename) => {
|
|
91
|
+
if (filename === 'sessions.json') {
|
|
92
|
+
if (debounceTimer)
|
|
93
|
+
clearTimeout(debounceTimer);
|
|
94
|
+
debounceTimer = setTimeout(broadcastSessionUpdate, 100);
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
// Watch events directory for live streaming
|
|
99
|
+
try {
|
|
100
|
+
await access(eventsDir);
|
|
101
|
+
eventsWatcher = watch(eventsDir, { persistent: true }, (_, filename) => {
|
|
102
|
+
if (filename?.endsWith('.json')) {
|
|
103
|
+
const sessionId = filename.replace('.json', '');
|
|
104
|
+
if (eventsDebounceTimer)
|
|
105
|
+
clearTimeout(eventsDebounceTimer);
|
|
106
|
+
eventsDebounceTimer = setTimeout(() => broadcastNewEvents(sessionId), 50);
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
// Events directory might not exist yet - will be created when first session starts
|
|
112
|
+
}
|
|
27
113
|
// Start Next.js dev server
|
|
28
114
|
const webPath = join(cwd, 'node_modules', '@claudetree', 'web');
|
|
29
115
|
// For development, use the packages/web directly
|
|
@@ -50,6 +136,14 @@ export const webCommand = new Command('web')
|
|
|
50
136
|
// Handle cleanup
|
|
51
137
|
const cleanup = () => {
|
|
52
138
|
console.log('\nShutting down...');
|
|
139
|
+
if (debounceTimer)
|
|
140
|
+
clearTimeout(debounceTimer);
|
|
141
|
+
if (eventsDebounceTimer)
|
|
142
|
+
clearTimeout(eventsDebounceTimer);
|
|
143
|
+
if (sessionFileWatcher)
|
|
144
|
+
sessionFileWatcher.close();
|
|
145
|
+
if (eventsWatcher)
|
|
146
|
+
eventsWatcher.close();
|
|
53
147
|
wss.close();
|
|
54
148
|
nextProcess.kill();
|
|
55
149
|
process.exit(0);
|
package/dist/commands/web.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"web.js","sourceRoot":"","sources":["../../src/commands/web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"web.js","sourceRoot":"","sources":["../../src/commands/web.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"web.test.d.ts","sourceRoot":"","sources":["../../src/commands/web.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
|
|
2
|
+
import { mkdtemp, rm, mkdir } from 'node:fs/promises';
|
|
3
|
+
import { tmpdir } from 'node:os';
|
|
4
|
+
import { join } from 'node:path';
|
|
5
|
+
// Mock WebSocketBroadcaster
|
|
6
|
+
vi.mock('@claudetree/core', () => ({
|
|
7
|
+
WebSocketBroadcaster: vi.fn().mockImplementation(() => ({
|
|
8
|
+
close: vi.fn(),
|
|
9
|
+
})),
|
|
10
|
+
}));
|
|
11
|
+
// Mock child_process spawn
|
|
12
|
+
vi.mock('node:child_process', () => ({
|
|
13
|
+
spawn: vi.fn().mockReturnValue({
|
|
14
|
+
on: vi.fn(),
|
|
15
|
+
kill: vi.fn(),
|
|
16
|
+
}),
|
|
17
|
+
}));
|
|
18
|
+
// Import after mock
|
|
19
|
+
import { webCommand } from './web.js';
|
|
20
|
+
import { spawn } from 'node:child_process';
|
|
21
|
+
import { WebSocketBroadcaster } from '@claudetree/core';
|
|
22
|
+
describe('webCommand', () => {
|
|
23
|
+
let testDir;
|
|
24
|
+
let originalCwd;
|
|
25
|
+
let originalExit;
|
|
26
|
+
let consoleLogSpy;
|
|
27
|
+
let consoleErrorSpy;
|
|
28
|
+
beforeEach(async () => {
|
|
29
|
+
testDir = await mkdtemp(join(tmpdir(), 'claudetree-web-test-'));
|
|
30
|
+
originalCwd = process.cwd();
|
|
31
|
+
process.chdir(testDir);
|
|
32
|
+
originalExit = process.exit;
|
|
33
|
+
process.exit = vi.fn();
|
|
34
|
+
consoleLogSpy = vi.spyOn(console, 'log').mockImplementation(() => { });
|
|
35
|
+
consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => { });
|
|
36
|
+
vi.clearAllMocks();
|
|
37
|
+
// Default spawn mock that returns an object with on and kill methods
|
|
38
|
+
vi.mocked(spawn).mockReturnValue({
|
|
39
|
+
on: vi.fn(),
|
|
40
|
+
kill: vi.fn(),
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
afterEach(async () => {
|
|
44
|
+
process.chdir(originalCwd);
|
|
45
|
+
process.exit = originalExit;
|
|
46
|
+
consoleLogSpy.mockRestore();
|
|
47
|
+
consoleErrorSpy.mockRestore();
|
|
48
|
+
vi.clearAllMocks();
|
|
49
|
+
await rm(testDir, { recursive: true, force: true });
|
|
50
|
+
});
|
|
51
|
+
describe('when not initialized', () => {
|
|
52
|
+
it('should display error and exit with code 1', async () => {
|
|
53
|
+
const exitError = new Error('process.exit called');
|
|
54
|
+
process.exit.mockImplementation(() => {
|
|
55
|
+
throw exitError;
|
|
56
|
+
});
|
|
57
|
+
await expect(webCommand.parseAsync(['node', 'test'])).rejects.toThrow('process.exit called');
|
|
58
|
+
expect(consoleErrorSpy).toHaveBeenCalledWith('Error: claudetree not initialized. Run "claudetree init" first.');
|
|
59
|
+
expect(process.exit).toHaveBeenCalledWith(1);
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
describe('when initialized', () => {
|
|
63
|
+
beforeEach(async () => {
|
|
64
|
+
await mkdir(join(testDir, '.claudetree'), { recursive: true });
|
|
65
|
+
});
|
|
66
|
+
it('should display startup message with default ports', async () => {
|
|
67
|
+
await webCommand.parseAsync(['node', 'test']);
|
|
68
|
+
expect(consoleLogSpy).toHaveBeenCalledWith('Starting claudetree dashboard...\n');
|
|
69
|
+
expect(consoleLogSpy).toHaveBeenCalledWith(' WebSocket: ws://localhost:3001');
|
|
70
|
+
expect(consoleLogSpy).toHaveBeenCalledWith(' Web UI: http://localhost:3000');
|
|
71
|
+
});
|
|
72
|
+
it('should use custom port when --port option is provided', async () => {
|
|
73
|
+
await webCommand.parseAsync(['node', 'test', '--port', '4000']);
|
|
74
|
+
expect(consoleLogSpy).toHaveBeenCalledWith(' Web UI: http://localhost:4000');
|
|
75
|
+
});
|
|
76
|
+
it('should use custom WebSocket port when --ws-port option is provided', async () => {
|
|
77
|
+
await webCommand.parseAsync(['node', 'test', '--ws-port', '4001']);
|
|
78
|
+
expect(consoleLogSpy).toHaveBeenCalledWith(' WebSocket: ws://localhost:4001');
|
|
79
|
+
});
|
|
80
|
+
it('should spawn Next.js dev server with correct arguments', async () => {
|
|
81
|
+
await webCommand.parseAsync(['node', 'test', '--port', '5000']);
|
|
82
|
+
expect(spawn).toHaveBeenCalledWith('npx', ['next', 'dev', '-p', '5000'], expect.objectContaining({
|
|
83
|
+
stdio: 'inherit',
|
|
84
|
+
}));
|
|
85
|
+
// Verify env contains the required values
|
|
86
|
+
const spawnCall = vi.mocked(spawn).mock.calls[0];
|
|
87
|
+
const options = spawnCall?.[2];
|
|
88
|
+
expect(options?.env?.CLAUDETREE_WS_PORT).toBe('3001');
|
|
89
|
+
expect(options?.env?.CLAUDETREE_ROOT).toContain('claudetree-web-test');
|
|
90
|
+
});
|
|
91
|
+
it('should set CLAUDETREE_WS_PORT environment variable', async () => {
|
|
92
|
+
await webCommand.parseAsync([
|
|
93
|
+
'node',
|
|
94
|
+
'test',
|
|
95
|
+
'--port',
|
|
96
|
+
'3000',
|
|
97
|
+
'--ws-port',
|
|
98
|
+
'3002',
|
|
99
|
+
]);
|
|
100
|
+
const spawnCall = vi.mocked(spawn).mock.calls[0];
|
|
101
|
+
const options = spawnCall?.[2];
|
|
102
|
+
expect(options?.env?.CLAUDETREE_WS_PORT).toBe('3002');
|
|
103
|
+
});
|
|
104
|
+
it('should display instructions for stopping', async () => {
|
|
105
|
+
await webCommand.parseAsync(['node', 'test']);
|
|
106
|
+
expect(consoleLogSpy).toHaveBeenCalledWith('\nPress Ctrl+C to stop.\n');
|
|
107
|
+
});
|
|
108
|
+
describe('error handling', () => {
|
|
109
|
+
it('should handle spawn error and close WebSocket', async () => {
|
|
110
|
+
const mockOn = vi.fn();
|
|
111
|
+
vi.mocked(spawn).mockReturnValue({
|
|
112
|
+
on: mockOn,
|
|
113
|
+
kill: vi.fn(),
|
|
114
|
+
});
|
|
115
|
+
await webCommand.parseAsync(['node', 'test']);
|
|
116
|
+
// Find the error handler
|
|
117
|
+
const errorHandler = mockOn.mock.calls.find((call) => call[0] === 'error')?.[1];
|
|
118
|
+
// Setup process.exit to throw
|
|
119
|
+
const exitError = new Error('process.exit called');
|
|
120
|
+
process.exit.mockImplementation(() => {
|
|
121
|
+
throw exitError;
|
|
122
|
+
});
|
|
123
|
+
if (errorHandler) {
|
|
124
|
+
expect(() => errorHandler(new Error('spawn error'))).toThrow('process.exit called');
|
|
125
|
+
expect(consoleErrorSpy).toHaveBeenCalledWith('Failed to start web server:', 'spawn error');
|
|
126
|
+
// Verify WebSocketBroadcaster was instantiated and close would be called
|
|
127
|
+
expect(WebSocketBroadcaster).toHaveBeenCalled();
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
//# sourceMappingURL=web.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"web.test.js","sourceRoot":"","sources":["../../src/commands/web.test.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { program } from 'commander';
|
|
3
3
|
import { batchCommand } from './commands/batch.js';
|
|
4
4
|
import { bustercallCommand } from './commands/bustercall.js';
|
|
5
|
+
import { chainCommand } from './commands/chain.js';
|
|
5
6
|
import { cleanCommand } from './commands/clean.js';
|
|
6
7
|
import { demoCommand } from './commands/demo.js';
|
|
7
8
|
import { doctorCommand } from './commands/doctor.js';
|
|
@@ -18,6 +19,7 @@ program
|
|
|
18
19
|
.version('0.1.0');
|
|
19
20
|
program.addCommand(batchCommand);
|
|
20
21
|
program.addCommand(bustercallCommand);
|
|
22
|
+
program.addCommand(chainCommand);
|
|
21
23
|
program.addCommand(cleanCommand);
|
|
22
24
|
program.addCommand(demoCommand);
|
|
23
25
|
program.addCommand(doctorCommand);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE/C,OAAO;KACJ,IAAI,CAAC,YAAY,CAAC;KAClB,WAAW,CAAC,sDAAsD,CAAC;KACnE,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;AACjC,OAAO,CAAC,UAAU,CAAC,iBAAiB,CAAC,CAAC;AACtC,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;AACjC,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;AAChC,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;AAChC,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;AAChC,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;AACjC,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;AAChC,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;AAE/B,OAAO,CAAC,KAAK,EAAE,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE/C,OAAO;KACJ,IAAI,CAAC,YAAY,CAAC;KAClB,WAAW,CAAC,sDAAsD,CAAC;KACnE,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;AACjC,OAAO,CAAC,UAAU,CAAC,iBAAiB,CAAC,CAAC;AACtC,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;AACjC,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;AACjC,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;AAChC,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;AAChC,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;AAChC,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;AACjC,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;AAChC,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;AAE/B,OAAO,CAAC,KAAK,EAAE,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@claudetree/cli",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.4",
|
|
4
4
|
"description": "CLI for claudetree - Manage Claude sessions with git worktrees",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -29,16 +29,19 @@
|
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"async-mutex": "^0.5.0",
|
|
31
31
|
"commander": "^13.0.0",
|
|
32
|
-
"@claudetree/core": "0.4.
|
|
33
|
-
"@claudetree/shared": "0.4.
|
|
32
|
+
"@claudetree/core": "0.4.4",
|
|
33
|
+
"@claudetree/shared": "0.4.4"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"@types/node": "^22.10.0",
|
|
37
|
-
"typescript": "^5.7.0"
|
|
37
|
+
"typescript": "^5.7.0",
|
|
38
|
+
"vitest": "^3.0.0"
|
|
38
39
|
},
|
|
39
40
|
"scripts": {
|
|
40
41
|
"build": "tsc",
|
|
41
42
|
"dev": "tsc --watch",
|
|
42
|
-
"start": "node dist/index.js"
|
|
43
|
+
"start": "node dist/index.js",
|
|
44
|
+
"test": "vitest",
|
|
45
|
+
"test:run": "vitest run"
|
|
43
46
|
}
|
|
44
47
|
}
|