@vellumai/cli 0.10.8-dev.202607152039.bc8b1a6 → 0.10.8-staging.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.
@@ -1,12 +1,6 @@
1
1
  import { describe, expect, test } from "bun:test";
2
- import fs from "node:fs";
3
- import os from "node:os";
4
- import path from "node:path";
5
2
 
6
- import {
7
- readAllowedGatewayPorts,
8
- resolveGatewayProxyTarget,
9
- } from "../gateway-proxy";
3
+ import { resolveGatewayProxyTarget } from "../gateway-proxy";
10
4
 
11
5
  const allow =
12
6
  (...ports: number[]) =>
@@ -70,41 +64,6 @@ describe("resolveGatewayProxyTarget", () => {
70
64
  });
71
65
  });
72
66
 
73
- test("allowlists ports from resources, loopback URLs, and docker runtimeUrls — never remote URLs", () => {
74
- const dir = fs.mkdtempSync(path.join(os.tmpdir(), "gateway-proxy-test-"));
75
- const lockfilePath = path.join(dir, "assistants.json");
76
- try {
77
- fs.writeFileSync(
78
- lockfilePath,
79
- JSON.stringify({
80
- assistants: [
81
- { assistantId: "local-a", resources: { gatewayPort: 7830 } },
82
- { assistantId: "local-b", localUrl: "http://127.0.0.1:7831" },
83
- // Docker entries record their published gateway only as a
84
- // loopback runtimeUrl.
85
- {
86
- assistantId: "docker-a",
87
- cloud: "docker",
88
- runtimeUrl: "http://localhost:7930",
89
- },
90
- // Remote runtimeUrls (managed / gcp / paired) must never widen
91
- // the allowlist.
92
- {
93
- assistantId: "remote-a",
94
- cloud: "gcp",
95
- runtimeUrl: "https://assistant.example.com:8443",
96
- },
97
- ],
98
- }),
99
- );
100
- expect(readAllowedGatewayPorts([lockfilePath])).toEqual(
101
- new Set([7830, 7831, 7930]),
102
- );
103
- } finally {
104
- fs.rmSync(dir, { recursive: true, force: true });
105
- }
106
- });
107
-
108
67
  test("never reads the allowlist for non-gateway or invalid-port paths", () => {
109
68
  let reads = 0;
110
69
  const counting = () => {
@@ -87,7 +87,6 @@ export function readAllowedGatewayPorts(lockfilePaths: string[]): Set<number> {
87
87
  assistants?: Array<{
88
88
  gatewayUrl?: unknown;
89
89
  localUrl?: unknown;
90
- runtimeUrl?: unknown;
91
90
  resources?: { gatewayPort?: unknown };
92
91
  }>;
93
92
  };
@@ -96,10 +95,6 @@ export function readAllowedGatewayPorts(lockfilePaths: string[]): Set<number> {
96
95
  if (!assistant) continue;
97
96
  addPortFromUrl(assistant.gatewayUrl, ports);
98
97
  addPortFromUrl(assistant.localUrl, ports);
99
- // Docker entries record their published gateway as a loopback
100
- // `runtimeUrl` with no `resources` block; the loopback-hostname filter
101
- // in addPortFromUrl keeps remote runtimeUrls out of the allowlist.
102
- addPortFromUrl(assistant.runtimeUrl, ports);
103
98
  const gp = assistant.resources?.gatewayPort;
104
99
  if (typeof gp === "number" && Number.isInteger(gp) && gp >= 1024 && gp <= 65535) {
105
100
  ports.add(gp);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vellumai/cli",
3
- "version": "0.10.8-dev.202607152039.bc8b1a6",
3
+ "version": "0.10.8-staging.1",
4
4
  "description": "CLI tools for vellum-assistant",
5
5
  "type": "module",
6
6
  "exports": {
@@ -7,7 +7,6 @@ import {
7
7
  AVATAR_DEVICE_ENV_VAR,
8
8
  collectWatchTargets,
9
9
  dockerResourceNames,
10
- ensureDockerDaemonRunning,
11
10
  resolveAvatarDevicePath,
12
11
  resolveDockerHatchMode,
13
12
  resolveDockerProviderCredentialSetupAction,
@@ -381,58 +380,3 @@ describe("collectWatchTargets", () => {
381
380
  expect(files).toEqual([join(repoRoot, "gateway", "package.json")]);
382
381
  });
383
382
  });
384
-
385
- /**
386
- * Build a fake `exec` that records calls and fails the probes named in `fail`.
387
- * Injected into `ensureDockerDaemonRunning` so these cases need no `mock.module`
388
- * (which is process-global and would leak across the CLI's single-process test
389
- * run) and no real Docker/Colima subprocesses.
390
- */
391
- function fakeExec(fail: { dockerInfo?: boolean; colimaStatus?: boolean }) {
392
- const calls: Array<{ cmd: string; args: string[] }> = [];
393
- const exec = async (cmd: string, args: string[] = []): Promise<void> => {
394
- calls.push({ cmd, args });
395
- if (cmd === "docker" && args[0] === "info" && fail.dockerInfo) {
396
- throw new Error("Cannot connect to the Docker daemon");
397
- }
398
- if (cmd === "colima" && args[0] === "status" && fail.colimaStatus) {
399
- throw new Error("colima is not running");
400
- }
401
- };
402
- const ran = (cmd: string, sub: string): boolean =>
403
- calls.some((c) => c.cmd === cmd && c.args[0] === sub);
404
- return { exec: exec as typeof import("../step-runner.js").exec, ran };
405
- }
406
-
407
- describe("ensureDockerDaemonRunning", () => {
408
- // Regression: waking an instance hatched under Docker Desktop must NOT start
409
- // Colima, because that switches the active `docker context` and points
410
- // `docker start` at a VM that never held the instance's containers.
411
- test("reuses an already-reachable daemon (e.g. Docker Desktop) and never touches Colima", async () => {
412
- const { exec, ran } = fakeExec({ dockerInfo: false });
413
-
414
- await ensureDockerDaemonRunning(exec);
415
-
416
- expect(ran("docker", "info")).toBe(true);
417
- expect(ran("colima", "status")).toBe(false);
418
- expect(ran("colima", "start")).toBe(false);
419
- });
420
-
421
- test("starts Colima only when no daemon is reachable", async () => {
422
- const { exec, ran } = fakeExec({ dockerInfo: true, colimaStatus: true });
423
-
424
- await ensureDockerDaemonRunning(exec);
425
-
426
- expect(ran("docker", "info")).toBe(true);
427
- expect(ran("colima", "start")).toBe(true);
428
- });
429
-
430
- test("does not restart Colima when it is already running", async () => {
431
- const { exec, ran } = fakeExec({ dockerInfo: true, colimaStatus: false });
432
-
433
- await ensureDockerDaemonRunning(exec);
434
-
435
- expect(ran("colima", "status")).toBe(true);
436
- expect(ran("colima", "start")).toBe(false);
437
- });
438
- });
package/src/lib/docker.ts CHANGED
@@ -776,12 +776,12 @@ export async function sleepContainers(
776
776
  }
777
777
  }
778
778
 
779
- /** Start existing stopped containers, ensuring a Docker daemon is up first (macOS only). */
779
+ /** Start existing stopped containers, starting Colima first if it isn't running (macOS only). */
780
780
  export async function wakeContainers(
781
781
  res: ReturnType<typeof dockerResourceNames>,
782
782
  ): Promise<void> {
783
783
  if (platform() !== "linux") {
784
- await ensureDockerDaemonRunning();
784
+ await ensureColimaRunning();
785
785
  }
786
786
  for (const container of [
787
787
  res.assistantContainer,
@@ -793,42 +793,16 @@ export async function wakeContainers(
793
793
  }
794
794
 
795
795
  /**
796
- * Ensure a Docker daemon is reachable before waking an instance's containers
797
- * (macOS only on Linux the daemon runs natively).
798
- *
799
- * If a daemon is already reachable, reuse it and return: `hatch` created the
800
- * containers under whatever `docker context` was active at the time (Docker
801
- * Desktop, an already-running Colima, a remote context, …), and `docker start`
802
- * targets the active context. Unconditionally starting Colima would switch the
803
- * active context to `colima` and point `docker start` at a VM that never held
804
- * those containers — so Colima is only started as a fallback when no daemon is
805
- * reachable at all (the toolchain `hatch` installs on macOS when Docker Desktop
806
- * isn't present). This mirrors {@link ensureDockerInstalled}, which likewise
807
- * only starts Colima when `docker info` fails.
808
- *
809
- * `execFn` is injectable so unit tests can drive the probe outcomes without a
810
- * real Docker/Colima toolchain; production callers use the real {@link exec}.
811
- * Assumes the toolchain is already installed (handled during hatch).
796
+ * Checks whether Colima is running and starts it if not.
797
+ * Assumes the Docker/Colima toolchain is already installed (handled during hatch).
812
798
  */
813
- export async function ensureDockerDaemonRunning(
814
- execFn: typeof exec = exec,
815
- ): Promise<void> {
799
+ async function ensureColimaRunning(): Promise<void> {
816
800
  ensureLocalBinOnPath();
817
-
818
- // A reachable daemon — Docker Desktop, a running Colima, or any other active
819
- // context — is exactly what hatch used. Reuse it rather than forcing Colima.
820
- try {
821
- await execFn("docker", ["info"]);
822
- return;
823
- } catch {
824
- // No daemon reachable — fall through to the Colima fallback below.
825
- }
826
-
827
801
  try {
828
- await execFn("colima", ["status"]);
802
+ await exec("colima", ["status"]);
829
803
  } catch {
830
- console.log("🚀 Docker daemon not running. Starting Colima...");
831
- await execFn("colima", ["start"]);
804
+ console.log("🚀 Colima is not running. Starting Colima...");
805
+ await exec("colima", ["start"]);
832
806
  }
833
807
  }
834
808
 
@@ -176,11 +176,6 @@ export function inferProviderFromModel(model: string): string | undefined {
176
176
  if (model.startsWith("accounts/fireworks/models/")) {
177
177
  return "fireworks";
178
178
  }
179
- if (model.startsWith("openai/gpt-5.6")) {
180
- // Listed by OpenRouter (#37856), the earlier catalog entry; the Vercel
181
- // AI Gateway does not carry these IDs.
182
- return "openrouter";
183
- }
184
179
  if (model.startsWith("openai/") || model.startsWith("xai/")) {
185
180
  return "vercel-ai-gateway";
186
181
  }