@mycadet/cli 0.12.7 → 0.12.9
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 +3 -2
- 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 +2 -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 +21 -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 +1 -8
- package/src/__tests__/{ps-platform-status.test.ts → ps-cloud-status.test.ts} +79 -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 +181 -197
- package/src/__tests__/tunnel.test.ts +257 -222
- package/src/__tests__/uninstall.test.ts +13 -4
- 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 -76
- 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 +23 -23
- package/src/commands/login.ts +22 -22
- package/src/commands/logs.ts +8 -8
- package/src/commands/ps.ts +244 -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 +109 -109
- package/src/commands/terminal.ts +158 -18
- package/src/commands/tunnel.ts +138 -157
- package/src/commands/uninstall.ts +57 -9
- 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-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} +107 -98
- package/src/lib/cloud-login.ts +24 -24
- package/src/lib/{platform-releases.ts → cloud-releases.ts} +11 -9
- package/src/lib/cloud-values.ts +3 -0
- package/src/lib/config-utils.ts +1 -1
- package/src/lib/detached-process.ts +1 -1
- package/src/lib/docker.ts +260 -53
- package/src/lib/ensure-binary.ts +171 -0
- package/src/lib/environments/__tests__/paths.test.ts +2 -2
- package/src/lib/environments/__tests__/resolve.test.ts +26 -26
- package/src/lib/environments/resolve.ts +8 -8
- 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 +19 -23
- 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 +10 -31
- package/src/lib/nginx-ingress.ts +42 -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/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
package/node_modules/@mycadet/local-mode/node_modules/@mycadet/environments/src/shell.test.ts
CHANGED
|
@@ -72,7 +72,7 @@ describe("buildShellSpawnFlags", () => {
|
|
|
72
72
|
});
|
|
73
73
|
|
|
74
74
|
describe("path list handling", () => {
|
|
75
|
-
test("uses the
|
|
75
|
+
test("uses the cloud delimiter", () => {
|
|
76
76
|
expect(pathListDelimiter("win32")).toBe(";");
|
|
77
77
|
expect(pathListDelimiter("linux")).toBe(":");
|
|
78
78
|
});
|
|
@@ -21,14 +21,14 @@ export interface PortMap {
|
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
23
|
* A resolved environment definition. Required fields are `name` and
|
|
24
|
-
* `
|
|
24
|
+
* `cloudUrl`. All other fields are optional and declared upfront — new
|
|
25
25
|
* fields are additive, never breaking. `name` is intentionally typed as
|
|
26
26
|
* `string` (not `keyof SEEDS`) so custom environments can be represented by
|
|
27
27
|
* future layers (user config file, ad-hoc env vars, etc.).
|
|
28
28
|
*/
|
|
29
29
|
export interface EnvironmentDefinition {
|
|
30
30
|
name: string;
|
|
31
|
-
|
|
31
|
+
cloudUrl: string;
|
|
32
32
|
|
|
33
33
|
/**
|
|
34
34
|
* The web app (Next.js) base URL for browser-facing pages like
|
|
@@ -41,13 +41,13 @@ export interface EnvironmentDefinition {
|
|
|
41
41
|
webUrl: string;
|
|
42
42
|
|
|
43
43
|
/**
|
|
44
|
-
* Override for the
|
|
45
|
-
* differs from `
|
|
44
|
+
* Override for the cloud URL the assistant process itself uses. Only
|
|
45
|
+
* differs from `cloudUrl` when the assistant runs in a different network
|
|
46
46
|
* namespace than the host (e.g. Docker on macOS, where the host's localhost
|
|
47
|
-
* is reached via `host.docker.internal`). Falls back to `
|
|
47
|
+
* is reached via `host.docker.internal`). Falls back to `cloudUrl` when
|
|
48
48
|
* unset.
|
|
49
49
|
*/
|
|
50
|
-
|
|
50
|
+
assistantCloudUrl?: string;
|
|
51
51
|
|
|
52
52
|
/** Human-readable label for UI surfaces. */
|
|
53
53
|
displayName?: string;
|
package/node_modules/@mycadet/local-mode/node_modules/@mycadet/service-contracts/package.json
CHANGED
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"./error": "./src/error.ts",
|
|
27
27
|
"./reactions": "./src/reactions.ts",
|
|
28
28
|
"./guardian-requests": "./src/guardian-requests.ts",
|
|
29
|
-
"./
|
|
29
|
+
"./cloud-credential": "./src/cloud-credential.ts",
|
|
30
30
|
"./plan-credit": "./src/plan-credit.ts",
|
|
31
31
|
"./integration-categories": "./src/integration-categories.ts",
|
|
32
32
|
"./mcp-oauth": "./src/mcp-oauth.ts"
|
|
@@ -40,6 +40,6 @@
|
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"@types/bun": "1.2.4",
|
|
43
|
-
"typescript": "5.
|
|
43
|
+
"typescript": "5.9.3"
|
|
44
44
|
}
|
|
45
45
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Wire contract for asking an assistant whether its stored
|
|
2
|
+
* Wire contract for asking an assistant whether its stored cloud-managed
|
|
3
3
|
* credential still authenticates.
|
|
4
4
|
*
|
|
5
5
|
* The daemon route is the authoritative serving side:
|
|
6
6
|
* - `POST /v1/platform/verify-credential`
|
|
7
|
-
* (`assistant/src/runtime/routes/
|
|
7
|
+
* (`assistant/src/runtime/routes/cloud-routes.ts`)
|
|
8
8
|
*
|
|
9
9
|
* The daemon's platform client produces the verdict, the route reports it,
|
|
10
10
|
* and the `cadet` CLI reads it before deciding whether a stored key can be
|
|
@@ -15,26 +15,26 @@
|
|
|
15
15
|
import { z } from "zod";
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
|
-
* What the
|
|
18
|
+
* What the cloud said about the stored credential, right now.
|
|
19
19
|
*
|
|
20
|
-
* - `valid`: the
|
|
21
|
-
* - `rejected`: the
|
|
20
|
+
* - `valid`: the cloud accepted it.
|
|
21
|
+
* - `rejected`: the cloud refused it (unauthorized or forbidden); the
|
|
22
22
|
* credential needs replacing.
|
|
23
23
|
* - `unknown`: the check itself could not run (no credential stored, the
|
|
24
24
|
* platform unreachable, a server error). Not evidence either way.
|
|
25
25
|
*/
|
|
26
|
-
export const
|
|
26
|
+
export const CloudCredentialVerificationStatusSchema = z.enum([
|
|
27
27
|
"valid",
|
|
28
28
|
"rejected",
|
|
29
29
|
"unknown",
|
|
30
30
|
]);
|
|
31
|
-
export type
|
|
32
|
-
typeof
|
|
31
|
+
export type CloudCredentialVerificationStatus = z.infer<
|
|
32
|
+
typeof CloudCredentialVerificationStatusSchema
|
|
33
33
|
>;
|
|
34
34
|
|
|
35
35
|
/** `POST /v1/platform/verify-credential` response body. */
|
|
36
36
|
export const PlatformVerifyCredentialResponseSchema = z.object({
|
|
37
|
-
status:
|
|
37
|
+
status: CloudCredentialVerificationStatusSchema,
|
|
38
38
|
});
|
|
39
39
|
export type PlatformVerifyCredentialResponse = z.infer<
|
|
40
40
|
typeof PlatformVerifyCredentialResponseSchema
|
package/node_modules/@mycadet/local-mode/node_modules/@mycadet/service-contracts/src/handles.ts
CHANGED
|
@@ -15,9 +15,9 @@
|
|
|
15
15
|
* Format: `local_oauth:<providerKey>/<connectionId>` where providerKey
|
|
16
16
|
* is the bare provider name (e.g. `google`).
|
|
17
17
|
*
|
|
18
|
-
* 3. **
|
|
18
|
+
* 3. **Cloud OAuth** — references an OAuth connection managed by the
|
|
19
19
|
* platform. Format: `platform_oauth:<connectionId>` where connectionId
|
|
20
|
-
* is the
|
|
20
|
+
* is the cloud-assigned connection identifier.
|
|
21
21
|
*/
|
|
22
22
|
|
|
23
23
|
import { z } from "zod";
|
|
@@ -96,7 +96,7 @@ export function localOAuthHandle(
|
|
|
96
96
|
}
|
|
97
97
|
|
|
98
98
|
/**
|
|
99
|
-
* Build a
|
|
99
|
+
* Build a cloud (platform) OAuth credential handle from a connection ID.
|
|
100
100
|
*/
|
|
101
101
|
export function platformOAuthHandle(connectionId: string): string {
|
|
102
102
|
return `${HandleType.PlatformOAuth}:${connectionId}`;
|
package/node_modules/@mycadet/local-mode/node_modules/@mycadet/service-contracts/src/index.ts
CHANGED
|
@@ -31,7 +31,7 @@ export * from "./no-response.js";
|
|
|
31
31
|
export * from "./plan-credit.js";
|
|
32
32
|
export * from "./integration-categories.js";
|
|
33
33
|
export * from "./mcp-oauth.js";
|
|
34
|
-
export * from "./
|
|
34
|
+
export * from "./cloud-credential.js";
|
|
35
35
|
export * from "./remote-web-pairing.js";
|
|
36
36
|
export * from "./twilio-ingress.js";
|
|
37
37
|
export * from "./url-normalization.js";
|
package/node_modules/@mycadet/local-mode/node_modules/@mycadet/service-contracts/src/ingress.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* `{env}-cloud.mycadet.ai` → `tunnel-{env}.mycadet.ai`). Returns null for
|
|
5
5
|
* hosts outside that convention (localhost, custom domains). Shared by the
|
|
6
6
|
* gateway speech relay and the web live-voice client so the two ends of the
|
|
7
|
-
*
|
|
7
|
+
* cloud-speech transport can't drift.
|
|
8
8
|
*/
|
|
9
9
|
export function tunnelHostForPlatformHost(host: string): string | null {
|
|
10
10
|
if (host === "cloud.mycadet.ai") {
|
|
@@ -100,11 +100,17 @@ export const INGRESS_PAIRING_TUNNEL_KEY = "pairingTunnel";
|
|
|
100
100
|
export const INGRESS_ASSISTANT_ID_KEY = "assistantId";
|
|
101
101
|
|
|
102
102
|
/**
|
|
103
|
-
* The
|
|
104
|
-
* `cadet tunnel
|
|
105
|
-
*
|
|
103
|
+
* The tunnel providers the CLI offers, in the order they are presented —
|
|
104
|
+
* the managed `cadet` tunnel first (listed, not yet implemented), then the
|
|
105
|
+
* local ones. `cadet tunnel`'s accepted `--provider` values and the
|
|
106
|
+
* persisted-record validation below both derive from it.
|
|
106
107
|
*/
|
|
107
|
-
export const TUNNEL_PROVIDERS = [
|
|
108
|
+
export const TUNNEL_PROVIDERS = [
|
|
109
|
+
"cadet",
|
|
110
|
+
"ngrok",
|
|
111
|
+
"cloudflare",
|
|
112
|
+
"tailscale",
|
|
113
|
+
] as const;
|
|
108
114
|
|
|
109
115
|
export type TunnelProviderName = (typeof TUNNEL_PROVIDERS)[number];
|
|
110
116
|
|
|
@@ -152,7 +152,7 @@ export const DEFAULT_REMOTE_WEB_PAIRING_PLATFORM: RemoteWebPairingPlatform =
|
|
|
152
152
|
|
|
153
153
|
/**
|
|
154
154
|
* A requested platform coerced to a known value. The pairing-token route is
|
|
155
|
-
* publicly reachable and the
|
|
155
|
+
* publicly reachable and the cloud renders verbatim in the host's
|
|
156
156
|
* paired-devices list, so an unrecognized value never reaches the DB.
|
|
157
157
|
*/
|
|
158
158
|
export function resolveRemoteWebPairingPlatform(
|
|
@@ -34,7 +34,7 @@ import { RpcErrorSchema } from "./error.js";
|
|
|
34
34
|
|
|
35
35
|
export const CesRpcMethod = {
|
|
36
36
|
/** Push an updated assistant credential to CES after post-hatch provisioning. */
|
|
37
|
-
|
|
37
|
+
UpdateCloudCredential: "update_managed_credential",
|
|
38
38
|
/** Retrieve a single credential by account name. */
|
|
39
39
|
GetCredential: "get_credential",
|
|
40
40
|
/** Store or update a credential by account name. */
|
|
@@ -63,7 +63,7 @@ export type CesRpcMethod = (typeof CesRpcMethod)[keyof typeof CesRpcMethod];
|
|
|
63
63
|
// update_managed_credential
|
|
64
64
|
// ---------------------------------------------------------------------------
|
|
65
65
|
|
|
66
|
-
export const
|
|
66
|
+
export const UpdateCloudCredentialSchema = z.object({
|
|
67
67
|
/** The assistant API key to push to CES for platform credential materialization. */
|
|
68
68
|
assistantApiKey: z.string(), // nosemgrep: not-a-secret
|
|
69
69
|
/**
|
|
@@ -72,16 +72,16 @@ export const UpdateManagedCredentialSchema = z.object({
|
|
|
72
72
|
*/
|
|
73
73
|
assistantId: z.string().optional(),
|
|
74
74
|
});
|
|
75
|
-
export type
|
|
76
|
-
typeof
|
|
75
|
+
export type UpdateCloudCredential = z.infer<
|
|
76
|
+
typeof UpdateCloudCredentialSchema
|
|
77
77
|
>;
|
|
78
78
|
|
|
79
|
-
export const
|
|
80
|
-
/** Whether the
|
|
79
|
+
export const UpdateCloudCredentialResponseSchema = z.object({
|
|
80
|
+
/** Whether the cloud credential was successfully updated. */
|
|
81
81
|
updated: z.boolean(),
|
|
82
82
|
});
|
|
83
|
-
export type
|
|
84
|
-
typeof
|
|
83
|
+
export type UpdateCloudCredentialResponse = z.infer<
|
|
84
|
+
typeof UpdateCloudCredentialResponseSchema
|
|
85
85
|
>;
|
|
86
86
|
|
|
87
87
|
// ---------------------------------------------------------------------------
|
|
@@ -311,9 +311,9 @@ export type BulkSetCredentialRecordsResponse = z.infer<
|
|
|
311
311
|
* schemas. Useful for building type-safe RPC dispatch layers.
|
|
312
312
|
*/
|
|
313
313
|
export interface CesRpcContract {
|
|
314
|
-
[CesRpcMethod.
|
|
315
|
-
request:
|
|
316
|
-
response:
|
|
314
|
+
[CesRpcMethod.UpdateCloudCredential]: {
|
|
315
|
+
request: UpdateCloudCredential;
|
|
316
|
+
response: UpdateCloudCredentialResponse;
|
|
317
317
|
};
|
|
318
318
|
[CesRpcMethod.GetCredential]: {
|
|
319
319
|
request: GetCredential;
|
|
@@ -361,9 +361,9 @@ export interface CesRpcContract {
|
|
|
361
361
|
* Schema lookup map for runtime validation of RPC payloads.
|
|
362
362
|
*/
|
|
363
363
|
export const CesRpcSchemas = {
|
|
364
|
-
[CesRpcMethod.
|
|
365
|
-
request:
|
|
366
|
-
response:
|
|
364
|
+
[CesRpcMethod.UpdateCloudCredential]: {
|
|
365
|
+
request: UpdateCloudCredentialSchema,
|
|
366
|
+
response: UpdateCloudCredentialResponseSchema,
|
|
367
367
|
},
|
|
368
368
|
[CesRpcMethod.GetCredential]: {
|
|
369
369
|
request: GetCredentialSchema,
|
package/node_modules/@mycadet/local-mode/node_modules/@mycadet/service-contracts/src/trust-rules.ts
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
* - **URL**: tools whose candidates include a URL (`web_fetch`,
|
|
16
16
|
* `network_request`).
|
|
17
17
|
* - **Managed skill**: tools that manage first-party skill packages
|
|
18
|
-
* (`
|
|
18
|
+
* (`scaffold_cloud_skill`, `delete_cloud_skill`).
|
|
19
19
|
* - **Skill load**: the `skill_load` tool, which uses a distinct candidate
|
|
20
20
|
* namespace (`skill_load:selector` or `skill_load_dynamic:selector`).
|
|
21
21
|
* - **Generic**: everything else (computer-use tools, UI surface tools,
|
|
@@ -58,8 +58,8 @@ export const URL_TOOLS = ["web_fetch", "network_request"] as const;
|
|
|
58
58
|
* Tools that manage first-party skill packages (scaffold/delete).
|
|
59
59
|
*/
|
|
60
60
|
export const MANAGED_SKILL_TOOLS = [
|
|
61
|
-
"
|
|
62
|
-
"
|
|
61
|
+
"scaffold_cloud_skill",
|
|
62
|
+
"delete_cloud_skill",
|
|
63
63
|
] as const;
|
|
64
64
|
|
|
65
65
|
/**
|
|
@@ -89,8 +89,8 @@ export function isUrlRule(rule: { tool: string }): boolean {
|
|
|
89
89
|
return URL_TOOLS_SET.has(rule.tool);
|
|
90
90
|
}
|
|
91
91
|
|
|
92
|
-
/** Returns true when the rule's tool belongs to the
|
|
93
|
-
export function
|
|
92
|
+
/** Returns true when the rule's tool belongs to the cloud-skill-tool family. */
|
|
93
|
+
export function isCloudSkillRule(rule: { tool: string }): boolean {
|
|
94
94
|
return MANAGED_SKILL_TOOLS_SET.has(rule.tool);
|
|
95
95
|
}
|
|
96
96
|
|
|
@@ -50,7 +50,7 @@ beforeEach(() => {
|
|
|
50
50
|
};
|
|
51
51
|
fetchCalls.push(call);
|
|
52
52
|
const response = await respond(call);
|
|
53
|
-
// Mirror the
|
|
53
|
+
// Mirror the cloud: a 3xx under `redirect: "error"` rejects instead of
|
|
54
54
|
// being followed.
|
|
55
55
|
if (
|
|
56
56
|
init?.redirect === "error" &&
|
|
@@ -654,7 +654,7 @@ describe("pairAssistant", () => {
|
|
|
654
654
|
expect(readGuardianToken("desk").accessToken).toBe("t2");
|
|
655
655
|
});
|
|
656
656
|
|
|
657
|
-
test("re-pairing to a new gateway drops a cached
|
|
657
|
+
test("re-pairing to a new gateway drops a cached cloudAssistantId", () => {
|
|
658
658
|
const first = pairAssistant([lockfilePath], configDir, {
|
|
659
659
|
credentials: credentials({ deviceId: "dev-re", token: "t1" }),
|
|
660
660
|
name: "desk",
|
|
@@ -663,7 +663,7 @@ describe("pairAssistant", () => {
|
|
|
663
663
|
const cached = readLockfileFromDisk();
|
|
664
664
|
(
|
|
665
665
|
cached.assistants as Array<Record<string, unknown>>
|
|
666
|
-
)[0]!.
|
|
666
|
+
)[0]!.cloudAssistantId = "11111111-1111-4111-8111-111111111111";
|
|
667
667
|
fs.writeFileSync(lockfilePath, JSON.stringify(cached, null, 2));
|
|
668
668
|
|
|
669
669
|
const second = pairAssistant([lockfilePath], configDir, {
|
|
@@ -681,7 +681,7 @@ describe("pairAssistant", () => {
|
|
|
681
681
|
>;
|
|
682
682
|
expect(assistants).toHaveLength(1);
|
|
683
683
|
expect(assistants[0]!.runtimeUrl).toBe("https://new.example.com");
|
|
684
|
-
expect(assistants[0]!).not.toHaveProperty("
|
|
684
|
+
expect(assistants[0]!).not.toHaveProperty("cloudAssistantId");
|
|
685
685
|
});
|
|
686
686
|
|
|
687
687
|
test("deletes the just-written token when the lockfile write fails", () => {
|
|
@@ -1318,7 +1318,7 @@ describe("pairingPoll", () => {
|
|
|
1318
1318
|
expect(readGuardianToken(first.assistantId).accessToken).toBe("acc-2");
|
|
1319
1319
|
});
|
|
1320
1320
|
|
|
1321
|
-
test("records the
|
|
1321
|
+
test("records the cloud the caller names, defaulting to desktop", async () => {
|
|
1322
1322
|
respond = () => json(202, pendingBody());
|
|
1323
1323
|
|
|
1324
1324
|
const cliHandle = await startFromLink();
|
|
@@ -50,7 +50,7 @@ describe("runRetire", () => {
|
|
|
50
50
|
|
|
51
51
|
test("passes a host platform token to the CLI subprocess", async () => {
|
|
52
52
|
const pending = runRetire(invocation, "asst-42", {
|
|
53
|
-
|
|
53
|
+
cloudToken: "session-token",
|
|
54
54
|
});
|
|
55
55
|
lastChild.emit("close", 0);
|
|
56
56
|
|
|
@@ -17,7 +17,7 @@ export interface LocalEndpointConfig {
|
|
|
17
17
|
lockfilePaths: string[];
|
|
18
18
|
configDir: string;
|
|
19
19
|
webUrl: string;
|
|
20
|
-
|
|
20
|
+
cloudUrl: string;
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
/**
|
|
@@ -36,7 +36,7 @@ export function resolveLocalConfigFromEnv(
|
|
|
36
36
|
lockfilePaths: resolveLockfilePaths(env, options),
|
|
37
37
|
configDir: resolveConfigDir(env, options),
|
|
38
38
|
webUrl: env.CADET_WEB_URL || seed.webUrl,
|
|
39
|
-
|
|
39
|
+
cloudUrl: env.CADET_CLOUD_URL || seed.cloudUrl,
|
|
40
40
|
};
|
|
41
41
|
}
|
|
42
42
|
|
|
@@ -21,9 +21,9 @@ describe("parseLockfile", () => {
|
|
|
21
21
|
runtimeUrl: "http://127.0.0.1:7777",
|
|
22
22
|
hatchedAt: "2026-01-01T00:00:00.000Z",
|
|
23
23
|
organizationId: "org_1",
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
cloudAssistantId: "platform-assistant-1",
|
|
25
|
+
cloudBaseUrl: "https://platform.example.com",
|
|
26
|
+
cloudOrganizationId: "org_1",
|
|
27
27
|
ingressUrl: "https://tunnel.example.ts.net",
|
|
28
28
|
resources: { gatewayPort: 7777, daemonPort: 7778 },
|
|
29
29
|
},
|
|
@@ -29,7 +29,7 @@ import { z } from "zod";
|
|
|
29
29
|
* - `local` — on-machine daemon
|
|
30
30
|
* - `docker` — local container
|
|
31
31
|
* - `apple-container` — macOS-app-managed container
|
|
32
|
-
* - `cloud` —
|
|
32
|
+
* - `cloud` — cloud-managed (uses the X-Session-Token auth path);
|
|
33
33
|
* canonical since the Cadet rebrand
|
|
34
34
|
* - `cadet` — legacy alias of `cloud`, still read from existing lockfiles
|
|
35
35
|
* - `gcp` / `aws` / `custom` — remote, SSH-managed
|
|
@@ -80,12 +80,12 @@ export function resolveCloud(raw: {
|
|
|
80
80
|
}
|
|
81
81
|
|
|
82
82
|
/**
|
|
83
|
-
* Whether a cloud value denotes the
|
|
83
|
+
* Whether a cloud value denotes the cloud-managed topology. `cloud` is
|
|
84
84
|
* canonical; `cadet` is the legacy spelling kept for entries written before
|
|
85
85
|
* the rebrand. Every reader that used to compare `=== "cadet"` switches on
|
|
86
86
|
* this instead so both spellings dispatch identically.
|
|
87
87
|
*/
|
|
88
|
-
export function
|
|
88
|
+
export function isCloudHome(cloud: unknown): boolean {
|
|
89
89
|
return cloud === "cloud" || cloud === "cadet";
|
|
90
90
|
}
|
|
91
91
|
|
|
@@ -200,10 +200,15 @@ export const LockfileAssistantSchema = z.object({
|
|
|
200
200
|
/** Owning org for platform assistants; absent for local ones. */
|
|
201
201
|
organizationId: z.string().optional(),
|
|
202
202
|
/** Platform assistant UUID for a self-hosted local assistant registration. */
|
|
203
|
-
|
|
203
|
+
cloudAssistantId: z.string().optional(),
|
|
204
204
|
/** Platform base URL used for a self-hosted local assistant registration. */
|
|
205
|
-
|
|
205
|
+
cloudBaseUrl: z.string().optional(),
|
|
206
206
|
/** Platform organization UUID used for a self-hosted local assistant registration. */
|
|
207
|
+
cloudOrganizationId: z.string().optional(),
|
|
208
|
+
/** Pre-rename spellings of the cloud* fields above; readers fall back to
|
|
209
|
+
* them so lockfiles written before the platform→cloud rename still resolve. */
|
|
210
|
+
platformAssistantId: z.string().optional(),
|
|
211
|
+
platformBaseUrl: z.string().optional(),
|
|
207
212
|
platformOrganizationId: z.string().optional(),
|
|
208
213
|
/**
|
|
209
214
|
* Public https URL a `cadet tunnel` provider recorded for this assistant
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
isPairedLockfileEntry,
|
|
9
9
|
renameLockfileAssistantIfPresent,
|
|
10
10
|
stampLockfileAssistantOnboardedIfPresent,
|
|
11
|
-
|
|
11
|
+
replaceCloudAssistants,
|
|
12
12
|
upsertLockfileAssistant,
|
|
13
13
|
upsertRendererLockfileAssistant,
|
|
14
14
|
} from "./lockfile";
|
|
@@ -549,7 +549,7 @@ describe("lockfile writers under lock contention", () => {
|
|
|
549
549
|
const before = fs.readFileSync(lockfilePath, "utf-8");
|
|
550
550
|
holdLock();
|
|
551
551
|
|
|
552
|
-
const result =
|
|
552
|
+
const result = replaceCloudAssistants(
|
|
553
553
|
[lockfilePath],
|
|
554
554
|
[{ assistantId: "asst_p", cloud: "cadet", runtimeUrl: "http://p" }],
|
|
555
555
|
);
|
|
@@ -648,7 +648,7 @@ describe("upsertRendererLockfileAssistant", () => {
|
|
|
648
648
|
});
|
|
649
649
|
});
|
|
650
650
|
|
|
651
|
-
describe("
|
|
651
|
+
describe("replaceCloudAssistants", () => {
|
|
652
652
|
test("rejects a renderer sync that tries to create a paired entry", () => {
|
|
653
653
|
writeOnDisk({
|
|
654
654
|
activeAssistant: "asst_local",
|
|
@@ -658,7 +658,7 @@ describe("replacePlatformAssistants", () => {
|
|
|
658
658
|
});
|
|
659
659
|
|
|
660
660
|
expect(
|
|
661
|
-
|
|
661
|
+
replaceCloudAssistants(
|
|
662
662
|
[lockfilePath],
|
|
663
663
|
[
|
|
664
664
|
{
|
|
@@ -678,7 +678,7 @@ describe("replacePlatformAssistants", () => {
|
|
|
678
678
|
});
|
|
679
679
|
});
|
|
680
680
|
|
|
681
|
-
// `onboardedAt` is recorded by the client and unknown to the
|
|
681
|
+
// `onboardedAt` is recorded by the client and unknown to the cloud, so the
|
|
682
682
|
// rows a sync builds from the API never carry it. Dropping it here would let
|
|
683
683
|
// a routine session refresh erase the completion record.
|
|
684
684
|
test("carries an existing onboardedAt onto the replacement row", () => {
|
|
@@ -694,7 +694,7 @@ describe("replacePlatformAssistants", () => {
|
|
|
694
694
|
],
|
|
695
695
|
});
|
|
696
696
|
|
|
697
|
-
const result =
|
|
697
|
+
const result = replaceCloudAssistants(
|
|
698
698
|
[lockfilePath],
|
|
699
699
|
[{ assistantId: "asst_p", cloud: "cadet", runtimeUrl: "http://new" }],
|
|
700
700
|
);
|
|
@@ -722,7 +722,7 @@ describe("replacePlatformAssistants", () => {
|
|
|
722
722
|
],
|
|
723
723
|
});
|
|
724
724
|
|
|
725
|
-
|
|
725
|
+
replaceCloudAssistants(
|
|
726
726
|
[lockfilePath],
|
|
727
727
|
[
|
|
728
728
|
{
|
|
@@ -751,7 +751,7 @@ describe("replacePlatformAssistants", () => {
|
|
|
751
751
|
],
|
|
752
752
|
});
|
|
753
753
|
|
|
754
|
-
|
|
754
|
+
replaceCloudAssistants(
|
|
755
755
|
[lockfilePath],
|
|
756
756
|
[{ assistantId: "asst_b", cloud: "cadet" }],
|
|
757
757
|
);
|
|
@@ -775,7 +775,7 @@ describe("replacePlatformAssistants", () => {
|
|
|
775
775
|
],
|
|
776
776
|
});
|
|
777
777
|
|
|
778
|
-
const result =
|
|
778
|
+
const result = replaceCloudAssistants(
|
|
779
779
|
[lockfilePath],
|
|
780
780
|
[
|
|
781
781
|
{
|
|
@@ -815,7 +815,7 @@ describe("replacePlatformAssistants", () => {
|
|
|
815
815
|
],
|
|
816
816
|
});
|
|
817
817
|
|
|
818
|
-
|
|
818
|
+
replaceCloudAssistants(
|
|
819
819
|
[lockfilePath],
|
|
820
820
|
[
|
|
821
821
|
{
|
|
@@ -844,7 +844,7 @@ describe("replacePlatformAssistants", () => {
|
|
|
844
844
|
],
|
|
845
845
|
});
|
|
846
846
|
|
|
847
|
-
|
|
847
|
+
replaceCloudAssistants(
|
|
848
848
|
[lockfilePath],
|
|
849
849
|
[
|
|
850
850
|
{
|
|
@@ -887,7 +887,7 @@ describe("replacePlatformAssistants", () => {
|
|
|
887
887
|
],
|
|
888
888
|
});
|
|
889
889
|
|
|
890
|
-
|
|
890
|
+
replaceCloudAssistants(
|
|
891
891
|
[lockfilePath],
|
|
892
892
|
[
|
|
893
893
|
{
|
|
@@ -918,7 +918,7 @@ describe("replacePlatformAssistants", () => {
|
|
|
918
918
|
],
|
|
919
919
|
});
|
|
920
920
|
|
|
921
|
-
|
|
921
|
+
replaceCloudAssistants(
|
|
922
922
|
[lockfilePath],
|
|
923
923
|
[
|
|
924
924
|
{
|
|
@@ -950,7 +950,7 @@ describe("replacePlatformAssistants", () => {
|
|
|
950
950
|
],
|
|
951
951
|
});
|
|
952
952
|
|
|
953
|
-
|
|
953
|
+
replaceCloudAssistants(
|
|
954
954
|
[lockfilePath],
|
|
955
955
|
[
|
|
956
956
|
{
|
|
@@ -979,7 +979,7 @@ describe("replacePlatformAssistants", () => {
|
|
|
979
979
|
],
|
|
980
980
|
});
|
|
981
981
|
|
|
982
|
-
|
|
982
|
+
replaceCloudAssistants(
|
|
983
983
|
[lockfilePath],
|
|
984
984
|
[
|
|
985
985
|
{
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
resolveCloud,
|
|
8
8
|
type Lockfile,
|
|
9
9
|
} from "./lockfile-contract";
|
|
10
|
-
import {
|
|
10
|
+
import { isCloudHome } from "./lockfile-contract";
|
|
11
11
|
import { withLockfileLock } from "./lockfile-lock";
|
|
12
12
|
import { stripSensitiveFields } from "./util";
|
|
13
13
|
|
|
@@ -377,17 +377,17 @@ export function isActiveAssistant(
|
|
|
377
377
|
return false;
|
|
378
378
|
}
|
|
379
379
|
|
|
380
|
-
export function
|
|
380
|
+
export function replaceCloudAssistants(
|
|
381
381
|
lockfilePaths: string[],
|
|
382
|
-
|
|
382
|
+
cloudAssistants: Array<Record<string, unknown>>,
|
|
383
383
|
organizationId?: string,
|
|
384
384
|
): WriteResult {
|
|
385
385
|
if (
|
|
386
|
-
|
|
386
|
+
cloudAssistants.some(
|
|
387
387
|
(assistant) =>
|
|
388
388
|
typeof assistant?.assistantId !== "string" ||
|
|
389
389
|
assistant.assistantId === "" ||
|
|
390
|
-
!
|
|
390
|
+
!isCloudHome(resolveCloud(assistant)) ||
|
|
391
391
|
assistant.paired === true,
|
|
392
392
|
)
|
|
393
393
|
) {
|
|
@@ -403,14 +403,14 @@ export function replacePlatformAssistants(
|
|
|
403
403
|
const existing = Array.isArray(lockfile.assistants)
|
|
404
404
|
? lockfile.assistants
|
|
405
405
|
: [];
|
|
406
|
-
const syncedIds = new Set(
|
|
406
|
+
const syncedIds = new Set(cloudAssistants.map((a) => a.assistantId));
|
|
407
407
|
// Org-scoped sync preserves other orgs' platform entries; no org full-replaces.
|
|
408
408
|
const preserved = existing.filter((a: Record<string, unknown>) => {
|
|
409
|
-
if (!
|
|
409
|
+
if (!isCloudHome(a?.cloud)) return true;
|
|
410
410
|
if (syncedIds.has(a.assistantId)) return false;
|
|
411
411
|
return organizationId != null && a.organizationId !== organizationId;
|
|
412
412
|
});
|
|
413
|
-
// `onboardedAt` is recorded by the client and unknown to the
|
|
413
|
+
// `onboardedAt` is recorded by the client and unknown to the cloud, so
|
|
414
414
|
// the replacement rows never carry it. Without this it is erased by every
|
|
415
415
|
// routine session sync.
|
|
416
416
|
const priorOnboardedAt = new Map<string, unknown>();
|
|
@@ -421,7 +421,7 @@ export function replacePlatformAssistants(
|
|
|
421
421
|
}
|
|
422
422
|
lockfile.assistants = [
|
|
423
423
|
...preserved,
|
|
424
|
-
...
|
|
424
|
+
...cloudAssistants.map((a) => {
|
|
425
425
|
const prior = priorOnboardedAt.get(a.assistantId as string);
|
|
426
426
|
return a.onboardedAt == null && prior != null
|
|
427
427
|
? { ...a, onboardedAt: prior }
|
|
@@ -393,10 +393,10 @@ export function pairAssistant(
|
|
|
393
393
|
// while imports never silently overwrite a non-paired assistant (see
|
|
394
394
|
// guard above).
|
|
395
395
|
paired: true,
|
|
396
|
-
// A re-pair may point at a different gateway, so the
|
|
396
|
+
// A re-pair may point at a different gateway, so the cloud id the
|
|
397
397
|
// web resolver cached for the old target is dropped; the upsert merge
|
|
398
398
|
// would otherwise keep it and the resolver would never re-probe.
|
|
399
|
-
|
|
399
|
+
cloudAssistantId: undefined,
|
|
400
400
|
},
|
|
401
401
|
undefined,
|
|
402
402
|
);
|
|
@@ -14,7 +14,7 @@ export type RetireResult =
|
|
|
14
14
|
| { ok: false; status: number; error: string };
|
|
15
15
|
|
|
16
16
|
export interface RetireOptions {
|
|
17
|
-
|
|
17
|
+
cloudToken?: string;
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
export function runRetire(
|
|
@@ -27,11 +27,11 @@ export function runRetire(
|
|
|
27
27
|
invocation.command,
|
|
28
28
|
[...invocation.baseArgs, "retire", assistantId, "--yes"],
|
|
29
29
|
{
|
|
30
|
-
...(options.
|
|
30
|
+
...(options.cloudToken
|
|
31
31
|
? {
|
|
32
32
|
env: {
|
|
33
33
|
...process.env,
|
|
34
|
-
CADET_PLATFORM_TOKEN: options.
|
|
34
|
+
CADET_PLATFORM_TOKEN: options.cloudToken,
|
|
35
35
|
},
|
|
36
36
|
}
|
|
37
37
|
: {}),
|