@vellumai/cli 0.4.45 → 0.4.46
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 +2 -2
- package/src/adapters/install.sh +24 -11
- package/src/commands/hatch.ts +18 -1
- package/src/lib/docker.ts +17 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vellumai/cli",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.46",
|
|
4
4
|
"description": "CLI tools for vellum-assistant",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"./src/commands/*": "./src/commands/*.ts"
|
|
12
12
|
},
|
|
13
13
|
"bin": {
|
|
14
|
-
"
|
|
14
|
+
"vellum": "./src/index.ts"
|
|
15
15
|
},
|
|
16
16
|
"scripts": {
|
|
17
17
|
"format": "prettier --write .",
|
package/src/adapters/install.sh
CHANGED
|
@@ -179,27 +179,30 @@ configure_shell_profile() {
|
|
|
179
179
|
done
|
|
180
180
|
}
|
|
181
181
|
|
|
182
|
-
# Create a symlink so
|
|
182
|
+
# Create a symlink so a CLI command is available without ~/.bun/bin in PATH.
|
|
183
183
|
# Tries /usr/local/bin first (works on most systems), falls back to
|
|
184
184
|
# ~/.local/bin (user-writable, no sudo needed).
|
|
185
185
|
# This is best-effort — failure must not abort the install script.
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
186
|
+
#
|
|
187
|
+
# Usage: symlink_cli <command_name>
|
|
188
|
+
symlink_cli() {
|
|
189
|
+
local cmd_name="$1"
|
|
190
|
+
local cmd_bin="$HOME/.bun/bin/$cmd_name"
|
|
191
|
+
if [ ! -f "$cmd_bin" ]; then
|
|
189
192
|
return 0
|
|
190
193
|
fi
|
|
191
194
|
|
|
192
|
-
# Skip if
|
|
195
|
+
# Skip if the command is already resolvable outside of ~/.bun/bin
|
|
193
196
|
local resolved
|
|
194
|
-
resolved=$(command -v
|
|
195
|
-
if [ -n "$resolved" ] && [ "$resolved" != "$
|
|
197
|
+
resolved=$(command -v "$cmd_name" 2>/dev/null || true)
|
|
198
|
+
if [ -n "$resolved" ] && [ "$resolved" != "$cmd_bin" ]; then
|
|
196
199
|
return 0
|
|
197
200
|
fi
|
|
198
201
|
|
|
199
202
|
# Try /usr/local/bin (may need sudo on some systems)
|
|
200
203
|
if [ -d "/usr/local/bin" ] && [ -w "/usr/local/bin" ]; then
|
|
201
|
-
if ln -sf "$
|
|
202
|
-
success "Symlinked /usr/local/bin
|
|
204
|
+
if ln -sf "$cmd_bin" "/usr/local/bin/$cmd_name" 2>/dev/null; then
|
|
205
|
+
success "Symlinked /usr/local/bin/$cmd_name → $cmd_bin"
|
|
203
206
|
return 0
|
|
204
207
|
fi
|
|
205
208
|
fi
|
|
@@ -207,8 +210,8 @@ symlink_vellum() {
|
|
|
207
210
|
# Fallback: ~/.local/bin
|
|
208
211
|
local local_bin="$HOME/.local/bin"
|
|
209
212
|
mkdir -p "$local_bin" 2>/dev/null || true
|
|
210
|
-
if ln -sf "$
|
|
211
|
-
success "Symlinked $local_bin
|
|
213
|
+
if ln -sf "$cmd_bin" "$local_bin/$cmd_name" 2>/dev/null; then
|
|
214
|
+
success "Symlinked $local_bin/$cmd_name → $cmd_bin"
|
|
212
215
|
# Ensure ~/.local/bin is in PATH in shell profile
|
|
213
216
|
for profile in "$HOME/.zshrc" "$HOME/.bashrc" "$HOME/.bash_profile"; do
|
|
214
217
|
if [ -f "$profile" ] && ! grep -q "$local_bin" "$profile" 2>/dev/null; then
|
|
@@ -221,6 +224,11 @@ symlink_vellum() {
|
|
|
221
224
|
return 0
|
|
222
225
|
}
|
|
223
226
|
|
|
227
|
+
symlink_vellum() {
|
|
228
|
+
symlink_cli "vellum"
|
|
229
|
+
symlink_cli "assistant"
|
|
230
|
+
}
|
|
231
|
+
|
|
224
232
|
# Write a small sourceable env file to ~/.config/vellum/env so callers can
|
|
225
233
|
# pick up PATH changes without restarting their shell:
|
|
226
234
|
# curl -fsSL https://assistant.vellum.ai/install.sh | bash && . ~/.config/vellum/env
|
|
@@ -265,6 +273,11 @@ main() {
|
|
|
265
273
|
install_vellum
|
|
266
274
|
symlink_vellum
|
|
267
275
|
|
|
276
|
+
# Verify the assistant CLI is available
|
|
277
|
+
if ! command -v assistant >/dev/null 2>&1; then
|
|
278
|
+
info "Note: 'assistant' command may require opening a new terminal session"
|
|
279
|
+
fi
|
|
280
|
+
|
|
268
281
|
# Write a sourceable env file so the quickstart one-liner can pick up
|
|
269
282
|
# PATH changes in the caller's shell:
|
|
270
283
|
# curl ... | bash && . ~/.config/vellum/env
|
package/src/commands/hatch.ts
CHANGED
|
@@ -48,7 +48,8 @@ import {
|
|
|
48
48
|
stopLocalProcesses,
|
|
49
49
|
} from "../lib/local";
|
|
50
50
|
import { maybeStartNgrokTunnel } from "../lib/ngrok";
|
|
51
|
-
import {
|
|
51
|
+
import { detectOrphanedProcesses } from "../lib/orphan-detection";
|
|
52
|
+
import { isProcessAlive, stopProcess } from "../lib/process";
|
|
52
53
|
import { generateRandomSuffix } from "../lib/random-name";
|
|
53
54
|
import { validateAssistantName } from "../lib/retire-archive";
|
|
54
55
|
import { archiveLogFile, resetLogFile } from "../lib/xdg-log";
|
|
@@ -731,6 +732,22 @@ async function hatchLocal(
|
|
|
731
732
|
}
|
|
732
733
|
}
|
|
733
734
|
|
|
735
|
+
// On desktop, scan the process table for orphaned vellum processes that
|
|
736
|
+
// are not tracked by any PID file or lock file entry and kill them before
|
|
737
|
+
// starting new ones. This prevents resource leaks when the desktop app
|
|
738
|
+
// crashes or is force-quit without a clean shutdown.
|
|
739
|
+
if (IS_DESKTOP) {
|
|
740
|
+
const orphans = await detectOrphanedProcesses();
|
|
741
|
+
if (orphans.length > 0) {
|
|
742
|
+
desktopLog(
|
|
743
|
+
`🧹 Found ${orphans.length} orphaned process${orphans.length === 1 ? "" : "es"} — cleaning up...`,
|
|
744
|
+
);
|
|
745
|
+
for (const orphan of orphans) {
|
|
746
|
+
await stopProcess(parseInt(orphan.pid, 10), `${orphan.name} (PID ${orphan.pid})`);
|
|
747
|
+
}
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
|
|
734
751
|
// Reuse existing resources if re-hatching with --name that matches a known
|
|
735
752
|
// local assistant, otherwise allocate fresh per-instance ports and directories.
|
|
736
753
|
let resources: LocalInstanceResources;
|
package/src/lib/docker.ts
CHANGED
|
@@ -31,7 +31,7 @@ interface DockerRoot {
|
|
|
31
31
|
* Dockerfiles live under `meta/`, but when installed as an npm package they
|
|
32
32
|
* are at the package root.
|
|
33
33
|
*/
|
|
34
|
-
function findDockerRoot(): DockerRoot {
|
|
34
|
+
function findDockerRoot(developmentMode: boolean = false): DockerRoot {
|
|
35
35
|
// Source tree: cli/src/lib/ -> repo root (Dockerfiles in meta/)
|
|
36
36
|
const sourceTreeRoot = join(import.meta.dir, "..", "..", "..");
|
|
37
37
|
if (existsSync(join(sourceTreeRoot, "meta", "Dockerfile"))) {
|
|
@@ -55,6 +55,21 @@ function findDockerRoot(): DockerRoot {
|
|
|
55
55
|
dir = parent;
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
+
// In development mode, walk up from the executable path to find the repo
|
|
59
|
+
// root. This handles the macOS app bundle case where the binary lives inside
|
|
60
|
+
// the repo at e.g. clients/macos/dist/Vellum.app/Contents/MacOS/.
|
|
61
|
+
if (developmentMode) {
|
|
62
|
+
let execDir = dirname(process.execPath);
|
|
63
|
+
while (true) {
|
|
64
|
+
if (existsSync(join(execDir, "meta", "Dockerfile.development"))) {
|
|
65
|
+
return { root: execDir, dockerfileDir: "meta" };
|
|
66
|
+
}
|
|
67
|
+
const parent = dirname(execDir);
|
|
68
|
+
if (parent === execDir) break;
|
|
69
|
+
execDir = parent;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
58
73
|
// macOS app bundle: Contents/MacOS/vellum-cli -> Contents/Resources/Dockerfile
|
|
59
74
|
const appResourcesDir = join(dirname(process.execPath), "..", "Resources");
|
|
60
75
|
if (existsSync(join(appResourcesDir, "Dockerfile"))) {
|
|
@@ -168,7 +183,7 @@ export async function hatchDocker(
|
|
|
168
183
|
let repoRoot: string;
|
|
169
184
|
let dockerfileDir: string;
|
|
170
185
|
try {
|
|
171
|
-
({ root: repoRoot, dockerfileDir } = findDockerRoot());
|
|
186
|
+
({ root: repoRoot, dockerfileDir } = findDockerRoot(watch));
|
|
172
187
|
} catch (err) {
|
|
173
188
|
const message = err instanceof Error ? err.message : String(err);
|
|
174
189
|
const logFd = openLogFile("hatch.log");
|