@ai-ide-bridge/cli 1.0.5 → 1.1.1
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/.turbo/turbo-build.log +1 -1
- package/dist/commands/configure.js +78 -10
- package/dist/commands/daemon.d.ts +1 -0
- package/dist/commands/daemon.js +107 -13
- package/dist/commands/doctor.js +1 -1
- package/dist/commands/init.js +70 -5
- package/dist/commands/login.d.ts +1 -0
- package/dist/commands/login.js +62 -0
- package/dist/commands/logout.d.ts +1 -0
- package/dist/commands/logout.js +12 -0
- package/dist/commands/start.js +4 -4
- package/dist/core/config.d.ts +4 -0
- package/dist/core/config.js +43 -0
- package/dist/core/daemon-session.d.ts +14 -0
- package/dist/core/daemon-session.js +179 -0
- package/dist/core/daemon.d.ts +16 -0
- package/dist/core/daemon.js +168 -0
- package/dist/core/formatter.d.ts +3 -0
- package/dist/core/formatter.js +44 -0
- package/dist/core/index.d.ts +9 -0
- package/dist/core/index.js +9 -0
- package/dist/core/parser.d.ts +164 -0
- package/dist/core/parser.js +37 -0
- package/dist/core/registry.d.ts +16 -0
- package/dist/core/registry.js +53 -0
- package/dist/core/server.d.ts +19 -0
- package/dist/core/server.js +185 -0
- package/dist/core/session.d.ts +11 -0
- package/dist/core/session.js +39 -0
- package/dist/core/types.d.ts +166 -0
- package/dist/core/types.js +44 -0
- package/dist/index.js +22 -5
- package/dist/oauth/device-flow.d.ts +12 -0
- package/dist/oauth/device-flow.js +93 -0
- package/dist/oauth/flow.d.ts +11 -0
- package/dist/oauth/flow.js +75 -0
- package/dist/oauth/index.d.ts +6 -0
- package/dist/oauth/index.js +5 -0
- package/dist/oauth/lifecycle.d.ts +13 -0
- package/dist/oauth/lifecycle.js +56 -0
- package/dist/oauth/providers.d.ts +2 -0
- package/dist/oauth/providers.js +19 -0
- package/dist/oauth/storage-file.d.ts +2 -0
- package/dist/oauth/storage-file.js +68 -0
- package/dist/oauth/storage.d.ts +2 -0
- package/dist/oauth/storage.js +4 -0
- package/dist/oauth/types.d.ts +44 -0
- package/dist/oauth/types.js +1 -0
- package/dist/plugins/copilot/auth.d.ts +7 -0
- package/dist/plugins/copilot/auth.js +30 -0
- package/dist/plugins/copilot/index.d.ts +5 -0
- package/dist/plugins/copilot/index.js +4 -0
- package/dist/plugins/copilot/plugin.d.ts +8 -0
- package/dist/plugins/copilot/plugin.js +29 -0
- package/dist/plugins/copilot/session.d.ts +8 -0
- package/dist/plugins/copilot/session.js +115 -0
- package/dist/plugins/copilot/tools.d.ts +10 -0
- package/dist/plugins/copilot/tools.js +10 -0
- package/dist/plugins/copilot/types.d.ts +15 -0
- package/dist/plugins/copilot/types.js +27 -0
- package/dist/plugins/cursor/index.d.ts +2 -0
- package/dist/plugins/cursor/index.js +2 -0
- package/dist/plugins/cursor/plugin.d.ts +8 -0
- package/dist/plugins/cursor/plugin.js +36 -0
- package/dist/plugins/cursor/session.d.ts +11 -0
- package/dist/plugins/cursor/session.js +69 -0
- package/dist/plugins/cursor/tools.d.ts +11 -0
- package/dist/plugins/cursor/tools.js +13 -0
- package/dist/plugins/windsurf/auth.d.ts +3 -0
- package/dist/plugins/windsurf/auth.js +20 -0
- package/dist/plugins/windsurf/daemon.d.ts +6 -0
- package/dist/plugins/windsurf/daemon.js +16 -0
- package/dist/plugins/windsurf/index.d.ts +5 -0
- package/dist/plugins/windsurf/index.js +4 -0
- package/dist/plugins/windsurf/models.d.ts +2 -0
- package/dist/plugins/windsurf/models.js +42 -0
- package/dist/plugins/windsurf/plugin.d.ts +8 -0
- package/dist/plugins/windsurf/plugin.js +31 -0
- package/dist/plugins/windsurf/session.d.ts +5 -0
- package/dist/plugins/windsurf/session.js +6 -0
- package/dist/plugins/windsurf/tools.d.ts +3 -0
- package/dist/plugins/windsurf/tools.js +10 -0
- package/dist/plugins/windsurf/types.d.ts +22 -0
- package/dist/plugins/windsurf/types.js +1 -0
- package/dist/utils/config.d.ts +1 -1
- package/dist/utils/config.js +1 -1
- package/dist/utils/opencode.d.ts +3 -1
- package/dist/utils/opencode.js +3 -3
- package/dist/utils/platform.d.ts +1 -0
- package/dist/utils/platform.js +3 -0
- package/package.json +3 -5
- package/src/commands/configure.ts +107 -12
- package/src/commands/daemon.ts +112 -13
- package/src/commands/doctor.ts +1 -1
- package/src/commands/init.ts +72 -5
- package/src/commands/login.ts +98 -0
- package/src/commands/logout.ts +15 -0
- package/src/commands/start.ts +4 -4
- package/src/core/config.ts +45 -0
- package/src/core/daemon-session.ts +199 -0
- package/src/core/daemon.ts +206 -0
- package/src/core/formatter.ts +56 -0
- package/src/core/index.ts +9 -0
- package/src/core/parser.ts +47 -0
- package/src/core/registry.ts +62 -0
- package/src/core/server.ts +211 -0
- package/src/core/session.ts +54 -0
- package/src/core/types.ts +100 -0
- package/src/index.ts +22 -4
- package/src/oauth/device-flow.ts +111 -0
- package/src/oauth/flow.ts +94 -0
- package/src/oauth/index.ts +6 -0
- package/src/oauth/lifecycle.ts +77 -0
- package/src/oauth/providers.ts +21 -0
- package/src/oauth/storage-file.ts +77 -0
- package/src/oauth/storage.ts +6 -0
- package/src/oauth/types.ts +50 -0
- package/src/plugins/copilot/auth.ts +39 -0
- package/src/plugins/copilot/index.ts +5 -0
- package/src/plugins/copilot/plugin.ts +31 -0
- package/src/plugins/copilot/session.ts +130 -0
- package/src/plugins/copilot/tools.ts +21 -0
- package/src/plugins/copilot/types.ts +43 -0
- package/src/plugins/cursor/index.ts +2 -0
- package/src/plugins/cursor/plugin.ts +37 -0
- package/src/plugins/cursor/session.ts +78 -0
- package/src/plugins/cursor/tools.ts +25 -0
- package/src/plugins/windsurf/auth.ts +23 -0
- package/src/plugins/windsurf/daemon.ts +24 -0
- package/src/plugins/windsurf/index.ts +5 -0
- package/src/plugins/windsurf/models.ts +44 -0
- package/src/plugins/windsurf/plugin.ts +34 -0
- package/src/plugins/windsurf/session.ts +8 -0
- package/src/plugins/windsurf/tools.ts +13 -0
- package/src/plugins/windsurf/types.ts +24 -0
- package/src/utils/config.ts +1 -1
- package/src/utils/opencode.ts +4 -3
- package/src/utils/platform.ts +3 -0
- package/test/configure.test.ts +19 -4
- package/test/daemon.test.ts +224 -0
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
2
|
+
|
|
3
|
+
vi.mock('node:child_process', () => ({
|
|
4
|
+
execSync: vi.fn(),
|
|
5
|
+
}));
|
|
6
|
+
|
|
7
|
+
vi.mock('node:fs', () => ({
|
|
8
|
+
default: {
|
|
9
|
+
mkdirSync: vi.fn(),
|
|
10
|
+
writeFileSync: vi.fn(),
|
|
11
|
+
existsSync: vi.fn(),
|
|
12
|
+
unlinkSync: vi.fn(),
|
|
13
|
+
},
|
|
14
|
+
}));
|
|
15
|
+
|
|
16
|
+
vi.mock('../src/utils/platform.js', () => ({
|
|
17
|
+
getPlatform: vi.fn(() => process.platform),
|
|
18
|
+
}));
|
|
19
|
+
|
|
20
|
+
const { execSync } = await import('node:child_process');
|
|
21
|
+
const mockedExecSync = vi.mocked(execSync);
|
|
22
|
+
const { getPlatform } = await import('../src/utils/platform.js');
|
|
23
|
+
const mockedGetPlatform = vi.mocked(getPlatform);
|
|
24
|
+
|
|
25
|
+
describe('installDaemonCommand', () => {
|
|
26
|
+
beforeEach(() => {
|
|
27
|
+
vi.clearAllMocks();
|
|
28
|
+
mockedGetPlatform.mockReturnValue(process.platform);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it('generates systemd unit file on Linux', async () => {
|
|
32
|
+
mockedGetPlatform.mockReturnValue('linux');
|
|
33
|
+
|
|
34
|
+
const { installDaemonCommand } = await import('../src/commands/daemon.js');
|
|
35
|
+
|
|
36
|
+
await installDaemonCommand();
|
|
37
|
+
|
|
38
|
+
const fs = await import('node:fs');
|
|
39
|
+
const mockedFs = vi.mocked(fs.default);
|
|
40
|
+
|
|
41
|
+
expect(mockedFs.mkdirSync).toHaveBeenCalled();
|
|
42
|
+
const writeCall = mockedFs.writeFileSync.mock.calls[0];
|
|
43
|
+
const unitPath = writeCall[0] as string;
|
|
44
|
+
expect(unitPath).toContain('.config/systemd/user/llm-bridge.service');
|
|
45
|
+
|
|
46
|
+
const unitContent = writeCall[1] as string;
|
|
47
|
+
expect(unitContent).toContain('[Unit]');
|
|
48
|
+
expect(unitContent).toContain('Description=llm-bridge daemon');
|
|
49
|
+
expect(unitContent).toContain('After=network.target');
|
|
50
|
+
expect(unitContent).toContain('[Service]');
|
|
51
|
+
expect(unitContent).toContain('Type=simple');
|
|
52
|
+
expect(unitContent).toContain('Restart=on-failure');
|
|
53
|
+
expect(unitContent).toContain('RestartSec=5');
|
|
54
|
+
expect(unitContent).toContain('[Install]');
|
|
55
|
+
expect(unitContent).toContain('WantedBy=default.target');
|
|
56
|
+
|
|
57
|
+
expect(mockedExecSync).toHaveBeenCalledWith('systemctl --user daemon-reload', {
|
|
58
|
+
stdio: 'inherit',
|
|
59
|
+
});
|
|
60
|
+
expect(mockedExecSync).toHaveBeenCalledWith('systemctl --user enable --now llm-bridge', {
|
|
61
|
+
stdio: 'inherit',
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
it('routes to installMacOSDaemon on darwin', async () => {
|
|
66
|
+
mockedGetPlatform.mockReturnValue('darwin');
|
|
67
|
+
|
|
68
|
+
const { installDaemonCommand } = await import('../src/commands/daemon.js');
|
|
69
|
+
const fs = await import('node:fs');
|
|
70
|
+
const mockedFs = vi.mocked(fs.default);
|
|
71
|
+
|
|
72
|
+
await installDaemonCommand();
|
|
73
|
+
|
|
74
|
+
expect(mockedFs.writeFileSync).toHaveBeenCalled();
|
|
75
|
+
const writeCall = mockedFs.writeFileSync.mock.calls[0];
|
|
76
|
+
const plistPath = writeCall[0] as string;
|
|
77
|
+
expect(plistPath).toContain('Library/LaunchAgents/com.llm-bridge.daemon.plist');
|
|
78
|
+
|
|
79
|
+
expect(mockedExecSync).toHaveBeenCalledWith(expect.stringContaining('launchctl bootstrap'), {
|
|
80
|
+
stdio: 'inherit',
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
it('exits with error on unsupported platforms', async () => {
|
|
85
|
+
mockedGetPlatform.mockReturnValue('win32');
|
|
86
|
+
|
|
87
|
+
const exitSpy = vi.spyOn(process, 'exit').mockImplementation(() => undefined as never);
|
|
88
|
+
const errorSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
|
|
89
|
+
|
|
90
|
+
const { installDaemonCommand } = await import('../src/commands/daemon.js');
|
|
91
|
+
|
|
92
|
+
await installDaemonCommand();
|
|
93
|
+
|
|
94
|
+
expect(errorSpy).toHaveBeenCalledWith(
|
|
95
|
+
'Daemon installation is only supported on macOS and Linux.',
|
|
96
|
+
);
|
|
97
|
+
expect(exitSpy).toHaveBeenCalledWith(1);
|
|
98
|
+
|
|
99
|
+
exitSpy.mockRestore();
|
|
100
|
+
errorSpy.mockRestore();
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
describe('uninstallDaemonCommand', () => {
|
|
105
|
+
beforeEach(() => {
|
|
106
|
+
vi.clearAllMocks();
|
|
107
|
+
mockedGetPlatform.mockReturnValue(process.platform);
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
it('removes systemd unit file on Linux', async () => {
|
|
111
|
+
mockedGetPlatform.mockReturnValue('linux');
|
|
112
|
+
|
|
113
|
+
const { uninstallDaemonCommand } = await import('../src/commands/daemon.js');
|
|
114
|
+
const fs = await import('node:fs');
|
|
115
|
+
const mockedFs = vi.mocked(fs.default);
|
|
116
|
+
|
|
117
|
+
mockedFs.existsSync.mockReturnValue(true);
|
|
118
|
+
|
|
119
|
+
await uninstallDaemonCommand();
|
|
120
|
+
|
|
121
|
+
expect(mockedExecSync).toHaveBeenCalledWith(
|
|
122
|
+
'systemctl --user disable --now llm-bridge 2>/dev/null || true',
|
|
123
|
+
{ stdio: 'inherit' },
|
|
124
|
+
);
|
|
125
|
+
|
|
126
|
+
const unlinkCall = mockedFs.unlinkSync.mock.calls[0];
|
|
127
|
+
expect(unlinkCall[0]).toContain('.config/systemd/user/llm-bridge.service');
|
|
128
|
+
|
|
129
|
+
expect(mockedExecSync).toHaveBeenCalledWith('systemctl --user daemon-reload', {
|
|
130
|
+
stdio: 'inherit',
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
it('routes to uninstallMacOSDaemon on darwin', async () => {
|
|
135
|
+
mockedGetPlatform.mockReturnValue('darwin');
|
|
136
|
+
|
|
137
|
+
const { uninstallDaemonCommand } = await import('../src/commands/daemon.js');
|
|
138
|
+
const fs = await import('node:fs');
|
|
139
|
+
const mockedFs = vi.mocked(fs.default);
|
|
140
|
+
|
|
141
|
+
mockedFs.existsSync.mockReturnValue(true);
|
|
142
|
+
|
|
143
|
+
await uninstallDaemonCommand();
|
|
144
|
+
|
|
145
|
+
const unlinkCall = mockedFs.unlinkSync.mock.calls[0];
|
|
146
|
+
expect(unlinkCall[0]).toContain('Library/LaunchAgents/com.llm-bridge.daemon.plist');
|
|
147
|
+
|
|
148
|
+
expect(mockedExecSync).toHaveBeenCalledWith(expect.stringContaining('launchctl bootout'), {
|
|
149
|
+
stdio: 'inherit',
|
|
150
|
+
});
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
it('errors on unsupported platforms', async () => {
|
|
154
|
+
mockedGetPlatform.mockReturnValue('win32');
|
|
155
|
+
|
|
156
|
+
const { uninstallDaemonCommand } = await import('../src/commands/daemon.js');
|
|
157
|
+
|
|
158
|
+
const exitSpy = vi.spyOn(process, 'exit').mockImplementation(() => undefined as never);
|
|
159
|
+
const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
|
|
160
|
+
|
|
161
|
+
await uninstallDaemonCommand();
|
|
162
|
+
|
|
163
|
+
expect(exitSpy).toHaveBeenCalledWith(1);
|
|
164
|
+
expect(consoleSpy).toHaveBeenCalledWith(
|
|
165
|
+
'Daemon uninstallation is only supported on macOS and Linux.',
|
|
166
|
+
);
|
|
167
|
+
|
|
168
|
+
exitSpy.mockRestore();
|
|
169
|
+
consoleSpy.mockRestore();
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
it('handles missing service file gracefully on Linux', async () => {
|
|
173
|
+
mockedGetPlatform.mockReturnValue('linux');
|
|
174
|
+
|
|
175
|
+
const { uninstallDaemonCommand } = await import('../src/commands/daemon.js');
|
|
176
|
+
const fs = await import('node:fs');
|
|
177
|
+
const mockedFs = vi.mocked(fs.default);
|
|
178
|
+
|
|
179
|
+
mockedFs.existsSync.mockReturnValue(false);
|
|
180
|
+
|
|
181
|
+
await uninstallDaemonCommand();
|
|
182
|
+
|
|
183
|
+
expect(mockedFs.unlinkSync).not.toHaveBeenCalled();
|
|
184
|
+
expect(mockedExecSync).toHaveBeenCalledWith('systemctl --user daemon-reload', {
|
|
185
|
+
stdio: 'inherit',
|
|
186
|
+
});
|
|
187
|
+
});
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
describe('daemonReloadCommand', () => {
|
|
191
|
+
beforeEach(() => {
|
|
192
|
+
vi.clearAllMocks();
|
|
193
|
+
mockedGetPlatform.mockReturnValue(process.platform);
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
it('runs systemctl daemon-reload on Linux', async () => {
|
|
197
|
+
mockedGetPlatform.mockReturnValue('linux');
|
|
198
|
+
|
|
199
|
+
const { daemonReloadCommand } = await import('../src/commands/daemon.js');
|
|
200
|
+
|
|
201
|
+
await daemonReloadCommand();
|
|
202
|
+
|
|
203
|
+
expect(mockedExecSync).toHaveBeenCalledWith('systemctl --user reload-or-restart llm-bridge', {
|
|
204
|
+
stdio: 'inherit',
|
|
205
|
+
});
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
it('errors on unsupported platforms', async () => {
|
|
209
|
+
mockedGetPlatform.mockReturnValue('win32');
|
|
210
|
+
|
|
211
|
+
const { daemonReloadCommand } = await import('../src/commands/daemon.js');
|
|
212
|
+
|
|
213
|
+
const exitSpy = vi.spyOn(process, 'exit').mockImplementation(() => undefined as never);
|
|
214
|
+
const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
|
|
215
|
+
|
|
216
|
+
await daemonReloadCommand();
|
|
217
|
+
|
|
218
|
+
expect(exitSpy).toHaveBeenCalledWith(1);
|
|
219
|
+
expect(consoleSpy).toHaveBeenCalledWith('Daemon reload is only supported on Linux.');
|
|
220
|
+
|
|
221
|
+
exitSpy.mockRestore();
|
|
222
|
+
consoleSpy.mockRestore();
|
|
223
|
+
});
|
|
224
|
+
});
|