it's alive

This commit is contained in:
Chris Wanstrath 2026-02-17 09:55:53 -08:00
parent 994c26647d
commit 606b440891
2 changed files with 36 additions and 2 deletions

View File

@ -117,6 +117,14 @@ program
const vmCmd = program.command("vm").description("Manage the sandlot VM")
vmCmd
.command("shell")
.description("Open a shell in the VM")
.action(async () => {
await vm.ensure()
await vm.shell()
})
vmCmd
.command("status")
.description("Show VM status")

View File

@ -19,7 +19,10 @@ export async function ensure(): Promise<void> {
await $`limactl start ${VM_NAME}`.quiet()
// Provision
await $`limactl shell ${VM_NAME} -- sudo bash -c "curl -fsSL https://deb.nodesource.com/setup_22.x | bash - && apt-get install -y nodejs && npm install -g @anthropic-ai/claude-code"`.quiet()
await $`limactl shell ${VM_NAME} -- bash -c "curl -fsSL https://claude.ai/install.sh | bash"`.quiet()
// Replace ~/.claude and ~/.claude.json with symlinks to host credentials
await $`limactl shell ${VM_NAME} -- bash -c "rm -rf ~/.claude ~/.claude.json && ln -sf ${home}/.claude ~/.claude && ln -sf ${home}/.claude.json ~/.claude.json"`.quiet()
}
/** Check VM status. */
@ -41,10 +44,33 @@ export async function status(): Promise<"running" | "stopped" | "missing"> {
return "missing"
}
/** Load env vars from ~/.env */
async function loadEnv(): Promise<Record<string, string>> {
const envFile = Bun.file(`${homedir()}/.env`)
if (!(await envFile.exists())) return {}
const vars: Record<string, string> = {}
for (const line of (await envFile.text()).split("\n")) {
const match = line.match(/^([A-Z_]+)=(.+)$/)
if (match) vars[match[1]] = match[2]
}
return vars
}
/** Launch claude in the VM at the given workdir. */
export async function claude(workdir: string): Promise<void> {
const env = await loadEnv()
const envArgs = Object.entries(env).map(([k, v]) => `${k}=${v}`)
const proc = Bun.spawn(
["limactl", "shell", `--workdir=${workdir}`, VM_NAME, "claude", "--dangerously-skip-permissions"],
["limactl", "shell", `--workdir=${workdir}`, VM_NAME, "env", ...envArgs, "claude", "--dangerously-skip-permissions"],
{ stdin: "inherit", stdout: "inherit", stderr: "inherit" },
)
await proc.exited
}
/** Open an interactive shell in the VM. */
export async function shell(): Promise<void> {
const proc = Bun.spawn(
["limactl", "shell", VM_NAME],
{ stdin: "inherit", stdout: "inherit", stderr: "inherit" },
)
await proc.exited