@vellumai/cli 0.1.4 → 0.1.5

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.1.4",
3
+ "version": "0.1.5",
4
4
  "description": "CLI tools for vellum-assistant",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,15 +1,15 @@
1
1
  import { GATEWAY_PORT } from "../lib/constants";
2
2
  import { buildOpenclawRuntimeServer } from "../lib/openclaw-runtime-server";
3
3
 
4
- export function buildOpenclawStartupScript(
4
+ export async function buildOpenclawStartupScript(
5
5
  bearerToken: string,
6
6
  sshUser: string,
7
7
  anthropicApiKey: string,
8
8
  timestampRedirect: string,
9
9
  userSetup: string,
10
10
  ownershipFixup: string,
11
- ): string {
12
- const runtimeServer = buildOpenclawRuntimeServer();
11
+ ): Promise<string> {
12
+ const runtimeServer = await buildOpenclawRuntimeServer();
13
13
 
14
14
  return `#!/bin/bash
15
15
  set -e
@@ -1,6 +1,7 @@
1
1
  import { spawn } from "child_process";
2
2
  import { randomBytes } from "crypto";
3
3
  import { existsSync, unlinkSync, writeFileSync } from "fs";
4
+ import { createRequire } from "module";
4
5
  import { tmpdir, userInfo } from "os";
5
6
  import { dirname, join } from "path";
6
7
 
@@ -22,6 +23,8 @@ import { buildInterfacesSeed } from "../lib/interfaces-seed";
22
23
  import { generateRandomSuffix } from "../lib/random-name";
23
24
  import { exec, execOutput } from "../lib/step-runner";
24
25
 
26
+ const _require = createRequire(import.meta.url);
27
+
25
28
  const INSTALL_SCRIPT_REMOTE_PATH = "/tmp/vellum-install.sh";
26
29
  const INSTALL_SCRIPT_PATH = join(import.meta.dir, "..", "adapters", "install.sh");
27
30
  const MACHINE_TYPE = "e2-standard-4"; // 4 vCPUs, 16 GB memory
@@ -76,19 +79,19 @@ chown -R "$SSH_USER:$SSH_USER" "$SSH_USER_HOME" 2>/dev/null || true
76
79
  `;
77
80
  }
78
81
 
79
- export function buildStartupScript(
82
+ export async function buildStartupScript(
80
83
  species: Species,
81
84
  bearerToken: string,
82
85
  sshUser: string,
83
86
  anthropicApiKey: string,
84
- ): string {
87
+ ): Promise<string> {
85
88
  const platformUrl = process.env.VELLUM_ASSISTANT_PLATFORM_URL ?? "https://assistant.vellum.ai";
86
89
  const timestampRedirect = buildTimestampRedirect();
87
90
  const userSetup = buildUserSetup(sshUser);
88
91
  const ownershipFixup = buildOwnershipFixup();
89
92
 
90
93
  if (species === "openclaw") {
91
- return buildOpenclawStartupScript(
94
+ return await buildOpenclawStartupScript(
92
95
  bearerToken,
93
96
  sshUser,
94
97
  anthropicApiKey,
@@ -117,6 +120,7 @@ ANTHROPIC_API_KEY=\$ANTHROPIC_API_KEY
117
120
  GATEWAY_RUNTIME_PROXY_ENABLED=\$GATEWAY_RUNTIME_PROXY_ENABLED
118
121
  RUNTIME_PROXY_BEARER_TOKEN=\$RUNTIME_PROXY_BEARER_TOKEN
119
122
  INTERFACES_SEED_DIR=\$INTERFACES_SEED_DIR
123
+ RUNTIME_HTTP_PORT=7821
120
124
  DOTENV_EOF
121
125
 
122
126
  mkdir -p "\$HOME/.vellum/workspace"
@@ -485,7 +489,7 @@ async function hatchGcp(
485
489
  console.error("Error: ANTHROPIC_API_KEY environment variable is not set.");
486
490
  process.exit(1);
487
491
  }
488
- const startupScript = buildStartupScript(species, bearerToken, sshUser, anthropicApiKey);
492
+ const startupScript = await buildStartupScript(species, bearerToken, sshUser, anthropicApiKey);
489
493
  const startupScriptPath = join(tmpdir(), `${instanceName}-startup.sh`);
490
494
  writeFileSync(startupScriptPath, startupScript);
491
495
 
@@ -650,7 +654,7 @@ async function hatchCustom(
650
654
  process.exit(1);
651
655
  }
652
656
 
653
- const startupScript = buildStartupScript(species, bearerToken, sshUser, anthropicApiKey);
657
+ const startupScript = await buildStartupScript(species, bearerToken, sshUser, anthropicApiKey);
654
658
  const startupScriptPath = join(tmpdir(), `${instanceName}-startup.sh`);
655
659
  writeFileSync(startupScriptPath, startupScript);
656
660
 
@@ -715,6 +719,22 @@ async function hatchCustom(
715
719
  }
716
720
  }
717
721
 
722
+ function resolveGatewayDir(): string {
723
+ const sourceDir = join(import.meta.dir, "..", "..", "..", "gateway");
724
+ if (existsSync(sourceDir)) {
725
+ return sourceDir;
726
+ }
727
+
728
+ try {
729
+ const pkgPath = _require.resolve("@vellumai/vellum-gateway/package.json");
730
+ return dirname(pkgPath);
731
+ } catch {
732
+ throw new Error(
733
+ "Gateway not found. Ensure @vellumai/vellum-gateway is installed or run from the source tree.",
734
+ );
735
+ }
736
+ }
737
+
718
738
  async function hatchLocal(species: Species, name: string | null): Promise<void> {
719
739
  const instanceName = name ?? `${species}-${generateRandomSuffix()}`;
720
740
 
@@ -777,24 +797,19 @@ async function hatchLocal(species: Species, name: string | null): Promise<void>
777
797
  }
778
798
 
779
799
  console.log("🌐 Starting gateway...");
780
- const gatewayDir = join(import.meta.dir, "..", "..", "..", "gateway");
781
- if (!existsSync(gatewayDir)) {
782
- console.warn("⚠️ Gateway directory not found at", gatewayDir);
783
- console.warn(' Gateway will not be started\n');
784
- } else {
785
- const gateway = spawn("bun", ["run", "src/index.ts"], {
786
- cwd: gatewayDir,
787
- detached: true,
788
- stdio: "ignore",
789
- env: {
790
- ...process.env,
791
- GATEWAY_RUNTIME_PROXY_ENABLED: "true",
792
- GATEWAY_RUNTIME_PROXY_REQUIRE_AUTH: "false",
793
- },
794
- });
795
- gateway.unref();
796
- console.log("✅ Gateway started\n");
797
- }
800
+ const gatewayDir = resolveGatewayDir();
801
+ const gateway = spawn("bun", ["run", "src/index.ts"], {
802
+ cwd: gatewayDir,
803
+ detached: true,
804
+ stdio: "ignore",
805
+ env: {
806
+ ...process.env,
807
+ GATEWAY_RUNTIME_PROXY_ENABLED: "true",
808
+ GATEWAY_RUNTIME_PROXY_REQUIRE_AUTH: "false",
809
+ },
810
+ });
811
+ gateway.unref();
812
+ console.log("✅ Gateway started\n");
798
813
 
799
814
  const runtimeUrl = `http://localhost:${GATEWAY_PORT}`;
800
815
  const localEntry: AssistantEntry = {
package/src/lib/aws.ts CHANGED
@@ -420,7 +420,7 @@ export async function hatchAws(
420
420
  console.log("\u{1F50D} Finding latest Debian AMI...");
421
421
  const amiId = await getLatestDebianAmi(region);
422
422
 
423
- const startupScript = buildStartupScript(species, bearerToken, sshUser, anthropicApiKey);
423
+ const startupScript = await buildStartupScript(species, bearerToken, sshUser, anthropicApiKey);
424
424
  const startupScriptPath = join(tmpdir(), `${instanceName}-startup.sh`);
425
425
  writeFileSync(startupScriptPath, startupScript);
426
426
 
package/src/lib/gcp.ts CHANGED
@@ -139,15 +139,14 @@ export async function syncFirewallRules(
139
139
  "firewall-rules",
140
140
  "list",
141
141
  `--project=${project}`,
142
- `--filter=targetTags:${tag}`,
143
- "--format=value(name)",
142
+ "--format=json(name,targetTags)",
144
143
  ];
145
144
  if (account) listArgs.push(`--account=${account}`);
146
145
  const output = await execOutput("gcloud", listArgs);
147
- existingNames = output
148
- .split("\n")
149
- .map((s) => s.trim())
150
- .filter(Boolean);
146
+ const allRules = JSON.parse(output) as Array<{ name: string; targetTags?: string[] }>;
147
+ existingNames = allRules
148
+ .filter((r) => r.targetTags?.includes(tag))
149
+ .map((r) => r.name);
151
150
  } catch {
152
151
  existingNames = [];
153
152
  }
@@ -190,10 +189,11 @@ export async function fetchFirewallRules(
190
189
  "firewall-rules",
191
190
  "list",
192
191
  `--project=${project}`,
193
- `--filter=targetTags:${tag}`,
194
192
  "--format=json",
195
193
  ]);
196
- return output;
194
+ const rules = JSON.parse(output) as Array<{ targetTags?: string[] }>;
195
+ const filtered = rules.filter((r) => r.targetTags?.includes(tag));
196
+ return JSON.stringify(filtered, null, 2);
197
197
  }
198
198
 
199
199
  export interface GcpInstance {
@@ -1,8 +1,7 @@
1
1
  import { join } from "path";
2
2
 
3
- const serverSource = await Bun.file(join(import.meta.dir, "..", "adapters", "openclaw-http-server.ts")).text();
4
-
5
- export function buildOpenclawRuntimeServer(): string {
3
+ export async function buildOpenclawRuntimeServer(): Promise<string> {
4
+ const serverSource = await Bun.file(join(import.meta.dir, "..", "adapters", "openclaw-http-server.ts")).text();
6
5
 
7
6
  return `
8
7
  cat > /opt/openclaw-runtime-server.ts << 'RUNTIME_SERVER_EOF'