@cleocode/adapters 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +27 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1927 -0
- package/dist/index.js.map +7 -0
- package/dist/providers/claude-code/adapter.d.ts +75 -0
- package/dist/providers/claude-code/adapter.d.ts.map +1 -0
- package/dist/providers/claude-code/adapter.js +154 -0
- package/dist/providers/claude-code/adapter.js.map +1 -0
- package/dist/providers/claude-code/context-monitor.d.ts +24 -0
- package/dist/providers/claude-code/context-monitor.d.ts.map +1 -0
- package/dist/providers/claude-code/context-monitor.js +148 -0
- package/dist/providers/claude-code/context-monitor.js.map +1 -0
- package/dist/providers/claude-code/hooks.d.ts +59 -0
- package/dist/providers/claude-code/hooks.d.ts.map +1 -0
- package/dist/providers/claude-code/hooks.js +77 -0
- package/dist/providers/claude-code/hooks.js.map +1 -0
- package/dist/providers/claude-code/index.d.ts +24 -0
- package/dist/providers/claude-code/index.d.ts.map +1 -0
- package/dist/providers/claude-code/index.js +26 -0
- package/dist/providers/claude-code/index.js.map +1 -0
- package/dist/providers/claude-code/install.d.ts +75 -0
- package/dist/providers/claude-code/install.d.ts.map +1 -0
- package/dist/providers/claude-code/install.js +237 -0
- package/dist/providers/claude-code/install.js.map +1 -0
- package/dist/providers/claude-code/paths.d.ts +24 -0
- package/dist/providers/claude-code/paths.d.ts.map +1 -0
- package/dist/providers/claude-code/paths.js +33 -0
- package/dist/providers/claude-code/paths.js.map +1 -0
- package/dist/providers/claude-code/spawn.d.ts +60 -0
- package/dist/providers/claude-code/spawn.d.ts.map +1 -0
- package/dist/providers/claude-code/spawn.js +160 -0
- package/dist/providers/claude-code/spawn.js.map +1 -0
- package/dist/providers/claude-code/statusline.d.ts +24 -0
- package/dist/providers/claude-code/statusline.d.ts.map +1 -0
- package/dist/providers/claude-code/statusline.js +85 -0
- package/dist/providers/claude-code/statusline.js.map +1 -0
- package/dist/providers/claude-code/task-sync.d.ts +27 -0
- package/dist/providers/claude-code/task-sync.d.ts.map +1 -0
- package/dist/providers/claude-code/task-sync.js +124 -0
- package/dist/providers/claude-code/task-sync.js.map +1 -0
- package/dist/providers/claude-code/transport.d.ts +14 -0
- package/dist/providers/claude-code/transport.d.ts.map +1 -0
- package/dist/providers/claude-code/transport.js +18 -0
- package/dist/providers/claude-code/transport.js.map +1 -0
- package/dist/providers/cursor/adapter.d.ts +62 -0
- package/dist/providers/cursor/adapter.d.ts.map +1 -0
- package/dist/providers/cursor/adapter.js +124 -0
- package/dist/providers/cursor/adapter.js.map +1 -0
- package/dist/providers/cursor/hooks.d.ts +48 -0
- package/dist/providers/cursor/hooks.d.ts.map +1 -0
- package/dist/providers/cursor/hooks.js +55 -0
- package/dist/providers/cursor/hooks.js.map +1 -0
- package/dist/providers/cursor/index.d.ts +19 -0
- package/dist/providers/cursor/index.d.ts.map +1 -0
- package/dist/providers/cursor/index.js +21 -0
- package/dist/providers/cursor/index.js.map +1 -0
- package/dist/providers/cursor/install.d.ts +94 -0
- package/dist/providers/cursor/install.d.ts.map +1 -0
- package/dist/providers/cursor/install.js +241 -0
- package/dist/providers/cursor/install.js.map +1 -0
- package/dist/providers/cursor/spawn.d.ts +50 -0
- package/dist/providers/cursor/spawn.d.ts.map +1 -0
- package/dist/providers/cursor/spawn.js +59 -0
- package/dist/providers/cursor/spawn.js.map +1 -0
- package/dist/providers/opencode/adapter.d.ts +67 -0
- package/dist/providers/opencode/adapter.d.ts.map +1 -0
- package/dist/providers/opencode/adapter.js +144 -0
- package/dist/providers/opencode/adapter.js.map +1 -0
- package/dist/providers/opencode/hooks.d.ts +66 -0
- package/dist/providers/opencode/hooks.d.ts.map +1 -0
- package/dist/providers/opencode/hooks.js +89 -0
- package/dist/providers/opencode/hooks.js.map +1 -0
- package/dist/providers/opencode/index.d.ts +20 -0
- package/dist/providers/opencode/index.d.ts.map +1 -0
- package/dist/providers/opencode/index.js +22 -0
- package/dist/providers/opencode/index.js.map +1 -0
- package/dist/providers/opencode/install.d.ts +65 -0
- package/dist/providers/opencode/install.d.ts.map +1 -0
- package/dist/providers/opencode/install.js +183 -0
- package/dist/providers/opencode/install.js.map +1 -0
- package/dist/providers/opencode/spawn.d.ts +72 -0
- package/dist/providers/opencode/spawn.d.ts.map +1 -0
- package/dist/providers/opencode/spawn.js +219 -0
- package/dist/providers/opencode/spawn.js.map +1 -0
- package/dist/registry.d.ts +36 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +55 -0
- package/dist/registry.js.map +1 -0
- package/package.json +32 -0
- package/src/index.d.ts +27 -0
- package/src/index.d.ts.map +1 -0
- package/src/index.js +28 -0
- package/src/index.js.map +1 -0
- package/src/index.ts +37 -0
- package/src/providers/claude-code/__tests__/adapter.test.d.ts +7 -0
- package/src/providers/claude-code/__tests__/adapter.test.d.ts.map +1 -0
- package/src/providers/claude-code/__tests__/adapter.test.js +249 -0
- package/src/providers/claude-code/__tests__/adapter.test.js.map +1 -0
- package/src/providers/claude-code/__tests__/adapter.test.ts +291 -0
- package/src/providers/claude-code/adapter.d.ts +75 -0
- package/src/providers/claude-code/adapter.d.ts.map +1 -0
- package/src/providers/claude-code/adapter.js +154 -0
- package/src/providers/claude-code/adapter.js.map +1 -0
- package/src/providers/claude-code/adapter.ts +175 -0
- package/src/providers/claude-code/context-monitor.d.ts +24 -0
- package/src/providers/claude-code/context-monitor.d.ts.map +1 -0
- package/src/providers/claude-code/context-monitor.js +148 -0
- package/src/providers/claude-code/context-monitor.js.map +1 -0
- package/src/providers/claude-code/context-monitor.ts +175 -0
- package/src/providers/claude-code/hooks.d.ts +59 -0
- package/src/providers/claude-code/hooks.d.ts.map +1 -0
- package/src/providers/claude-code/hooks.js +77 -0
- package/src/providers/claude-code/hooks.js.map +1 -0
- package/src/providers/claude-code/hooks.ts +85 -0
- package/src/providers/claude-code/index.d.ts +24 -0
- package/src/providers/claude-code/index.d.ts.map +1 -0
- package/src/providers/claude-code/index.js +26 -0
- package/src/providers/claude-code/index.js.map +1 -0
- package/src/providers/claude-code/index.ts +33 -0
- package/src/providers/claude-code/install.d.ts +75 -0
- package/src/providers/claude-code/install.d.ts.map +1 -0
- package/src/providers/claude-code/install.js +237 -0
- package/src/providers/claude-code/install.js.map +1 -0
- package/src/providers/claude-code/install.ts +267 -0
- package/src/providers/claude-code/manifest.json +26 -0
- package/src/providers/claude-code/paths.d.ts +24 -0
- package/src/providers/claude-code/paths.d.ts.map +1 -0
- package/src/providers/claude-code/paths.js +33 -0
- package/src/providers/claude-code/paths.js.map +1 -0
- package/src/providers/claude-code/paths.ts +38 -0
- package/src/providers/claude-code/spawn.d.ts +60 -0
- package/src/providers/claude-code/spawn.d.ts.map +1 -0
- package/src/providers/claude-code/spawn.js +160 -0
- package/src/providers/claude-code/spawn.js.map +1 -0
- package/src/providers/claude-code/spawn.ts +178 -0
- package/src/providers/claude-code/statusline.d.ts +24 -0
- package/src/providers/claude-code/statusline.d.ts.map +1 -0
- package/src/providers/claude-code/statusline.js +85 -0
- package/src/providers/claude-code/statusline.js.map +1 -0
- package/src/providers/claude-code/statusline.ts +99 -0
- package/src/providers/claude-code/task-sync.d.ts +27 -0
- package/src/providers/claude-code/task-sync.d.ts.map +1 -0
- package/src/providers/claude-code/task-sync.js +124 -0
- package/src/providers/claude-code/task-sync.js.map +1 -0
- package/src/providers/claude-code/task-sync.ts +158 -0
- package/src/providers/claude-code/transport.d.ts +14 -0
- package/src/providers/claude-code/transport.d.ts.map +1 -0
- package/src/providers/claude-code/transport.js +18 -0
- package/src/providers/claude-code/transport.js.map +1 -0
- package/src/providers/claude-code/transport.ts +21 -0
- package/src/providers/cursor/__tests__/adapter.test.d.ts +7 -0
- package/src/providers/cursor/__tests__/adapter.test.d.ts.map +1 -0
- package/src/providers/cursor/__tests__/adapter.test.js +246 -0
- package/src/providers/cursor/__tests__/adapter.test.js.map +1 -0
- package/src/providers/cursor/__tests__/adapter.test.ts +291 -0
- package/src/providers/cursor/adapter.d.ts +62 -0
- package/src/providers/cursor/adapter.d.ts.map +1 -0
- package/src/providers/cursor/adapter.js +124 -0
- package/src/providers/cursor/adapter.js.map +1 -0
- package/src/providers/cursor/adapter.ts +145 -0
- package/src/providers/cursor/hooks.d.ts +48 -0
- package/src/providers/cursor/hooks.d.ts.map +1 -0
- package/src/providers/cursor/hooks.js +55 -0
- package/src/providers/cursor/hooks.js.map +1 -0
- package/src/providers/cursor/hooks.ts +61 -0
- package/src/providers/cursor/index.d.ts +19 -0
- package/src/providers/cursor/index.d.ts.map +1 -0
- package/src/providers/cursor/index.js +21 -0
- package/src/providers/cursor/index.js.map +1 -0
- package/src/providers/cursor/index.ts +24 -0
- package/src/providers/cursor/install.d.ts +94 -0
- package/src/providers/cursor/install.d.ts.map +1 -0
- package/src/providers/cursor/install.js +241 -0
- package/src/providers/cursor/install.js.map +1 -0
- package/src/providers/cursor/install.ts +271 -0
- package/src/providers/cursor/manifest.json +26 -0
- package/src/providers/cursor/spawn.d.ts +50 -0
- package/src/providers/cursor/spawn.d.ts.map +1 -0
- package/src/providers/cursor/spawn.js +59 -0
- package/src/providers/cursor/spawn.js.map +1 -0
- package/src/providers/cursor/spawn.ts +66 -0
- package/src/providers/opencode/__tests__/adapter.test.d.ts +7 -0
- package/src/providers/opencode/__tests__/adapter.test.d.ts.map +1 -0
- package/src/providers/opencode/__tests__/adapter.test.js +263 -0
- package/src/providers/opencode/__tests__/adapter.test.js.map +1 -0
- package/src/providers/opencode/__tests__/adapter.test.ts +309 -0
- package/src/providers/opencode/adapter.d.ts +67 -0
- package/src/providers/opencode/adapter.d.ts.map +1 -0
- package/src/providers/opencode/adapter.js +144 -0
- package/src/providers/opencode/adapter.js.map +1 -0
- package/src/providers/opencode/adapter.ts +165 -0
- package/src/providers/opencode/hooks.d.ts +66 -0
- package/src/providers/opencode/hooks.d.ts.map +1 -0
- package/src/providers/opencode/hooks.js +89 -0
- package/src/providers/opencode/hooks.js.map +1 -0
- package/src/providers/opencode/hooks.ts +97 -0
- package/src/providers/opencode/index.d.ts +20 -0
- package/src/providers/opencode/index.d.ts.map +1 -0
- package/src/providers/opencode/index.js +22 -0
- package/src/providers/opencode/index.js.map +1 -0
- package/src/providers/opencode/index.ts +25 -0
- package/src/providers/opencode/install.d.ts +65 -0
- package/src/providers/opencode/install.d.ts.map +1 -0
- package/src/providers/opencode/install.js +183 -0
- package/src/providers/opencode/install.js.map +1 -0
- package/src/providers/opencode/install.ts +206 -0
- package/src/providers/opencode/manifest.json +26 -0
- package/src/providers/opencode/spawn.d.ts +72 -0
- package/src/providers/opencode/spawn.d.ts.map +1 -0
- package/src/providers/opencode/spawn.js +219 -0
- package/src/providers/opencode/spawn.js.map +1 -0
- package/src/providers/opencode/spawn.ts +253 -0
- package/src/registry.d.ts +36 -0
- package/src/registry.d.ts.map +1 -0
- package/src/registry.js +55 -0
- package/src/registry.js.map +1 -0
- package/src/registry.ts +81 -0
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for the Claude Code adapter package.
|
|
3
|
+
*
|
|
4
|
+
* @task T5240
|
|
5
|
+
*/
|
|
6
|
+
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
|
|
7
|
+
import { ClaudeCodeAdapter } from '../adapter.js';
|
|
8
|
+
import { ClaudeCodeHookProvider } from '../hooks.js';
|
|
9
|
+
import { ClaudeCodeSpawnProvider } from '../spawn.js';
|
|
10
|
+
import { ClaudeCodeInstallProvider } from '../install.js';
|
|
11
|
+
// Mock child_process for health check and spawn tests
|
|
12
|
+
vi.mock('node:child_process', () => ({
|
|
13
|
+
exec: vi.fn(),
|
|
14
|
+
execFile: vi.fn(),
|
|
15
|
+
spawn: vi.fn(() => ({
|
|
16
|
+
pid: 12345,
|
|
17
|
+
unref: vi.fn(),
|
|
18
|
+
on: vi.fn(),
|
|
19
|
+
})),
|
|
20
|
+
}));
|
|
21
|
+
vi.mock('node:util', async (importOriginal) => {
|
|
22
|
+
const actual = await importOriginal();
|
|
23
|
+
return {
|
|
24
|
+
...actual,
|
|
25
|
+
promisify: (fn) => {
|
|
26
|
+
// Return a mock for exec that simulates 'which claude' succeeding
|
|
27
|
+
return vi.fn().mockResolvedValue({ stdout: '/usr/local/bin/claude', stderr: '' });
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
});
|
|
31
|
+
vi.mock('node:fs', async (importOriginal) => {
|
|
32
|
+
const actual = await importOriginal();
|
|
33
|
+
return {
|
|
34
|
+
...actual,
|
|
35
|
+
existsSync: vi.fn((path) => {
|
|
36
|
+
if (typeof path === 'string' && path.includes('.claude'))
|
|
37
|
+
return true;
|
|
38
|
+
if (typeof path === 'string' && path.includes('.mcp.json'))
|
|
39
|
+
return false;
|
|
40
|
+
if (typeof path === 'string' && path.includes('CLAUDE.md'))
|
|
41
|
+
return false;
|
|
42
|
+
return false;
|
|
43
|
+
}),
|
|
44
|
+
readFileSync: vi.fn(() => '{}'),
|
|
45
|
+
writeFileSync: vi.fn(),
|
|
46
|
+
mkdirSync: vi.fn(),
|
|
47
|
+
};
|
|
48
|
+
});
|
|
49
|
+
vi.mock('node:fs/promises', () => ({
|
|
50
|
+
writeFile: vi.fn().mockResolvedValue(undefined),
|
|
51
|
+
unlink: vi.fn().mockResolvedValue(undefined),
|
|
52
|
+
}));
|
|
53
|
+
describe('ClaudeCodeAdapter', () => {
|
|
54
|
+
let adapter;
|
|
55
|
+
beforeEach(() => {
|
|
56
|
+
adapter = new ClaudeCodeAdapter();
|
|
57
|
+
});
|
|
58
|
+
afterEach(async () => {
|
|
59
|
+
if (adapter.isInitialized()) {
|
|
60
|
+
await adapter.dispose();
|
|
61
|
+
}
|
|
62
|
+
vi.restoreAllMocks();
|
|
63
|
+
});
|
|
64
|
+
describe('identity', () => {
|
|
65
|
+
it('has correct id', () => {
|
|
66
|
+
expect(adapter.id).toBe('claude-code');
|
|
67
|
+
});
|
|
68
|
+
it('has correct name', () => {
|
|
69
|
+
expect(adapter.name).toBe('Claude Code');
|
|
70
|
+
});
|
|
71
|
+
it('has correct version', () => {
|
|
72
|
+
expect(adapter.version).toBe('1.0.0');
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
describe('capabilities', () => {
|
|
76
|
+
it('supports hooks', () => {
|
|
77
|
+
expect(adapter.capabilities.supportsHooks).toBe(true);
|
|
78
|
+
});
|
|
79
|
+
it('supports spawn', () => {
|
|
80
|
+
expect(adapter.capabilities.supportsSpawn).toBe(true);
|
|
81
|
+
});
|
|
82
|
+
it('supports install', () => {
|
|
83
|
+
expect(adapter.capabilities.supportsInstall).toBe(true);
|
|
84
|
+
});
|
|
85
|
+
it('supports MCP', () => {
|
|
86
|
+
expect(adapter.capabilities.supportsMcp).toBe(true);
|
|
87
|
+
});
|
|
88
|
+
it('supports instruction files with CLAUDE.md pattern', () => {
|
|
89
|
+
expect(adapter.capabilities.supportsInstructionFiles).toBe(true);
|
|
90
|
+
expect(adapter.capabilities.instructionFilePattern).toBe('CLAUDE.md');
|
|
91
|
+
});
|
|
92
|
+
it('declares expected hook events', () => {
|
|
93
|
+
expect(adapter.capabilities.supportedHookEvents).toContain('onSessionStart');
|
|
94
|
+
expect(adapter.capabilities.supportedHookEvents).toContain('onSessionEnd');
|
|
95
|
+
expect(adapter.capabilities.supportedHookEvents).toContain('onToolComplete');
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
describe('sub-providers', () => {
|
|
99
|
+
it('provides a hook provider', () => {
|
|
100
|
+
expect(adapter.hooks).toBeInstanceOf(ClaudeCodeHookProvider);
|
|
101
|
+
});
|
|
102
|
+
it('provides a spawn provider', () => {
|
|
103
|
+
expect(adapter.spawn).toBeInstanceOf(ClaudeCodeSpawnProvider);
|
|
104
|
+
});
|
|
105
|
+
it('provides an install provider', () => {
|
|
106
|
+
expect(adapter.install).toBeInstanceOf(ClaudeCodeInstallProvider);
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
describe('initialize', () => {
|
|
110
|
+
it('sets initialized state', async () => {
|
|
111
|
+
expect(adapter.isInitialized()).toBe(false);
|
|
112
|
+
await adapter.initialize('/tmp/test-project');
|
|
113
|
+
expect(adapter.isInitialized()).toBe(true);
|
|
114
|
+
});
|
|
115
|
+
it('stores project directory', async () => {
|
|
116
|
+
await adapter.initialize('/tmp/test-project');
|
|
117
|
+
expect(adapter.getProjectDir()).toBe('/tmp/test-project');
|
|
118
|
+
});
|
|
119
|
+
});
|
|
120
|
+
describe('dispose', () => {
|
|
121
|
+
it('resets initialized state', async () => {
|
|
122
|
+
await adapter.initialize('/tmp/test-project');
|
|
123
|
+
await adapter.dispose();
|
|
124
|
+
expect(adapter.isInitialized()).toBe(false);
|
|
125
|
+
expect(adapter.getProjectDir()).toBeNull();
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
describe('healthCheck', () => {
|
|
129
|
+
it('returns unhealthy when not initialized', async () => {
|
|
130
|
+
const status = await adapter.healthCheck();
|
|
131
|
+
expect(status.healthy).toBe(false);
|
|
132
|
+
expect(status.provider).toBe('claude-code');
|
|
133
|
+
expect(status.details?.error).toBe('Adapter not initialized');
|
|
134
|
+
});
|
|
135
|
+
it('returns health status with provider id', async () => {
|
|
136
|
+
await adapter.initialize('/tmp/test-project');
|
|
137
|
+
const status = await adapter.healthCheck();
|
|
138
|
+
expect(status.provider).toBe('claude-code');
|
|
139
|
+
expect(typeof status.healthy).toBe('boolean');
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
});
|
|
143
|
+
describe('ClaudeCodeHookProvider', () => {
|
|
144
|
+
let hooks;
|
|
145
|
+
beforeEach(() => {
|
|
146
|
+
hooks = new ClaudeCodeHookProvider();
|
|
147
|
+
});
|
|
148
|
+
describe('mapProviderEvent', () => {
|
|
149
|
+
it('maps SessionStart to onSessionStart', () => {
|
|
150
|
+
expect(hooks.mapProviderEvent('SessionStart')).toBe('onSessionStart');
|
|
151
|
+
});
|
|
152
|
+
it('maps PostToolUse to onToolComplete', () => {
|
|
153
|
+
expect(hooks.mapProviderEvent('PostToolUse')).toBe('onToolComplete');
|
|
154
|
+
});
|
|
155
|
+
it('maps UserPromptSubmit to onPromptSubmit', () => {
|
|
156
|
+
expect(hooks.mapProviderEvent('UserPromptSubmit')).toBe('onPromptSubmit');
|
|
157
|
+
});
|
|
158
|
+
it('maps Stop to onSessionEnd', () => {
|
|
159
|
+
expect(hooks.mapProviderEvent('Stop')).toBe('onSessionEnd');
|
|
160
|
+
});
|
|
161
|
+
it('returns null for unknown events', () => {
|
|
162
|
+
expect(hooks.mapProviderEvent('UnknownEvent')).toBeNull();
|
|
163
|
+
expect(hooks.mapProviderEvent('')).toBeNull();
|
|
164
|
+
});
|
|
165
|
+
});
|
|
166
|
+
describe('registerNativeHooks', () => {
|
|
167
|
+
it('marks hooks as registered', async () => {
|
|
168
|
+
expect(hooks.isRegistered()).toBe(false);
|
|
169
|
+
await hooks.registerNativeHooks('/tmp/project');
|
|
170
|
+
expect(hooks.isRegistered()).toBe(true);
|
|
171
|
+
});
|
|
172
|
+
});
|
|
173
|
+
describe('unregisterNativeHooks', () => {
|
|
174
|
+
it('marks hooks as unregistered', async () => {
|
|
175
|
+
await hooks.registerNativeHooks('/tmp/project');
|
|
176
|
+
await hooks.unregisterNativeHooks();
|
|
177
|
+
expect(hooks.isRegistered()).toBe(false);
|
|
178
|
+
});
|
|
179
|
+
});
|
|
180
|
+
describe('getEventMap', () => {
|
|
181
|
+
it('returns all mapped events', () => {
|
|
182
|
+
const map = hooks.getEventMap();
|
|
183
|
+
expect(Object.keys(map)).toHaveLength(4);
|
|
184
|
+
expect(map.SessionStart).toBe('onSessionStart');
|
|
185
|
+
expect(map.PostToolUse).toBe('onToolComplete');
|
|
186
|
+
expect(map.UserPromptSubmit).toBe('onPromptSubmit');
|
|
187
|
+
expect(map.Stop).toBe('onSessionEnd');
|
|
188
|
+
});
|
|
189
|
+
});
|
|
190
|
+
});
|
|
191
|
+
describe('ClaudeCodeSpawnProvider', () => {
|
|
192
|
+
let spawn;
|
|
193
|
+
beforeEach(() => {
|
|
194
|
+
spawn = new ClaudeCodeSpawnProvider();
|
|
195
|
+
});
|
|
196
|
+
describe('canSpawn', () => {
|
|
197
|
+
it('returns a boolean', async () => {
|
|
198
|
+
const result = await spawn.canSpawn();
|
|
199
|
+
expect(typeof result).toBe('boolean');
|
|
200
|
+
});
|
|
201
|
+
});
|
|
202
|
+
describe('listRunning', () => {
|
|
203
|
+
it('returns empty array when no processes spawned', async () => {
|
|
204
|
+
const running = await spawn.listRunning();
|
|
205
|
+
expect(running).toEqual([]);
|
|
206
|
+
});
|
|
207
|
+
});
|
|
208
|
+
describe('terminate', () => {
|
|
209
|
+
it('handles non-existent instance gracefully', async () => {
|
|
210
|
+
await expect(spawn.terminate('non-existent')).resolves.toBeUndefined();
|
|
211
|
+
});
|
|
212
|
+
});
|
|
213
|
+
});
|
|
214
|
+
describe('ClaudeCodeInstallProvider', () => {
|
|
215
|
+
let installProvider;
|
|
216
|
+
beforeEach(() => {
|
|
217
|
+
installProvider = new ClaudeCodeInstallProvider();
|
|
218
|
+
});
|
|
219
|
+
describe('isInstalled', () => {
|
|
220
|
+
it('returns a boolean', async () => {
|
|
221
|
+
const result = await installProvider.isInstalled();
|
|
222
|
+
expect(typeof result).toBe('boolean');
|
|
223
|
+
});
|
|
224
|
+
});
|
|
225
|
+
describe('install', () => {
|
|
226
|
+
it('returns a success result', async () => {
|
|
227
|
+
const result = await installProvider.install({
|
|
228
|
+
projectDir: '/tmp/test-project',
|
|
229
|
+
});
|
|
230
|
+
expect(result.success).toBe(true);
|
|
231
|
+
expect(result.installedAt).toBeTruthy();
|
|
232
|
+
expect(typeof result.instructionFileUpdated).toBe('boolean');
|
|
233
|
+
expect(typeof result.mcpRegistered).toBe('boolean');
|
|
234
|
+
});
|
|
235
|
+
it('registers MCP when mcpServerPath provided', async () => {
|
|
236
|
+
const result = await installProvider.install({
|
|
237
|
+
projectDir: '/tmp/test-project',
|
|
238
|
+
mcpServerPath: '/path/to/mcp-server.js',
|
|
239
|
+
});
|
|
240
|
+
expect(result.mcpRegistered).toBe(true);
|
|
241
|
+
});
|
|
242
|
+
});
|
|
243
|
+
describe('uninstall', () => {
|
|
244
|
+
it('handles uninstall when not installed', async () => {
|
|
245
|
+
await expect(installProvider.uninstall()).resolves.toBeUndefined();
|
|
246
|
+
});
|
|
247
|
+
});
|
|
248
|
+
});
|
|
249
|
+
//# sourceMappingURL=adapter.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.test.js","sourceRoot":"","sources":["adapter.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for the Claude Code adapter package.
|
|
3
|
+
*
|
|
4
|
+
* @task T5240
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
|
|
8
|
+
import { ClaudeCodeAdapter } from '../adapter.js';
|
|
9
|
+
import { ClaudeCodeHookProvider } from '../hooks.js';
|
|
10
|
+
import { ClaudeCodeSpawnProvider } from '../spawn.js';
|
|
11
|
+
import { ClaudeCodeInstallProvider } from '../install.js';
|
|
12
|
+
|
|
13
|
+
// Mock child_process for health check and spawn tests
|
|
14
|
+
vi.mock('node:child_process', () => ({
|
|
15
|
+
exec: vi.fn(),
|
|
16
|
+
execFile: vi.fn(),
|
|
17
|
+
spawn: vi.fn(() => ({
|
|
18
|
+
pid: 12345,
|
|
19
|
+
unref: vi.fn(),
|
|
20
|
+
on: vi.fn(),
|
|
21
|
+
})),
|
|
22
|
+
}));
|
|
23
|
+
|
|
24
|
+
vi.mock('node:util', async (importOriginal) => {
|
|
25
|
+
const actual = await importOriginal<typeof import('node:util')>();
|
|
26
|
+
return {
|
|
27
|
+
...actual,
|
|
28
|
+
promisify: (fn: unknown) => {
|
|
29
|
+
// Return a mock for exec that simulates 'which claude' succeeding
|
|
30
|
+
return vi.fn().mockResolvedValue({ stdout: '/usr/local/bin/claude', stderr: '' });
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
vi.mock('node:fs', async (importOriginal) => {
|
|
36
|
+
const actual = await importOriginal<typeof import('node:fs')>();
|
|
37
|
+
return {
|
|
38
|
+
...actual,
|
|
39
|
+
existsSync: vi.fn((path: string) => {
|
|
40
|
+
if (typeof path === 'string' && path.includes('.claude')) return true;
|
|
41
|
+
if (typeof path === 'string' && path.includes('.mcp.json')) return false;
|
|
42
|
+
if (typeof path === 'string' && path.includes('CLAUDE.md')) return false;
|
|
43
|
+
return false;
|
|
44
|
+
}),
|
|
45
|
+
readFileSync: vi.fn(() => '{}'),
|
|
46
|
+
writeFileSync: vi.fn(),
|
|
47
|
+
mkdirSync: vi.fn(),
|
|
48
|
+
};
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
vi.mock('node:fs/promises', () => ({
|
|
52
|
+
writeFile: vi.fn().mockResolvedValue(undefined),
|
|
53
|
+
unlink: vi.fn().mockResolvedValue(undefined),
|
|
54
|
+
}));
|
|
55
|
+
|
|
56
|
+
describe('ClaudeCodeAdapter', () => {
|
|
57
|
+
let adapter: ClaudeCodeAdapter;
|
|
58
|
+
|
|
59
|
+
beforeEach(() => {
|
|
60
|
+
adapter = new ClaudeCodeAdapter();
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
afterEach(async () => {
|
|
64
|
+
if (adapter.isInitialized()) {
|
|
65
|
+
await adapter.dispose();
|
|
66
|
+
}
|
|
67
|
+
vi.restoreAllMocks();
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
describe('identity', () => {
|
|
71
|
+
it('has correct id', () => {
|
|
72
|
+
expect(adapter.id).toBe('claude-code');
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
it('has correct name', () => {
|
|
76
|
+
expect(adapter.name).toBe('Claude Code');
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
it('has correct version', () => {
|
|
80
|
+
expect(adapter.version).toBe('1.0.0');
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
describe('capabilities', () => {
|
|
85
|
+
it('supports hooks', () => {
|
|
86
|
+
expect(adapter.capabilities.supportsHooks).toBe(true);
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
it('supports spawn', () => {
|
|
90
|
+
expect(adapter.capabilities.supportsSpawn).toBe(true);
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
it('supports install', () => {
|
|
94
|
+
expect(adapter.capabilities.supportsInstall).toBe(true);
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
it('supports MCP', () => {
|
|
98
|
+
expect(adapter.capabilities.supportsMcp).toBe(true);
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
it('supports instruction files with CLAUDE.md pattern', () => {
|
|
102
|
+
expect(adapter.capabilities.supportsInstructionFiles).toBe(true);
|
|
103
|
+
expect(adapter.capabilities.instructionFilePattern).toBe('CLAUDE.md');
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
it('declares expected hook events', () => {
|
|
107
|
+
expect(adapter.capabilities.supportedHookEvents).toContain('onSessionStart');
|
|
108
|
+
expect(adapter.capabilities.supportedHookEvents).toContain('onSessionEnd');
|
|
109
|
+
expect(adapter.capabilities.supportedHookEvents).toContain('onToolComplete');
|
|
110
|
+
});
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
describe('sub-providers', () => {
|
|
114
|
+
it('provides a hook provider', () => {
|
|
115
|
+
expect(adapter.hooks).toBeInstanceOf(ClaudeCodeHookProvider);
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
it('provides a spawn provider', () => {
|
|
119
|
+
expect(adapter.spawn).toBeInstanceOf(ClaudeCodeSpawnProvider);
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
it('provides an install provider', () => {
|
|
123
|
+
expect(adapter.install).toBeInstanceOf(ClaudeCodeInstallProvider);
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
describe('initialize', () => {
|
|
128
|
+
it('sets initialized state', async () => {
|
|
129
|
+
expect(adapter.isInitialized()).toBe(false);
|
|
130
|
+
await adapter.initialize('/tmp/test-project');
|
|
131
|
+
expect(adapter.isInitialized()).toBe(true);
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
it('stores project directory', async () => {
|
|
135
|
+
await adapter.initialize('/tmp/test-project');
|
|
136
|
+
expect(adapter.getProjectDir()).toBe('/tmp/test-project');
|
|
137
|
+
});
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
describe('dispose', () => {
|
|
141
|
+
it('resets initialized state', async () => {
|
|
142
|
+
await adapter.initialize('/tmp/test-project');
|
|
143
|
+
await adapter.dispose();
|
|
144
|
+
expect(adapter.isInitialized()).toBe(false);
|
|
145
|
+
expect(adapter.getProjectDir()).toBeNull();
|
|
146
|
+
});
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
describe('healthCheck', () => {
|
|
150
|
+
it('returns unhealthy when not initialized', async () => {
|
|
151
|
+
const status = await adapter.healthCheck();
|
|
152
|
+
expect(status.healthy).toBe(false);
|
|
153
|
+
expect(status.provider).toBe('claude-code');
|
|
154
|
+
expect(status.details?.error).toBe('Adapter not initialized');
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
it('returns health status with provider id', async () => {
|
|
158
|
+
await adapter.initialize('/tmp/test-project');
|
|
159
|
+
const status = await adapter.healthCheck();
|
|
160
|
+
expect(status.provider).toBe('claude-code');
|
|
161
|
+
expect(typeof status.healthy).toBe('boolean');
|
|
162
|
+
});
|
|
163
|
+
});
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
describe('ClaudeCodeHookProvider', () => {
|
|
167
|
+
let hooks: ClaudeCodeHookProvider;
|
|
168
|
+
|
|
169
|
+
beforeEach(() => {
|
|
170
|
+
hooks = new ClaudeCodeHookProvider();
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
describe('mapProviderEvent', () => {
|
|
174
|
+
it('maps SessionStart to onSessionStart', () => {
|
|
175
|
+
expect(hooks.mapProviderEvent('SessionStart')).toBe('onSessionStart');
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
it('maps PostToolUse to onToolComplete', () => {
|
|
179
|
+
expect(hooks.mapProviderEvent('PostToolUse')).toBe('onToolComplete');
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
it('maps UserPromptSubmit to onPromptSubmit', () => {
|
|
183
|
+
expect(hooks.mapProviderEvent('UserPromptSubmit')).toBe('onPromptSubmit');
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
it('maps Stop to onSessionEnd', () => {
|
|
187
|
+
expect(hooks.mapProviderEvent('Stop')).toBe('onSessionEnd');
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
it('returns null for unknown events', () => {
|
|
191
|
+
expect(hooks.mapProviderEvent('UnknownEvent')).toBeNull();
|
|
192
|
+
expect(hooks.mapProviderEvent('')).toBeNull();
|
|
193
|
+
});
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
describe('registerNativeHooks', () => {
|
|
197
|
+
it('marks hooks as registered', async () => {
|
|
198
|
+
expect(hooks.isRegistered()).toBe(false);
|
|
199
|
+
await hooks.registerNativeHooks('/tmp/project');
|
|
200
|
+
expect(hooks.isRegistered()).toBe(true);
|
|
201
|
+
});
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
describe('unregisterNativeHooks', () => {
|
|
205
|
+
it('marks hooks as unregistered', async () => {
|
|
206
|
+
await hooks.registerNativeHooks('/tmp/project');
|
|
207
|
+
await hooks.unregisterNativeHooks();
|
|
208
|
+
expect(hooks.isRegistered()).toBe(false);
|
|
209
|
+
});
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
describe('getEventMap', () => {
|
|
213
|
+
it('returns all mapped events', () => {
|
|
214
|
+
const map = hooks.getEventMap();
|
|
215
|
+
expect(Object.keys(map)).toHaveLength(4);
|
|
216
|
+
expect(map.SessionStart).toBe('onSessionStart');
|
|
217
|
+
expect(map.PostToolUse).toBe('onToolComplete');
|
|
218
|
+
expect(map.UserPromptSubmit).toBe('onPromptSubmit');
|
|
219
|
+
expect(map.Stop).toBe('onSessionEnd');
|
|
220
|
+
});
|
|
221
|
+
});
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
describe('ClaudeCodeSpawnProvider', () => {
|
|
225
|
+
let spawn: ClaudeCodeSpawnProvider;
|
|
226
|
+
|
|
227
|
+
beforeEach(() => {
|
|
228
|
+
spawn = new ClaudeCodeSpawnProvider();
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
describe('canSpawn', () => {
|
|
232
|
+
it('returns a boolean', async () => {
|
|
233
|
+
const result = await spawn.canSpawn();
|
|
234
|
+
expect(typeof result).toBe('boolean');
|
|
235
|
+
});
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
describe('listRunning', () => {
|
|
239
|
+
it('returns empty array when no processes spawned', async () => {
|
|
240
|
+
const running = await spawn.listRunning();
|
|
241
|
+
expect(running).toEqual([]);
|
|
242
|
+
});
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
describe('terminate', () => {
|
|
246
|
+
it('handles non-existent instance gracefully', async () => {
|
|
247
|
+
await expect(spawn.terminate('non-existent')).resolves.toBeUndefined();
|
|
248
|
+
});
|
|
249
|
+
});
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
describe('ClaudeCodeInstallProvider', () => {
|
|
253
|
+
let installProvider: ClaudeCodeInstallProvider;
|
|
254
|
+
|
|
255
|
+
beforeEach(() => {
|
|
256
|
+
installProvider = new ClaudeCodeInstallProvider();
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
describe('isInstalled', () => {
|
|
260
|
+
it('returns a boolean', async () => {
|
|
261
|
+
const result = await installProvider.isInstalled();
|
|
262
|
+
expect(typeof result).toBe('boolean');
|
|
263
|
+
});
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
describe('install', () => {
|
|
267
|
+
it('returns a success result', async () => {
|
|
268
|
+
const result = await installProvider.install({
|
|
269
|
+
projectDir: '/tmp/test-project',
|
|
270
|
+
});
|
|
271
|
+
expect(result.success).toBe(true);
|
|
272
|
+
expect(result.installedAt).toBeTruthy();
|
|
273
|
+
expect(typeof result.instructionFileUpdated).toBe('boolean');
|
|
274
|
+
expect(typeof result.mcpRegistered).toBe('boolean');
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
it('registers MCP when mcpServerPath provided', async () => {
|
|
278
|
+
const result = await installProvider.install({
|
|
279
|
+
projectDir: '/tmp/test-project',
|
|
280
|
+
mcpServerPath: '/path/to/mcp-server.js',
|
|
281
|
+
});
|
|
282
|
+
expect(result.mcpRegistered).toBe(true);
|
|
283
|
+
});
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
describe('uninstall', () => {
|
|
287
|
+
it('handles uninstall when not installed', async () => {
|
|
288
|
+
await expect(installProvider.uninstall()).resolves.toBeUndefined();
|
|
289
|
+
});
|
|
290
|
+
});
|
|
291
|
+
});
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Claude Code Adapter
|
|
3
|
+
*
|
|
4
|
+
* Main CLEOProviderAdapter implementation for Anthropic's Claude Code CLI.
|
|
5
|
+
* Provides spawn, hooks, and install capabilities for CLEO integration.
|
|
6
|
+
*
|
|
7
|
+
* @task T5240
|
|
8
|
+
*/
|
|
9
|
+
import type { AdapterCapabilities, AdapterHealthStatus, CLEOProviderAdapter } from '@cleocode/contracts';
|
|
10
|
+
import { ClaudeCodeContextMonitorProvider } from './context-monitor.js';
|
|
11
|
+
import { ClaudeCodeHookProvider } from './hooks.js';
|
|
12
|
+
import { ClaudeCodeInstallProvider } from './install.js';
|
|
13
|
+
import { ClaudeCodePathProvider } from './paths.js';
|
|
14
|
+
import { ClaudeCodeSpawnProvider } from './spawn.js';
|
|
15
|
+
import { ClaudeCodeTaskSyncProvider } from './task-sync.js';
|
|
16
|
+
import { ClaudeCodeTransportProvider } from './transport.js';
|
|
17
|
+
/**
|
|
18
|
+
* CLEO provider adapter for Anthropic Claude Code CLI.
|
|
19
|
+
*
|
|
20
|
+
* Bridges CLEO's adapter system with Claude Code's native capabilities:
|
|
21
|
+
* - Hooks: Maps Claude Code events (SessionStart, PostToolUse, etc.) to CAAMP events
|
|
22
|
+
* - Spawn: Launches subagent processes via the `claude` CLI
|
|
23
|
+
* - Install: Registers MCP server, instruction files, and brain observation plugin
|
|
24
|
+
*/
|
|
25
|
+
export declare class ClaudeCodeAdapter implements CLEOProviderAdapter {
|
|
26
|
+
readonly id = "claude-code";
|
|
27
|
+
readonly name = "Claude Code";
|
|
28
|
+
readonly version = "1.0.0";
|
|
29
|
+
capabilities: AdapterCapabilities;
|
|
30
|
+
hooks: ClaudeCodeHookProvider;
|
|
31
|
+
spawn: ClaudeCodeSpawnProvider;
|
|
32
|
+
install: ClaudeCodeInstallProvider;
|
|
33
|
+
paths: ClaudeCodePathProvider;
|
|
34
|
+
contextMonitor: ClaudeCodeContextMonitorProvider;
|
|
35
|
+
transport: ClaudeCodeTransportProvider;
|
|
36
|
+
taskSync: ClaudeCodeTaskSyncProvider;
|
|
37
|
+
private projectDir;
|
|
38
|
+
private initialized;
|
|
39
|
+
constructor();
|
|
40
|
+
/**
|
|
41
|
+
* Initialize the adapter for a given project directory.
|
|
42
|
+
*
|
|
43
|
+
* Validates the environment by checking for the Claude CLI
|
|
44
|
+
* and Claude Code configuration directory.
|
|
45
|
+
*
|
|
46
|
+
* @param projectDir - Root directory of the project
|
|
47
|
+
*/
|
|
48
|
+
initialize(projectDir: string): Promise<void>;
|
|
49
|
+
/**
|
|
50
|
+
* Dispose the adapter and clean up resources.
|
|
51
|
+
*
|
|
52
|
+
* Unregisters hooks and releases any tracked state.
|
|
53
|
+
*/
|
|
54
|
+
dispose(): Promise<void>;
|
|
55
|
+
/**
|
|
56
|
+
* Run a health check to verify Claude Code is accessible.
|
|
57
|
+
*
|
|
58
|
+
* Checks:
|
|
59
|
+
* 1. Adapter has been initialized
|
|
60
|
+
* 2. Claude CLI is available in PATH
|
|
61
|
+
* 3. ~/.claude/ configuration directory exists
|
|
62
|
+
*
|
|
63
|
+
* @returns Health status with details about each check
|
|
64
|
+
*/
|
|
65
|
+
healthCheck(): Promise<AdapterHealthStatus>;
|
|
66
|
+
/**
|
|
67
|
+
* Check whether the adapter has been initialized.
|
|
68
|
+
*/
|
|
69
|
+
isInitialized(): boolean;
|
|
70
|
+
/**
|
|
71
|
+
* Get the project directory this adapter was initialized with.
|
|
72
|
+
*/
|
|
73
|
+
getProjectDir(): string | null;
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAOH,OAAO,KAAK,EACV,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACpB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,gCAAgC,EAAE,MAAM,sBAAsB,CAAC;AACxE,OAAO,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AACpD,OAAO,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAC;AACzD,OAAO,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AACpD,OAAO,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AACrD,OAAO,EAAE,0BAA0B,EAAE,MAAM,gBAAgB,CAAC;AAC5D,OAAO,EAAE,2BAA2B,EAAE,MAAM,gBAAgB,CAAC;AAI7D;;;;;;;GAOG;AACH,qBAAa,iBAAkB,YAAW,mBAAmB;IAC3D,QAAQ,CAAC,EAAE,iBAAiB;IAC5B,QAAQ,CAAC,IAAI,iBAAiB;IAC9B,QAAQ,CAAC,OAAO,WAAW;IAE3B,YAAY,EAAE,mBAAmB,CAmB/B;IAEF,KAAK,EAAE,sBAAsB,CAAC;IAC9B,KAAK,EAAE,uBAAuB,CAAC;IAC/B,OAAO,EAAE,yBAAyB,CAAC;IACnC,KAAK,EAAE,sBAAsB,CAAC;IAC9B,cAAc,EAAE,gCAAgC,CAAC;IACjD,SAAS,EAAE,2BAA2B,CAAC;IACvC,QAAQ,EAAE,0BAA0B,CAAC;IAErC,OAAO,CAAC,UAAU,CAAuB;IACzC,OAAO,CAAC,WAAW,CAAS;;IAY5B;;;;;;;OAOG;IACG,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKnD;;;;OAIG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ9B;;;;;;;;;OASG;IACG,WAAW,IAAI,OAAO,CAAC,mBAAmB,CAAC;IAyCjD;;OAEG;IACH,aAAa,IAAI,OAAO;IAIxB;;OAEG;IACH,aAAa,IAAI,MAAM,GAAG,IAAI;CAG/B"}
|