@vellumai/cli 0.8.10-dev.202606092238.d04fd59 → 0.8.10

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vellumai/cli",
3
- "version": "0.8.10-dev.202606092238.d04fd59",
3
+ "version": "0.8.10",
4
4
  "description": "CLI tools for vellum-assistant",
5
5
  "type": "module",
6
6
  "exports": {
@@ -85,7 +85,6 @@ interface ParsedArgs {
85
85
  flagEnvVars: Record<string, string>;
86
86
  /** Parsed --flag overrides: kebab-case key -> typed value (for web injection). */
87
87
  parsedFlagOverrides: Record<string, boolean | string>;
88
- disablePlatform: boolean;
89
88
  }
90
89
 
91
90
  function readAssistantName(entry: AssistantEntry | null): string | undefined {
@@ -100,8 +99,6 @@ export function parseArgs(): ParsedArgs {
100
99
  const { envVars: cliFlagVars, remaining: argsWithoutFlags } =
101
100
  parseFeatureFlagArgs(process.argv.slice(3));
102
101
  const flagEnvVars = { ...readAmbientFlagEnvVars(), ...cliFlagVars };
103
- const disablePlatformAmbient = process.env.VELLUM_DISABLE_PLATFORM?.trim().toLowerCase();
104
- let disablePlatform = disablePlatformAmbient === "true" || disablePlatformAmbient === "1";
105
102
  const args = argsWithoutFlags;
106
103
 
107
104
  // Build parsedFlagOverrides from the extracted env vars:
@@ -136,8 +133,6 @@ export function parseArgs(): ParsedArgs {
136
133
  if (arg === "--help" || arg === "-h") {
137
134
  printUsage();
138
135
  process.exit(0);
139
- } else if (arg === "--disable-platform") {
140
- disablePlatform = true;
141
136
  } else if (
142
137
  (arg === "--url" ||
143
138
  arg === "-u" ||
@@ -257,7 +252,6 @@ export function parseArgs(): ParsedArgs {
257
252
  interfaceId,
258
253
  flagEnvVars,
259
254
  parsedFlagOverrides,
260
- disablePlatform,
261
255
  };
262
256
  }
263
257
 
@@ -278,7 +272,6 @@ ${ANSI.bold}OPTIONS:${ANSI.reset}
278
272
  -a, --assistant-id <id> Assistant ID
279
273
  -i, --interface <id> Interface identifier: cli (default) or web
280
274
  --flag <key=value> Feature flag override (repeatable, kebab-case key)
281
- --disable-platform Suppress all outbound platform API calls
282
275
  -h, --help Show this help message
283
276
 
284
277
  ${ANSI.bold}DEFAULTS:${ANSI.reset}
@@ -659,7 +652,6 @@ function getBaseDir(): string {
659
652
  async function runWebInterface(
660
653
  flagEnvVars: Record<string, string>,
661
654
  parsedFlagOverrides: Record<string, boolean | string>,
662
- disablePlatform: boolean,
663
655
  ): Promise<void> {
664
656
  // Propagate flag env vars so child processes (e.g. hatch from the web UI) inherit them.
665
657
  Object.assign(process.env, flagEnvVars);
@@ -668,7 +660,7 @@ async function runWebInterface(
668
660
  // (HMR, __local endpoints, gateway proxy).
669
661
  const webSourceDir = findWebSourceDir();
670
662
  if (webSourceDir) {
671
- return runViteDevServer(webSourceDir, flagEnvVars, disablePlatform);
663
+ return runViteDevServer(webSourceDir, flagEnvVars);
672
664
  }
673
665
 
674
666
  const distDir = findWebDistDir();
@@ -687,7 +679,7 @@ async function runWebInterface(
687
679
  const webUrl = getWebUrl();
688
680
  const safeJson = (v: unknown) =>
689
681
  JSON.stringify(v).replace(/</g, "\\u003c").replace(/>/g, "\\u003e");
690
- const configJson = safeJson({ webUrl, platformUrl, disablePlatform });
682
+ const configJson = safeJson({ webUrl, platformUrl });
691
683
  const hasOverrides = Object.keys(parsedFlagOverrides).length > 0;
692
684
  const flagOverridesSnippet = hasOverrides
693
685
  ? `;window.__VELLUM_FLAG_OVERRIDES__=${safeJson(parsedFlagOverrides)}`
@@ -822,7 +814,6 @@ async function runWebInterface(
822
814
  async function runViteDevServer(
823
815
  webSourceDir: string,
824
816
  flagEnvVars: Record<string, string>,
825
- disablePlatform: boolean,
826
817
  ): Promise<void> {
827
818
  const platformUrl = getPlatformUrl();
828
819
 
@@ -839,7 +830,6 @@ async function runViteDevServer(
839
830
  ...process.env,
840
831
  ...flagEnvVars,
841
832
  ...viteFlagVars,
842
- ...(disablePlatform ? { VITE_VELLUM_DISABLE_PLATFORM: "true" } : {}),
843
833
  VITE_PLATFORM_MODE: "false",
844
834
  API_PROXY_TARGET: platformUrl,
845
835
  VELLUM_WEB_URL: getWebUrl(),
@@ -919,15 +909,10 @@ export async function client(): Promise<void> {
919
909
  interfaceId,
920
910
  flagEnvVars,
921
911
  parsedFlagOverrides,
922
- disablePlatform,
923
912
  } = parseArgs();
924
913
 
925
- if (disablePlatform) {
926
- process.env.VELLUM_DISABLE_PLATFORM = "true";
927
- }
928
-
929
914
  if (interfaceId === WEB_INTERFACE_ID) {
930
- await runWebInterface(flagEnvVars, parsedFlagOverrides, disablePlatform);
915
+ await runWebInterface(flagEnvVars, parsedFlagOverrides);
931
916
  return;
932
917
  }
933
918
 
@@ -181,7 +181,6 @@ interface HatchArgs {
181
181
  configValues: Record<string, string>;
182
182
  flagEnvVars: Record<string, string>;
183
183
  analyze: boolean;
184
- disablePlatform: boolean;
185
184
  }
186
185
 
187
186
  function parseArgs(): HatchArgs {
@@ -189,8 +188,6 @@ function parseArgs(): HatchArgs {
189
188
  process.argv.slice(3),
190
189
  );
191
190
  const flagEnvVars = { ...readAmbientFlagEnvVars(), ...cliFlagVars };
192
- const disablePlatformAmbient = process.env.VELLUM_DISABLE_PLATFORM?.trim().toLowerCase();
193
- let disablePlatform = disablePlatformAmbient === "true" || disablePlatformAmbient === "1";
194
191
  let species: Species = DEFAULT_SPECIES;
195
192
  let detached = false;
196
193
  let keepAlive = false;
@@ -236,9 +233,6 @@ function parseArgs(): HatchArgs {
236
233
  console.log(
237
234
  " --analyze Emit a structured hatch-timing log line on stdout",
238
235
  );
239
- console.log(
240
- " --disable-platform Suppress all outbound platform API calls",
241
- );
242
236
  process.exit(0);
243
237
  } else if (arg === "-d") {
244
238
  detached = true;
@@ -299,13 +293,11 @@ function parseArgs(): HatchArgs {
299
293
  const value = next.slice(eqIndex + 1);
300
294
  configValues[key] = value;
301
295
  i++;
302
- } else if (arg === "--disable-platform") {
303
- disablePlatform = true;
304
296
  } else if (VALID_SPECIES.includes(arg as Species)) {
305
297
  species = arg as Species;
306
298
  } else {
307
299
  console.error(
308
- `Error: Unknown argument '${arg}'. Valid options: ${VALID_SPECIES.join(", ")}, -d, --watch, --source <path>, --keep-alive, --name <name>, --remote <${VALID_REMOTE_HOSTS.join("|")}>, --config <key=value>, --flag <key=value>, --analyze, --disable-platform`,
300
+ `Error: Unknown argument '${arg}'. Valid options: ${VALID_SPECIES.join(", ")}, -d, --watch, --source <path>, --keep-alive, --name <name>, --remote <${VALID_REMOTE_HOSTS.join("|")}>, --config <key=value>, --flag <key=value>, --analyze`,
309
301
  );
310
302
  process.exit(1);
311
303
  }
@@ -322,7 +314,6 @@ function parseArgs(): HatchArgs {
322
314
  configValues,
323
315
  flagEnvVars,
324
316
  analyze,
325
- disablePlatform,
326
317
  };
327
318
  }
328
319
 
@@ -558,14 +549,8 @@ export async function hatch(): Promise<void> {
558
549
  configValues,
559
550
  flagEnvVars,
560
551
  analyze,
561
- disablePlatform,
562
552
  } = parseArgs();
563
553
 
564
- if (disablePlatform) {
565
- process.env.VELLUM_DISABLE_PLATFORM = "true";
566
- flagEnvVars.VELLUM_DISABLE_PLATFORM = "true";
567
- }
568
-
569
554
  if (watch && remote !== "local" && remote !== "docker") {
570
555
  console.error(
571
556
  "Error: --watch is only supported for local and docker hatch targets.",
package/src/index.ts CHANGED
@@ -4,7 +4,6 @@ import cliPkg from "../package.json";
4
4
  import { backup } from "./commands/backup";
5
5
  import { clean } from "./commands/clean";
6
6
  import { client } from "./commands/client";
7
- import { confirm } from "./commands/confirm";
8
7
  import { connect } from "./commands/connect";
9
8
  import { devices } from "./commands/devices";
10
9
  import { env } from "./commands/env";
@@ -41,7 +40,6 @@ const commands = {
41
40
  backup,
42
41
  clean,
43
42
  client,
44
- confirm,
45
43
  connect,
46
44
  devices,
47
45
  env,
@@ -83,7 +81,6 @@ function printHelp(): void {
83
81
  console.log(" backup Export a backup of a running assistant");
84
82
  console.log(" clean Kill orphaned vellum processes");
85
83
  console.log(" client Connect to a hatched assistant");
86
- console.log(" confirm Resolve a pending tool confirmation on an assistant");
87
84
  console.log(" connect Import an assistant paired from another machine");
88
85
  console.log(" devices List or revoke devices paired to a local assistant");
89
86
  console.log(" env Manage the default CLI environment");
package/src/lib/docker.ts CHANGED
@@ -1323,10 +1323,6 @@ export async function hatchDocker(
1323
1323
  : ownSecret;
1324
1324
 
1325
1325
  emitProgress(4, 6, "Starting containers...");
1326
- if (flagEnvVars.VELLUM_DISABLE_PLATFORM) {
1327
- extraAssistantEnv.VELLUM_DISABLE_PLATFORM =
1328
- flagEnvVars.VELLUM_DISABLE_PLATFORM;
1329
- }
1330
1326
  const extraGatewayEnv =
1331
1327
  Object.keys(flagEnvVars).length > 0 ? flagEnvVars : undefined;
1332
1328
  await startContainers(
package/src/lib/local.ts CHANGED
@@ -961,7 +961,6 @@ export async function startLocalDaemon(
961
961
  "VELLUM_DEBUG",
962
962
  "VELLUM_DEV",
963
963
  "VELLUM_DESKTOP_APP",
964
- "VELLUM_DISABLE_PLATFORM",
965
964
  "VELLUM_WORKSPACE_DIR",
966
965
  ]) {
967
966
  if (process.env[key]) {
@@ -1,85 +0,0 @@
1
- import { describe, test, expect } from "bun:test";
2
-
3
- import { parseConfirmArgs } from "../commands/confirm.js";
4
-
5
- describe("parseConfirmArgs", () => {
6
- test("parses a request id with the active assistant and defaults to allow", () => {
7
- const r = parseConfirmArgs(["--request-id", "req-1"]);
8
- expect(r).toEqual({
9
- ok: true,
10
- value: {
11
- assistantId: undefined,
12
- requestId: "req-1",
13
- decision: "allow",
14
- jsonOutput: false,
15
- },
16
- });
17
- });
18
-
19
- test("parses an explicit assistant plus request id", () => {
20
- const r = parseConfirmArgs(["my-assistant", "--request-id", "req-1"]);
21
- expect(r.ok).toBe(true);
22
- if (!r.ok) return;
23
- expect(r.value.assistantId).toBe("my-assistant");
24
- expect(r.value.requestId).toBe("req-1");
25
- });
26
-
27
- test("honors an explicit deny decision", () => {
28
- const r = parseConfirmArgs(["--request-id", "req-1", "--decision", "deny"]);
29
- expect(r.ok).toBe(true);
30
- if (!r.ok) return;
31
- expect(r.value.decision).toBe("deny");
32
- });
33
-
34
- test("requires a request id", () => {
35
- const r = parseConfirmArgs([]);
36
- expect(r).toEqual({ ok: false, error: "--request-id is required." });
37
- });
38
-
39
- test("rejects an unknown decision", () => {
40
- const r = parseConfirmArgs([
41
- "--request-id",
42
- "req-1",
43
- "--decision",
44
- "maybe",
45
- ]);
46
- expect(r).toEqual({
47
- ok: false,
48
- error: '--decision must be "allow" or "deny" (got "maybe").',
49
- });
50
- });
51
-
52
- test("rejects a value-less --decision instead of defaulting to allow", () => {
53
- // A trailing `--decision` with no value (e.g. an empty shell expansion)
54
- // must not silently approve via the "allow" default.
55
- const r = parseConfirmArgs(["--request-id", "req-1", "--decision"]);
56
- expect(r).toEqual({
57
- ok: false,
58
- error: '--decision requires a value ("allow" or "deny").',
59
- });
60
- });
61
-
62
- test("rejects an empty-string --decision value", () => {
63
- const r = parseConfirmArgs(["--request-id", "req-1", "--decision", ""]);
64
- expect(r).toEqual({
65
- ok: false,
66
- error: '--decision must be "allow" or "deny" (got "").',
67
- });
68
- });
69
-
70
- test("rejects a value-less --request-id", () => {
71
- const r = parseConfirmArgs(["--request-id"]);
72
- expect(r).toEqual({
73
- ok: false,
74
- error: "--request-id requires a value.",
75
- });
76
- });
77
-
78
- test("preserves --json alongside the request id", () => {
79
- const r = parseConfirmArgs(["--json", "--request-id", "req-1"]);
80
- expect(r.ok).toBe(true);
81
- if (!r.ok) return;
82
- expect(r.value.jsonOutput).toBe(true);
83
- expect(r.value.requestId).toBe("req-1");
84
- });
85
- });
@@ -1,144 +0,0 @@
1
- /**
2
- * `vellum confirm <assistant> --request-id <id> --decision allow|deny`
3
- *
4
- * Resolve a pending tool confirmation on a running assistant via its
5
- * runtime HTTP API. The assistant raises a `confirmation_request` event
6
- * (with a `requestId`) when a tool exceeds the auto-approve risk
7
- * threshold; this command answers it so the turn can proceed. Headless
8
- * automation (e.g. the evals harness) uses it to approve requests that
9
- * would otherwise hang waiting for an interactive user.
10
- */
11
-
12
- import { extractFlag } from "../lib/arg-utils.js";
13
- import { AssistantClient } from "../lib/assistant-client.js";
14
-
15
- function printUsage(): void {
16
- console.log(`vellum confirm - Resolve a pending tool confirmation
17
-
18
- USAGE:
19
- vellum confirm [assistant] --request-id <id> [--decision allow|deny]
20
-
21
- ARGUMENTS:
22
- [assistant] Instance name (default: active assistant)
23
-
24
- OPTIONS:
25
- --request-id <id> The requestId from the confirmation_request event (required)
26
- --decision <value> allow or deny (default: allow)
27
- --json Output raw JSON response
28
-
29
- EXAMPLES:
30
- vellum confirm --request-id ede263d9-cc45-4d63-86f8-a656d17b3a3a
31
- vellum confirm my-assistant --request-id req-1 --decision deny
32
- vellum confirm --json --request-id req-1
33
- `);
34
- }
35
-
36
- interface ParsedConfirmArgs {
37
- assistantId?: string;
38
- requestId: string;
39
- decision: "allow" | "deny";
40
- jsonOutput: boolean;
41
- }
42
-
43
- type ParseResult =
44
- | { ok: true; value: ParsedConfirmArgs }
45
- | { ok: false; error: string };
46
-
47
- /**
48
- * Parse `vellum confirm` arguments. Pure: does no I/O and never exits, so the
49
- * positional/flag rules can be unit-tested. Defaults the decision to `allow`,
50
- * which is the common automation case (approve and continue).
51
- */
52
- export function parseConfirmArgs(rawArgs: string[]): ParseResult {
53
- const jsonOutput = rawArgs.includes("--json");
54
- let args = rawArgs.filter((a) => a !== "--json");
55
-
56
- const requestIdFlagPresent = args.includes("--request-id");
57
- const [requestId, afterRequestId] = extractFlag(args, "--request-id");
58
- args = afterRequestId;
59
-
60
- const decisionFlagPresent = args.includes("--decision");
61
- const [decisionRaw, afterDecision] = extractFlag(args, "--decision");
62
- args = afterDecision;
63
-
64
- // `extractFlag` strips a trailing value-less flag, which would otherwise let
65
- // the next positional masquerade as the flag's value (or, for --decision,
66
- // silently fall back to "allow" and approve a tool call the caller never
67
- // meant to approve). Treat a flag supplied without a value as an error.
68
- if (requestIdFlagPresent && requestId === undefined) {
69
- return { ok: false, error: "--request-id requires a value." };
70
- }
71
- if (!requestId) {
72
- return { ok: false, error: "--request-id is required." };
73
- }
74
-
75
- if (decisionFlagPresent && decisionRaw === undefined) {
76
- return {
77
- ok: false,
78
- error: '--decision requires a value ("allow" or "deny").',
79
- };
80
- }
81
- const decision = decisionRaw ?? "allow";
82
- if (decision !== "allow" && decision !== "deny") {
83
- return {
84
- ok: false,
85
- error: `--decision must be "allow" or "deny" (got "${decision}").`,
86
- };
87
- }
88
-
89
- if (args.length >= 2) {
90
- return { ok: false, error: "unexpected extra arguments." };
91
- }
92
-
93
- return {
94
- ok: true,
95
- value: { assistantId: args[0], requestId, decision, jsonOutput },
96
- };
97
- }
98
-
99
- function exitWithUsage(error: string): never {
100
- console.error(`Error: ${error}`);
101
- console.error("");
102
- printUsage();
103
- process.exit(1);
104
- }
105
-
106
- export async function confirm(): Promise<void> {
107
- const rawArgs = process.argv.slice(3);
108
-
109
- if (rawArgs.includes("--help") || rawArgs.includes("-h")) {
110
- printUsage();
111
- return;
112
- }
113
-
114
- const parsed = parseConfirmArgs(rawArgs);
115
- if (!parsed.ok) {
116
- exitWithUsage(parsed.error);
117
- }
118
-
119
- const { assistantId, requestId, decision, jsonOutput } = parsed.value;
120
-
121
- const client = new AssistantClient({ assistantId });
122
-
123
- const response = await client.post("/confirm", { requestId, decision });
124
-
125
- if (!response.ok) {
126
- const body = await response.text().catch(() => "");
127
- console.error(
128
- `Error: HTTP ${response.status}: ${body || response.statusText}`,
129
- );
130
- process.exit(1);
131
- }
132
-
133
- const result = (await response.json()) as { accepted: boolean };
134
-
135
- if (jsonOutput) {
136
- console.log(JSON.stringify(result, null, 2));
137
- } else {
138
- console.log(
139
- result.accepted
140
- ? `Confirmation resolved (${decision})`
141
- : `Confirmation not accepted`,
142
- );
143
- }
144
- }