diff --git a/CHANGELOG.md b/CHANGELOG.md index f1ec31f6d..46037f224 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -94,7 +94,7 @@ - Gateway/Discovery: include `gatewayPort`/`sshPort`/`cliPath` in wide-area Bonjour records, and add a tailnet DNS fallback for `gateway discover` when split DNS isn’t configured. — thanks @steipete - CLI: add global `--no-color` (and respect `NO_COLOR=1`) to disable ANSI output. — thanks @steipete - CLI: centralize lobster palette + apply it to onboarding/config prompts. — thanks @steipete -- Gateway/CLI: add `clawdbot gateway --dev/--reset` to auto-create a dev config/workspace with a robot identity (no BOOTSTRAP.md), and reset wipes config/creds/sessions/workspace. — thanks @steipete +- Gateway/CLI: add `clawdbot gateway --dev/--reset` to auto-create a dev config/workspace with a robot identity (no BOOTSTRAP.md), and reset wipes config/creds/sessions/workspace (subcommand --dev no longer collides with global --dev profile). — thanks @steipete - Configure: stop prompting to open the Control UI (still shown in onboarding). — thanks @steipete - Config: fix Minimax hosted onboarding to write `agents.defaults` and allow `msteams` as a heartbeat target. — thanks @steipete diff --git a/src/cli/gateway-cli.ts b/src/cli/gateway-cli.ts index a47303e74..11ecd42b9 100644 --- a/src/cli/gateway-cli.ts +++ b/src/cli/gateway-cli.ts @@ -97,6 +97,10 @@ Protocol droid for debugging and operations. - Ask for missing context before guessing. - Prefer reproducible steps and logs. `; +const DEV_TOOLS_TEMPLATE = `# TOOLS.md - Dev Tool Notes + +Use local tools carefully. Prefer read-only inspection before changes. +`; const DEV_IDENTITY_TEMPLATE = `# IDENTITY.md - Agent Identity - Name: ${DEV_IDENTITY_NAME} @@ -104,6 +108,16 @@ const DEV_IDENTITY_TEMPLATE = `# IDENTITY.md - Agent Identity - Vibe: ${DEV_IDENTITY_THEME} - Emoji: ${DEV_IDENTITY_EMOJI} `; +const DEV_USER_TEMPLATE = `# USER.md - User Profile + +- Name: +- Preferred address: +- Notes: +`; +const DEV_HEARTBEAT_TEMPLATE = `# HEARTBEAT.md + +Keep it short. Check logs, health, and connectivity. +`; type GatewayRunSignalAction = "stop" | "restart"; @@ -162,6 +176,15 @@ async function ensureDevWorkspace(dir: string) { path.join(resolvedDir, "IDENTITY.md"), DEV_IDENTITY_TEMPLATE, ); + await writeFileIfMissing( + path.join(resolvedDir, "TOOLS.md"), + DEV_TOOLS_TEMPLATE, + ); + await writeFileIfMissing(path.join(resolvedDir, "USER.md"), DEV_USER_TEMPLATE); + await writeFileIfMissing( + path.join(resolvedDir, "HEARTBEAT.md"), + DEV_HEARTBEAT_TEMPLATE, + ); } async function ensureDevGatewayConfig(opts: { reset?: boolean }) { diff --git a/src/cli/profile.test.ts b/src/cli/profile.test.ts index 131b6d25d..daf51071d 100644 --- a/src/cli/profile.test.ts +++ b/src/cli/profile.test.ts @@ -3,7 +3,7 @@ import { describe, expect, it } from "vitest"; import { applyCliProfileEnv, parseCliProfileArgs } from "./profile.js"; describe("parseCliProfileArgs", () => { - it("strips --dev anywhere in argv", () => { + it("leaves gateway --dev for subcommands", () => { const res = parseCliProfileArgs([ "node", "clawdbot", @@ -12,15 +12,28 @@ describe("parseCliProfileArgs", () => { "--allow-unconfigured", ]); if (!res.ok) throw new Error(res.error); - expect(res.profile).toBe("dev"); + expect(res.profile).toBeNull(); expect(res.argv).toEqual([ "node", "clawdbot", "gateway", + "--dev", "--allow-unconfigured", ]); }); + it("still accepts global --dev before subcommand", () => { + const res = parseCliProfileArgs([ + "node", + "clawdbot", + "--dev", + "gateway", + ]); + if (!res.ok) throw new Error(res.error); + expect(res.profile).toBe("dev"); + expect(res.argv).toEqual(["node", "clawdbot", "gateway"]); + }); + it("parses --profile value and strips it", () => { const res = parseCliProfileArgs([ "node", diff --git a/src/cli/profile.ts b/src/cli/profile.ts index a0725caae..038bbf23a 100644 --- a/src/cli/profile.ts +++ b/src/cli/profile.ts @@ -33,12 +33,18 @@ export function parseCliProfileArgs(argv: string[]): CliProfileParseResult { const out: string[] = argv.slice(0, 2); let profile: string | null = null; let sawDev = false; + let sawCommand = false; const args = argv.slice(2); for (let i = 0; i < args.length; i += 1) { const arg = args[i]; if (arg === undefined) continue; + if (sawCommand) { + out.push(arg); + continue; + } + if (arg === "--dev") { if (profile && profile !== "dev") { return { ok: false, error: "Cannot combine --dev with --profile" }; @@ -66,6 +72,12 @@ export function parseCliProfileArgs(argv: string[]): CliProfileParseResult { continue; } + if (!arg.startsWith("-")) { + sawCommand = true; + out.push(arg); + continue; + } + out.push(arg); }