forkoff 1.0.17 → 1.0.19
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/LICENSE +11 -7
- package/README.md +77 -118
- package/dist/approval.d.ts +1 -0
- package/dist/approval.js +9 -0
- package/dist/config.d.ts +3 -0
- package/dist/config.js +62 -16
- package/dist/crypto/e2eeManager.d.ts +49 -52
- package/dist/crypto/e2eeManager.js +256 -181
- package/dist/crypto/encryption.d.ts +8 -10
- package/dist/crypto/encryption.js +29 -94
- package/dist/crypto/index.d.ts +10 -0
- package/dist/crypto/index.js +22 -0
- package/dist/crypto/keyExchange.d.ts +6 -20
- package/dist/crypto/keyExchange.js +18 -110
- package/dist/crypto/keyGeneration.d.ts +2 -13
- package/dist/crypto/keyGeneration.js +14 -88
- package/dist/crypto/keyStorage.d.ts +32 -5
- package/dist/crypto/keyStorage.js +152 -8
- package/dist/crypto/sessionPersistence.d.ts +7 -13
- package/dist/crypto/sessionPersistence.js +108 -33
- package/dist/crypto/types.d.ts +24 -3
- package/dist/crypto/types.js +2 -1
- package/dist/crypto/websocketE2EE.d.ts +6 -17
- package/dist/crypto/websocketE2EE.js +21 -38
- package/dist/index.js +203 -280
- package/dist/integration.d.ts +0 -1
- package/dist/integration.js +2 -4
- package/dist/logger.d.ts +15 -0
- package/dist/logger.js +209 -1
- package/dist/server.d.ts +30 -0
- package/dist/server.js +162 -0
- package/dist/startup.js +15 -6
- package/dist/terminal.d.ts +1 -0
- package/dist/terminal.js +94 -1
- package/dist/tools/claude-process.d.ts +8 -0
- package/dist/tools/claude-process.js +199 -26
- package/dist/tools/claude-sessions.d.ts +1 -0
- package/dist/tools/claude-sessions.js +36 -10
- package/dist/tools/detector.js +11 -3
- package/dist/tools/permission-hook.js +94 -27
- package/dist/tools/permission-ipc.d.ts +1 -0
- package/dist/tools/permission-ipc.js +61 -14
- package/dist/transcript-streamer.d.ts +1 -0
- package/dist/transcript-streamer.js +18 -4
- package/dist/usage-tracker.d.ts +45 -0
- package/dist/usage-tracker.js +243 -0
- package/dist/websocket.d.ts +43 -12
- package/dist/websocket.js +418 -214
- package/package.json +5 -4
- package/dist/__tests__/cli-commands.test.d.ts +0 -6
- package/dist/__tests__/cli-commands.test.d.ts.map +0 -1
- package/dist/__tests__/cli-commands.test.js +0 -213
- package/dist/__tests__/cli-commands.test.js.map +0 -1
- package/dist/__tests__/crypto/e2e-integration.test.d.ts +0 -17
- package/dist/__tests__/crypto/e2e-integration.test.d.ts.map +0 -1
- package/dist/__tests__/crypto/e2e-integration.test.js +0 -338
- package/dist/__tests__/crypto/e2e-integration.test.js.map +0 -1
- package/dist/__tests__/crypto/e2eeManager.test.d.ts +0 -2
- package/dist/__tests__/crypto/e2eeManager.test.d.ts.map +0 -1
- package/dist/__tests__/crypto/e2eeManager.test.js +0 -242
- package/dist/__tests__/crypto/e2eeManager.test.js.map +0 -1
- package/dist/__tests__/crypto/encryption.test.d.ts +0 -2
- package/dist/__tests__/crypto/encryption.test.d.ts.map +0 -1
- package/dist/__tests__/crypto/encryption.test.js +0 -116
- package/dist/__tests__/crypto/encryption.test.js.map +0 -1
- package/dist/__tests__/crypto/keyExchange.test.d.ts +0 -2
- package/dist/__tests__/crypto/keyExchange.test.d.ts.map +0 -1
- package/dist/__tests__/crypto/keyExchange.test.js +0 -84
- package/dist/__tests__/crypto/keyExchange.test.js.map +0 -1
- package/dist/__tests__/crypto/keyGeneration.test.d.ts +0 -2
- package/dist/__tests__/crypto/keyGeneration.test.d.ts.map +0 -1
- package/dist/__tests__/crypto/keyGeneration.test.js +0 -61
- package/dist/__tests__/crypto/keyGeneration.test.js.map +0 -1
- package/dist/__tests__/crypto/keyStorage.test.d.ts +0 -2
- package/dist/__tests__/crypto/keyStorage.test.d.ts.map +0 -1
- package/dist/__tests__/crypto/keyStorage.test.js +0 -133
- package/dist/__tests__/crypto/keyStorage.test.js.map +0 -1
- package/dist/__tests__/crypto/websocketIntegration.test.d.ts +0 -2
- package/dist/__tests__/crypto/websocketIntegration.test.d.ts.map +0 -1
- package/dist/__tests__/crypto/websocketIntegration.test.js +0 -259
- package/dist/__tests__/crypto/websocketIntegration.test.js.map +0 -1
- package/dist/__tests__/startup.test.d.ts +0 -11
- package/dist/__tests__/startup.test.d.ts.map +0 -1
- package/dist/__tests__/startup.test.js +0 -241
- package/dist/__tests__/startup.test.js.map +0 -1
- package/dist/__tests__/tools/claude-process.test.d.ts +0 -8
- package/dist/__tests__/tools/claude-process.test.d.ts.map +0 -1
- package/dist/__tests__/tools/claude-process.test.js +0 -430
- package/dist/__tests__/tools/claude-process.test.js.map +0 -1
- package/dist/__tests__/tools/permission-hook.test.d.ts +0 -17
- package/dist/__tests__/tools/permission-hook.test.d.ts.map +0 -1
- package/dist/__tests__/tools/permission-hook.test.js +0 -616
- package/dist/__tests__/tools/permission-hook.test.js.map +0 -1
- package/dist/__tests__/tools/permission-ipc.test.d.ts +0 -11
- package/dist/__tests__/tools/permission-ipc.test.d.ts.map +0 -1
- package/dist/__tests__/tools/permission-ipc.test.js +0 -612
- package/dist/__tests__/tools/permission-ipc.test.js.map +0 -1
- package/dist/__tests__/websocket.test.d.ts +0 -13
- package/dist/__tests__/websocket.test.d.ts.map +0 -1
- package/dist/__tests__/websocket.test.js +0 -204
- package/dist/__tests__/websocket.test.js.map +0 -1
- package/dist/api.d.ts +0 -44
- package/dist/api.d.ts.map +0 -1
- package/dist/api.js +0 -76
- package/dist/api.js.map +0 -1
- package/dist/approval.d.ts.map +0 -1
- package/dist/approval.js.map +0 -1
- package/dist/config.d.ts.map +0 -1
- package/dist/config.js.map +0 -1
- package/dist/crypto/e2eeManager.d.ts.map +0 -1
- package/dist/crypto/e2eeManager.js.map +0 -1
- package/dist/crypto/encryption.d.ts.map +0 -1
- package/dist/crypto/encryption.js.map +0 -1
- package/dist/crypto/keyExchange.d.ts.map +0 -1
- package/dist/crypto/keyExchange.js.map +0 -1
- package/dist/crypto/keyGeneration.d.ts.map +0 -1
- package/dist/crypto/keyGeneration.js.map +0 -1
- package/dist/crypto/keyStorage.d.ts.map +0 -1
- package/dist/crypto/keyStorage.js.map +0 -1
- package/dist/crypto/sessionPersistence.d.ts.map +0 -1
- package/dist/crypto/sessionPersistence.js.map +0 -1
- package/dist/crypto/types.d.ts.map +0 -1
- package/dist/crypto/types.js.map +0 -1
- package/dist/crypto/websocketE2EE.d.ts.map +0 -1
- package/dist/crypto/websocketE2EE.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/integration.d.ts.map +0 -1
- package/dist/integration.js.map +0 -1
- package/dist/logger.d.ts.map +0 -1
- package/dist/logger.js.map +0 -1
- package/dist/startup.d.ts.map +0 -1
- package/dist/startup.js.map +0 -1
- package/dist/terminal.d.ts.map +0 -1
- package/dist/terminal.js.map +0 -1
- package/dist/tools/__tests__/claude-sessions.test.d.ts +0 -2
- package/dist/tools/__tests__/claude-sessions.test.d.ts.map +0 -1
- package/dist/tools/__tests__/claude-sessions.test.js +0 -306
- package/dist/tools/__tests__/claude-sessions.test.js.map +0 -1
- package/dist/tools/claude-hooks.d.ts.map +0 -1
- package/dist/tools/claude-hooks.js.map +0 -1
- package/dist/tools/claude-process.d.ts.map +0 -1
- package/dist/tools/claude-process.js.map +0 -1
- package/dist/tools/claude-sessions.d.ts.map +0 -1
- package/dist/tools/claude-sessions.js.map +0 -1
- package/dist/tools/detector.d.ts.map +0 -1
- package/dist/tools/detector.js.map +0 -1
- package/dist/tools/index.d.ts.map +0 -1
- package/dist/tools/index.js.map +0 -1
- package/dist/tools/permission-hook.d.ts.map +0 -1
- package/dist/tools/permission-hook.js.map +0 -1
- package/dist/tools/permission-ipc.d.ts.map +0 -1
- package/dist/tools/permission-ipc.js.map +0 -1
- package/dist/transcript-streamer.d.ts.map +0 -1
- package/dist/transcript-streamer.js.map +0 -1
- package/dist/websocket.d.ts.map +0 -1
- package/dist/websocket.js.map +0 -1
- package/jest.config.js +0 -18
|
@@ -1,430 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Tests for Claude Process Manager
|
|
4
|
-
* Covers:
|
|
5
|
-
* - Bug 1: dangerouslySkipPermissions threading through startSession, resumeSession, sendInput, registerSession
|
|
6
|
-
* - Bug 2: tool_activity event instead of claude_approval_request for SDK tool_use, disabled regex approval, guarded stdin writes
|
|
7
|
-
*/
|
|
8
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
const events_1 = require("events");
|
|
10
|
-
// Mock cross-spawn before importing the module
|
|
11
|
-
const mockSpawn = jest.fn();
|
|
12
|
-
jest.mock('cross-spawn', () => mockSpawn);
|
|
13
|
-
// Mock fs to prevent hook config from writing real files
|
|
14
|
-
jest.mock('fs', () => {
|
|
15
|
-
const actual = jest.requireActual('fs');
|
|
16
|
-
return {
|
|
17
|
-
...actual,
|
|
18
|
-
existsSync: jest.fn((p) => {
|
|
19
|
-
// Hook script doesn't exist in test env — skip hook config
|
|
20
|
-
if (typeof p === 'string' && p.includes('permission-hook'))
|
|
21
|
-
return false;
|
|
22
|
-
return actual.existsSync(p);
|
|
23
|
-
}),
|
|
24
|
-
mkdirSync: jest.fn(),
|
|
25
|
-
writeFileSync: jest.fn(),
|
|
26
|
-
readFileSync: jest.fn((p, enc) => {
|
|
27
|
-
if (typeof p === 'string' && p.includes('settings.local.json'))
|
|
28
|
-
return '{}';
|
|
29
|
-
return actual.readFileSync(p, enc);
|
|
30
|
-
}),
|
|
31
|
-
};
|
|
32
|
-
});
|
|
33
|
-
// Create a mock child process
|
|
34
|
-
function createMockProcess() {
|
|
35
|
-
const stdin = {
|
|
36
|
-
write: jest.fn((_data, cb) => { if (cb)
|
|
37
|
-
cb(null); }),
|
|
38
|
-
destroyed: false,
|
|
39
|
-
};
|
|
40
|
-
const stdout = new events_1.EventEmitter();
|
|
41
|
-
const stderr = new events_1.EventEmitter();
|
|
42
|
-
const proc = new events_1.EventEmitter();
|
|
43
|
-
proc.stdin = stdin;
|
|
44
|
-
proc.stdout = stdout;
|
|
45
|
-
proc.stderr = stderr;
|
|
46
|
-
proc.exitCode = null;
|
|
47
|
-
proc.kill = jest.fn(() => {
|
|
48
|
-
proc.exitCode = 0;
|
|
49
|
-
});
|
|
50
|
-
return proc;
|
|
51
|
-
}
|
|
52
|
-
const claude_process_1 = require("../../tools/claude-process");
|
|
53
|
-
describe('ClaudeProcessManager', () => {
|
|
54
|
-
let manager;
|
|
55
|
-
let mockProc;
|
|
56
|
-
beforeEach(() => {
|
|
57
|
-
jest.clearAllMocks();
|
|
58
|
-
mockProc = createMockProcess();
|
|
59
|
-
mockSpawn.mockReturnValue(mockProc);
|
|
60
|
-
manager = new claude_process_1.ClaudeProcessManager();
|
|
61
|
-
});
|
|
62
|
-
// ==================== Bug 1: dangerouslySkipPermissions ====================
|
|
63
|
-
describe('Bug 1: dangerouslySkipPermissions flag', () => {
|
|
64
|
-
describe('startSession', () => {
|
|
65
|
-
it('should NOT include --dangerously-skip-permissions when flag is false', async () => {
|
|
66
|
-
await manager.startSession('/test/dir', 'session-1', false);
|
|
67
|
-
expect(mockSpawn).toHaveBeenCalledTimes(1);
|
|
68
|
-
const args = mockSpawn.mock.calls[0][1];
|
|
69
|
-
expect(args).not.toContain('--dangerously-skip-permissions');
|
|
70
|
-
});
|
|
71
|
-
it('should NOT include --dangerously-skip-permissions when flag is undefined', async () => {
|
|
72
|
-
await manager.startSession('/test/dir', 'session-1');
|
|
73
|
-
expect(mockSpawn).toHaveBeenCalledTimes(1);
|
|
74
|
-
const args = mockSpawn.mock.calls[0][1];
|
|
75
|
-
expect(args).not.toContain('--dangerously-skip-permissions');
|
|
76
|
-
});
|
|
77
|
-
it('should include --dangerously-skip-permissions when flag is true', async () => {
|
|
78
|
-
await manager.startSession('/test/dir', 'session-1', true);
|
|
79
|
-
expect(mockSpawn).toHaveBeenCalledTimes(1);
|
|
80
|
-
const args = mockSpawn.mock.calls[0][1];
|
|
81
|
-
expect(args).toContain('--dangerously-skip-permissions');
|
|
82
|
-
});
|
|
83
|
-
});
|
|
84
|
-
describe('resumeSession', () => {
|
|
85
|
-
it('should NOT include --dangerously-skip-permissions when flag is false (uses hooks instead)', async () => {
|
|
86
|
-
await manager.resumeSession('key-1', '/test/dir', 'session-1', false);
|
|
87
|
-
const args = mockSpawn.mock.calls[0][1];
|
|
88
|
-
expect(args).not.toContain('--dangerously-skip-permissions');
|
|
89
|
-
// No longer uses --permission-mode; interactive hooks handle permissions
|
|
90
|
-
expect(args).not.toContain('--permission-mode');
|
|
91
|
-
});
|
|
92
|
-
it('should use --dangerously-skip-permissions when flag is true', async () => {
|
|
93
|
-
await manager.resumeSession('key-1', '/test/dir', 'session-1', true);
|
|
94
|
-
const args = mockSpawn.mock.calls[0][1];
|
|
95
|
-
expect(args).toContain('--dangerously-skip-permissions');
|
|
96
|
-
expect(args).not.toContain('--permission-mode');
|
|
97
|
-
});
|
|
98
|
-
});
|
|
99
|
-
describe('registerSession', () => {
|
|
100
|
-
it('should store dangerouslySkipPermissions in closedSessions', () => {
|
|
101
|
-
manager.registerSession('key-1', '/test/dir', 'session-1', true);
|
|
102
|
-
// Verify the session can be retrieved and used (sendInput will use it)
|
|
103
|
-
expect(manager.isClaudeSession('session-1')).toBe(true);
|
|
104
|
-
});
|
|
105
|
-
});
|
|
106
|
-
describe('sendInput (preserves flag across respawns)', () => {
|
|
107
|
-
it('should pass dangerouslySkipPermissions=true to resumeSession when respawning', async () => {
|
|
108
|
-
// Register a session with the flag set
|
|
109
|
-
manager.registerSession('key-1', '/test/dir', 'session-1', true);
|
|
110
|
-
// Spy on resumeSession to check the flag is passed
|
|
111
|
-
const resumeSpy = jest.spyOn(manager, 'resumeSession');
|
|
112
|
-
await manager.sendInput('session-1', 'hello');
|
|
113
|
-
expect(resumeSpy).toHaveBeenCalledWith('key-1', expect.any(String), 'session-1', true, undefined);
|
|
114
|
-
});
|
|
115
|
-
it('should not pass dangerouslySkipPermissions when not set', async () => {
|
|
116
|
-
manager.registerSession('key-1', '/test/dir', 'session-1');
|
|
117
|
-
const resumeSpy = jest.spyOn(manager, 'resumeSession');
|
|
118
|
-
await manager.sendInput('session-1', 'hello');
|
|
119
|
-
expect(resumeSpy).toHaveBeenCalledWith('key-1', expect.any(String), 'session-1', undefined, undefined);
|
|
120
|
-
});
|
|
121
|
-
it('should pass interactivePermissions=true to resumeSession when respawning', async () => {
|
|
122
|
-
manager.registerSession('key-1', '/test/dir', 'session-1', false, true);
|
|
123
|
-
const resumeSpy = jest.spyOn(manager, 'resumeSession');
|
|
124
|
-
await manager.sendInput('session-1', 'hello');
|
|
125
|
-
expect(resumeSpy).toHaveBeenCalledWith('key-1', expect.any(String), 'session-1', false, true);
|
|
126
|
-
});
|
|
127
|
-
});
|
|
128
|
-
});
|
|
129
|
-
// ==================== Bug 2: Approval system fix ====================
|
|
130
|
-
describe('Bug 2: Approval system fix', () => {
|
|
131
|
-
describe('checkForToolUseInSdkMessage → tool_activity', () => {
|
|
132
|
-
it('should emit tool_activity instead of claude_approval_request for SDK tool_use', async () => {
|
|
133
|
-
await manager.startSession('/test/dir', 'session-1');
|
|
134
|
-
const toolActivityEvents = [];
|
|
135
|
-
const approvalEvents = [];
|
|
136
|
-
manager.on('tool_activity', (event) => toolActivityEvents.push(event));
|
|
137
|
-
manager.on('claude_approval_request', (event) => approvalEvents.push(event));
|
|
138
|
-
// Simulate an SDK assistant message with tool_use via stdout
|
|
139
|
-
const sdkMessage = {
|
|
140
|
-
type: 'assistant',
|
|
141
|
-
message: {
|
|
142
|
-
content: [
|
|
143
|
-
{
|
|
144
|
-
type: 'tool_use',
|
|
145
|
-
id: 'tool-123',
|
|
146
|
-
name: 'Read',
|
|
147
|
-
input: { file_path: '/some/file.ts' },
|
|
148
|
-
},
|
|
149
|
-
],
|
|
150
|
-
},
|
|
151
|
-
};
|
|
152
|
-
mockProc.stdout.emit('data', Buffer.from(JSON.stringify(sdkMessage) + '\n'));
|
|
153
|
-
await new Promise(resolve => setTimeout(resolve, 50));
|
|
154
|
-
expect(toolActivityEvents.length).toBe(1);
|
|
155
|
-
expect(toolActivityEvents[0].toolName).toBe('Read');
|
|
156
|
-
expect(toolActivityEvents[0].toolId).toBe('tool-123');
|
|
157
|
-
expect(toolActivityEvents[0].terminalSessionId).toBe('session-1');
|
|
158
|
-
// Should NOT emit approval requests
|
|
159
|
-
expect(approvalEvents.length).toBe(0);
|
|
160
|
-
});
|
|
161
|
-
it('should NOT emit tool_activity for non-tool_use assistant messages', async () => {
|
|
162
|
-
await manager.startSession('/test/dir', 'session-1');
|
|
163
|
-
const toolActivityEvents = [];
|
|
164
|
-
manager.on('tool_activity', (event) => toolActivityEvents.push(event));
|
|
165
|
-
const sdkMessage = {
|
|
166
|
-
type: 'assistant',
|
|
167
|
-
message: {
|
|
168
|
-
content: [{ type: 'text', text: 'Here is the answer' }],
|
|
169
|
-
},
|
|
170
|
-
};
|
|
171
|
-
mockProc.stdout.emit('data', Buffer.from(JSON.stringify(sdkMessage) + '\n'));
|
|
172
|
-
await new Promise(resolve => setTimeout(resolve, 50));
|
|
173
|
-
expect(toolActivityEvents.length).toBe(0);
|
|
174
|
-
});
|
|
175
|
-
it('should include inputSummary with file_path for file tools', async () => {
|
|
176
|
-
await manager.startSession('/test/dir', 'session-1');
|
|
177
|
-
const events = [];
|
|
178
|
-
manager.on('tool_activity', (event) => events.push(event));
|
|
179
|
-
const sdkMessage = {
|
|
180
|
-
type: 'assistant',
|
|
181
|
-
message: {
|
|
182
|
-
content: [{
|
|
183
|
-
type: 'tool_use',
|
|
184
|
-
id: 'tool-456',
|
|
185
|
-
name: 'Read',
|
|
186
|
-
input: { file_path: '/path/to/file.ts' },
|
|
187
|
-
}],
|
|
188
|
-
},
|
|
189
|
-
};
|
|
190
|
-
mockProc.stdout.emit('data', Buffer.from(JSON.stringify(sdkMessage) + '\n'));
|
|
191
|
-
await new Promise(resolve => setTimeout(resolve, 50));
|
|
192
|
-
expect(events[0].inputSummary).toContain('/path/to/file.ts');
|
|
193
|
-
});
|
|
194
|
-
it('should include inputSummary with command for Bash tools', async () => {
|
|
195
|
-
await manager.startSession('/test/dir', 'session-1');
|
|
196
|
-
const events = [];
|
|
197
|
-
manager.on('tool_activity', (event) => events.push(event));
|
|
198
|
-
const sdkMessage = {
|
|
199
|
-
type: 'assistant',
|
|
200
|
-
message: {
|
|
201
|
-
content: [{
|
|
202
|
-
type: 'tool_use',
|
|
203
|
-
id: 'tool-789',
|
|
204
|
-
name: 'Bash',
|
|
205
|
-
input: { command: 'npm run build' },
|
|
206
|
-
}],
|
|
207
|
-
},
|
|
208
|
-
};
|
|
209
|
-
mockProc.stdout.emit('data', Buffer.from(JSON.stringify(sdkMessage) + '\n'));
|
|
210
|
-
await new Promise(resolve => setTimeout(resolve, 50));
|
|
211
|
-
expect(events[0].inputSummary).toContain('npm run build');
|
|
212
|
-
});
|
|
213
|
-
});
|
|
214
|
-
describe('checkForApprovalPattern disabled for SDK mode', () => {
|
|
215
|
-
it('should NOT emit claude_approval_request when SDK JSON output contains approval-like patterns', async () => {
|
|
216
|
-
await manager.startSession('/test/dir', 'session-1');
|
|
217
|
-
const approvalEvents = [];
|
|
218
|
-
manager.on('claude_approval_request', (event) => approvalEvents.push(event));
|
|
219
|
-
// SDK JSON that contains "[y]es" pattern in a text field
|
|
220
|
-
const jsonWithPattern = JSON.stringify({
|
|
221
|
-
type: 'assistant',
|
|
222
|
-
message: { content: [{ type: 'text', text: 'Do you want to proceed? [y]es, [n]o' }] },
|
|
223
|
-
}) + '\n';
|
|
224
|
-
mockProc.stdout.emit('data', Buffer.from(jsonWithPattern));
|
|
225
|
-
await new Promise(resolve => setTimeout(resolve, 50));
|
|
226
|
-
// Regex-based detection should be disabled for SDK mode
|
|
227
|
-
expect(approvalEvents.length).toBe(0);
|
|
228
|
-
});
|
|
229
|
-
});
|
|
230
|
-
describe('handleApprovalResponse guards SDK mode', () => {
|
|
231
|
-
it('should NOT write raw characters to stdin for SDK mode processes', async () => {
|
|
232
|
-
await manager.startSession('/test/dir', 'session-1');
|
|
233
|
-
// Manually set up a pending approval to test the guard
|
|
234
|
-
const approvalId = 'test-approval-1';
|
|
235
|
-
manager.pendingApprovals?.set(approvalId, {
|
|
236
|
-
approvalId,
|
|
237
|
-
terminalSessionId: 'session-1',
|
|
238
|
-
createdAt: Date.now(),
|
|
239
|
-
timeoutId: setTimeout(() => { }, 10000),
|
|
240
|
-
});
|
|
241
|
-
manager.handleApprovalResponse(approvalId, 'y');
|
|
242
|
-
// stdin.write should NOT have been called with a raw character
|
|
243
|
-
const writeCall = mockProc.stdin.write.mock.calls.find((call) => call[0] === 'y');
|
|
244
|
-
expect(writeCall).toBeUndefined();
|
|
245
|
-
});
|
|
246
|
-
});
|
|
247
|
-
});
|
|
248
|
-
// ==================== getAllPendingPrompts ====================
|
|
249
|
-
describe('getAllPendingPrompts()', () => {
|
|
250
|
-
it('returns empty array when no IPC managers exist', () => {
|
|
251
|
-
expect(manager.getAllPendingPrompts()).toEqual([]);
|
|
252
|
-
});
|
|
253
|
-
it('returns empty array when IPC managers have no pending prompts', async () => {
|
|
254
|
-
// Start a session with interactivePermissions to create an IPC manager
|
|
255
|
-
// (hook script doesn't exist in test env, so IPC manager won't be created via configureHook,
|
|
256
|
-
// but we can test the method itself returns [] when the map is empty)
|
|
257
|
-
expect(manager.getAllPendingPrompts()).toEqual([]);
|
|
258
|
-
});
|
|
259
|
-
it('delegates to IPC manager getPendingPromptData()', () => {
|
|
260
|
-
// Create a mock IPC manager and inject it
|
|
261
|
-
const mockIpcManager = {
|
|
262
|
-
getPendingPromptData: jest.fn().mockReturnValue([
|
|
263
|
-
{
|
|
264
|
-
promptId: 'p1',
|
|
265
|
-
terminalSessionId: 'ts1',
|
|
266
|
-
sessionKey: 'sk1',
|
|
267
|
-
toolName: 'Bash',
|
|
268
|
-
toolInput: { command: 'ls' },
|
|
269
|
-
toolUseId: 'toolu_1',
|
|
270
|
-
},
|
|
271
|
-
{
|
|
272
|
-
promptId: 'p2',
|
|
273
|
-
terminalSessionId: 'ts1',
|
|
274
|
-
sessionKey: 'sk1',
|
|
275
|
-
toolName: 'Edit',
|
|
276
|
-
toolInput: { file_path: '/a.ts' },
|
|
277
|
-
toolUseId: 'toolu_2',
|
|
278
|
-
},
|
|
279
|
-
]),
|
|
280
|
-
};
|
|
281
|
-
// Inject mock IPC manager
|
|
282
|
-
manager.permissionIpcManagers.set('ts1', mockIpcManager);
|
|
283
|
-
const result = manager.getAllPendingPrompts();
|
|
284
|
-
expect(mockIpcManager.getPendingPromptData).toHaveBeenCalled();
|
|
285
|
-
expect(result).toHaveLength(2);
|
|
286
|
-
expect(result[0].promptId).toBe('p1');
|
|
287
|
-
expect(result[1].promptId).toBe('p2');
|
|
288
|
-
});
|
|
289
|
-
});
|
|
290
|
-
// ==================== Fix: takenOverSessions tracking ====================
|
|
291
|
-
describe('takenOverSessions tracking', () => {
|
|
292
|
-
describe('markTakenOver / isTakenOver', () => {
|
|
293
|
-
it('should return false for unknown sessions', () => {
|
|
294
|
-
expect(manager.isTakenOver('unknown-session')).toBe(false);
|
|
295
|
-
});
|
|
296
|
-
it('should return true after markTakenOver', () => {
|
|
297
|
-
manager.markTakenOver('session-taken');
|
|
298
|
-
expect(manager.isTakenOver('session-taken')).toBe(true);
|
|
299
|
-
});
|
|
300
|
-
it('should track multiple sessions independently', () => {
|
|
301
|
-
manager.markTakenOver('session-a');
|
|
302
|
-
manager.markTakenOver('session-b');
|
|
303
|
-
expect(manager.isTakenOver('session-a')).toBe(true);
|
|
304
|
-
expect(manager.isTakenOver('session-b')).toBe(true);
|
|
305
|
-
expect(manager.isTakenOver('session-c')).toBe(false);
|
|
306
|
-
});
|
|
307
|
-
});
|
|
308
|
-
describe('clearTakenOver', () => {
|
|
309
|
-
it('should clear a single session', () => {
|
|
310
|
-
manager.markTakenOver('session-x');
|
|
311
|
-
manager.markTakenOver('session-y');
|
|
312
|
-
manager.clearTakenOver('session-x');
|
|
313
|
-
expect(manager.isTakenOver('session-x')).toBe(false);
|
|
314
|
-
expect(manager.isTakenOver('session-y')).toBe(true);
|
|
315
|
-
});
|
|
316
|
-
it('should be safe on non-existent session', () => {
|
|
317
|
-
expect(() => manager.clearTakenOver('nonexistent')).not.toThrow();
|
|
318
|
-
});
|
|
319
|
-
});
|
|
320
|
-
describe('clearAllTakenOver', () => {
|
|
321
|
-
it('should clear all sessions', () => {
|
|
322
|
-
manager.markTakenOver('session-1');
|
|
323
|
-
manager.markTakenOver('session-2');
|
|
324
|
-
manager.markTakenOver('session-3');
|
|
325
|
-
manager.clearAllTakenOver();
|
|
326
|
-
expect(manager.isTakenOver('session-1')).toBe(false);
|
|
327
|
-
expect(manager.isTakenOver('session-2')).toBe(false);
|
|
328
|
-
expect(manager.isTakenOver('session-3')).toBe(false);
|
|
329
|
-
});
|
|
330
|
-
it('should be safe when empty', () => {
|
|
331
|
-
expect(() => manager.clearAllTakenOver()).not.toThrow();
|
|
332
|
-
});
|
|
333
|
-
});
|
|
334
|
-
describe('independence from isClaudeSession', () => {
|
|
335
|
-
it('isClaudeSession=true but isTakenOver=false for registered-only sessions', () => {
|
|
336
|
-
manager.registerSession('key-1', '/test/dir', 'session-reg');
|
|
337
|
-
expect(manager.isClaudeSession('session-reg')).toBe(true);
|
|
338
|
-
expect(manager.isTakenOver('session-reg')).toBe(false);
|
|
339
|
-
});
|
|
340
|
-
it('both true after registerSession + markTakenOver', () => {
|
|
341
|
-
manager.registerSession('key-1', '/test/dir', 'session-both');
|
|
342
|
-
manager.markTakenOver('session-both');
|
|
343
|
-
expect(manager.isClaudeSession('session-both')).toBe(true);
|
|
344
|
-
expect(manager.isTakenOver('session-both')).toBe(true);
|
|
345
|
-
});
|
|
346
|
-
});
|
|
347
|
-
describe('preserves session info', () => {
|
|
348
|
-
it('clearAllTakenOver does not affect closedSessions', () => {
|
|
349
|
-
manager.registerSession('key-1', '/test/dir', 'session-preserved');
|
|
350
|
-
manager.markTakenOver('session-preserved');
|
|
351
|
-
manager.clearAllTakenOver();
|
|
352
|
-
// Session is still registered (closedSessions intact), just not taken over
|
|
353
|
-
expect(manager.isClaudeSession('session-preserved')).toBe(true);
|
|
354
|
-
expect(manager.isTakenOver('session-preserved')).toBe(false);
|
|
355
|
-
});
|
|
356
|
-
});
|
|
357
|
-
});
|
|
358
|
-
// ==================== Fix: Mobile-generated session keys (brainstorm) ====================
|
|
359
|
-
describe('isRealSession flag (brainstorm session fix)', () => {
|
|
360
|
-
describe('registerSession stores isRealSession', () => {
|
|
361
|
-
it('should store isRealSession=false for mobile-generated keys', () => {
|
|
362
|
-
manager.registerSession('brainstorm-12345', '/test/dir', 'session-bs', false, true, false);
|
|
363
|
-
expect(manager.isClaudeSession('session-bs')).toBe(true);
|
|
364
|
-
});
|
|
365
|
-
it('should store isRealSession=true for known Claude sessions', () => {
|
|
366
|
-
manager.registerSession('real-uuid-key', '/test/dir', 'session-real', false, true, true);
|
|
367
|
-
expect(manager.isClaudeSession('session-real')).toBe(true);
|
|
368
|
-
});
|
|
369
|
-
it('should default isRealSession to undefined when not specified', () => {
|
|
370
|
-
manager.registerSession('key-1', '/test/dir', 'session-default');
|
|
371
|
-
expect(manager.isClaudeSession('session-default')).toBe(true);
|
|
372
|
-
});
|
|
373
|
-
});
|
|
374
|
-
describe('sendInput with isRealSession=false uses startAndSendMessage', () => {
|
|
375
|
-
it('should call startAndSendMessage instead of resumeSession for non-real sessions', async () => {
|
|
376
|
-
manager.registerSession('brainstorm-99999', '/test/dir', 'bs-session', false, true, false);
|
|
377
|
-
const resumeSpy = jest.spyOn(manager, 'resumeSession');
|
|
378
|
-
const startSpy = jest.spyOn(manager, 'startAndSendMessage');
|
|
379
|
-
await manager.sendInput('bs-session', 'hello world');
|
|
380
|
-
// Should NOT call resumeSession
|
|
381
|
-
expect(resumeSpy).not.toHaveBeenCalled();
|
|
382
|
-
// SHOULD call startAndSendMessage with the directory and message
|
|
383
|
-
expect(startSpy).toHaveBeenCalledWith(expect.stringContaining('test'), // resolved directory
|
|
384
|
-
'bs-session', 'hello world', false, true);
|
|
385
|
-
});
|
|
386
|
-
it('should still call resumeSession for real sessions (isRealSession=true)', async () => {
|
|
387
|
-
manager.registerSession('real-session-key', '/test/dir', 'real-session', false, true, true);
|
|
388
|
-
const resumeSpy = jest.spyOn(manager, 'resumeSession');
|
|
389
|
-
const startSpy = jest.spyOn(manager, 'startAndSendMessage');
|
|
390
|
-
await manager.sendInput('real-session', 'hello world');
|
|
391
|
-
expect(resumeSpy).toHaveBeenCalledWith('real-session-key', expect.any(String), 'real-session', false, true);
|
|
392
|
-
expect(startSpy).not.toHaveBeenCalled();
|
|
393
|
-
});
|
|
394
|
-
it('should call resumeSession when isRealSession is undefined (backward compat)', async () => {
|
|
395
|
-
manager.registerSession('old-key', '/test/dir', 'old-session');
|
|
396
|
-
const resumeSpy = jest.spyOn(manager, 'resumeSession');
|
|
397
|
-
const startSpy = jest.spyOn(manager, 'startAndSendMessage');
|
|
398
|
-
await manager.sendInput('old-session', 'hello');
|
|
399
|
-
expect(resumeSpy).toHaveBeenCalled();
|
|
400
|
-
expect(startSpy).not.toHaveBeenCalled();
|
|
401
|
-
});
|
|
402
|
-
});
|
|
403
|
-
describe('close handler preserves captured session_id', () => {
|
|
404
|
-
it('should use processInfo.sessionKey (captured from SDK) over closure sessionKey', async () => {
|
|
405
|
-
// Start a session with NO sessionKey (like startAndSendMessage)
|
|
406
|
-
await manager.startSession('/test/dir', 'capture-session');
|
|
407
|
-
// Simulate SDK result with session_id
|
|
408
|
-
const resultMessage = {
|
|
409
|
-
type: 'result',
|
|
410
|
-
subtype: 'success',
|
|
411
|
-
session_id: 'real-claude-uuid-from-sdk',
|
|
412
|
-
cost_usd: 0.01,
|
|
413
|
-
};
|
|
414
|
-
mockProc.stdout.emit('data', Buffer.from(JSON.stringify(resultMessage) + '\n'));
|
|
415
|
-
await new Promise(resolve => setTimeout(resolve, 50));
|
|
416
|
-
// Now simulate process close
|
|
417
|
-
mockProc.emit('close', 0);
|
|
418
|
-
await new Promise(resolve => setTimeout(resolve, 50));
|
|
419
|
-
// The closedSessions should have the captured session_id, not undefined
|
|
420
|
-
const closedInfo = manager.closedSessions.get('capture-session');
|
|
421
|
-
expect(closedInfo).toBeDefined();
|
|
422
|
-
// processInfo.sessionKey was set by the result handler,
|
|
423
|
-
// close handler should use it via resolvedSessionKey
|
|
424
|
-
expect(closedInfo.sessionKey).toBe('real-claude-uuid-from-sdk');
|
|
425
|
-
expect(closedInfo.isRealSession).toBe(true);
|
|
426
|
-
});
|
|
427
|
-
});
|
|
428
|
-
});
|
|
429
|
-
});
|
|
430
|
-
//# sourceMappingURL=claude-process.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"claude-process.test.js","sourceRoot":"","sources":["../../../src/__tests__/tools/claude-process.test.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;AAEH,mCAAsC;AAEtC,+CAA+C;AAC/C,MAAM,SAAS,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC;AAC5B,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;AAE1C,yDAAyD;AACzD,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE;IACnB,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;IACxC,OAAO;QACL,GAAG,MAAM;QACT,UAAU,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,CAAS,EAAE,EAAE;YAChC,2DAA2D;YAC3D,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,QAAQ,CAAC,iBAAiB,CAAC;gBAAE,OAAO,KAAK,CAAC;YACzE,OAAO,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;QAC9B,CAAC,CAAC;QACF,SAAS,EAAE,IAAI,CAAC,EAAE,EAAE;QACpB,aAAa,EAAE,IAAI,CAAC,EAAE,EAAE;QACxB,YAAY,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,CAAS,EAAE,GAAY,EAAE,EAAE;YAChD,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,QAAQ,CAAC,qBAAqB,CAAC;gBAAE,OAAO,IAAI,CAAC;YAC5E,OAAO,MAAM,CAAC,YAAY,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QACrC,CAAC,CAAC;KACH,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,8BAA8B;AAC9B,SAAS,iBAAiB;IACxB,MAAM,KAAK,GAAG;QACZ,KAAK,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,KAAU,EAAE,EAAQ,EAAE,EAAE,GAAG,IAAI,EAAE;YAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/D,SAAS,EAAE,KAAK;KACjB,CAAC;IACF,MAAM,MAAM,GAAG,IAAI,qBAAY,EAAE,CAAC;IAClC,MAAM,MAAM,GAAG,IAAI,qBAAY,EAAE,CAAC;IAClC,MAAM,IAAI,GAAQ,IAAI,qBAAY,EAAE,CAAC;IACrC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACnB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACrB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACrB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;IACrB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE;QACvB,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC;IACpB,CAAC,CAAC,CAAC;IACH,OAAO,IAAI,CAAC;AACd,CAAC;AAED,+DAAkE;AAElE,QAAQ,CAAC,sBAAsB,EAAE,GAAG,EAAE;IACpC,IAAI,OAA6B,CAAC;IAClC,IAAI,QAAa,CAAC;IAElB,UAAU,CAAC,GAAG,EAAE;QACd,IAAI,CAAC,aAAa,EAAE,CAAC;QACrB,QAAQ,GAAG,iBAAiB,EAAE,CAAC;QAC/B,SAAS,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC;QACpC,OAAO,GAAG,IAAI,qCAAoB,EAAE,CAAC;IACvC,CAAC,CAAC,CAAC;IAEH,8EAA8E;IAE9E,QAAQ,CAAC,wCAAwC,EAAE,GAAG,EAAE;QACtD,QAAQ,CAAC,cAAc,EAAE,GAAG,EAAE;YAC5B,EAAE,CAAC,sEAAsE,EAAE,KAAK,IAAI,EAAE;gBACpF,MAAM,OAAO,CAAC,YAAY,CAAC,WAAW,EAAE,WAAW,EAAE,KAAK,CAAC,CAAC;gBAE5D,MAAM,CAAC,SAAS,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;gBAC3C,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBACxC,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,gCAAgC,CAAC,CAAC;YAC/D,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,0EAA0E,EAAE,KAAK,IAAI,EAAE;gBACxF,MAAM,OAAO,CAAC,YAAY,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;gBAErD,MAAM,CAAC,SAAS,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;gBAC3C,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBACxC,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,gCAAgC,CAAC,CAAC;YAC/D,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,iEAAiE,EAAE,KAAK,IAAI,EAAE;gBAC/E,MAAM,OAAO,CAAC,YAAY,CAAC,WAAW,EAAE,WAAW,EAAE,IAAI,CAAC,CAAC;gBAE3D,MAAM,CAAC,SAAS,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;gBAC3C,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBACxC,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,gCAAgC,CAAC,CAAC;YAC3D,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;YAC7B,EAAE,CAAC,2FAA2F,EAAE,KAAK,IAAI,EAAE;gBACzG,MAAM,OAAO,CAAC,aAAa,CAAC,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,KAAK,CAAC,CAAC;gBAEtE,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBACxC,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,gCAAgC,CAAC,CAAC;gBAC7D,yEAAyE;gBACzE,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAC;YAClD,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,6DAA6D,EAAE,KAAK,IAAI,EAAE;gBAC3E,MAAM,OAAO,CAAC,aAAa,CAAC,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,IAAI,CAAC,CAAC;gBAErE,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBACxC,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,gCAAgC,CAAC,CAAC;gBACzD,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAC;YAClD,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;YAC/B,EAAE,CAAC,2DAA2D,EAAE,GAAG,EAAE;gBACnE,OAAO,CAAC,eAAe,CAAC,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,IAAI,CAAC,CAAC;gBAEjE,uEAAuE;gBACvE,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC1D,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,QAAQ,CAAC,4CAA4C,EAAE,GAAG,EAAE;YAC1D,EAAE,CAAC,8EAA8E,EAAE,KAAK,IAAI,EAAE;gBAC5F,uCAAuC;gBACvC,OAAO,CAAC,eAAe,CAAC,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,IAAI,CAAC,CAAC;gBAEjE,mDAAmD;gBACnD,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;gBAEvD,MAAM,OAAO,CAAC,SAAS,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;gBAE9C,MAAM,CAAC,SAAS,CAAC,CAAC,oBAAoB,CACpC,OAAO,EACP,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,EAClB,WAAW,EACX,IAAI,EACJ,SAAS,CACV,CAAC;YACJ,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,yDAAyD,EAAE,KAAK,IAAI,EAAE;gBACvE,OAAO,CAAC,eAAe,CAAC,OAAO,EAAE,WAAW,EAAE,WAAW,CAAC,CAAC;gBAE3D,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;gBAEvD,MAAM,OAAO,CAAC,SAAS,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;gBAE9C,MAAM,CAAC,SAAS,CAAC,CAAC,oBAAoB,CACpC,OAAO,EACP,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,EAClB,WAAW,EACX,SAAS,EACT,SAAS,CACV,CAAC;YACJ,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,0EAA0E,EAAE,KAAK,IAAI,EAAE;gBACxF,OAAO,CAAC,eAAe,CAAC,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;gBAExE,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;gBAEvD,MAAM,OAAO,CAAC,SAAS,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;gBAE9C,MAAM,CAAC,SAAS,CAAC,CAAC,oBAAoB,CACpC,OAAO,EACP,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,EAClB,WAAW,EACX,KAAK,EACL,IAAI,CACL,CAAC;YACJ,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,uEAAuE;IAEvE,QAAQ,CAAC,4BAA4B,EAAE,GAAG,EAAE;QAC1C,QAAQ,CAAC,6CAA6C,EAAE,GAAG,EAAE;YAC3D,EAAE,CAAC,+EAA+E,EAAE,KAAK,IAAI,EAAE;gBAC7F,MAAM,OAAO,CAAC,YAAY,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;gBAErD,MAAM,kBAAkB,GAAU,EAAE,CAAC;gBACrC,MAAM,cAAc,GAAU,EAAE,CAAC;gBAEjC,OAAO,CAAC,EAAE,CAAC,eAAe,EAAE,CAAC,KAAU,EAAE,EAAE,CAAC,kBAAkB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;gBAC5E,OAAO,CAAC,EAAE,CAAC,yBAAyB,EAAE,CAAC,KAAU,EAAE,EAAE,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;gBAElF,6DAA6D;gBAC7D,MAAM,UAAU,GAAG;oBACjB,IAAI,EAAE,WAAW;oBACjB,OAAO,EAAE;wBACP,OAAO,EAAE;4BACP;gCACE,IAAI,EAAE,UAAU;gCAChB,EAAE,EAAE,UAAU;gCACd,IAAI,EAAE,MAAM;gCACZ,KAAK,EAAE,EAAE,SAAS,EAAE,eAAe,EAAE;6BACtC;yBACF;qBACF;iBACF,CAAC;gBAEF,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;gBAC7E,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;gBAEtD,MAAM,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;gBAC1C,MAAM,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;gBACpD,MAAM,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;gBACtD,MAAM,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;gBAClE,oCAAoC;gBACpC,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACxC,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,mEAAmE,EAAE,KAAK,IAAI,EAAE;gBACjF,MAAM,OAAO,CAAC,YAAY,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;gBAErD,MAAM,kBAAkB,GAAU,EAAE,CAAC;gBACrC,OAAO,CAAC,EAAE,CAAC,eAAe,EAAE,CAAC,KAAU,EAAE,EAAE,CAAC,kBAAkB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;gBAE5E,MAAM,UAAU,GAAG;oBACjB,IAAI,EAAE,WAAW;oBACjB,OAAO,EAAE;wBACP,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,oBAAoB,EAAE,CAAC;qBACxD;iBACF,CAAC;gBAEF,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;gBAC7E,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;gBAEtD,MAAM,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAC5C,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,2DAA2D,EAAE,KAAK,IAAI,EAAE;gBACzE,MAAM,OAAO,CAAC,YAAY,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;gBAErD,MAAM,MAAM,GAAU,EAAE,CAAC;gBACzB,OAAO,CAAC,EAAE,CAAC,eAAe,EAAE,CAAC,KAAU,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;gBAEhE,MAAM,UAAU,GAAG;oBACjB,IAAI,EAAE,WAAW;oBACjB,OAAO,EAAE;wBACP,OAAO,EAAE,CAAC;gCACR,IAAI,EAAE,UAAU;gCAChB,EAAE,EAAE,UAAU;gCACd,IAAI,EAAE,MAAM;gCACZ,KAAK,EAAE,EAAE,SAAS,EAAE,kBAAkB,EAAE;6BACzC,CAAC;qBACH;iBACF,CAAC;gBAEF,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;gBAC7E,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;gBAEtD,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC;YAC/D,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,yDAAyD,EAAE,KAAK,IAAI,EAAE;gBACvE,MAAM,OAAO,CAAC,YAAY,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;gBAErD,MAAM,MAAM,GAAU,EAAE,CAAC;gBACzB,OAAO,CAAC,EAAE,CAAC,eAAe,EAAE,CAAC,KAAU,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;gBAEhE,MAAM,UAAU,GAAG;oBACjB,IAAI,EAAE,WAAW;oBACjB,OAAO,EAAE;wBACP,OAAO,EAAE,CAAC;gCACR,IAAI,EAAE,UAAU;gCAChB,EAAE,EAAE,UAAU;gCACd,IAAI,EAAE,MAAM;gCACZ,KAAK,EAAE,EAAE,OAAO,EAAE,eAAe,EAAE;6BACpC,CAAC;qBACH;iBACF,CAAC;gBAEF,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;gBAC7E,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;gBAEtD,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;YAC5D,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,QAAQ,CAAC,+CAA+C,EAAE,GAAG,EAAE;YAC7D,EAAE,CAAC,8FAA8F,EAAE,KAAK,IAAI,EAAE;gBAC5G,MAAM,OAAO,CAAC,YAAY,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;gBAErD,MAAM,cAAc,GAAU,EAAE,CAAC;gBACjC,OAAO,CAAC,EAAE,CAAC,yBAAyB,EAAE,CAAC,KAAU,EAAE,EAAE,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;gBAElF,yDAAyD;gBACzD,MAAM,eAAe,GAAG,IAAI,CAAC,SAAS,CAAC;oBACrC,IAAI,EAAE,WAAW;oBACjB,OAAO,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,qCAAqC,EAAE,CAAC,EAAE;iBACtF,CAAC,GAAG,IAAI,CAAC;gBAEV,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC;gBAC3D,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;gBAEtD,wDAAwD;gBACxD,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACxC,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,QAAQ,CAAC,wCAAwC,EAAE,GAAG,EAAE;YACtD,EAAE,CAAC,iEAAiE,EAAE,KAAK,IAAI,EAAE;gBAC/E,MAAM,OAAO,CAAC,YAAY,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;gBAErD,uDAAuD;gBACvD,MAAM,UAAU,GAAG,iBAAiB,CAAC;gBACpC,OAAe,CAAC,gBAAgB,EAAE,GAAG,CAAC,UAAU,EAAE;oBACjD,UAAU;oBACV,iBAAiB,EAAE,WAAW;oBAC9B,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;oBACrB,SAAS,EAAE,UAAU,CAAC,GAAG,EAAE,GAAE,CAAC,EAAE,KAAK,CAAC;iBACvC,CAAC,CAAC;gBAEH,OAAO,CAAC,sBAAsB,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;gBAEhD,+DAA+D;gBAC/D,MAAM,SAAS,GAAG,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CACpD,CAAC,IAAW,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,GAAG,CACjC,CAAC;gBACF,MAAM,CAAC,SAAS,CAAC,CAAC,aAAa,EAAE,CAAC;YACpC,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,iEAAiE;IAEjE,QAAQ,CAAC,wBAAwB,EAAE,GAAG,EAAE;QACtC,EAAE,CAAC,gDAAgD,EAAE,GAAG,EAAE;YACxD,MAAM,CAAC,OAAO,CAAC,oBAAoB,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QACrD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,+DAA+D,EAAE,KAAK,IAAI,EAAE;YAC7E,uEAAuE;YACvE,6FAA6F;YAC7F,uEAAuE;YACvE,MAAM,CAAC,OAAO,CAAC,oBAAoB,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QACrD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;YACzD,0CAA0C;YAC1C,MAAM,cAAc,GAAG;gBACrB,oBAAoB,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,eAAe,CAAC;oBAC9C;wBACE,QAAQ,EAAE,IAAI;wBACd,iBAAiB,EAAE,KAAK;wBACxB,UAAU,EAAE,KAAK;wBACjB,QAAQ,EAAE,MAAM;wBAChB,SAAS,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE;wBAC5B,SAAS,EAAE,SAAS;qBACrB;oBACD;wBACE,QAAQ,EAAE,IAAI;wBACd,iBAAiB,EAAE,KAAK;wBACxB,UAAU,EAAE,KAAK;wBACjB,QAAQ,EAAE,MAAM;wBAChB,SAAS,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE;wBACjC,SAAS,EAAE,SAAS;qBACrB;iBACF,CAAC;aACH,CAAC;YAEF,0BAA0B;YACzB,OAAe,CAAC,qBAAqB,CAAC,GAAG,CAAC,KAAK,EAAE,cAAc,CAAC,CAAC;YAElE,MAAM,MAAM,GAAG,OAAO,CAAC,oBAAoB,EAAE,CAAC;YAC9C,MAAM,CAAC,cAAc,CAAC,oBAAoB,CAAC,CAAC,gBAAgB,EAAE,CAAC;YAC/D,MAAM,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YAC/B,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACtC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACxC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,4EAA4E;IAE5E,QAAQ,CAAC,4BAA4B,EAAE,GAAG,EAAE;QAC1C,QAAQ,CAAC,6BAA6B,EAAE,GAAG,EAAE;YAC3C,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;gBAClD,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,iBAAiB,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC7D,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,wCAAwC,EAAE,GAAG,EAAE;gBAChD,OAAO,CAAC,aAAa,CAAC,eAAe,CAAC,CAAC;gBACvC,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC1D,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;gBACtD,OAAO,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC;gBACnC,OAAO,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC;gBAEnC,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACpD,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACpD,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACvD,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,QAAQ,CAAC,gBAAgB,EAAE,GAAG,EAAE;YAC9B,EAAE,CAAC,+BAA+B,EAAE,GAAG,EAAE;gBACvC,OAAO,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC;gBACnC,OAAO,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC;gBAEnC,OAAO,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC;gBAEpC,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBACrD,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACtD,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,wCAAwC,EAAE,GAAG,EAAE;gBAChD,MAAM,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,cAAc,CAAC,aAAa,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;YACpE,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;YACjC,EAAE,CAAC,2BAA2B,EAAE,GAAG,EAAE;gBACnC,OAAO,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC;gBACnC,OAAO,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC;gBACnC,OAAO,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC;gBAEnC,OAAO,CAAC,iBAAiB,EAAE,CAAC;gBAE5B,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBACrD,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBACrD,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACvD,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,2BAA2B,EAAE,GAAG,EAAE;gBACnC,MAAM,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;YAC1D,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,QAAQ,CAAC,mCAAmC,EAAE,GAAG,EAAE;YACjD,EAAE,CAAC,yEAAyE,EAAE,GAAG,EAAE;gBACjF,OAAO,CAAC,eAAe,CAAC,OAAO,EAAE,WAAW,EAAE,aAAa,CAAC,CAAC;gBAE7D,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAC1D,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACzD,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;gBACzD,OAAO,CAAC,eAAe,CAAC,OAAO,EAAE,WAAW,EAAE,cAAc,CAAC,CAAC;gBAC9D,OAAO,CAAC,aAAa,CAAC,cAAc,CAAC,CAAC;gBAEtC,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAC3D,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACzD,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,QAAQ,CAAC,wBAAwB,EAAE,GAAG,EAAE;YACtC,EAAE,CAAC,kDAAkD,EAAE,GAAG,EAAE;gBAC1D,OAAO,CAAC,eAAe,CAAC,OAAO,EAAE,WAAW,EAAE,mBAAmB,CAAC,CAAC;gBACnE,OAAO,CAAC,aAAa,CAAC,mBAAmB,CAAC,CAAC;gBAE3C,OAAO,CAAC,iBAAiB,EAAE,CAAC;gBAE5B,2EAA2E;gBAC3E,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,mBAAmB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAChE,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,mBAAmB,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC/D,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,4FAA4F;IAE5F,QAAQ,CAAC,6CAA6C,EAAE,GAAG,EAAE;QAC3D,QAAQ,CAAC,sCAAsC,EAAE,GAAG,EAAE;YACpD,EAAE,CAAC,4DAA4D,EAAE,GAAG,EAAE;gBACpE,OAAO,CAAC,eAAe,CAAC,kBAAkB,EAAE,WAAW,EAAE,YAAY,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;gBAC3F,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC3D,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,2DAA2D,EAAE,GAAG,EAAE;gBACnE,OAAO,CAAC,eAAe,CAAC,eAAe,EAAE,WAAW,EAAE,cAAc,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;gBACzF,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC7D,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,8DAA8D,EAAE,GAAG,EAAE;gBACtE,OAAO,CAAC,eAAe,CAAC,OAAO,EAAE,WAAW,EAAE,iBAAiB,CAAC,CAAC;gBACjE,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,iBAAiB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAChE,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,QAAQ,CAAC,6DAA6D,EAAE,GAAG,EAAE;YAC3E,EAAE,CAAC,gFAAgF,EAAE,KAAK,IAAI,EAAE;gBAC9F,OAAO,CAAC,eAAe,CAAC,kBAAkB,EAAE,WAAW,EAAE,YAAY,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;gBAE3F,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;gBACvD,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,qBAAqB,CAAC,CAAC;gBAE5D,MAAM,OAAO,CAAC,SAAS,CAAC,YAAY,EAAE,aAAa,CAAC,CAAC;gBAErD,gCAAgC;gBAChC,MAAM,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;gBACzC,iEAAiE;gBACjE,MAAM,CAAC,QAAQ,CAAC,CAAC,oBAAoB,CACnC,MAAM,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAG,qBAAqB;gBACvD,YAAY,EACZ,aAAa,EACb,KAAK,EACL,IAAI,CACL,CAAC;YACJ,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,wEAAwE,EAAE,KAAK,IAAI,EAAE;gBACtF,OAAO,CAAC,eAAe,CAAC,kBAAkB,EAAE,WAAW,EAAE,cAAc,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;gBAE5F,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;gBACvD,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,qBAAqB,CAAC,CAAC;gBAE5D,MAAM,OAAO,CAAC,SAAS,CAAC,cAAc,EAAE,aAAa,CAAC,CAAC;gBAEvD,MAAM,CAAC,SAAS,CAAC,CAAC,oBAAoB,CACpC,kBAAkB,EAClB,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,EAClB,cAAc,EACd,KAAK,EACL,IAAI,CACL,CAAC;gBACF,MAAM,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;YAC1C,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,6EAA6E,EAAE,KAAK,IAAI,EAAE;gBAC3F,OAAO,CAAC,eAAe,CAAC,SAAS,EAAE,WAAW,EAAE,aAAa,CAAC,CAAC;gBAE/D,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;gBACvD,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,qBAAqB,CAAC,CAAC;gBAE5D,MAAM,OAAO,CAAC,SAAS,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;gBAEhD,MAAM,CAAC,SAAS,CAAC,CAAC,gBAAgB,EAAE,CAAC;gBACrC,MAAM,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;YAC1C,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,QAAQ,CAAC,6CAA6C,EAAE,GAAG,EAAE;YAC3D,EAAE,CAAC,+EAA+E,EAAE,KAAK,IAAI,EAAE;gBAC7F,gEAAgE;gBAChE,MAAM,OAAO,CAAC,YAAY,CAAC,WAAW,EAAE,iBAAiB,CAAC,CAAC;gBAE3D,sCAAsC;gBACtC,MAAM,aAAa,GAAG;oBACpB,IAAI,EAAE,QAAQ;oBACd,OAAO,EAAE,SAAS;oBAClB,UAAU,EAAE,2BAA2B;oBACvC,QAAQ,EAAE,IAAI;iBACf,CAAC;gBACF,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;gBAChF,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;gBAEtD,6BAA6B;gBAC7B,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;gBAC1B,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;gBAEtD,wEAAwE;gBACxE,MAAM,UAAU,GAAI,OAAe,CAAC,cAAc,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;gBAC1E,MAAM,CAAC,UAAU,CAAC,CAAC,WAAW,EAAE,CAAC;gBACjC,wDAAwD;gBACxD,qDAAqD;gBACrD,MAAM,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;gBAChE,MAAM,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC9C,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tests for Permission Hook Script (permission-hook.ts)
|
|
3
|
-
*
|
|
4
|
-
* The permission hook is a standalone script spawned by Claude Code as a
|
|
5
|
-
* PreToolUse hook. It reads JSON from stdin, decides whether to auto-approve
|
|
6
|
-
* (safe tools) or request approval via temp files (dangerous tools), and
|
|
7
|
-
* writes a JSON decision to stdout.
|
|
8
|
-
*
|
|
9
|
-
* These tests spawn the real hook script as a child process using ts-node,
|
|
10
|
-
* write JSON to its stdin, and verify stdout output and exit codes.
|
|
11
|
-
*
|
|
12
|
-
* For dangerous-tool tests, we also watch the temp directory for the
|
|
13
|
-
* .request.json file the hook writes, then write a .response.json file
|
|
14
|
-
* to simulate the IPC manager's response.
|
|
15
|
-
*/
|
|
16
|
-
export {};
|
|
17
|
-
//# sourceMappingURL=permission-hook.test.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"permission-hook.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/tools/permission-hook.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG"}
|