Spaces:
Configuration error
Configuration error
File size: 7,977 Bytes
3a65265 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 |
import type { Command } from "commander";
import type { GatewayDaemonRuntime } from "../../commands/daemon-runtime.js";
import { onboardCommand } from "../../commands/onboard.js";
import type {
AuthChoice,
GatewayAuthChoice,
GatewayBind,
NodeManagerChoice,
TailscaleMode,
} from "../../commands/onboard-types.js";
import { defaultRuntime } from "../../runtime.js";
import { formatDocsLink } from "../../terminal/links.js";
import { theme } from "../../terminal/theme.js";
import { runCommandWithRuntime } from "../cli-utils.js";
function resolveInstallDaemonFlag(
command: unknown,
opts: { installDaemon?: boolean },
): boolean | undefined {
if (!command || typeof command !== "object") return undefined;
const getOptionValueSource =
"getOptionValueSource" in command ? command.getOptionValueSource : undefined;
if (typeof getOptionValueSource !== "function") return undefined;
// Commander doesn't support option conflicts natively; keep original behavior.
// If --skip-daemon is explicitly passed, it wins.
if (getOptionValueSource.call(command, "skipDaemon") === "cli") return false;
if (getOptionValueSource.call(command, "installDaemon") === "cli") {
return Boolean(opts.installDaemon);
}
return undefined;
}
export function registerOnboardCommand(program: Command) {
program
.command("onboard")
.description("Interactive wizard to set up the gateway, workspace, and skills")
.addHelpText(
"after",
() =>
`\n${theme.muted("Docs:")} ${formatDocsLink("/cli/onboard", "docs.molt.bot/cli/onboard")}\n`,
)
.option("--workspace <dir>", "Agent workspace directory (default: ~/clawd)")
.option("--reset", "Reset config + credentials + sessions + workspace before running wizard")
.option("--non-interactive", "Run without prompts", false)
.option(
"--accept-risk",
"Acknowledge that agents are powerful and full system access is risky (required for --non-interactive)",
false,
)
.option("--flow <flow>", "Wizard flow: quickstart|advanced|manual")
.option("--mode <mode>", "Wizard mode: local|remote")
.option(
"--auth-choice <choice>",
"Auth: setup-token|token|chutes|openai-codex|openai-api-key|openrouter-api-key|ai-gateway-api-key|moonshot-api-key|kimi-code-api-key|synthetic-api-key|venice-api-key|gemini-api-key|zai-api-key|apiKey|minimax-api|minimax-api-lightning|opencode-zen|skip",
)
.option(
"--token-provider <id>",
"Token provider id (non-interactive; used with --auth-choice token)",
)
.option("--token <token>", "Token value (non-interactive; used with --auth-choice token)")
.option(
"--token-profile-id <id>",
"Auth profile id (non-interactive; default: <provider>:manual)",
)
.option("--token-expires-in <duration>", "Optional token expiry duration (e.g. 365d, 12h)")
.option("--anthropic-api-key <key>", "Anthropic API key")
.option("--openai-api-key <key>", "OpenAI API key")
.option("--openrouter-api-key <key>", "OpenRouter API key")
.option("--ai-gateway-api-key <key>", "Vercel AI Gateway API key")
.option("--moonshot-api-key <key>", "Moonshot API key")
.option("--kimi-code-api-key <key>", "Kimi Code API key")
.option("--gemini-api-key <key>", "Gemini API key")
.option("--zai-api-key <key>", "Z.AI API key")
.option("--minimax-api-key <key>", "MiniMax API key")
.option("--synthetic-api-key <key>", "Synthetic API key")
.option("--venice-api-key <key>", "Venice API key")
.option("--opencode-zen-api-key <key>", "OpenCode Zen API key")
.option("--gateway-port <port>", "Gateway port")
.option("--gateway-bind <mode>", "Gateway bind: loopback|tailnet|lan|auto|custom")
.option("--gateway-auth <mode>", "Gateway auth: token|password")
.option("--gateway-token <token>", "Gateway token (token auth)")
.option("--gateway-password <password>", "Gateway password (password auth)")
.option("--remote-url <url>", "Remote Gateway WebSocket URL")
.option("--remote-token <token>", "Remote Gateway token (optional)")
.option("--tailscale <mode>", "Tailscale: off|serve|funnel")
.option("--tailscale-reset-on-exit", "Reset tailscale serve/funnel on exit")
.option("--install-daemon", "Install gateway service")
.option("--no-install-daemon", "Skip gateway service install")
.option("--skip-daemon", "Skip gateway service install")
.option("--daemon-runtime <runtime>", "Daemon runtime: node|bun")
.option("--skip-channels", "Skip channel setup")
.option("--skip-skills", "Skip skills setup")
.option("--skip-health", "Skip health check")
.option("--skip-ui", "Skip Control UI/TUI prompts")
.option("--node-manager <name>", "Node manager for skills: npm|pnpm|bun")
.option("--json", "Output JSON summary", false)
.action(async (opts, command) => {
await runCommandWithRuntime(defaultRuntime, async () => {
const installDaemon = resolveInstallDaemonFlag(command, {
installDaemon: Boolean(opts.installDaemon),
});
const gatewayPort =
typeof opts.gatewayPort === "string" ? Number.parseInt(opts.gatewayPort, 10) : undefined;
await onboardCommand(
{
workspace: opts.workspace as string | undefined,
nonInteractive: Boolean(opts.nonInteractive),
acceptRisk: Boolean(opts.acceptRisk),
flow: opts.flow as "quickstart" | "advanced" | "manual" | undefined,
mode: opts.mode as "local" | "remote" | undefined,
authChoice: opts.authChoice as AuthChoice | undefined,
tokenProvider: opts.tokenProvider as string | undefined,
token: opts.token as string | undefined,
tokenProfileId: opts.tokenProfileId as string | undefined,
tokenExpiresIn: opts.tokenExpiresIn as string | undefined,
anthropicApiKey: opts.anthropicApiKey as string | undefined,
openaiApiKey: opts.openaiApiKey as string | undefined,
openrouterApiKey: opts.openrouterApiKey as string | undefined,
aiGatewayApiKey: opts.aiGatewayApiKey as string | undefined,
moonshotApiKey: opts.moonshotApiKey as string | undefined,
kimiCodeApiKey: opts.kimiCodeApiKey as string | undefined,
geminiApiKey: opts.geminiApiKey as string | undefined,
zaiApiKey: opts.zaiApiKey as string | undefined,
minimaxApiKey: opts.minimaxApiKey as string | undefined,
syntheticApiKey: opts.syntheticApiKey as string | undefined,
veniceApiKey: opts.veniceApiKey as string | undefined,
opencodeZenApiKey: opts.opencodeZenApiKey as string | undefined,
gatewayPort:
typeof gatewayPort === "number" && Number.isFinite(gatewayPort)
? gatewayPort
: undefined,
gatewayBind: opts.gatewayBind as GatewayBind | undefined,
gatewayAuth: opts.gatewayAuth as GatewayAuthChoice | undefined,
gatewayToken: opts.gatewayToken as string | undefined,
gatewayPassword: opts.gatewayPassword as string | undefined,
remoteUrl: opts.remoteUrl as string | undefined,
remoteToken: opts.remoteToken as string | undefined,
tailscale: opts.tailscale as TailscaleMode | undefined,
tailscaleResetOnExit: Boolean(opts.tailscaleResetOnExit),
reset: Boolean(opts.reset),
installDaemon,
daemonRuntime: opts.daemonRuntime as GatewayDaemonRuntime | undefined,
skipChannels: Boolean(opts.skipChannels),
skipSkills: Boolean(opts.skipSkills),
skipHealth: Boolean(opts.skipHealth),
skipUi: Boolean(opts.skipUi),
nodeManager: opts.nodeManager as NodeManagerChoice | undefined,
json: Boolean(opts.json),
},
defaultRuntime,
);
});
});
}
|