@mycadet/cli 0.12.7 → 0.12.9-dev.202610131452.9acab64
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/README.md +2 -2
- package/knip.json +1 -1
- package/node_modules/@mycadet/assistant-api/events/cloud-disconnected.ts +21 -0
- package/node_modules/@mycadet/assistant-api/events/host-bash.ts +1 -1
- package/node_modules/@mycadet/assistant-api/events/host-cu.ts +1 -1
- package/node_modules/@mycadet/assistant-api/events/host-file.ts +1 -1
- package/node_modules/@mycadet/assistant-api/events/notification-intent.ts +1 -1
- package/node_modules/@mycadet/assistant-api/events/show-cloud-login.ts +18 -0
- package/node_modules/@mycadet/assistant-api/index.ts +11 -11
- package/node_modules/@mycadet/assistant-api/node_modules/@mycadet/service-contracts/package.json +2 -2
- package/node_modules/@mycadet/{service-contracts/src/platform-credential.ts → assistant-api/node_modules/@mycadet/service-contracts/src/cloud-credential.ts} +9 -9
- package/node_modules/@mycadet/assistant-api/node_modules/@mycadet/service-contracts/src/handles.ts +3 -3
- package/node_modules/@mycadet/assistant-api/node_modules/@mycadet/service-contracts/src/index.ts +1 -1
- package/node_modules/@mycadet/assistant-api/node_modules/@mycadet/service-contracts/src/ingress.ts +11 -5
- package/node_modules/@mycadet/assistant-api/node_modules/@mycadet/service-contracts/src/remote-web-pairing.ts +1 -1
- package/node_modules/@mycadet/assistant-api/node_modules/@mycadet/service-contracts/src/rpc.ts +14 -14
- package/node_modules/@mycadet/assistant-api/node_modules/@mycadet/service-contracts/src/trust-rules.ts +5 -5
- package/node_modules/@mycadet/assistant-api/responses/home.ts +1 -1
- package/node_modules/@mycadet/assistant-api/surfaces.ts +4 -4
- package/node_modules/@mycadet/avatar-manifest/src/__tests__/notification-avatar.test.ts +1 -1
- package/node_modules/@mycadet/avatar-manifest/src/notification-avatar.ts +2 -2
- package/node_modules/@mycadet/environments/src/seeds.ts +6 -6
- package/node_modules/@mycadet/environments/src/shell.test.ts +1 -1
- package/node_modules/@mycadet/environments/src/types.ts +6 -6
- package/node_modules/@mycadet/local-mode/node_modules/@mycadet/avatar-manifest/src/__tests__/notification-avatar.test.ts +1 -1
- package/node_modules/@mycadet/local-mode/node_modules/@mycadet/avatar-manifest/src/notification-avatar.ts +2 -2
- package/node_modules/@mycadet/local-mode/node_modules/@mycadet/environments/src/seeds.ts +6 -6
- package/node_modules/@mycadet/local-mode/node_modules/@mycadet/environments/src/shell.test.ts +1 -1
- package/node_modules/@mycadet/local-mode/node_modules/@mycadet/environments/src/types.ts +6 -6
- package/node_modules/@mycadet/local-mode/node_modules/@mycadet/service-contracts/package.json +2 -2
- package/node_modules/@mycadet/{assistant-api/node_modules/@mycadet/service-contracts/src/platform-credential.ts → local-mode/node_modules/@mycadet/service-contracts/src/cloud-credential.ts} +9 -9
- package/node_modules/@mycadet/local-mode/node_modules/@mycadet/service-contracts/src/handles.ts +3 -3
- package/node_modules/@mycadet/local-mode/node_modules/@mycadet/service-contracts/src/index.ts +1 -1
- package/node_modules/@mycadet/local-mode/node_modules/@mycadet/service-contracts/src/ingress.ts +11 -5
- package/node_modules/@mycadet/local-mode/node_modules/@mycadet/service-contracts/src/remote-web-pairing.ts +1 -1
- package/node_modules/@mycadet/local-mode/node_modules/@mycadet/service-contracts/src/rpc.ts +14 -14
- package/node_modules/@mycadet/local-mode/node_modules/@mycadet/service-contracts/src/trust-rules.ts +5 -5
- package/node_modules/@mycadet/local-mode/src/__tests__/pair.test.ts +5 -5
- package/node_modules/@mycadet/local-mode/src/__tests__/retire.test.ts +1 -1
- package/node_modules/@mycadet/local-mode/src/config.ts +2 -2
- package/node_modules/@mycadet/local-mode/src/index.ts +1 -1
- package/node_modules/@mycadet/local-mode/src/lockfile-contract.test.ts +3 -3
- package/node_modules/@mycadet/local-mode/src/lockfile-contract.ts +10 -5
- package/node_modules/@mycadet/local-mode/src/lockfile.test.ts +15 -15
- package/node_modules/@mycadet/local-mode/src/lockfile.ts +9 -9
- package/node_modules/@mycadet/local-mode/src/pair.ts +2 -2
- package/node_modules/@mycadet/local-mode/src/retire.ts +3 -3
- package/node_modules/@mycadet/local-mode/src/teleport-backup-policy.ts +2 -2
- package/node_modules/@mycadet/local-mode/src/unpair.ts +2 -2
- package/node_modules/@mycadet/service-contracts/package.json +2 -2
- package/node_modules/@mycadet/{local-mode/node_modules/@mycadet/service-contracts/src/platform-credential.ts → service-contracts/src/cloud-credential.ts} +9 -9
- package/node_modules/@mycadet/service-contracts/src/handles.ts +3 -3
- package/node_modules/@mycadet/service-contracts/src/index.ts +1 -1
- package/node_modules/@mycadet/service-contracts/src/ingress.ts +11 -5
- package/node_modules/@mycadet/service-contracts/src/remote-web-pairing.ts +1 -1
- package/node_modules/@mycadet/service-contracts/src/rpc.ts +14 -14
- package/node_modules/@mycadet/service-contracts/src/trust-rules.ts +5 -5
- package/package.json +6 -4
- package/src/__tests__/assistant-api-key-resolution.test.ts +6 -6
- package/src/__tests__/{assistant-client-platform-auth.test.ts → assistant-client-cloud-auth.test.ts} +10 -10
- package/src/__tests__/assistant-client-refresh.test.ts +2 -2
- package/src/__tests__/backup.test.ts +86 -91
- package/src/__tests__/client-token.test.ts +1 -1
- package/src/__tests__/client-tui-refresh.test.ts +1 -1
- package/src/__tests__/client-web-config.test.ts +1 -2
- package/src/__tests__/{platform-client.test.ts → cloud-client.test.ts} +59 -59
- package/src/__tests__/{platform-releases.test.ts → cloud-releases.test.ts} +28 -18
- package/src/__tests__/{cloudflare-tunnel.test.ts → cloudflare.test.ts} +1 -1
- package/src/__tests__/connect-import.test.ts +55 -39
- package/src/__tests__/debug.test.ts +38 -38
- package/src/__tests__/ensure-binary.test.ts +182 -0
- package/src/__tests__/guardian-token.test.ts +149 -56
- package/src/__tests__/hatch-provider-secrets.test.ts +2 -2
- package/src/__tests__/helpers/guardian-token.ts +22 -0
- package/src/__tests__/helpers/http.ts +10 -0
- package/src/__tests__/nginx-ingress.test.ts +15 -20
- package/src/__tests__/ngrok-spawn.test.ts +49 -0
- package/src/__tests__/orphan-detection.test.ts +1 -1
- package/src/__tests__/pair.test.ts +149 -85
- package/src/__tests__/{ps-platform-status.test.ts → ps-cloud-status.test.ts} +80 -26
- package/src/__tests__/ps-table.test.ts +79 -0
- package/src/__tests__/{recover.test.ts → restore.test.ts} +29 -28
- package/src/__tests__/retire.test.ts +58 -199
- package/src/__tests__/root-process-lockfile.test.ts +99 -0
- package/src/__tests__/sleep.test.ts +19 -19
- package/src/__tests__/statefulset.test.ts +8 -8
- package/src/__tests__/{tailscale-tunnel.test.ts → tailscale.test.ts} +2 -2
- package/src/__tests__/teleport-backup.test.ts +3 -3
- package/src/__tests__/teleport.test.ts +180 -211
- package/src/__tests__/tunnel.test.ts +490 -270
- package/src/__tests__/uninstall.test.ts +150 -9
- package/src/__tests__/upgrade-local.test.ts +3 -3
- package/src/__tests__/upgrade-replay-env.test.ts +12 -12
- package/src/__tests__/wake.test.ts +260 -43
- package/src/__tests__/workos-pkce.test.ts +2 -2
- package/src/commands/backup.ts +24 -24
- package/src/commands/client.ts +76 -78
- package/src/commands/completions.test.ts +104 -0
- package/src/commands/completions.ts +87 -0
- package/src/commands/debug.ts +20 -20
- package/src/commands/exec.ts +12 -12
- package/src/commands/flags.ts +2 -2
- package/src/commands/hatch.ts +27 -24
- package/src/commands/login.ts +22 -22
- package/src/commands/logs.ts +8 -8
- package/src/commands/pair.ts +140 -37
- package/src/commands/ps.ts +232 -86
- package/src/commands/restart.ts +30 -0
- package/src/commands/restore.ts +140 -22
- package/src/commands/retire.ts +48 -150
- package/src/commands/rollback.ts +20 -26
- package/src/commands/setup.ts +2 -2
- package/src/commands/sleep.ts +2 -2
- package/src/commands/teleport.ts +110 -129
- package/src/commands/terminal.ts +158 -18
- package/src/commands/tunnel.ts +156 -175
- package/src/commands/uninstall.ts +137 -54
- package/src/commands/unpair.ts +3 -3
- package/src/commands/upgrade.ts +30 -54
- package/src/commands/use.ts +1 -1
- package/src/commands/wake.ts +166 -50
- package/src/index.ts +18 -9
- package/src/lib/__tests__/{platform-client-signed-url.test.ts → cloud-client-signed-url.test.ts} +16 -16
- package/src/lib/__tests__/docker.test.ts +168 -20
- package/src/lib/__tests__/job-polling.test.ts +2 -2
- package/src/lib/__tests__/local-gateway-cli.test.ts +42 -0
- package/src/lib/__tests__/local-runtime-client.test.ts +4 -4
- package/src/lib/__tests__/runtime-url.test.ts +1 -1
- package/src/lib/assistant-api-key-resolution.ts +5 -5
- package/src/lib/assistant-client.ts +8 -8
- package/src/lib/assistant-config.ts +58 -12
- package/src/lib/{platform-client.ts → cloud-client.ts} +105 -99
- package/src/lib/cloud-login.ts +23 -24
- package/src/lib/{platform-releases.ts → cloud-releases.ts} +11 -9
- package/src/lib/cloud-values.ts +3 -0
- package/src/lib/color.ts +4 -0
- package/src/lib/config-utils.ts +1 -1
- package/src/lib/detached-process.ts +1 -1
- package/src/lib/docker.ts +300 -111
- package/src/lib/ensure-binary.ts +171 -0
- package/src/lib/environments/__tests__/paths.test.ts +29 -3
- package/src/lib/environments/__tests__/resolve.test.ts +26 -26
- package/src/lib/environments/paths.ts +16 -8
- package/src/lib/environments/resolve.ts +10 -12
- package/src/lib/flag-args.test.ts +1 -1
- package/src/lib/flag-args.ts +1 -1
- package/src/lib/guardian-token.ts +37 -5
- package/src/lib/hatch-local.ts +32 -29
- package/src/lib/hatch-next-steps.ts +5 -9
- package/src/lib/health-check.ts +6 -6
- package/src/lib/ingress-config.ts +8 -35
- package/src/lib/job-polling.ts +2 -2
- package/src/lib/live-voice/connection.ts +12 -12
- package/src/lib/live-voice/tunnel.test.ts +11 -11
- package/src/lib/live-voice/tunnel.ts +15 -15
- package/src/lib/local-runtime-client.ts +20 -20
- package/src/lib/local.ts +46 -34
- package/src/lib/nginx-ingress.ts +40 -15
- package/src/lib/pair.ts +1 -1
- package/src/lib/process.ts +1 -1
- package/src/lib/provider-secrets.ts +3 -3
- package/src/lib/retire-apple-container.ts +1 -1
- package/src/lib/runtime-url.ts +8 -8
- package/src/lib/statefulset.ts +2 -2
- package/src/lib/step-runner.ts +6 -1
- package/src/lib/sync-cloud-assistants.ts +19 -19
- package/src/lib/teleport-backup.ts +4 -4
- package/src/lib/terminal-client.ts +17 -17
- package/src/lib/terminal-session.ts +24 -24
- package/src/lib/{tunnel-edge.ts → tunnel.ts} +199 -11
- package/src/lib/tunnels/cadet.ts +29 -0
- package/src/lib/{cloudflare-tunnel.ts → tunnels/cloudflare.ts} +36 -15
- package/src/lib/tunnels/gateway-notify.ts +61 -0
- package/src/lib/{ngrok.ts → tunnels/ngrok.ts} +350 -89
- package/src/lib/{tailscale-tunnel.ts → tunnels/tailscale.ts} +53 -9
- package/src/lib/upgrade-lifecycle.ts +8 -21
- package/src/lib/upgrade-preflight.ts +2 -2
- package/src/lib/workos-pkce.ts +5 -5
- package/node_modules/@mycadet/assistant-api/events/platform-disconnected.ts +0 -21
- package/node_modules/@mycadet/assistant-api/events/show-platform-login.ts +0 -20
- package/src/commands/recover.ts +0 -131
- package/src/commands/roadmap.ts +0 -459
- package/src/commands/ssh.ts +0 -144
- package/src/commands/workflows.ts +0 -305
- package/src/lib/managed-cloud.ts +0 -3
|
@@ -1,4 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
afterAll,
|
|
3
|
+
afterEach,
|
|
4
|
+
describe,
|
|
5
|
+
expect,
|
|
6
|
+
mock,
|
|
7
|
+
spyOn,
|
|
8
|
+
test,
|
|
9
|
+
} from "bun:test";
|
|
2
10
|
import { existsSync, mkdirSync, mkdtempSync, rmSync, writeFileSync } from "fs";
|
|
3
11
|
import { tmpdir } from "os";
|
|
4
12
|
import { dirname, join } from "path";
|
|
@@ -8,6 +16,7 @@ import {
|
|
|
8
16
|
getConfigDirs,
|
|
9
17
|
getInputHistoryPath,
|
|
10
18
|
getLogDir,
|
|
19
|
+
getSharedStateDir,
|
|
11
20
|
getStateDir,
|
|
12
21
|
} from "../lib/environments/paths.js";
|
|
13
22
|
import { getCurrentEnvironment } from "../lib/environments/resolve.js";
|
|
@@ -16,6 +25,20 @@ import type { AssistantEntry } from "../lib/assistant-config.js";
|
|
|
16
25
|
// The command reads its argv at call time.
|
|
17
26
|
const ORIGINAL_ARGV = process.argv;
|
|
18
27
|
|
|
28
|
+
// retireDocker is the one retirement path with observable side effects
|
|
29
|
+
// (docker teardown), and uninstall is the only importer in its graph.
|
|
30
|
+
// Mocked module-wide so tests pin WHEN it runs — never before the
|
|
31
|
+
// confirmation gate — as much as whether it runs.
|
|
32
|
+
const retireDockerCalls: string[] = [];
|
|
33
|
+
let onRetireDocker: ((name: string) => void) | undefined;
|
|
34
|
+
|
|
35
|
+
mock.module("../lib/docker.js", () => ({
|
|
36
|
+
retireDocker: (name: string) => {
|
|
37
|
+
retireDockerCalls.push(name);
|
|
38
|
+
onRetireDocker?.(name);
|
|
39
|
+
},
|
|
40
|
+
}));
|
|
41
|
+
|
|
19
42
|
// Every XDG location the command touches MUST be redirected: the homedir
|
|
20
43
|
// fallback would otherwise point at the real user's data dirs.
|
|
21
44
|
function redirectXdg(): string {
|
|
@@ -70,7 +93,15 @@ describe("cadet uninstall", () => {
|
|
|
70
93
|
const errorSpy = spyOn(console, "error").mockImplementation(() => {});
|
|
71
94
|
const warnSpy = spyOn(console, "warn").mockImplementation(() => {});
|
|
72
95
|
|
|
96
|
+
function printedOutput(): string {
|
|
97
|
+
return logSpy.mock.calls
|
|
98
|
+
.map((args) => args.map(String).join(" "))
|
|
99
|
+
.join("\n");
|
|
100
|
+
}
|
|
101
|
+
|
|
73
102
|
afterEach(() => {
|
|
103
|
+
retireDockerCalls.length = 0;
|
|
104
|
+
onRetireDocker = undefined;
|
|
74
105
|
logSpy.mockClear();
|
|
75
106
|
errorSpy.mockClear();
|
|
76
107
|
warnSpy.mockClear();
|
|
@@ -82,11 +113,13 @@ describe("cadet uninstall", () => {
|
|
|
82
113
|
warnSpy.mockRestore();
|
|
83
114
|
});
|
|
84
115
|
|
|
85
|
-
test("
|
|
116
|
+
test("warns that remaining assistants will be retired, then proceeds to the confirm gate", async () => {
|
|
86
117
|
await withRestoredEnv(async () => {
|
|
87
118
|
const root = redirectXdg();
|
|
88
|
-
// A remaining assistant
|
|
89
|
-
//
|
|
119
|
+
// A remaining assistant is retired — with its data deleted — as part
|
|
120
|
+
// of the uninstall AFTER the user confirms; the pre-confirm summary
|
|
121
|
+
// says so up front (v0.0.10 run feedback: the hard refusal just
|
|
122
|
+
// blocked the uninstall; the fs sweep deletes the archives anyway).
|
|
90
123
|
writeFileSync(
|
|
91
124
|
join(process.env.CADET_LOCKFILE_DIR!, "lockfile.json"),
|
|
92
125
|
JSON.stringify({ assistants: [makeEntry("test-assistant")] }) + "\n",
|
|
@@ -97,8 +130,16 @@ describe("cadet uninstall", () => {
|
|
|
97
130
|
throw new Error(`process.exit:${code}`);
|
|
98
131
|
});
|
|
99
132
|
try {
|
|
133
|
+
// Non-interactive without --yes, the CONFIRM gate is what refuses —
|
|
134
|
+
// not an assistant guard.
|
|
100
135
|
await expect(uninstall()).rejects.toThrow("process.exit:1");
|
|
101
|
-
expect(
|
|
136
|
+
expect(warnSpy).toHaveBeenCalledWith(
|
|
137
|
+
expect.stringContaining("1 assistant still exists"),
|
|
138
|
+
);
|
|
139
|
+
expect(warnSpy).toHaveBeenCalledWith(
|
|
140
|
+
expect.stringContaining("will be retired as part of this uninstall"),
|
|
141
|
+
);
|
|
142
|
+
expect(errorSpy).not.toHaveBeenCalledWith(
|
|
102
143
|
expect.stringContaining("Retire them first"),
|
|
103
144
|
);
|
|
104
145
|
} finally {
|
|
@@ -129,6 +170,67 @@ describe("cadet uninstall", () => {
|
|
|
129
170
|
});
|
|
130
171
|
});
|
|
131
172
|
|
|
173
|
+
test("does not retire assistants when the confirm gate refuses", async () => {
|
|
174
|
+
await withRestoredEnv(async () => {
|
|
175
|
+
const root = redirectXdg();
|
|
176
|
+
writeFileSync(
|
|
177
|
+
join(process.env.CADET_LOCKFILE_DIR!, "lockfile.json"),
|
|
178
|
+
JSON.stringify({
|
|
179
|
+
assistants: [{ ...makeEntry("docker-assistant"), cloud: "docker" }],
|
|
180
|
+
}) + "\n",
|
|
181
|
+
);
|
|
182
|
+
|
|
183
|
+
const exitMock = spyOn(process, "exit");
|
|
184
|
+
exitMock.mockImplementation((code?: number | string | undefined): never => {
|
|
185
|
+
throw new Error(`process.exit:${code}`);
|
|
186
|
+
});
|
|
187
|
+
try {
|
|
188
|
+
process.argv = ["bun", "cadet", "uninstall"];
|
|
189
|
+
await expect(uninstall()).rejects.toThrow("process.exit:1");
|
|
190
|
+
} finally {
|
|
191
|
+
exitMock.mockRestore();
|
|
192
|
+
}
|
|
193
|
+
// Retirement is part of the confirmed flow — a refusal must leave the
|
|
194
|
+
// assistant's docker resources untouched.
|
|
195
|
+
expect(retireDockerCalls).toEqual([]);
|
|
196
|
+
|
|
197
|
+
rmSync(root, { recursive: true, force: true });
|
|
198
|
+
});
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
test("--yes retires remaining assistants after the deletion list is shown", async () => {
|
|
202
|
+
await withRestoredEnv(async () => {
|
|
203
|
+
const root = redirectXdg();
|
|
204
|
+
writeFileSync(
|
|
205
|
+
join(process.env.CADET_LOCKFILE_DIR!, "lockfile.json"),
|
|
206
|
+
JSON.stringify({
|
|
207
|
+
assistants: [{ ...makeEntry("docker-assistant"), cloud: "docker" }],
|
|
208
|
+
}) + "\n",
|
|
209
|
+
);
|
|
210
|
+
mkdirSync(getConfigDirs(getCurrentEnvironment())[0]!, {
|
|
211
|
+
recursive: true,
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
// Capture what had been printed by the time retirement ran — the list
|
|
215
|
+
// the user confirms against must already be on screen.
|
|
216
|
+
let outputAtRetire = "";
|
|
217
|
+
onRetireDocker = () => {
|
|
218
|
+
outputAtRetire = printedOutput();
|
|
219
|
+
};
|
|
220
|
+
|
|
221
|
+
process.argv = ["bun", "cadet", "uninstall", "--yes"];
|
|
222
|
+
await uninstall();
|
|
223
|
+
|
|
224
|
+
expect(retireDockerCalls).toEqual(["docker-assistant"]);
|
|
225
|
+
expect(outputAtRetire).toContain("It will permanently delete:");
|
|
226
|
+
expect(warnSpy).toHaveBeenCalledWith(
|
|
227
|
+
expect.stringContaining("will be retired as part of this uninstall"),
|
|
228
|
+
);
|
|
229
|
+
|
|
230
|
+
rmSync(root, { recursive: true, force: true });
|
|
231
|
+
});
|
|
232
|
+
});
|
|
233
|
+
|
|
132
234
|
test("--yes deletes the environment's XDG locations and leaves the source checkout alone", async () => {
|
|
133
235
|
await withRestoredEnv(async () => {
|
|
134
236
|
const root = redirectXdg();
|
|
@@ -157,15 +259,54 @@ describe("cadet uninstall", () => {
|
|
|
157
259
|
expect(existsSync(logDir)).toBe(false);
|
|
158
260
|
expect(existsSync(historyPath)).toBe(false);
|
|
159
261
|
|
|
262
|
+
// The list shows the shared state DIR (never the input-history FILE
|
|
263
|
+
// alone) and never names a nested path twice — the log dir goes with
|
|
264
|
+
// its parent's recursive delete.
|
|
265
|
+
const out = printedOutput();
|
|
266
|
+
expect(out).toContain(
|
|
267
|
+
` - ${getSharedStateDir()} — shared state, including the terminal input history`,
|
|
268
|
+
);
|
|
269
|
+
expect(out).not.toContain(logDir);
|
|
270
|
+
expect(out).not.toContain(historyPath);
|
|
271
|
+
expect(out).not.toContain("It will then remove the Cadet executable");
|
|
272
|
+
|
|
160
273
|
// Running under bun from a git checkout: self-removal must print the
|
|
161
274
|
// note and delete NOTHING outside the XDG targets.
|
|
162
|
-
|
|
163
|
-
.map((args) => args.map(String).join(" "))
|
|
164
|
-
.join("\n");
|
|
165
|
-
expect(note).toContain("source checkout");
|
|
275
|
+
expect(printedOutput()).toContain("source checkout");
|
|
166
276
|
expect(existsSync(process.execPath)).toBe(true);
|
|
167
277
|
|
|
168
278
|
rmSync(root, { recursive: true, force: true });
|
|
169
279
|
});
|
|
170
280
|
});
|
|
281
|
+
|
|
282
|
+
test("--yes lists and removes the Cadet executable itself", async () => {
|
|
283
|
+
await withRestoredEnv(async () => {
|
|
284
|
+
const root = redirectXdg();
|
|
285
|
+
const configDir = getConfigDirs(getCurrentEnvironment())[0]!;
|
|
286
|
+
mkdirSync(configDir, { recursive: true });
|
|
287
|
+
|
|
288
|
+
// A compiled-binary install: process.execPath IS the install, so the
|
|
289
|
+
// uninstall list must name it alongside the data dirs.
|
|
290
|
+
const fakeBinDir = join(root, "bin");
|
|
291
|
+
mkdirSync(fakeBinDir, { recursive: true });
|
|
292
|
+
const fakeBin = join(fakeBinDir, "cadet");
|
|
293
|
+
writeFileSync(fakeBin, "#!/bin/sh\n");
|
|
294
|
+
|
|
295
|
+
const realExecPath = process.execPath;
|
|
296
|
+
process.execPath = fakeBin;
|
|
297
|
+
try {
|
|
298
|
+
process.argv = ["bun", "cadet", "uninstall", "--yes"];
|
|
299
|
+
await uninstall();
|
|
300
|
+
} finally {
|
|
301
|
+
process.execPath = realExecPath;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
expect(printedOutput()).toContain(
|
|
305
|
+
` - ${fakeBin} — the Cadet executable`,
|
|
306
|
+
);
|
|
307
|
+
expect(existsSync(fakeBin)).toBe(false);
|
|
308
|
+
|
|
309
|
+
rmSync(root, { recursive: true, force: true });
|
|
310
|
+
});
|
|
311
|
+
});
|
|
171
312
|
});
|
|
@@ -20,7 +20,7 @@ import type { GuardianTokenData } from "../lib/guardian-token.js";
|
|
|
20
20
|
import * as guardianToken from "../lib/guardian-token.js";
|
|
21
21
|
import * as local from "../lib/local.js";
|
|
22
22
|
import * as loopbackFetch from "../lib/loopback-fetch.js";
|
|
23
|
-
import * as ngrok from "../lib/ngrok.js";
|
|
23
|
+
import * as ngrok from "../lib/tunnels/ngrok.js";
|
|
24
24
|
import * as upgradeLifecycle from "../lib/upgrade-lifecycle.js";
|
|
25
25
|
|
|
26
26
|
const realAssistantConfig = { ...assistantConfig };
|
|
@@ -157,7 +157,7 @@ const maybeStartNgrokTunnelMock = mock<typeof ngrok.maybeStartNgrokTunnel>(
|
|
|
157
157
|
async () => null,
|
|
158
158
|
);
|
|
159
159
|
|
|
160
|
-
mock.module("../lib/ngrok.js", () => ({
|
|
160
|
+
mock.module("../lib/tunnels/ngrok.js", () => ({
|
|
161
161
|
...realNgrok,
|
|
162
162
|
maybeStartNgrokTunnel: maybeStartNgrokTunnelMock,
|
|
163
163
|
}));
|
|
@@ -302,7 +302,7 @@ afterAll(() => {
|
|
|
302
302
|
mock.module("../lib/guardian-token.js", () => realGuardianToken);
|
|
303
303
|
mock.module("../lib/local.js", () => realLocal);
|
|
304
304
|
mock.module("../lib/loopback-fetch.js", () => realLoopbackFetch);
|
|
305
|
-
mock.module("../lib/ngrok.js", () => realNgrok);
|
|
305
|
+
mock.module("../lib/tunnels/ngrok.js", () => realNgrok);
|
|
306
306
|
mock.module("../lib/upgrade-lifecycle.js", () => realUpgradeLifecycle);
|
|
307
307
|
});
|
|
308
308
|
|
|
@@ -6,7 +6,7 @@ import { buildReplayEnv, buildReplayState } from "../lib/upgrade-lifecycle.js";
|
|
|
6
6
|
import { snapshotEnv } from "./helpers/env.js";
|
|
7
7
|
|
|
8
8
|
const restoreEnv = snapshotEnv([
|
|
9
|
-
"
|
|
9
|
+
"CADET_CLOUD_URL",
|
|
10
10
|
"ANTHROPIC_API_KEY",
|
|
11
11
|
"CADET_DEVICE_ID",
|
|
12
12
|
]);
|
|
@@ -24,33 +24,33 @@ describe("buildReplayEnv", () => {
|
|
|
24
24
|
ACTOR_TOKEN_SIGNING_KEY: "s3",
|
|
25
25
|
PATH: "/usr/bin",
|
|
26
26
|
GATEWAY_PORT: "18080",
|
|
27
|
-
|
|
27
|
+
CADET_DISABLE_CLOUD: "1",
|
|
28
28
|
CADET_DEVICE_ID: "abc",
|
|
29
29
|
};
|
|
30
30
|
|
|
31
31
|
expect(buildReplayEnv(captured, "gateway")).toEqual({
|
|
32
|
-
|
|
32
|
+
CADET_DISABLE_CLOUD: "1",
|
|
33
33
|
CADET_DEVICE_ID: "abc",
|
|
34
34
|
});
|
|
35
35
|
});
|
|
36
36
|
|
|
37
|
-
test("gateway: captured
|
|
38
|
-
process.env.
|
|
37
|
+
test("gateway: captured CADET_CLOUD_URL dropped when set on host", () => {
|
|
38
|
+
process.env.CADET_CLOUD_URL = "https://host.example.com";
|
|
39
39
|
const replay = buildReplayEnv(
|
|
40
|
-
{
|
|
40
|
+
{ CADET_CLOUD_URL: "https://stale.example.com" },
|
|
41
41
|
"gateway",
|
|
42
42
|
);
|
|
43
43
|
expect(replay).toEqual({});
|
|
44
44
|
});
|
|
45
45
|
|
|
46
|
-
test("gateway: captured
|
|
47
|
-
delete process.env.
|
|
46
|
+
test("gateway: captured CADET_CLOUD_URL kept when unset on host", () => {
|
|
47
|
+
delete process.env.CADET_CLOUD_URL;
|
|
48
48
|
const replay = buildReplayEnv(
|
|
49
|
-
{
|
|
49
|
+
{ CADET_CLOUD_URL: "https://stale.example.com" },
|
|
50
50
|
"gateway",
|
|
51
51
|
);
|
|
52
52
|
expect(replay).toEqual({
|
|
53
|
-
|
|
53
|
+
CADET_CLOUD_URL: "https://stale.example.com",
|
|
54
54
|
});
|
|
55
55
|
});
|
|
56
56
|
|
|
@@ -118,9 +118,9 @@ describe("buildReplayState", () => {
|
|
|
118
118
|
});
|
|
119
119
|
|
|
120
120
|
test("backfills CADET_DEVICE_ID on gateway replay env when absent", () => {
|
|
121
|
-
const state = buildReplayState({}, {
|
|
121
|
+
const state = buildReplayState({}, { CADET_DISABLE_CLOUD: "1" });
|
|
122
122
|
expect(state.extraGatewayEnv).toEqual({
|
|
123
|
-
|
|
123
|
+
CADET_DISABLE_CLOUD: "1",
|
|
124
124
|
CADET_DEVICE_ID: "host-device-id",
|
|
125
125
|
});
|
|
126
126
|
});
|