@mycadet/cli 0.13.0-dev.202610192312.0264b52 → 0.13.0-dev.202610201855.522ff0d

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.
Files changed (80) hide show
  1. package/node_modules/@mycadet/assistant-api/constants/personality-sliders.test.ts +0 -8
  2. package/node_modules/@mycadet/assistant-api/constants/personality-sliders.ts +5 -41
  3. package/node_modules/@mycadet/assistant-api/events/message-complete.ts +0 -5
  4. package/node_modules/@mycadet/assistant-api/index.ts +0 -2
  5. package/node_modules/@mycadet/assistant-api/responses/conversation-message.ts +0 -10
  6. package/node_modules/@mycadet/environments/src/seeds.ts +6 -2
  7. package/node_modules/@mycadet/local-mode/node_modules/@mycadet/environments/src/seeds.ts +6 -2
  8. package/node_modules/@mycadet/local-mode/src/config.ts +0 -2
  9. package/node_modules/@mycadet/local-mode/src/index.ts +1 -1
  10. package/node_modules/@mycadet/local-mode/src/lockfile-contract.test.ts +1 -22
  11. package/node_modules/@mycadet/local-mode/src/lockfile-contract.ts +26 -7
  12. package/node_modules/@mycadet/local-mode/src/util.ts +1 -20
  13. package/node_modules/@mycadet/shared/github-repository.ts +5 -0
  14. package/node_modules/@mycadet/shared/package.json +10 -0
  15. package/node_modules/@mycadet/shared/scripts/run-isolated-tests.ts +700 -0
  16. package/package.json +3 -2
  17. package/src/__tests__/app-command.test.ts +164 -0
  18. package/src/__tests__/client-web-config.test.ts +1 -1
  19. package/src/__tests__/cloud-releases.test.ts +1 -1
  20. package/src/__tests__/local-version.test.ts +16 -0
  21. package/src/__tests__/nginx-ingress.test.ts +248 -630
  22. package/src/__tests__/ps-cloud-status.test.ts +85 -11
  23. package/src/__tests__/root-process-lockfile.test.ts +29 -2
  24. package/src/__tests__/tunnel-holder-heal.test.ts +119 -0
  25. package/src/__tests__/tunnel-stop.test.ts +6 -13
  26. package/src/__tests__/tunnel.test.ts +50 -193
  27. package/src/__tests__/wake.test.ts +6 -38
  28. package/src/__tests__/web-dist.test.ts +267 -89
  29. package/src/commands/app.ts +113 -0
  30. package/src/commands/backup.ts +5 -4
  31. package/src/commands/clean.ts +2 -1
  32. package/src/commands/client.ts +14 -80
  33. package/src/commands/completions.ts +12 -1
  34. package/src/commands/connect.ts +2 -1
  35. package/src/commands/debug.ts +2 -1
  36. package/src/commands/exec.ts +7 -6
  37. package/src/commands/gateway/token.ts +2 -1
  38. package/src/commands/gateway.ts +2 -1
  39. package/src/commands/hatch.ts +74 -80
  40. package/src/commands/login.ts +7 -6
  41. package/src/commands/logs.ts +2 -1
  42. package/src/commands/ps.ts +136 -6
  43. package/src/commands/restart.ts +2 -1
  44. package/src/commands/restore.ts +10 -9
  45. package/src/commands/retire.ts +4 -3
  46. package/src/commands/setup.ts +5 -4
  47. package/src/commands/sleep.ts +3 -2
  48. package/src/commands/teleport.ts +2 -1
  49. package/src/commands/terminal.ts +7 -6
  50. package/src/commands/tunnel.ts +196 -242
  51. package/src/commands/uninstall.ts +2 -1
  52. package/src/commands/upgrade.ts +2 -1
  53. package/src/commands/use.ts +2 -1
  54. package/src/commands/wake.ts +3 -2
  55. package/src/index.ts +5 -4
  56. package/src/lib/__tests__/web-dist.test.ts +1 -27
  57. package/src/lib/assistant-config.ts +101 -37
  58. package/src/lib/cli-name.ts +14 -0
  59. package/src/lib/cloud-client.ts +2 -1
  60. package/src/lib/cloud-login-poll.ts +2 -1
  61. package/src/lib/cloud-releases.ts +1 -1
  62. package/src/lib/docker.ts +32 -21
  63. package/src/lib/hatch-local.ts +1 -3
  64. package/src/lib/hatch-next-steps.ts +1 -9
  65. package/src/lib/ingress-config.ts +0 -31
  66. package/src/lib/local-version.ts +25 -4
  67. package/src/lib/local.ts +34 -9
  68. package/src/lib/nginx-ingress.ts +143 -244
  69. package/src/lib/provider-secrets.ts +0 -5
  70. package/src/lib/statefulset.ts +0 -1
  71. package/src/lib/tunnel.ts +244 -43
  72. package/src/lib/tunnels/ngrok.ts +57 -9
  73. package/src/lib/tunnels/tailscale.ts +2 -1
  74. package/src/lib/web-dist.ts +134 -56
  75. package/src/__tests__/flags.test.ts +0 -318
  76. package/src/__tests__/shell-mode.test.ts +0 -83
  77. package/src/commands/flags.ts +0 -255
  78. package/src/lib/flag-args.test.ts +0 -84
  79. package/src/lib/flag-args.ts +0 -74
  80. package/src/lib/github-repository.ts +0 -2
@@ -1,8 +1,6 @@
1
1
  import { describe, expect, test } from "bun:test";
2
2
 
3
3
  import {
4
- PERSONALITY_AXIS_IDS,
5
- PERSONALITY_DIRECTION_AXES,
6
4
  PERSONALITY_SLIDER_DEFAULT,
7
5
  PERSONALITY_SLIDERS_PATH,
8
6
  } from "./personality-sliders.js";
@@ -12,10 +10,4 @@ describe("personality slider contract", () => {
12
10
  expect(PERSONALITY_SLIDERS_PATH).toBe("data/personality-sliders.json");
13
11
  expect(PERSONALITY_SLIDER_DEFAULT).toBe(50);
14
12
  });
15
-
16
- test("every slider axis has a left and right direction pole", () => {
17
- expect(PERSONALITY_DIRECTION_AXES.map((axis) => axis.sliderId)).toEqual(
18
- Object.values(PERSONALITY_AXIS_IDS),
19
- );
20
- });
21
13
  });
@@ -1,16 +1,15 @@
1
1
  /**
2
- * Personality slider sidecar path, the five 0-100 axis ids, and the
3
- * hosted-Qwen direction poles those sliders map onto.
2
+ * Personality slider sidecar path and the five 0-100 axis ids.
4
3
  *
5
- * The web writes `data/personality-sliders.json`. The assistant reads the
6
- * same path and maps each slider onto one left/right pole. Both import
7
- * these constants from `@mycadet/assistant-api` so the ids cannot drift.
4
+ * The web writes `data/personality-sliders.json` so the sliders reopen where
5
+ * the user left them. Both sides import these constants from
6
+ * `@mycadet/assistant-api` so the ids cannot drift.
8
7
  */
9
8
 
10
9
  /** Workspace-relative sidecar holding the five 0-100 slider values. */
11
10
  export const PERSONALITY_SLIDERS_PATH = "data/personality-sliders.json";
12
11
 
13
- /** Sliders start centered. Center is no steer on the hosted-Qwen route. */
12
+ /** Sliders start centered. */
14
13
  export const PERSONALITY_SLIDER_DEFAULT = 50;
15
14
 
16
15
  /**
@@ -27,38 +26,3 @@ export const PERSONALITY_AXIS_IDS = {
27
26
 
28
27
  export type PersonalityAxisId =
29
28
  (typeof PERSONALITY_AXIS_IDS)[keyof typeof PERSONALITY_AXIS_IDS];
30
-
31
- /**
32
- * One-sided direction poles for each slider. Center (50) activates neither.
33
- * Values below 50 activate `left`; values above 50 activate `right`.
34
- */
35
- export const PERSONALITY_DIRECTION_AXES = [
36
- {
37
- sliderId: PERSONALITY_AXIS_IDS.companionCoworker,
38
- left: "companion",
39
- right: "coworker",
40
- },
41
- {
42
- sliderId: PERSONALITY_AXIS_IDS.genzBoomer,
43
- left: "genz",
44
- right: "boomer",
45
- },
46
- {
47
- sliderId: PERSONALITY_AXIS_IDS.executeCollaborate,
48
- left: "independent",
49
- right: "collaborative",
50
- },
51
- {
52
- sliderId: PERSONALITY_AXIS_IDS.playfulSerious,
53
- left: "playful",
54
- right: "serious",
55
- },
56
- {
57
- sliderId: PERSONALITY_AXIS_IDS.politeUnfiltered,
58
- left: "polite",
59
- right: "unfiltered",
60
- },
61
- ] as const;
62
-
63
- export type PersonalityDirectionAxis =
64
- (typeof PERSONALITY_DIRECTION_AXES)[number];
@@ -37,11 +37,6 @@ export const MessageCompleteEventSchema = z.object({
37
37
  /** Soft warnings produced while resolving attachments (e.g. format
38
38
  * conversions, size truncations). Display-only — not blocking. */
39
39
  attachmentWarnings: z.array(z.string()).optional(),
40
- /** How the completed row's plain text reached the user, mirroring the field
41
- * of the same name on `ConversationMessage`. Set only on a turn that routed
42
- * its reply through the `send_user_message` tool, so a client can give the
43
- * live row the same per-row treatment it will get from history. */
44
- assistantTextVisibility: z.enum(["private", "visible"]).optional(),
45
40
  /** The default profile the Auto profile routed this turn to, mirroring the
46
41
  * field of the same name on `ConversationMessage`. Set only on a turn that
47
42
  * ran on Auto, so the live row can show which profile answered. */
@@ -163,11 +163,9 @@ export {
163
163
  } from "./constants/document-tools.js";
164
164
  export {
165
165
  PERSONALITY_AXIS_IDS,
166
- PERSONALITY_DIRECTION_AXES,
167
166
  PERSONALITY_SLIDER_DEFAULT,
168
167
  PERSONALITY_SLIDERS_PATH,
169
168
  type PersonalityAxisId,
170
- type PersonalityDirectionAxis,
171
169
  } from "./constants/personality-sliders.js";
172
170
  export {
173
171
  MIN_INPUT_RESERVE_TOKENS,
@@ -633,16 +633,6 @@ export const ConversationMessageSchema = z.object({
633
633
  * into the following user message. Absent on shutter photos, spoken turns
634
634
  * carrying parked frames, and every other row. */
635
635
  cameraFrame: z.literal(true).optional(),
636
- /** How this assistant row's plain text reached the user, set only on a turn
637
- * that routed its reply through the `send_user_message` tool. `"private"`
638
- * means the row's text blocks are the model's working notes and the text
639
- * the client shows came from the tool call; `"visible"` means the turn
640
- * ended without ever calling the tool, so its raw text was surfaced as the
641
- * fallback and is the reply. Absent on every other row. Clients gate
642
- * per-row presentation (e.g. collapsing intermediate activity) on this
643
- * rather than on the feature flag, so a row keeps the treatment it was
644
- * written with. */
645
- assistantTextVisibility: z.enum(["private", "visible"]).optional(),
646
636
  /** Present on a reaction row, either direction: an inbound reaction the
647
637
  * daemon persisted, or the assistant's own (`selfAuthored`). Clients
648
638
  * render a reaction line from this instead of the row's stored sentinel
@@ -41,9 +41,13 @@ function portBlock(base: number): PortMap {
41
41
  * package index's `.js`-suffixed runtime re-exports. Keep this file's
42
42
  * imports type-only so it stays loadable on its own.
43
43
  */
44
- export function cloudAssistantHubUrl(envName: string | undefined): string {
44
+ export function cloudWebUrl(envName: string | undefined): string {
45
45
  const seed = (envName && SEEDS[envName]) || SEEDS.dev;
46
- return `${seed.webUrl}/assistant`;
46
+ return seed.webUrl;
47
+ }
48
+
49
+ export function cloudAssistantHubUrl(envName: string | undefined): string {
50
+ return `${cloudWebUrl(envName)}/assistant`;
47
51
  }
48
52
 
49
53
  /**
@@ -41,9 +41,13 @@ function portBlock(base: number): PortMap {
41
41
  * package index's `.js`-suffixed runtime re-exports. Keep this file's
42
42
  * imports type-only so it stays loadable on its own.
43
43
  */
44
- export function cloudAssistantHubUrl(envName: string | undefined): string {
44
+ export function cloudWebUrl(envName: string | undefined): string {
45
45
  const seed = (envName && SEEDS[envName]) || SEEDS.dev;
46
- return `${seed.webUrl}/assistant`;
46
+ return seed.webUrl;
47
+ }
48
+
49
+ export function cloudAssistantHubUrl(envName: string | undefined): string {
50
+ return `${cloudWebUrl(envName)}/assistant`;
47
51
  }
48
52
 
49
53
  /**
@@ -16,7 +16,6 @@ const PRODUCTION_ENVIRONMENT_NAME = "production";
16
16
  export interface LocalEndpointConfig {
17
17
  lockfilePaths: string[];
18
18
  configDir: string;
19
- webUrl: string;
20
19
  cloudUrl: string;
21
20
  }
22
21
 
@@ -35,7 +34,6 @@ export function resolveLocalConfigFromEnv(
35
34
  return {
36
35
  lockfilePaths: resolveLockfilePaths(env, options),
37
36
  configDir: resolveConfigDir(env, options),
38
- webUrl: env.CADET_WEB_URL || seed.webUrl,
39
37
  cloudUrl: env.CADET_CLOUD_URL || seed.cloudUrl,
40
38
  };
41
39
  }
@@ -54,7 +54,7 @@ export {
54
54
  export type { LockfileResult, WriteResult } from "./lockfile";
55
55
  export { withLockfileLock } from "./lockfile-lock";
56
56
  export type { LockfileLockResult } from "./lockfile-lock";
57
- export { parseLockfile } from "./lockfile-contract";
57
+ export { getLoopbackGatewayPort, parseLockfile } from "./lockfile-contract";
58
58
  export type {
59
59
  Lockfile,
60
60
  LockfileAssistant,
@@ -20,7 +20,6 @@ describe("parseLockfile", () => {
20
20
  cloud: "cadet",
21
21
  runtimeUrl: "http://127.0.0.1:7777",
22
22
  hatchedAt: "2026-01-01T00:00:00.000Z",
23
- organizationId: "org_1",
24
23
  cloudAssistantId: "platform-assistant-1",
25
24
  cloudBaseUrl: "https://platform.example.com",
26
25
  cloudOrganizationId: "org_1",
@@ -169,24 +168,6 @@ describe("parseLockfile", () => {
169
168
  expect(parseLockfile(raw).assistants).toEqual([]);
170
169
  });
171
170
 
172
- test("keeps organizationId on platform entries and drops it when mistyped", () => {
173
- // Platform assistants carry their owning org so the host proxy can scope
174
- // requests without guessing; local entries simply omit it.
175
- const raw = {
176
- assistants: [
177
- { assistantId: "asst_1", cloud: "cadet", organizationId: "org_1" },
178
- { assistantId: "asst_2", cloud: "cadet", organizationId: 7 }, // mistyped
179
- { assistantId: "asst_3", cloud: "local" }, // local, no org
180
- ],
181
- activeAssistant: null,
182
- };
183
- expect(parseLockfile(raw).assistants).toEqual([
184
- { assistantId: "asst_1", cloud: "cadet", organizationId: "org_1" },
185
- { assistantId: "asst_2", cloud: "cadet" },
186
- { assistantId: "asst_3", cloud: "local" },
187
- ]);
188
- });
189
-
190
171
  test("keeps a well-typed ingressUrl and drops it when mistyped", () => {
191
172
  // The tunnel-recorded public URL rides the entry so remote-web pairing
192
173
  // surfaces can prefill it; a mistyped value is dropped, entry preserved.
@@ -312,9 +293,7 @@ describe("parseLockfile", () => {
312
293
 
313
294
  test("prefers an explicit cloud over legacy remote markers", () => {
314
295
  const raw = {
315
- assistants: [
316
- { assistantId: "a", cloud: "cadet", project: "stale-proj" },
317
- ],
296
+ assistants: [{ assistantId: "a", cloud: "cadet", project: "stale-proj" }],
318
297
  activeAssistant: null,
319
298
  };
320
299
  expect(parseLockfile(raw).assistants).toEqual([
@@ -61,6 +61,32 @@ export const SENSITIVE_KEYS = [
61
61
  "guardianBootstrapSecret",
62
62
  ] as const;
63
63
 
64
+ /**
65
+ * Strip every `SENSITIVE_KEYS` field from a parsed lockfile, in place: from
66
+ * each assistant entry and from that entry's `resources`. The one redaction
67
+ * every host runs before lockfile data crosses to the renderer — pure, no
68
+ * node built-ins, so it lives beside the keys it enforces and bundles into
69
+ * the renderer through the `./contract` subpath.
70
+ */
71
+ export function stripSensitiveFields(data: Record<string, unknown>): void {
72
+ const assistants = data.assistants;
73
+ if (!Array.isArray(assistants)) return;
74
+ for (const assistant of assistants) {
75
+ if (assistant && typeof assistant === "object") {
76
+ const entry = assistant as Record<string, unknown>;
77
+ for (const field of SENSITIVE_KEYS) {
78
+ delete entry[field];
79
+ }
80
+ const resources = entry.resources;
81
+ if (resources && typeof resources === "object") {
82
+ for (const field of SENSITIVE_KEYS) {
83
+ delete (resources as Record<string, unknown>)[field];
84
+ }
85
+ }
86
+ }
87
+ }
88
+ }
89
+
64
90
  /**
65
91
  * Resolve an entry's deployment topology from its raw on-disk fields. Prefers
66
92
  * an explicit `cloud`, then the legacy markers that predate the field
@@ -197,19 +223,12 @@ export const LockfileAssistantSchema = z.object({
197
223
  * `onboarded-assistant.ts`).
198
224
  */
199
225
  onboardedAt: z.string().optional(),
200
- /** Owning org for platform assistants; absent for local ones. */
201
- organizationId: z.string().optional(),
202
226
  /** Platform assistant UUID for a self-hosted local assistant registration. */
203
227
  cloudAssistantId: z.string().optional(),
204
228
  /** Platform base URL used for a self-hosted local assistant registration. */
205
229
  cloudBaseUrl: z.string().optional(),
206
230
  /** Platform organization UUID used for a self-hosted local assistant registration. */
207
231
  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(),
212
- platformOrganizationId: z.string().optional(),
213
232
  /**
214
233
  * Public https URL a `cadet tunnel` provider recorded for this assistant
215
234
  * (mirrored from the workspace ingress config). A public address, so it is
@@ -2,8 +2,6 @@ import fs from "node:fs";
2
2
  import { createRequire } from "node:module";
3
3
  import path from "node:path";
4
4
 
5
- import { SENSITIVE_KEYS } from "./lockfile-contract";
6
-
7
5
  const CLI_PACKAGE_NAME = "@mycadet/cli";
8
6
 
9
7
  /**
@@ -19,24 +17,7 @@ export interface CliInvocation {
19
17
  baseArgs: string[];
20
18
  }
21
19
 
22
- export function stripSensitiveFields(data: Record<string, unknown>): void {
23
- const assistants = data.assistants;
24
- if (!Array.isArray(assistants)) return;
25
- for (const assistant of assistants) {
26
- if (assistant && typeof assistant === "object") {
27
- const entry = assistant as Record<string, unknown>;
28
- for (const field of SENSITIVE_KEYS) {
29
- delete entry[field];
30
- }
31
- const resources = entry.resources;
32
- if (resources && typeof resources === "object") {
33
- for (const field of SENSITIVE_KEYS) {
34
- delete (resources as Record<string, unknown>)[field];
35
- }
36
- }
37
- }
38
- }
39
- }
20
+ export { stripSensitiveFields } from "./lockfile-contract";
40
21
 
41
22
  function isLoopbackHostname(hostname: string): boolean {
42
23
  const normalized = hostname.toLowerCase();
@@ -0,0 +1,5 @@
1
+ /** The GitHub repository Cadet's source and releases live in. */
2
+ export const CADET_GITHUB_REPOSITORY = "vargasjr-dev/mycadet-temp";
3
+
4
+ /** URL of the public GitHub repository. */
5
+ export const CADET_GITHUB_REPOSITORY_URL = `https://github.com/${CADET_GITHUB_REPOSITORY}`;
@@ -0,0 +1,10 @@
1
+ {
2
+ "name": "@mycadet/shared",
3
+ "version": "0.0.1",
4
+ "private": true,
5
+ "exports": {
6
+ ".": "./github-repository.ts",
7
+ "./github-repository": "./github-repository.ts",
8
+ "./scripts/run-isolated-tests": "./scripts/run-isolated-tests.ts"
9
+ }
10
+ }