clawbr 0.0.9 β 0.0.10
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/dist/commands/docker.init.command.js +16 -3
- package/dist/commands/docker.init.command.js.map +1 -1
- package/dist/commands/onboard.command.js +10 -37
- package/dist/commands/onboard.command.js.map +1 -1
- package/docker/Dockerfile +8 -16
- package/docker/scripts/docker-entrypoint.sh +71 -0
- package/package.json +1 -1
|
@@ -233,8 +233,10 @@ export class DockerInitCommand extends CommandRunner {
|
|
|
233
233
|
}
|
|
234
234
|
}
|
|
235
235
|
}
|
|
236
|
-
// Check if dist exists
|
|
237
|
-
await this.
|
|
236
|
+
// Check if dist exists (only if running in dev repo)
|
|
237
|
+
if (await this.isDevMode()) {
|
|
238
|
+
await this.ensureBuilt();
|
|
239
|
+
}
|
|
238
240
|
const agents = [];
|
|
239
241
|
let addMore = true;
|
|
240
242
|
console.log(chalk.bold("Let's set up your agents!\n"));
|
|
@@ -966,7 +968,7 @@ ${services}
|
|
|
966
968
|
recursive: true
|
|
967
969
|
});
|
|
968
970
|
try {
|
|
969
|
-
//
|
|
971
|
+
// Copy Dockerfile and scripts to ensure latest version
|
|
970
972
|
await cp(join(sourceDir, "Dockerfile"), join(targetDir, "Dockerfile"));
|
|
971
973
|
const sourceScripts = join(sourceDir, "scripts");
|
|
972
974
|
if (existsSync(sourceScripts)) {
|
|
@@ -979,6 +981,17 @@ ${services}
|
|
|
979
981
|
// Ignore copy errors
|
|
980
982
|
}
|
|
981
983
|
}
|
|
984
|
+
async isDevMode() {
|
|
985
|
+
try {
|
|
986
|
+
const pkgPath = join(process.cwd(), "package.json");
|
|
987
|
+
if (existsSync(pkgPath)) {
|
|
988
|
+
const content = await readFile(pkgPath, "utf-8");
|
|
989
|
+
const pkg = JSON.parse(content);
|
|
990
|
+
return pkg.name === "clawbr";
|
|
991
|
+
}
|
|
992
|
+
} catch {}
|
|
993
|
+
return false;
|
|
994
|
+
}
|
|
982
995
|
}
|
|
983
996
|
DockerInitCommand = _ts_decorate([
|
|
984
997
|
Command({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/commands/docker.init.command.ts"],"sourcesContent":["import { Command, CommandRunner } from \"nest-commander\";\nimport inquirer from \"inquirer\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport { homedir } from \"os\";\nimport { join, dirname } from \"path\";\nimport { writeFile, readFile, mkdir, unlink, cp } from \"fs/promises\";\nimport { fileURLToPath } from \"url\";\nimport { existsSync } from \"fs\";\nimport { execSync, exec } from \"child_process\";\nimport { promisify } from \"util\";\n\nconst execPromise = promisify(exec);\nimport { registerAgent } from \"../utils/api.js\";\nimport { createServer } from \"net\";\nimport { v4 } from \"uuid\";\n\ninterface AgentConfig {\n name: string;\n username: string;\n provider: string;\n apiKey: string;\n port?: number;\n token?: string; // Clawbr token\n gatewayToken?: string; // OpenClaw gateway token\n}\n\n@Command({\n name: \"docker:init\",\n description: \"Interactive setup for multiple Docker agents\",\n aliases: [\"docker-init\", \"docker:setup\"],\n})\nexport class DockerInitCommand extends CommandRunner {\n async run(): Promise<void> {\n console.log(chalk.bold.cyan(\"\\nπ³ Clawbr Docker Multi-Agent Setup\\n\"));\n console.log(\n chalk.gray(\"Perfect isolation for running multiple AI agents without context bleeding\\n\")\n );\n\n // Ensure Docker files exist locally (for npx usage)\n await this.scaffoldDockerFiles();\n\n // Check Docker installation\n if (!this.checkDocker()) {\n return;\n }\n\n // Check for existing containers\n const existingContainers = await this.checkExistingContainers();\n if (existingContainers.length > 0) {\n console.log(chalk.yellow(\"\\nβ οΈ Found existing Clawbr containers:\\n\"));\n existingContainers.forEach((container) => {\n console.log(chalk.gray(` - ${container}`));\n });\n\n const { removeExisting } = await inquirer.prompt([\n {\n type: \"confirm\",\n name: \"removeExisting\",\n message: chalk.bold(\"Do you want to remove existing containers and reconfigure?\"),\n default: false,\n },\n ]);\n\n if (!removeExisting) {\n console.log(chalk.yellow(\"\\nβ Setup cancelled. Existing containers remain.\\n\"));\n return;\n }\n\n // Remove existing containers and volumes\n await this.removeExistingSetup();\n }\n\n // Check for existing configuration files\n const hasDockerCompose = existsSync(\"docker/docker-compose.yml\");\n const hasEnvDocker = existsSync(\".env.docker\");\n\n if (hasDockerCompose && hasEnvDocker) {\n console.log(chalk.yellow(\"\\nβ οΈ Found existing configuration files:\\n\"));\n console.log(chalk.gray(\" - docker/docker-compose.yml\"));\n console.log(chalk.gray(\" - .env.docker\\n\"));\n\n const { resumeAction } = await inquirer.prompt([\n {\n type: \"list\",\n name: \"resumeAction\",\n message: \"What would you like to do?\",\n choices: [\n { name: \"Resume setup (continue from Docker build)\", value: \"resume\" },\n { name: \"Reconfigure (start over)\", value: \"reconfigure\" },\n { name: \"Cancel\", value: \"cancel\" },\n ],\n },\n ]);\n\n if (resumeAction === \"cancel\") {\n console.log(chalk.yellow(\"\\nβ Setup cancelled\\n\"));\n return;\n }\n\n if (resumeAction === \"resume\") {\n console.log(chalk.cyan(\"\\nβΆοΈ Resuming setup from Docker build...\\n\"));\n\n // Try to parse agents from docker-compose.yml\n const agents: AgentConfig[] = [];\n\n let composeContent = \"\";\n try {\n composeContent = await readFile(\"docker/docker-compose.yml\", \"utf-8\");\n\n // Patch docker/docker-compose.yml with correct BIND settings\n let modified = false;\n\n // Replace old HOST vars or missing checks with OPENCLAW_GATEWAY_BIND=ln (which means 0.0.0.0 basically)\n // actually \"ln\" binds to all interfaces in OpenClaw logic\n\n // Check if we need to fix \"ln\" to \"lan\" OR if missing completely\n // Check if we need to fix \"lan\"/\"ln\" to \"0.0.0.0\" OR if missing completely\n // Check if we need to fix \"0.0.0.0\" or \"lan\" back to \"ln\" for host mode\n // Fix BIND to lan (which maps to 0.0.0.0 internally but passes validation)\n if (composeContent.includes(\"OPENCLAW_GATEWAY_BIND=lan\")) {\n console.log(chalk.yellow(\" βΊ Fixing bind: OPENCLAW_GATEWAY_BIND=lan -> custom...\"));\n composeContent = composeContent.replace(\n /OPENCLAW_GATEWAY_BIND=lan/g,\n \"OPENCLAW_GATEWAY_BIND=custom\"\n );\n // Add custom host vars if missing\n if (!composeContent.includes(\"OPENCLAW_GATEWAY_HOST=\")) {\n composeContent = composeContent.replace(\n \"OPENCLAW_GATEWAY_BIND=custom\",\n \"OPENCLAW_GATEWAY_BIND=custom\\n - OPENCLAW_GATEWAY_IP=0.0.0.0\\n - OPENCLAW_GATEWAY_HOST=0.0.0.0\"\n );\n }\n modified = true;\n } else if (composeContent.includes(\"OPENCLAW_GATEWAY_BIND=0.0.0.0\")) {\n console.log(\n chalk.yellow(\" βΊ Fixing bind: OPENCLAW_GATEWAY_BIND=0.0.0.0 -> custom...\")\n );\n composeContent = composeContent.replace(\n /OPENCLAW_GATEWAY_BIND=0.0.0.0/g,\n \"OPENCLAW_GATEWAY_BIND=custom\"\n );\n // Add custom host vars if missing\n if (!composeContent.includes(\"OPENCLAW_GATEWAY_HOST=\")) {\n composeContent = composeContent.replace(\n \"OPENCLAW_GATEWAY_BIND=custom\",\n \"OPENCLAW_GATEWAY_BIND=custom\\n - OPENCLAW_GATEWAY_IP=0.0.0.0\\n - OPENCLAW_GATEWAY_HOST=0.0.0.0\"\n );\n }\n modified = true;\n }\n\n // Remove network_mode: host if present\n if (composeContent.includes(\"network_mode: host\")) {\n console.log(chalk.yellow(\" βΊ Removing network_mode: host (migrating to bridge)...\"));\n composeContent = composeContent.replace(/\\s+network_mode: host/g, \"\");\n modified = true;\n }\n\n // Fix volume paths from /root to /home/node\n if (composeContent.includes(\"/root/.config/clawbr\")) {\n console.log(chalk.yellow(\" βΊ Fix volume paths to /home/node...\"));\n composeContent = composeContent.replace(\n /\\/root\\/.config\\/clawbr/g,\n \"/home/node/.config/clawbr\"\n );\n composeContent = composeContent.replace(/\\/root\\/.openclaw/g, \"/home/node/.openclaw\");\n modified = true;\n }\n\n if (modified) {\n await writeFile(\"docker/docker-compose.yml\", composeContent, \"utf-8\");\n }\n\n const serviceMatches = composeContent.matchAll(/agent-(\\w+):/g);\n for (const match of serviceMatches) {\n agents.push({\n name: match[1].charAt(0).toUpperCase() + match[1].slice(1),\n username: \"\", // Will be loaded from .env if needed\n provider: \"google\", // Default, actual value in .env\n apiKey: \"\", // In .env\n });\n }\n } catch {\n console.log(chalk.red(\"\\nβ Could not parse configuration files\\n\"));\n return;\n }\n\n if (agents.length === 0) {\n console.log(chalk.red(\"\\nβ No agents found in configuration\\n\"));\n return;\n }\n\n // Try to load tokens from .env.docker for resume\n try {\n const envContent = await readFile(\".env.docker\", \"utf-8\");\n agents.forEach((agent) => {\n const envPrefix = agent.name.toUpperCase();\n const match = envContent.match(new RegExp(`${envPrefix}_TOKEN=(.+)`));\n if (match && match[1]) {\n agent.token = match[1].trim();\n }\n\n // Restore API Key and Provider\n const openrouterMatch = envContent.match(\n new RegExp(`${envPrefix}_OPENROUTER_KEY=(.+)`)\n );\n const geminiMatch = envContent.match(new RegExp(`${envPrefix}_GEMINI_KEY=(.+)`));\n const openaiMatch = envContent.match(new RegExp(`${envPrefix}_OPENAI_KEY=(.+)`));\n\n if (openrouterMatch && openrouterMatch[1]) {\n agent.apiKey = openrouterMatch[1].trim();\n agent.provider = \"openrouter\";\n } else if (geminiMatch && geminiMatch[1]) {\n agent.apiKey = geminiMatch[1].trim();\n agent.provider = \"google\";\n } else if (openaiMatch && openaiMatch[1]) {\n agent.apiKey = openaiMatch[1].trim();\n agent.provider = \"openai\";\n }\n\n // Extract port from docker-compose if possible\n // Look for ports mapping OR env var OPENCLAW_GATEWAY_PORT\n const serviceBlock =\n composeContent.match(\n new RegExp(`agent-${agent.name.toLowerCase()}:[\\\\s\\\\S]*?(?=agent-|volumes:|$)`, \"i\")\n )?.[0] || \"\";\n\n const portMatch = serviceBlock.match(/ports:\\s*-\\s*\"(\\d+):/i);\n const envPortMatch = serviceBlock.match(/OPENCLAW_GATEWAY_PORT=(\\d+)/i);\n\n if (portMatch && portMatch[1]) {\n agent.port = parseInt(portMatch[1], 10);\n } else if (envPortMatch && envPortMatch[1]) {\n agent.port = parseInt(envPortMatch[1], 10);\n } else {\n // Fallback assignment if parsing failed\n agent.port = 18790 + agents.indexOf(agent);\n }\n });\n\n // Verify ports are actually free (solves \"89 prohibited\" if busy)\n // This updates agent objects with new ports if conflicts exist\n await this.ensurePortsAreFree(agents);\n\n // FORCE REGENERATION of configuration files to ensure correct config\n // This avoids messy regex patching and guarantees clean state\n console.log(chalk.cyan(\" βΊ Regenerating configuration files...\"));\n await this.generateDockerFiles(agents);\n } catch {\n // Ignore\n }\n\n // Fix Docker credentials if needed\n await this.fixDockerCredentials();\n\n // Skip to Docker build\n try {\n await this.buildDockerImage();\n } catch (error) {\n return; // Error already logged\n }\n\n // Double-check ports before starting (resume path)\n await this.ensurePortsAreFree(agents);\n\n try {\n await this.startContainers(agents);\n await this.waitForOpenClawReady(agents);\n } catch (error) {\n return; // Error already logged\n }\n\n await this.configureContainers(agents);\n this.showSuccessMessage(agents);\n return;\n }\n\n // Reconfigure - remove existing files\n if (existsSync(\"docker/docker-compose.yml\")) {\n try {\n const { unlinkSync } = await import(\"fs\");\n unlinkSync(\"docker/docker-compose.yml\");\n } catch {\n // Ignore errors\n }\n }\n if (existsSync(\".env.docker\")) {\n try {\n const { unlinkSync } = await import(\"fs\");\n unlinkSync(\".env.docker\");\n } catch {\n // Ignore errors\n }\n }\n }\n\n // Check if dist exists\n await this.ensureBuilt();\n\n const agents: AgentConfig[] = [];\n let addMore = true;\n\n console.log(chalk.bold(\"Let's set up your agents!\\n\"));\n\n // Agent collection loop\n while (addMore) {\n const agentNumber = agents.length + 1;\n console.log(chalk.bold.cyan(`\\nπ Agent #${agentNumber} Configuration\\n`));\n\n const agent = await this.collectAgentInfo(agentNumber);\n agents.push(agent);\n\n // Ask if they want to add more\n const { continueAdding } = await inquirer.prompt([\n {\n type: \"confirm\",\n name: \"continueAdding\",\n message: chalk.bold(\"Would you like to add another agent?\"),\n default: true,\n },\n ]);\n\n addMore = continueAdding;\n }\n\n // Summary\n console.log(chalk.bold.cyan(\"\\nπ Summary\\n\"));\n console.log(chalk.gray(`Total agents: ${agents.length}\\n`));\n agents.forEach((agent, idx) => {\n console.log(chalk.cyan(` ${idx + 1}. ${agent.name} (@${agent.username})`));\n const openclawPort = agent.port || 18790 + idx;\n console.log(chalk.gray(` Dashboard: http://localhost:${openclawPort}`));\n console.log(chalk.gray(` Provider: ${agent.provider}\\n`));\n });\n\n const { confirmSetup } = await inquirer.prompt([\n {\n type: \"confirm\",\n name: \"confirmSetup\",\n message: chalk.bold(\"Ready to create these agents?\"),\n default: true,\n },\n ]);\n\n if (!confirmSetup) {\n console.log(chalk.yellow(\"\\nβ Setup cancelled\\n\"));\n return;\n }\n\n // Generate docker/docker-compose.yml and docker/.env.docker\n // This will now assign ports\n await this.generateDockerFiles(agents);\n\n // Fix Docker credentials if needed (cross-platform compatibility)\n await this.fixDockerCredentials();\n\n // Build Docker image\n try {\n await this.buildDockerImage();\n } catch (error) {\n console.log(chalk.yellow(\"\\nβ οΈ Docker build failed, but configuration files are ready.\"));\n console.log(chalk.gray(\"\\nYou can manually build and start containers:\\n\"));\n console.log(chalk.cyan(\" docker build -f docker/Dockerfile -t clawbr-cli:latest .\"));\n console.log(chalk.cyan(\" docker-compose -f docker/docker-compose.yml up -d\\n\"));\n\n const { continueAnyway } = await inquirer.prompt([\n {\n type: \"confirm\",\n name: \"continueAnyway\",\n message: \"Would you like to retry the build now?\",\n default: true,\n },\n ]);\n\n if (!continueAnyway) {\n console.log(\n chalk.yellow(\"\\nβΈοΈ Setup paused. Run 'clawbr docker:init' again to resume.\\n\")\n );\n return;\n }\n\n // Retry build\n await this.buildDockerImage();\n }\n\n // Double-check ports before starting\n // If ports were taken during build, we need to find new ones and regenerate config\n await this.ensurePortsAreFree(agents);\n\n // Start containers\n try {\n await this.startContainers(agents);\n await this.waitForOpenClawReady(agents);\n } catch (error) {\n console.log(chalk.red(\"\\nβ Failed to start containers\"));\n console.log(chalk.yellow(\"\\nTry starting manually:\\n\"));\n console.log(chalk.cyan(\" docker-compose --env-file .env.docker up -d\\n\"));\n return;\n }\n\n // Configure agents (copy skills, credentials)\n await this.configureContainers(agents);\n\n // Success!\n this.showSuccessMessage(agents);\n }\n\n private checkDocker(): boolean {\n const spinner = ora(\"Checking Docker installation...\").start();\n\n try {\n // Check if Docker is installed\n execSync(\"docker --version\", { stdio: \"ignore\" });\n execSync(\"docker-compose --version\", { stdio: \"ignore\" });\n\n spinner.text = \"Checking if Docker daemon is running...\";\n\n // Check if Docker daemon is running\n execSync(\"docker info\", { stdio: \"ignore\" });\n\n spinner.succeed(chalk.green(\"Docker is installed and running\"));\n return true;\n } catch (error) {\n spinner.fail(chalk.red(\"Docker check failed\"));\n\n // Try to determine the specific issue\n try {\n execSync(\"docker --version\", { stdio: \"ignore\" });\n // Docker is installed but daemon is not running\n console.log(chalk.yellow(\"\\nβ οΈ Docker is installed but not running\"));\n console.log(chalk.cyan(\" Please start Docker Desktop and try again\\n\"));\n } catch {\n // Docker is not installed\n console.log(chalk.yellow(\"\\nβ οΈ Docker is not installed\"));\n console.log(chalk.cyan(\" Install from: https://docs.docker.com/get-docker/\\n\"));\n }\n\n return false;\n }\n }\n\n private async fixDockerCredentials(): Promise<void> {\n // Fix Docker credential helper issue on macOS/Windows\n // This is a common issue where docker-credential-desktop is not in PATH\n const dockerConfigPath = join(homedir(), \".docker\", \"config.json\");\n\n try {\n if (existsSync(dockerConfigPath)) {\n const configContent = await readFile(dockerConfigPath, \"utf-8\");\n const config = JSON.parse(configContent);\n\n // Check if credsStore is set to \"desktop\" (problematic)\n if (config.credsStore === \"desktop\") {\n // Backup original config\n await writeFile(`${dockerConfigPath}.backup`, configContent, \"utf-8\");\n\n // Remove credsStore to avoid credential helper issues\n delete config.credsStore;\n\n // Write fixed config\n await writeFile(dockerConfigPath, JSON.stringify(config, null, \"\\t\"), \"utf-8\");\n\n console.log(chalk.gray(\" β Fixed Docker credentials configuration\\n\"));\n }\n }\n } catch (error) {\n // Silently fail - not critical\n }\n }\n\n private async ensureBuilt(): Promise<void> {\n if (!existsSync(\"dist\")) {\n const spinner = ora(\"Building Clawbr CLI...\").start();\n try {\n execSync(\"npm run build\", { stdio: \"ignore\" });\n spinner.succeed(chalk.green(\"CLI built successfully\"));\n } catch (error) {\n spinner.fail(chalk.red(\"Build failed\"));\n throw error;\n }\n }\n }\n\n private async checkExistingContainers(): Promise<string[]> {\n try {\n const output = execSync('docker ps -a --filter \"name=clawbr-agent-\" --format \"{{.Names}}\"', {\n encoding: \"utf-8\",\n });\n return output\n .trim()\n .split(\"\\n\")\n .filter((name) => name.length > 0);\n } catch {\n return [];\n }\n }\n\n private async removeExistingSetup(): Promise<void> {\n const spinner = ora(\"Removing existing containers and volumes...\").start();\n\n try {\n // Stop and remove containers (cross-platform)\n try {\n execSync(\"docker-compose down -v\", { stdio: \"ignore\" });\n } catch {\n // Ignore if docker-compose.yml doesn't exist\n }\n\n // Remove any remaining clawbr containers\n try {\n // Get container IDs first (cross-platform)\n const containerIds = execSync('docker ps -a --filter \"name=clawbr-agent-\" -q', {\n encoding: \"utf-8\",\n }).trim();\n\n if (containerIds) {\n execSync(`docker rm -f ${containerIds}`, { stdio: \"ignore\" });\n }\n } catch {\n // Ignore if no containers found\n }\n\n // Remove docker-compose.yml and .env.docker (cross-platform)\n const { unlinkSync } = await import(\"fs\");\n if (existsSync(\"docker/docker-compose.yml\")) {\n try {\n unlinkSync(\"docker/docker-compose.yml\");\n } catch {\n // Ignore errors\n }\n }\n if (existsSync(\".env.docker\")) {\n try {\n unlinkSync(\".env.docker\");\n } catch {\n // Ignore errors\n }\n }\n\n spinner.succeed(chalk.green(\"Existing setup removed\"));\n } catch (error) {\n spinner.fail(chalk.red(\"Failed to remove existing setup\"));\n throw error;\n }\n }\n\n private async collectAgentInfo(agentNumber: number): Promise<AgentConfig> {\n // Agent name (for container)\n const { name } = await inquirer.prompt([\n {\n type: \"input\",\n name: \"name\",\n message: \"Agent name (for container, e.g., Genesis, Nexus):\",\n default: agentNumber === 1 ? \"Genesis\" : undefined,\n validate: (input: string) => {\n if (!input || input.trim().length === 0) {\n return \"Agent name is required\";\n }\n if (!/^[a-zA-Z0-9_-]+$/.test(input)) {\n return \"Agent name must contain only letters, numbers, hyphens, and underscores\";\n }\n return true;\n },\n },\n ]);\n\n // Username confirmation loop (like in onboard)\n let username = \"\";\n let usernameConfirmed = false;\n\n while (!usernameConfirmed) {\n const { usernameInput } = await inquirer.prompt([\n {\n type: \"input\",\n name: \"usernameInput\",\n message: `Username for ${name} (will be visible on clawbr.com):`,\n default: `${name}_AI`,\n validate: (input: string) => {\n if (!input || input.trim().length === 0) {\n return \"Username is required\";\n }\n if (input.length < 3 || input.length > 30) {\n return \"Username must be 3-30 characters\";\n }\n if (!/^[a-zA-Z0-9_]{3,30}$/.test(input)) {\n return \"Username must contain only letters, numbers, and underscores\";\n }\n return true;\n },\n },\n ]);\n\n const { confirmUsername } = await inquirer.prompt([\n {\n type: \"confirm\",\n name: \"confirmUsername\",\n message: `Username will be \"${usernameInput}\". Is this okay?`,\n default: true,\n },\n ]);\n\n if (confirmUsername) {\n username = usernameInput;\n usernameConfirmed = true;\n } else {\n console.log(chalk.yellow(\"Let's try a different username...\\n\"));\n }\n }\n\n // Provider\n const { provider } = await inquirer.prompt([\n {\n type: \"list\",\n name: \"provider\",\n message: `AI provider for ${name}:`,\n choices: [\n {\n name: \"OpenRouter (Recommended - Multiple models)\",\n value: \"openrouter\",\n },\n {\n name: \"Google Gemini (Free tier available)\",\n value: \"google\",\n },\n {\n name: \"OpenAI (GPT-4o)\",\n value: \"openai\",\n },\n ],\n default: \"openrouter\",\n },\n ]);\n\n // API Key\n const providerMessages = {\n google: \"Google API key (get it at https://aistudio.google.com/apikey):\",\n openrouter: \"OpenRouter API key (get it at https://openrouter.ai/keys):\",\n openai: \"OpenAI API key (get it at https://platform.openai.com/api-keys):\",\n };\n\n const { apiKey } = await inquirer.prompt([\n {\n type: \"password\",\n name: \"apiKey\",\n message: providerMessages[provider as keyof typeof providerMessages] || \"API key:\",\n validate: (input: string) => {\n if (!input || input.trim().length === 0) {\n return \"API key is required\";\n }\n return true;\n },\n },\n ]);\n\n // Register agent immediately\n const spinner = ora(\"Registering agent...\").start();\n const baseUrl = process.env.CLAWBR_API_URL || \"https://clawbr.com\";\n let token = \"\";\n\n try {\n const apiKeyField = `${provider}ApiKey`;\n const requestBody = {\n username: username,\n aiProvider: provider,\n [apiKeyField]: apiKey,\n };\n\n const response = await registerAgent(baseUrl, requestBody);\n token = response.token;\n spinner.succeed(chalk.green(`Registered @${response.agent.username}`));\n } catch (error: any) {\n spinner.fail(chalk.red(\"Registration failed\"));\n console.log(chalk.red(`\\nError: ${error.message}`));\n\n const { retry } = await inquirer.prompt([\n {\n type: \"confirm\",\n name: \"retry\",\n message: \"Registration failed. strict mode requires successful registration. Retry?\",\n default: true,\n },\n ]);\n\n if (retry) {\n return this.collectAgentInfo(agentNumber);\n } else {\n process.exit(1);\n }\n }\n\n return { name, username, provider, apiKey, token };\n }\n\n private async generateDockerFiles(agents: AgentConfig[]): Promise<void> {\n const spinner = ora(\"Generating Docker configuration files...\").start();\n\n try {\n // Assign ports if not already assigned\n let nextPort = 18790;\n for (const agent of agents) {\n if (!agent.gatewayToken) {\n agent.gatewayToken = v4();\n }\n if (!agent.port) {\n agent.port = await this.findAvailablePort(nextPort);\n nextPort = agent.port + 1;\n }\n }\n\n // Generate docker/docker-compose.yml\n const dockerCompose = this.generateDockerCompose(agents);\n await writeFile(\"docker/docker-compose.yml\", dockerCompose, \"utf-8\");\n\n // Generate .env.docker\n const envDocker = this.generateEnvDocker(agents);\n await writeFile(\".env.docker\", envDocker, \"utf-8\");\n\n spinner.succeed(chalk.green(\"Docker configuration files created\"));\n } catch (error) {\n spinner.fail(chalk.red(\"Failed to generate Docker files\"));\n throw error;\n }\n }\n\n private generateDockerCompose(agents: AgentConfig[]): string {\n const services = agents\n .map((agent, index) => {\n const serviceName = `agent-${agent.name.toLowerCase()}`;\n const envPrefix = agent.name.toUpperCase();\n const openclawPort = agent.port || 18790 + index; // Start from 18790 to avoid 18789\n\n return ` ${serviceName}:\n build:\n context: ..\n dockerfile: docker/Dockerfile\n container_name: clawbr-${serviceName}\n ports:\n - \"${openclawPort}:${openclawPort}\"\n environment:\n # Network binding - host access\n - OPENCLAW_GATEWAY_BIND=0.0.0.0\n - OPENCLAW_GATEWAY_PORT=${openclawPort}\n \n # Clawbr API\n - CLAWBR_API_URL=https://clawbr.com\n - CLAWBR_TOKEN=${agent.token || \"\"}\n \n # AI Provider Keys\n - OPENROUTER_API_KEY=\\${${envPrefix}_OPENROUTER_KEY}\n - GEMINI_API_KEY=\\${${envPrefix}_GEMINI_KEY}\n - OPENAI_API_KEY=\\${${envPrefix}_OPENAI_KEY}\n \n # Agent Identity\n - AGENT_NAME=${agent.name}\n - OPENCLAW_GATEWAY_NAME=${agent.name.toLowerCase()}\n \n # FULL DISABLE OF AUTH AND PAIRING\n - OPENCLAW_GATEWAY_AUTH=none\n - OPENCLAW_AUTH_MODE=none\n - OPENCLAW_GATEWAY_TOKEN=${agent.gatewayToken}\n - OPENCLAW_CONTROL_UI_ALLOW_INSECURE_AUTH=true\n - OPENCLAW_CONTROL_UI_DANGEROUSLY_DISABLE_DEVICE_AUTH=true\n - OPENCLAW_CONTROL_UI_DANGEROUSLY_DISABLE_PAIRING=true\n - OPENCLAW_DISABLE_DEVICE_PAIRING=true\n - OPENCLAW_AUTO_APPROVE_DEVICES=true\n \n # Disable network discovery services\n - OPENCLAW_MDNS_DISABLE=true\n - OPENCLAW_BONJOUR_DISABLE=true\n \n # Dev mode for maximum simplicity\n - DEV_MODE=true\n - NODE_ENV=development\n volumes:\n - ./data/${serviceName}/config:/home/node/.config/clawbr\n - ./data/${serviceName}/workspace:/workspace\n working_dir: /workspace\n restart: unless-stopped`;\n })\n .join(\"\\n\\n\");\n\n return `services:\n${services}\n`;\n }\n\n private generateEnvDocker(agents: AgentConfig[]): string {\n const lines = [\n \"# Clawbr Docker Multi-Agent Configuration\",\n \"# Generated by clawbr docker:init\",\n \"# OpenClaw Authorization disabled for simplicity\",\n \"\",\n \"CLAWBR_API_URL=https://clawbr.com\",\n \"\",\n ];\n\n agents.forEach((agent, idx) => {\n const envPrefix = agent.name.toUpperCase();\n const openclawPort = agent.port || 18790 + idx;\n lines.push(`# Agent ${idx + 1}: ${agent.name} (@${agent.username})`);\n lines.push(`# OpenClaw Dashboard: http://localhost:${openclawPort}`);\n lines.push(`${envPrefix}_TOKEN=${agent.token || \"\"}`);\n lines.push(\n `${envPrefix}_OPENROUTER_KEY=${agent.provider === \"openrouter\" ? agent.apiKey : \"\"}`\n );\n lines.push(`${envPrefix}_GEMINI_KEY=${agent.provider === \"google\" ? agent.apiKey : \"\"}`);\n lines.push(`${envPrefix}_OPENAI_KEY=${agent.provider === \"openai\" ? agent.apiKey : \"\"}`);\n lines.push(\"\");\n });\n\n return lines.join(\"\\n\");\n }\n\n private async buildDockerImage(): Promise<void> {\n console.log(chalk.cyan(\"\\nποΈ Building Docker image...\"));\n\n try {\n execSync(\"docker build -f docker/Dockerfile -t clawbr-cli:latest .\", {\n stdio: \"inherit\",\n });\n console.log(chalk.green(\"\\nβ Docker image built\"));\n } catch (error: any) {\n console.log(chalk.red(\"\\nβ Docker build failed\"));\n\n // Show detailed error\n console.log(chalk.red(\"\\nβββ Docker Build Error βββ\\n\"));\n if (error.stderr) {\n console.log(chalk.gray(error.stderr.toString()));\n }\n if (error.stdout) {\n console.log(chalk.gray(error.stdout.toString()));\n }\n console.log(chalk.red(\"\\nβββββββββββββββββββββββββ\\n\"));\n\n throw error;\n }\n }\n\n private async startContainers(agents: AgentConfig[]): Promise<void> {\n const spinner = ora(\"Starting containers...\").start();\n\n try {\n // Manually load variables from .env.docker to ensure interpolation works\n // docker-compose variable substitution relies on shell environment\n const env: NodeJS.ProcessEnv = { ...process.env };\n\n if (existsSync(\".env.docker\")) {\n const content = await readFile(\".env.docker\", \"utf-8\");\n content.split(\"\\n\").forEach((line) => {\n const trimmed = line.trim();\n if (trimmed && !trimmed.startsWith(\"#\") && trimmed.includes(\"=\")) {\n const [key, ...values] = trimmed.split(\"=\");\n const value = values.join(\"=\");\n env[key.trim()] = value.trim();\n }\n });\n }\n\n execSync(\"docker-compose -f docker/docker-compose.yml up -d\", {\n stdio: \"ignore\",\n env: env,\n });\n spinner.succeed(chalk.green(`Started ${agents.length} container(s)`));\n } catch (error) {\n spinner.fail(chalk.red(\"Failed to start containers\"));\n throw error;\n }\n }\n\n private async waitForOpenClawReady(agents: AgentConfig[]): Promise<void> {\n const spinner = ora(\n \"Waiting for OpenClaw to start... (this may take up to 10 minutes)\"\n ).start();\n const startTime = Date.now();\n const timeout = 10 * 60 * 1000; // 10 minutes\n\n const readyContainers = new Set<string>();\n\n while (Date.now() - startTime < timeout) {\n if (readyContainers.size === agents.length) {\n spinner.succeed(\"All OpenClaw agents are ready!\");\n return;\n }\n\n await new Promise((r) => setTimeout(r, 2000)); // Check every 2s\n\n for (const agent of agents) {\n const serviceName = `agent-${agent.name.toLowerCase()}`;\n if (readyContainers.has(serviceName)) continue;\n\n try {\n // Use docker logs to check for gateway startup\n const logs = execSync(`docker logs clawbr-${serviceName} --tail 50 2>&1`).toString();\n if (logs.includes(\"[gateway]\") && logs.includes(\"listening on\")) {\n readyContainers.add(serviceName);\n spinner.text = `Waiting for OpenClaw to start... (${readyContainers.size}/${agents.length} ready)`;\n }\n } catch (e) {\n // Container might not be running yet or exec failed\n }\n }\n }\n\n spinner.fail(\"Timed out waiting for OpenClaw to start.\");\n console.log(\n chalk.red(\n \"\\nPossible issues:\\n- Docker resource limit\\n- Port conflict\\n- Configuration error\\n\"\n )\n );\n console.log(chalk.yellow(\"Check logs: npm run docker:logs\\n\"));\n process.exit(1);\n }\n\n private async configureContainers(agents: AgentConfig[]): Promise<void> {\n console.log(chalk.bold.cyan(\"\\nπ Configuring agents...\\n\"));\n\n const baseUrl = process.env.CLAWBR_API_URL || \"https://clawbr.com\";\n const mdfilesDir = join(process.cwd(), \"mdfiles\");\n\n for (const agent of agents) {\n const serviceName = `agent-${agent.name.toLowerCase()}`;\n const spinner = ora(`Configuring ${agent.name} (@${agent.username})...`).start();\n\n try {\n // Paths on HOST (docker/data/... is mounted to container)\n // Note: docker-compose is in docker/, volumes are ./data/... -> so it maps to project_root/docker/data\n const agentConfigDir = join(process.cwd(), \"docker\", \"data\", serviceName, \"config\");\n\n // Ensure directory exists\n await mkdir(agentConfigDir, { recursive: true });\n\n // 1. Generate credentials.json\n if (agent.token) {\n const credentials = {\n token: agent.token,\n apiKey: agent.token, // Required for getClawbrConfig compatibility\n username: agent.username || agent.name,\n agentName: agent.username || agent.name,\n url: baseUrl,\n aiProvider: agent.provider,\n apiKeys: {\n [agent.provider]: agent.apiKey,\n },\n };\n await writeFile(\n join(agentConfigDir, \"credentials.json\"),\n JSON.stringify(credentials, null, 2),\n \"utf-8\"\n );\n }\n\n // 2. Copy documentation files (SKILL.md, HEARTBEAT.md, references)\n // Using shell commands for recursive copy is safer/easier than recursive fs calls\n try {\n if (existsSync(join(mdfilesDir, \"SKILL.md\"))) {\n execSync(`cp \"${join(mdfilesDir, \"SKILL.md\")}\" \"${agentConfigDir}/\"`);\n }\n if (existsSync(join(mdfilesDir, \"HEARTBEAT.md\"))) {\n execSync(`cp \"${join(mdfilesDir, \"HEARTBEAT.md\")}\" \"${agentConfigDir}/\"`);\n }\n if (existsSync(join(mdfilesDir, \"references\"))) {\n execSync(`cp -r \"${join(mdfilesDir, \"references\")}\" \"${agentConfigDir}/\"`);\n }\n } catch (copyError) {\n // Ignore copy errors, not critical\n }\n\n // 3. Inject into OpenClaw (agent.md & HEARTBEAT.md)\n try {\n // Mounted at ./data/${serviceName}/workspace\n const agentWorkspaceDir = join(process.cwd(), \"docker\", \"data\", serviceName, \"workspace\");\n\n // Ensure workspace dir exists (it should be created by docker, but just in case)\n await mkdir(agentWorkspaceDir, { recursive: true });\n\n const agentMdPath = join(agentWorkspaceDir, \"agent.md\");\n if (existsSync(agentMdPath)) {\n let content = await readFile(agentMdPath, \"utf-8\");\n if (!content.includes(\"## Clawbr\")) {\n content +=\n \"\\n\\n## Clawbr\\n\\nIf you need to do anything with Clawbr, check out '~/.config/clawbr/SKILL.md' and follow through with the instructions there.\\n\";\n await writeFile(agentMdPath, content, \"utf-8\");\n }\n }\n\n const heartbeatPath = join(agentWorkspaceDir, \"HEARTBEAT.md\");\n if (existsSync(heartbeatPath)) {\n let content = await readFile(heartbeatPath, \"utf-8\");\n if (!content.includes(\"~/.config/clawbr/HEARTBEAT.md\")) {\n const redirectLine =\n \"Check `~/.config/clawbr/HEARTBEAT.md` for strictly follow the steps automatically\";\n await writeFile(heartbeatPath, redirectLine + \"\\n\\n\" + content, \"utf-8\");\n }\n }\n } catch (injectError) {\n // Ignore injection errors\n }\n\n spinner.succeed(chalk.green(`${agent.name} configured!`));\n } catch (error: any) {\n spinner.fail(chalk.red(`Failed to configure ${agent.name}: ${error.message}`));\n // Don't throw, try next agent\n }\n }\n }\n\n private showSuccessMessage(agents: AgentConfig[]): void {\n console.log(chalk.bold.green(\"\\nβ
All agents are ready!\\n\"));\n\n console.log(chalk.bold(\"Your agents:\\n\"));\n agents.forEach((agent, idx) => {\n const serviceName = `agent-${agent.name.toLowerCase()}`;\n const openclawPort = agent.port || 18790 + idx;\n console.log(chalk.cyan(` ${idx + 1}. ${agent.name} (@${agent.username})`));\n console.log(chalk.gray(` Container: ${serviceName}`));\n console.log(chalk.gray(` Provider: ${agent.provider}`));\n console.log(chalk.bold.magenta(` π Dashboard: http://localhost:${openclawPort}`));\n if (agent.gatewayToken) {\n console.log(chalk.gray(` π Gateway Token: ${agent.gatewayToken}`));\n }\n console.log(chalk.bold.green(` β Authorization disabled - just open the dashboard!\\n`));\n });\n\n console.log(chalk.bold.yellow(\"β οΈ OpenClaw Setup Required:\\n\"));\n console.log(chalk.gray(\" Each agent needs OpenClaw onboarding. For each agent, run:\\n\"));\n agents.forEach((agent, idx) => {\n const serviceName = `agent-${agent.name.toLowerCase()}`;\n const openclawPort = agent.port || 18790 + idx;\n console.log(chalk.cyan(` # ${agent.name}:`));\n console.log(\n chalk.white(` docker-compose exec ${serviceName} node /openclaw/dist/index.js onboard`)\n );\n console.log(chalk.gray(` # Then visit: http://localhost:${openclawPort}\\n`));\n });\n\n console.log(chalk.bold(\"Quick Commands:\\n\"));\n console.log(chalk.gray(\" View logs:\"));\n console.log(chalk.cyan(\" npm run docker:logs\\n\"));\n\n console.log(chalk.gray(\" Execute Clawbr commands:\"));\n agents.forEach((agent) => {\n const serviceName = `agent-${agent.name.toLowerCase()}`;\n console.log(chalk.cyan(` docker-compose exec ${serviceName} clawbr feed`));\n });\n\n console.log(chalk.gray(\"\\n Stop all agents:\"));\n console.log(chalk.cyan(\" npm run docker:down\\n\"));\n\n console.log(chalk.bold(\"π Documentation:\\n\"));\n console.log(chalk.gray(\" Full guide: \") + chalk.cyan(\"README.md\\n\"));\n }\n\n private async isPortAvailable(port: number): Promise<boolean> {\n return new Promise((resolve) => {\n const server = createServer();\n server.once(\"error\", () => resolve(false));\n server.once(\"listening\", () => {\n server.close();\n resolve(true);\n });\n server.listen(port);\n });\n }\n\n private async findAvailablePort(startPort: number): Promise<number> {\n let port = startPort;\n // Skip 18789 explicitly\n if (port === 18789) port++;\n\n while (!(await this.isPortAvailable(port))) {\n port++;\n // Skip 18789 if searching hits it\n if (port === 18789) port++;\n }\n return port;\n }\n\n private async ensurePortsAreFree(agents: AgentConfig[]): Promise<void> {\n let regenerationNeeded = false;\n const usedPorts = new Set<number>();\n\n for (const agent of agents) {\n if (agent.port) {\n // Double check if available, OR if we accidentally assigned duplicates in the list\n if (!(await this.isPortAvailable(agent.port)) || usedPorts.has(agent.port)) {\n console.log(\n chalk.yellow(\n `\\nPort ${agent.port} is busy or duplicate. Finding new port for ${agent.name}...`\n )\n );\n\n // Find new port satisfying uniqueness and blacklist\n let newPort = agent.port + 1;\n if (newPort === 18789) newPort++;\n\n while (\n !(await this.isPortAvailable(newPort)) ||\n usedPorts.has(newPort) ||\n newPort === 18789\n ) {\n newPort++;\n if (newPort === 18789) newPort++;\n }\n\n agent.port = newPort;\n regenerationNeeded = true;\n }\n usedPorts.add(agent.port);\n }\n }\n\n if (regenerationNeeded) {\n console.log(chalk.cyan(\"π Regenerating configuration with new ports...\"));\n await this.generateDockerFiles(agents);\n }\n }\n\n private async scaffoldDockerFiles(): Promise<void> {\n const __filename = fileURLToPath(import.meta.url);\n const __dirname = dirname(__filename);\n\n const potentialPaths = [\n join(__dirname, \"..\", \"..\", \"docker\"),\n join(__dirname, \"..\", \"..\", \"..\", \"docker\"),\n ];\n\n let sourceDir = \"\";\n for (const p of potentialPaths) {\n if (existsSync(join(p, \"Dockerfile\"))) {\n sourceDir = p;\n break;\n }\n }\n\n if (!sourceDir) {\n return;\n }\n\n const targetDir = join(process.cwd(), \"docker\");\n\n // Avoid copying if source is same as target (dev mode)\n if (sourceDir === targetDir) {\n return;\n }\n\n await mkdir(targetDir, { recursive: true });\n\n try {\n // Clean copy of scripts and Dockerfile to ensure latest version\n await cp(join(sourceDir, \"Dockerfile\"), join(targetDir, \"Dockerfile\"));\n\n const sourceScripts = join(sourceDir, \"scripts\");\n if (existsSync(sourceScripts)) {\n await cp(sourceScripts, join(targetDir, \"scripts\"), { recursive: true, force: true });\n }\n } catch (e) {\n // Ignore copy errors\n }\n }\n}\n"],"names":["Command","CommandRunner","inquirer","chalk","ora","homedir","join","dirname","writeFile","readFile","mkdir","cp","fileURLToPath","existsSync","execSync","exec","promisify","execPromise","registerAgent","createServer","v4","DockerInitCommand","run","console","log","bold","cyan","gray","scaffoldDockerFiles","checkDocker","existingContainers","checkExistingContainers","length","yellow","forEach","container","removeExisting","prompt","type","name","message","default","removeExistingSetup","hasDockerCompose","hasEnvDocker","resumeAction","choices","value","agents","composeContent","modified","includes","replace","serviceMatches","matchAll","match","push","charAt","toUpperCase","slice","username","provider","apiKey","red","envContent","agent","envPrefix","RegExp","token","trim","openrouterMatch","geminiMatch","openaiMatch","serviceBlock","toLowerCase","portMatch","envPortMatch","port","parseInt","indexOf","ensurePortsAreFree","generateDockerFiles","fixDockerCredentials","buildDockerImage","error","startContainers","waitForOpenClawReady","configureContainers","showSuccessMessage","unlinkSync","ensureBuilt","addMore","agentNumber","collectAgentInfo","continueAdding","idx","openclawPort","confirmSetup","continueAnyway","spinner","start","stdio","text","succeed","green","fail","dockerConfigPath","configContent","config","JSON","parse","credsStore","stringify","output","encoding","split","filter","containerIds","undefined","validate","input","test","usernameConfirmed","usernameInput","confirmUsername","providerMessages","google","openrouter","openai","baseUrl","process","env","CLAWBR_API_URL","apiKeyField","requestBody","aiProvider","response","retry","exit","nextPort","gatewayToken","findAvailablePort","dockerCompose","generateDockerCompose","envDocker","generateEnvDocker","services","map","index","serviceName","lines","stderr","toString","stdout","content","line","trimmed","startsWith","key","values","startTime","Date","now","timeout","readyContainers","Set","size","Promise","r","setTimeout","has","logs","add","e","mdfilesDir","cwd","agentConfigDir","recursive","credentials","agentName","url","apiKeys","copyError","agentWorkspaceDir","agentMdPath","heartbeatPath","redirectLine","injectError","magenta","white","isPortAvailable","resolve","server","once","close","listen","startPort","regenerationNeeded","usedPorts","newPort","__filename","__dirname","potentialPaths","sourceDir","p","targetDir","sourceScripts","force","description","aliases"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/commands/docker.init.command.ts"],"sourcesContent":["import { Command, CommandRunner } from \"nest-commander\";\nimport inquirer from \"inquirer\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport { homedir } from \"os\";\nimport { join, dirname } from \"path\";\nimport { writeFile, readFile, mkdir, unlink, cp } from \"fs/promises\";\nimport { fileURLToPath } from \"url\";\nimport { existsSync } from \"fs\";\nimport { execSync, exec } from \"child_process\";\nimport { promisify } from \"util\";\n\nconst execPromise = promisify(exec);\nimport { registerAgent } from \"../utils/api.js\";\nimport { createServer } from \"net\";\nimport { v4 } from \"uuid\";\n\ninterface AgentConfig {\n name: string;\n username: string;\n provider: string;\n apiKey: string;\n port?: number;\n token?: string; // Clawbr token\n gatewayToken?: string; // OpenClaw gateway token\n}\n\n@Command({\n name: \"docker:init\",\n description: \"Interactive setup for multiple Docker agents\",\n aliases: [\"docker-init\", \"docker:setup\"],\n})\nexport class DockerInitCommand extends CommandRunner {\n async run(): Promise<void> {\n console.log(chalk.bold.cyan(\"\\nπ³ Clawbr Docker Multi-Agent Setup\\n\"));\n console.log(\n chalk.gray(\"Perfect isolation for running multiple AI agents without context bleeding\\n\")\n );\n\n // Ensure Docker files exist locally (for npx usage)\n await this.scaffoldDockerFiles();\n\n // Check Docker installation\n if (!this.checkDocker()) {\n return;\n }\n\n // Check for existing containers\n const existingContainers = await this.checkExistingContainers();\n if (existingContainers.length > 0) {\n console.log(chalk.yellow(\"\\nβ οΈ Found existing Clawbr containers:\\n\"));\n existingContainers.forEach((container) => {\n console.log(chalk.gray(` - ${container}`));\n });\n\n const { removeExisting } = await inquirer.prompt([\n {\n type: \"confirm\",\n name: \"removeExisting\",\n message: chalk.bold(\"Do you want to remove existing containers and reconfigure?\"),\n default: false,\n },\n ]);\n\n if (!removeExisting) {\n console.log(chalk.yellow(\"\\nβ Setup cancelled. Existing containers remain.\\n\"));\n return;\n }\n\n // Remove existing containers and volumes\n await this.removeExistingSetup();\n }\n\n // Check for existing configuration files\n const hasDockerCompose = existsSync(\"docker/docker-compose.yml\");\n const hasEnvDocker = existsSync(\".env.docker\");\n\n if (hasDockerCompose && hasEnvDocker) {\n console.log(chalk.yellow(\"\\nβ οΈ Found existing configuration files:\\n\"));\n console.log(chalk.gray(\" - docker/docker-compose.yml\"));\n console.log(chalk.gray(\" - .env.docker\\n\"));\n\n const { resumeAction } = await inquirer.prompt([\n {\n type: \"list\",\n name: \"resumeAction\",\n message: \"What would you like to do?\",\n choices: [\n { name: \"Resume setup (continue from Docker build)\", value: \"resume\" },\n { name: \"Reconfigure (start over)\", value: \"reconfigure\" },\n { name: \"Cancel\", value: \"cancel\" },\n ],\n },\n ]);\n\n if (resumeAction === \"cancel\") {\n console.log(chalk.yellow(\"\\nβ Setup cancelled\\n\"));\n return;\n }\n\n if (resumeAction === \"resume\") {\n console.log(chalk.cyan(\"\\nβΆοΈ Resuming setup from Docker build...\\n\"));\n\n // Try to parse agents from docker-compose.yml\n const agents: AgentConfig[] = [];\n\n let composeContent = \"\";\n try {\n composeContent = await readFile(\"docker/docker-compose.yml\", \"utf-8\");\n\n // Patch docker/docker-compose.yml with correct BIND settings\n let modified = false;\n\n // Replace old HOST vars or missing checks with OPENCLAW_GATEWAY_BIND=ln (which means 0.0.0.0 basically)\n // actually \"ln\" binds to all interfaces in OpenClaw logic\n\n // Check if we need to fix \"ln\" to \"lan\" OR if missing completely\n // Check if we need to fix \"lan\"/\"ln\" to \"0.0.0.0\" OR if missing completely\n // Check if we need to fix \"0.0.0.0\" or \"lan\" back to \"ln\" for host mode\n // Fix BIND to lan (which maps to 0.0.0.0 internally but passes validation)\n if (composeContent.includes(\"OPENCLAW_GATEWAY_BIND=lan\")) {\n console.log(chalk.yellow(\" βΊ Fixing bind: OPENCLAW_GATEWAY_BIND=lan -> custom...\"));\n composeContent = composeContent.replace(\n /OPENCLAW_GATEWAY_BIND=lan/g,\n \"OPENCLAW_GATEWAY_BIND=custom\"\n );\n // Add custom host vars if missing\n if (!composeContent.includes(\"OPENCLAW_GATEWAY_HOST=\")) {\n composeContent = composeContent.replace(\n \"OPENCLAW_GATEWAY_BIND=custom\",\n \"OPENCLAW_GATEWAY_BIND=custom\\n - OPENCLAW_GATEWAY_IP=0.0.0.0\\n - OPENCLAW_GATEWAY_HOST=0.0.0.0\"\n );\n }\n modified = true;\n } else if (composeContent.includes(\"OPENCLAW_GATEWAY_BIND=0.0.0.0\")) {\n console.log(\n chalk.yellow(\" βΊ Fixing bind: OPENCLAW_GATEWAY_BIND=0.0.0.0 -> custom...\")\n );\n composeContent = composeContent.replace(\n /OPENCLAW_GATEWAY_BIND=0.0.0.0/g,\n \"OPENCLAW_GATEWAY_BIND=custom\"\n );\n // Add custom host vars if missing\n if (!composeContent.includes(\"OPENCLAW_GATEWAY_HOST=\")) {\n composeContent = composeContent.replace(\n \"OPENCLAW_GATEWAY_BIND=custom\",\n \"OPENCLAW_GATEWAY_BIND=custom\\n - OPENCLAW_GATEWAY_IP=0.0.0.0\\n - OPENCLAW_GATEWAY_HOST=0.0.0.0\"\n );\n }\n modified = true;\n }\n\n // Remove network_mode: host if present\n if (composeContent.includes(\"network_mode: host\")) {\n console.log(chalk.yellow(\" βΊ Removing network_mode: host (migrating to bridge)...\"));\n composeContent = composeContent.replace(/\\s+network_mode: host/g, \"\");\n modified = true;\n }\n\n // Fix volume paths from /root to /home/node\n if (composeContent.includes(\"/root/.config/clawbr\")) {\n console.log(chalk.yellow(\" βΊ Fix volume paths to /home/node...\"));\n composeContent = composeContent.replace(\n /\\/root\\/.config\\/clawbr/g,\n \"/home/node/.config/clawbr\"\n );\n composeContent = composeContent.replace(/\\/root\\/.openclaw/g, \"/home/node/.openclaw\");\n modified = true;\n }\n\n if (modified) {\n await writeFile(\"docker/docker-compose.yml\", composeContent, \"utf-8\");\n }\n\n const serviceMatches = composeContent.matchAll(/agent-(\\w+):/g);\n for (const match of serviceMatches) {\n agents.push({\n name: match[1].charAt(0).toUpperCase() + match[1].slice(1),\n username: \"\", // Will be loaded from .env if needed\n provider: \"google\", // Default, actual value in .env\n apiKey: \"\", // In .env\n });\n }\n } catch {\n console.log(chalk.red(\"\\nβ Could not parse configuration files\\n\"));\n return;\n }\n\n if (agents.length === 0) {\n console.log(chalk.red(\"\\nβ No agents found in configuration\\n\"));\n return;\n }\n\n // Try to load tokens from .env.docker for resume\n try {\n const envContent = await readFile(\".env.docker\", \"utf-8\");\n agents.forEach((agent) => {\n const envPrefix = agent.name.toUpperCase();\n const match = envContent.match(new RegExp(`${envPrefix}_TOKEN=(.+)`));\n if (match && match[1]) {\n agent.token = match[1].trim();\n }\n\n // Restore API Key and Provider\n const openrouterMatch = envContent.match(\n new RegExp(`${envPrefix}_OPENROUTER_KEY=(.+)`)\n );\n const geminiMatch = envContent.match(new RegExp(`${envPrefix}_GEMINI_KEY=(.+)`));\n const openaiMatch = envContent.match(new RegExp(`${envPrefix}_OPENAI_KEY=(.+)`));\n\n if (openrouterMatch && openrouterMatch[1]) {\n agent.apiKey = openrouterMatch[1].trim();\n agent.provider = \"openrouter\";\n } else if (geminiMatch && geminiMatch[1]) {\n agent.apiKey = geminiMatch[1].trim();\n agent.provider = \"google\";\n } else if (openaiMatch && openaiMatch[1]) {\n agent.apiKey = openaiMatch[1].trim();\n agent.provider = \"openai\";\n }\n\n // Extract port from docker-compose if possible\n // Look for ports mapping OR env var OPENCLAW_GATEWAY_PORT\n const serviceBlock =\n composeContent.match(\n new RegExp(`agent-${agent.name.toLowerCase()}:[\\\\s\\\\S]*?(?=agent-|volumes:|$)`, \"i\")\n )?.[0] || \"\";\n\n const portMatch = serviceBlock.match(/ports:\\s*-\\s*\"(\\d+):/i);\n const envPortMatch = serviceBlock.match(/OPENCLAW_GATEWAY_PORT=(\\d+)/i);\n\n if (portMatch && portMatch[1]) {\n agent.port = parseInt(portMatch[1], 10);\n } else if (envPortMatch && envPortMatch[1]) {\n agent.port = parseInt(envPortMatch[1], 10);\n } else {\n // Fallback assignment if parsing failed\n agent.port = 18790 + agents.indexOf(agent);\n }\n });\n\n // Verify ports are actually free (solves \"89 prohibited\" if busy)\n // This updates agent objects with new ports if conflicts exist\n await this.ensurePortsAreFree(agents);\n\n // FORCE REGENERATION of configuration files to ensure correct config\n // This avoids messy regex patching and guarantees clean state\n console.log(chalk.cyan(\" βΊ Regenerating configuration files...\"));\n await this.generateDockerFiles(agents);\n } catch {\n // Ignore\n }\n\n // Fix Docker credentials if needed\n await this.fixDockerCredentials();\n\n // Skip to Docker build\n try {\n await this.buildDockerImage();\n } catch (error) {\n return; // Error already logged\n }\n\n // Double-check ports before starting (resume path)\n await this.ensurePortsAreFree(agents);\n\n try {\n await this.startContainers(agents);\n await this.waitForOpenClawReady(agents);\n } catch (error) {\n return; // Error already logged\n }\n\n await this.configureContainers(agents);\n this.showSuccessMessage(agents);\n return;\n }\n\n // Reconfigure - remove existing files\n if (existsSync(\"docker/docker-compose.yml\")) {\n try {\n const { unlinkSync } = await import(\"fs\");\n unlinkSync(\"docker/docker-compose.yml\");\n } catch {\n // Ignore errors\n }\n }\n if (existsSync(\".env.docker\")) {\n try {\n const { unlinkSync } = await import(\"fs\");\n unlinkSync(\".env.docker\");\n } catch {\n // Ignore errors\n }\n }\n }\n\n // Check if dist exists (only if running in dev repo)\n if (await this.isDevMode()) {\n await this.ensureBuilt();\n }\n\n const agents: AgentConfig[] = [];\n let addMore = true;\n\n console.log(chalk.bold(\"Let's set up your agents!\\n\"));\n\n // Agent collection loop\n while (addMore) {\n const agentNumber = agents.length + 1;\n console.log(chalk.bold.cyan(`\\nπ Agent #${agentNumber} Configuration\\n`));\n\n const agent = await this.collectAgentInfo(agentNumber);\n agents.push(agent);\n\n // Ask if they want to add more\n const { continueAdding } = await inquirer.prompt([\n {\n type: \"confirm\",\n name: \"continueAdding\",\n message: chalk.bold(\"Would you like to add another agent?\"),\n default: true,\n },\n ]);\n\n addMore = continueAdding;\n }\n\n // Summary\n console.log(chalk.bold.cyan(\"\\nπ Summary\\n\"));\n console.log(chalk.gray(`Total agents: ${agents.length}\\n`));\n agents.forEach((agent, idx) => {\n console.log(chalk.cyan(` ${idx + 1}. ${agent.name} (@${agent.username})`));\n const openclawPort = agent.port || 18790 + idx;\n console.log(chalk.gray(` Dashboard: http://localhost:${openclawPort}`));\n console.log(chalk.gray(` Provider: ${agent.provider}\\n`));\n });\n\n const { confirmSetup } = await inquirer.prompt([\n {\n type: \"confirm\",\n name: \"confirmSetup\",\n message: chalk.bold(\"Ready to create these agents?\"),\n default: true,\n },\n ]);\n\n if (!confirmSetup) {\n console.log(chalk.yellow(\"\\nβ Setup cancelled\\n\"));\n return;\n }\n\n // Generate docker/docker-compose.yml and docker/.env.docker\n // This will now assign ports\n await this.generateDockerFiles(agents);\n\n // Fix Docker credentials if needed (cross-platform compatibility)\n await this.fixDockerCredentials();\n\n // Build Docker image\n try {\n await this.buildDockerImage();\n } catch (error) {\n console.log(chalk.yellow(\"\\nβ οΈ Docker build failed, but configuration files are ready.\"));\n console.log(chalk.gray(\"\\nYou can manually build and start containers:\\n\"));\n console.log(chalk.cyan(\" docker build -f docker/Dockerfile -t clawbr-cli:latest .\"));\n console.log(chalk.cyan(\" docker-compose -f docker/docker-compose.yml up -d\\n\"));\n\n const { continueAnyway } = await inquirer.prompt([\n {\n type: \"confirm\",\n name: \"continueAnyway\",\n message: \"Would you like to retry the build now?\",\n default: true,\n },\n ]);\n\n if (!continueAnyway) {\n console.log(\n chalk.yellow(\"\\nβΈοΈ Setup paused. Run 'clawbr docker:init' again to resume.\\n\")\n );\n return;\n }\n\n // Retry build\n await this.buildDockerImage();\n }\n\n // Double-check ports before starting\n // If ports were taken during build, we need to find new ones and regenerate config\n await this.ensurePortsAreFree(agents);\n\n // Start containers\n try {\n await this.startContainers(agents);\n await this.waitForOpenClawReady(agents);\n } catch (error) {\n console.log(chalk.red(\"\\nβ Failed to start containers\"));\n console.log(chalk.yellow(\"\\nTry starting manually:\\n\"));\n console.log(chalk.cyan(\" docker-compose --env-file .env.docker up -d\\n\"));\n return;\n }\n\n // Configure agents (copy skills, credentials)\n await this.configureContainers(agents);\n\n // Success!\n this.showSuccessMessage(agents);\n }\n\n private checkDocker(): boolean {\n const spinner = ora(\"Checking Docker installation...\").start();\n\n try {\n // Check if Docker is installed\n execSync(\"docker --version\", { stdio: \"ignore\" });\n execSync(\"docker-compose --version\", { stdio: \"ignore\" });\n\n spinner.text = \"Checking if Docker daemon is running...\";\n\n // Check if Docker daemon is running\n execSync(\"docker info\", { stdio: \"ignore\" });\n\n spinner.succeed(chalk.green(\"Docker is installed and running\"));\n return true;\n } catch (error) {\n spinner.fail(chalk.red(\"Docker check failed\"));\n\n // Try to determine the specific issue\n try {\n execSync(\"docker --version\", { stdio: \"ignore\" });\n // Docker is installed but daemon is not running\n console.log(chalk.yellow(\"\\nβ οΈ Docker is installed but not running\"));\n console.log(chalk.cyan(\" Please start Docker Desktop and try again\\n\"));\n } catch {\n // Docker is not installed\n console.log(chalk.yellow(\"\\nβ οΈ Docker is not installed\"));\n console.log(chalk.cyan(\" Install from: https://docs.docker.com/get-docker/\\n\"));\n }\n\n return false;\n }\n }\n\n private async fixDockerCredentials(): Promise<void> {\n // Fix Docker credential helper issue on macOS/Windows\n // This is a common issue where docker-credential-desktop is not in PATH\n const dockerConfigPath = join(homedir(), \".docker\", \"config.json\");\n\n try {\n if (existsSync(dockerConfigPath)) {\n const configContent = await readFile(dockerConfigPath, \"utf-8\");\n const config = JSON.parse(configContent);\n\n // Check if credsStore is set to \"desktop\" (problematic)\n if (config.credsStore === \"desktop\") {\n // Backup original config\n await writeFile(`${dockerConfigPath}.backup`, configContent, \"utf-8\");\n\n // Remove credsStore to avoid credential helper issues\n delete config.credsStore;\n\n // Write fixed config\n await writeFile(dockerConfigPath, JSON.stringify(config, null, \"\\t\"), \"utf-8\");\n\n console.log(chalk.gray(\" β Fixed Docker credentials configuration\\n\"));\n }\n }\n } catch (error) {\n // Silently fail - not critical\n }\n }\n\n private async ensureBuilt(): Promise<void> {\n if (!existsSync(\"dist\")) {\n const spinner = ora(\"Building Clawbr CLI...\").start();\n try {\n execSync(\"npm run build\", { stdio: \"ignore\" });\n spinner.succeed(chalk.green(\"CLI built successfully\"));\n } catch (error) {\n spinner.fail(chalk.red(\"Build failed\"));\n throw error;\n }\n }\n }\n\n private async checkExistingContainers(): Promise<string[]> {\n try {\n const output = execSync('docker ps -a --filter \"name=clawbr-agent-\" --format \"{{.Names}}\"', {\n encoding: \"utf-8\",\n });\n return output\n .trim()\n .split(\"\\n\")\n .filter((name) => name.length > 0);\n } catch {\n return [];\n }\n }\n\n private async removeExistingSetup(): Promise<void> {\n const spinner = ora(\"Removing existing containers and volumes...\").start();\n\n try {\n // Stop and remove containers (cross-platform)\n try {\n execSync(\"docker-compose down -v\", { stdio: \"ignore\" });\n } catch {\n // Ignore if docker-compose.yml doesn't exist\n }\n\n // Remove any remaining clawbr containers\n try {\n // Get container IDs first (cross-platform)\n const containerIds = execSync('docker ps -a --filter \"name=clawbr-agent-\" -q', {\n encoding: \"utf-8\",\n }).trim();\n\n if (containerIds) {\n execSync(`docker rm -f ${containerIds}`, { stdio: \"ignore\" });\n }\n } catch {\n // Ignore if no containers found\n }\n\n // Remove docker-compose.yml and .env.docker (cross-platform)\n const { unlinkSync } = await import(\"fs\");\n if (existsSync(\"docker/docker-compose.yml\")) {\n try {\n unlinkSync(\"docker/docker-compose.yml\");\n } catch {\n // Ignore errors\n }\n }\n if (existsSync(\".env.docker\")) {\n try {\n unlinkSync(\".env.docker\");\n } catch {\n // Ignore errors\n }\n }\n\n spinner.succeed(chalk.green(\"Existing setup removed\"));\n } catch (error) {\n spinner.fail(chalk.red(\"Failed to remove existing setup\"));\n throw error;\n }\n }\n\n private async collectAgentInfo(agentNumber: number): Promise<AgentConfig> {\n // Agent name (for container)\n const { name } = await inquirer.prompt([\n {\n type: \"input\",\n name: \"name\",\n message: \"Agent name (for container, e.g., Genesis, Nexus):\",\n default: agentNumber === 1 ? \"Genesis\" : undefined,\n validate: (input: string) => {\n if (!input || input.trim().length === 0) {\n return \"Agent name is required\";\n }\n if (!/^[a-zA-Z0-9_-]+$/.test(input)) {\n return \"Agent name must contain only letters, numbers, hyphens, and underscores\";\n }\n return true;\n },\n },\n ]);\n\n // Username confirmation loop (like in onboard)\n let username = \"\";\n let usernameConfirmed = false;\n\n while (!usernameConfirmed) {\n const { usernameInput } = await inquirer.prompt([\n {\n type: \"input\",\n name: \"usernameInput\",\n message: `Username for ${name} (will be visible on clawbr.com):`,\n default: `${name}_AI`,\n validate: (input: string) => {\n if (!input || input.trim().length === 0) {\n return \"Username is required\";\n }\n if (input.length < 3 || input.length > 30) {\n return \"Username must be 3-30 characters\";\n }\n if (!/^[a-zA-Z0-9_]{3,30}$/.test(input)) {\n return \"Username must contain only letters, numbers, and underscores\";\n }\n return true;\n },\n },\n ]);\n\n const { confirmUsername } = await inquirer.prompt([\n {\n type: \"confirm\",\n name: \"confirmUsername\",\n message: `Username will be \"${usernameInput}\". Is this okay?`,\n default: true,\n },\n ]);\n\n if (confirmUsername) {\n username = usernameInput;\n usernameConfirmed = true;\n } else {\n console.log(chalk.yellow(\"Let's try a different username...\\n\"));\n }\n }\n\n // Provider\n const { provider } = await inquirer.prompt([\n {\n type: \"list\",\n name: \"provider\",\n message: `AI provider for ${name}:`,\n choices: [\n {\n name: \"OpenRouter (Recommended - Multiple models)\",\n value: \"openrouter\",\n },\n {\n name: \"Google Gemini (Free tier available)\",\n value: \"google\",\n },\n {\n name: \"OpenAI (GPT-4o)\",\n value: \"openai\",\n },\n ],\n default: \"openrouter\",\n },\n ]);\n\n // API Key\n const providerMessages = {\n google: \"Google API key (get it at https://aistudio.google.com/apikey):\",\n openrouter: \"OpenRouter API key (get it at https://openrouter.ai/keys):\",\n openai: \"OpenAI API key (get it at https://platform.openai.com/api-keys):\",\n };\n\n const { apiKey } = await inquirer.prompt([\n {\n type: \"password\",\n name: \"apiKey\",\n message: providerMessages[provider as keyof typeof providerMessages] || \"API key:\",\n validate: (input: string) => {\n if (!input || input.trim().length === 0) {\n return \"API key is required\";\n }\n return true;\n },\n },\n ]);\n\n // Register agent immediately\n const spinner = ora(\"Registering agent...\").start();\n const baseUrl = process.env.CLAWBR_API_URL || \"https://clawbr.com\";\n let token = \"\";\n\n try {\n const apiKeyField = `${provider}ApiKey`;\n const requestBody = {\n username: username,\n aiProvider: provider,\n [apiKeyField]: apiKey,\n };\n\n const response = await registerAgent(baseUrl, requestBody);\n token = response.token;\n spinner.succeed(chalk.green(`Registered @${response.agent.username}`));\n } catch (error: any) {\n spinner.fail(chalk.red(\"Registration failed\"));\n console.log(chalk.red(`\\nError: ${error.message}`));\n\n const { retry } = await inquirer.prompt([\n {\n type: \"confirm\",\n name: \"retry\",\n message: \"Registration failed. strict mode requires successful registration. Retry?\",\n default: true,\n },\n ]);\n\n if (retry) {\n return this.collectAgentInfo(agentNumber);\n } else {\n process.exit(1);\n }\n }\n\n return { name, username, provider, apiKey, token };\n }\n\n private async generateDockerFiles(agents: AgentConfig[]): Promise<void> {\n const spinner = ora(\"Generating Docker configuration files...\").start();\n\n try {\n // Assign ports if not already assigned\n let nextPort = 18790;\n for (const agent of agents) {\n if (!agent.gatewayToken) {\n agent.gatewayToken = v4();\n }\n if (!agent.port) {\n agent.port = await this.findAvailablePort(nextPort);\n nextPort = agent.port + 1;\n }\n }\n\n // Generate docker/docker-compose.yml\n const dockerCompose = this.generateDockerCompose(agents);\n await writeFile(\"docker/docker-compose.yml\", dockerCompose, \"utf-8\");\n\n // Generate .env.docker\n const envDocker = this.generateEnvDocker(agents);\n await writeFile(\".env.docker\", envDocker, \"utf-8\");\n\n spinner.succeed(chalk.green(\"Docker configuration files created\"));\n } catch (error) {\n spinner.fail(chalk.red(\"Failed to generate Docker files\"));\n throw error;\n }\n }\n\n private generateDockerCompose(agents: AgentConfig[]): string {\n const services = agents\n .map((agent, index) => {\n const serviceName = `agent-${agent.name.toLowerCase()}`;\n const envPrefix = agent.name.toUpperCase();\n const openclawPort = agent.port || 18790 + index; // Start from 18790 to avoid 18789\n\n return ` ${serviceName}:\n build:\n context: ..\n dockerfile: docker/Dockerfile\n container_name: clawbr-${serviceName}\n ports:\n - \"${openclawPort}:${openclawPort}\"\n environment:\n # Network binding - host access\n - OPENCLAW_GATEWAY_BIND=0.0.0.0\n - OPENCLAW_GATEWAY_PORT=${openclawPort}\n \n # Clawbr API\n - CLAWBR_API_URL=https://clawbr.com\n - CLAWBR_TOKEN=${agent.token || \"\"}\n \n # AI Provider Keys\n - OPENROUTER_API_KEY=\\${${envPrefix}_OPENROUTER_KEY}\n - GEMINI_API_KEY=\\${${envPrefix}_GEMINI_KEY}\n - OPENAI_API_KEY=\\${${envPrefix}_OPENAI_KEY}\n \n # Agent Identity\n - AGENT_NAME=${agent.name}\n - OPENCLAW_GATEWAY_NAME=${agent.name.toLowerCase()}\n \n # FULL DISABLE OF AUTH AND PAIRING\n - OPENCLAW_GATEWAY_AUTH=none\n - OPENCLAW_AUTH_MODE=none\n - OPENCLAW_GATEWAY_TOKEN=${agent.gatewayToken}\n - OPENCLAW_CONTROL_UI_ALLOW_INSECURE_AUTH=true\n - OPENCLAW_CONTROL_UI_DANGEROUSLY_DISABLE_DEVICE_AUTH=true\n - OPENCLAW_CONTROL_UI_DANGEROUSLY_DISABLE_PAIRING=true\n - OPENCLAW_DISABLE_DEVICE_PAIRING=true\n - OPENCLAW_AUTO_APPROVE_DEVICES=true\n \n # Disable network discovery services\n - OPENCLAW_MDNS_DISABLE=true\n - OPENCLAW_BONJOUR_DISABLE=true\n \n # Dev mode for maximum simplicity\n - DEV_MODE=true\n - NODE_ENV=development\n volumes:\n - ./data/${serviceName}/config:/home/node/.config/clawbr\n - ./data/${serviceName}/workspace:/workspace\n working_dir: /workspace\n restart: unless-stopped`;\n })\n .join(\"\\n\\n\");\n\n return `services:\n${services}\n`;\n }\n\n private generateEnvDocker(agents: AgentConfig[]): string {\n const lines = [\n \"# Clawbr Docker Multi-Agent Configuration\",\n \"# Generated by clawbr docker:init\",\n \"# OpenClaw Authorization disabled for simplicity\",\n \"\",\n \"CLAWBR_API_URL=https://clawbr.com\",\n \"\",\n ];\n\n agents.forEach((agent, idx) => {\n const envPrefix = agent.name.toUpperCase();\n const openclawPort = agent.port || 18790 + idx;\n lines.push(`# Agent ${idx + 1}: ${agent.name} (@${agent.username})`);\n lines.push(`# OpenClaw Dashboard: http://localhost:${openclawPort}`);\n lines.push(`${envPrefix}_TOKEN=${agent.token || \"\"}`);\n lines.push(\n `${envPrefix}_OPENROUTER_KEY=${agent.provider === \"openrouter\" ? agent.apiKey : \"\"}`\n );\n lines.push(`${envPrefix}_GEMINI_KEY=${agent.provider === \"google\" ? agent.apiKey : \"\"}`);\n lines.push(`${envPrefix}_OPENAI_KEY=${agent.provider === \"openai\" ? agent.apiKey : \"\"}`);\n lines.push(\"\");\n });\n\n return lines.join(\"\\n\");\n }\n\n private async buildDockerImage(): Promise<void> {\n console.log(chalk.cyan(\"\\nποΈ Building Docker image...\"));\n\n try {\n execSync(\"docker build -f docker/Dockerfile -t clawbr-cli:latest .\", {\n stdio: \"inherit\",\n });\n console.log(chalk.green(\"\\nβ Docker image built\"));\n } catch (error: any) {\n console.log(chalk.red(\"\\nβ Docker build failed\"));\n\n // Show detailed error\n console.log(chalk.red(\"\\nβββ Docker Build Error βββ\\n\"));\n if (error.stderr) {\n console.log(chalk.gray(error.stderr.toString()));\n }\n if (error.stdout) {\n console.log(chalk.gray(error.stdout.toString()));\n }\n console.log(chalk.red(\"\\nβββββββββββββββββββββββββ\\n\"));\n\n throw error;\n }\n }\n\n private async startContainers(agents: AgentConfig[]): Promise<void> {\n const spinner = ora(\"Starting containers...\").start();\n\n try {\n // Manually load variables from .env.docker to ensure interpolation works\n // docker-compose variable substitution relies on shell environment\n const env: NodeJS.ProcessEnv = { ...process.env };\n\n if (existsSync(\".env.docker\")) {\n const content = await readFile(\".env.docker\", \"utf-8\");\n content.split(\"\\n\").forEach((line) => {\n const trimmed = line.trim();\n if (trimmed && !trimmed.startsWith(\"#\") && trimmed.includes(\"=\")) {\n const [key, ...values] = trimmed.split(\"=\");\n const value = values.join(\"=\");\n env[key.trim()] = value.trim();\n }\n });\n }\n\n execSync(\"docker-compose -f docker/docker-compose.yml up -d\", {\n stdio: \"ignore\",\n env: env,\n });\n spinner.succeed(chalk.green(`Started ${agents.length} container(s)`));\n } catch (error) {\n spinner.fail(chalk.red(\"Failed to start containers\"));\n throw error;\n }\n }\n\n private async waitForOpenClawReady(agents: AgentConfig[]): Promise<void> {\n const spinner = ora(\n \"Waiting for OpenClaw to start... (this may take up to 10 minutes)\"\n ).start();\n const startTime = Date.now();\n const timeout = 10 * 60 * 1000; // 10 minutes\n\n const readyContainers = new Set<string>();\n\n while (Date.now() - startTime < timeout) {\n if (readyContainers.size === agents.length) {\n spinner.succeed(\"All OpenClaw agents are ready!\");\n return;\n }\n\n await new Promise((r) => setTimeout(r, 2000)); // Check every 2s\n\n for (const agent of agents) {\n const serviceName = `agent-${agent.name.toLowerCase()}`;\n if (readyContainers.has(serviceName)) continue;\n\n try {\n // Use docker logs to check for gateway startup\n const logs = execSync(`docker logs clawbr-${serviceName} --tail 50 2>&1`).toString();\n if (logs.includes(\"[gateway]\") && logs.includes(\"listening on\")) {\n readyContainers.add(serviceName);\n spinner.text = `Waiting for OpenClaw to start... (${readyContainers.size}/${agents.length} ready)`;\n }\n } catch (e) {\n // Container might not be running yet or exec failed\n }\n }\n }\n\n spinner.fail(\"Timed out waiting for OpenClaw to start.\");\n console.log(\n chalk.red(\n \"\\nPossible issues:\\n- Docker resource limit\\n- Port conflict\\n- Configuration error\\n\"\n )\n );\n console.log(chalk.yellow(\"Check logs: npm run docker:logs\\n\"));\n process.exit(1);\n }\n\n private async configureContainers(agents: AgentConfig[]): Promise<void> {\n console.log(chalk.bold.cyan(\"\\nπ Configuring agents...\\n\"));\n\n const baseUrl = process.env.CLAWBR_API_URL || \"https://clawbr.com\";\n const mdfilesDir = join(process.cwd(), \"mdfiles\");\n\n for (const agent of agents) {\n const serviceName = `agent-${agent.name.toLowerCase()}`;\n const spinner = ora(`Configuring ${agent.name} (@${agent.username})...`).start();\n\n try {\n // Paths on HOST (docker/data/... is mounted to container)\n // Note: docker-compose is in docker/, volumes are ./data/... -> so it maps to project_root/docker/data\n const agentConfigDir = join(process.cwd(), \"docker\", \"data\", serviceName, \"config\");\n\n // Ensure directory exists\n await mkdir(agentConfigDir, { recursive: true });\n\n // 1. Generate credentials.json\n if (agent.token) {\n const credentials = {\n token: agent.token,\n apiKey: agent.token, // Required for getClawbrConfig compatibility\n username: agent.username || agent.name,\n agentName: agent.username || agent.name,\n url: baseUrl,\n aiProvider: agent.provider,\n apiKeys: {\n [agent.provider]: agent.apiKey,\n },\n };\n await writeFile(\n join(agentConfigDir, \"credentials.json\"),\n JSON.stringify(credentials, null, 2),\n \"utf-8\"\n );\n }\n\n // 2. Copy documentation files (SKILL.md, HEARTBEAT.md, references)\n // Using shell commands for recursive copy is safer/easier than recursive fs calls\n try {\n if (existsSync(join(mdfilesDir, \"SKILL.md\"))) {\n execSync(`cp \"${join(mdfilesDir, \"SKILL.md\")}\" \"${agentConfigDir}/\"`);\n }\n if (existsSync(join(mdfilesDir, \"HEARTBEAT.md\"))) {\n execSync(`cp \"${join(mdfilesDir, \"HEARTBEAT.md\")}\" \"${agentConfigDir}/\"`);\n }\n if (existsSync(join(mdfilesDir, \"references\"))) {\n execSync(`cp -r \"${join(mdfilesDir, \"references\")}\" \"${agentConfigDir}/\"`);\n }\n } catch (copyError) {\n // Ignore copy errors, not critical\n }\n\n // 3. Inject into OpenClaw (agent.md & HEARTBEAT.md)\n try {\n // Mounted at ./data/${serviceName}/workspace\n const agentWorkspaceDir = join(process.cwd(), \"docker\", \"data\", serviceName, \"workspace\");\n\n // Ensure workspace dir exists (it should be created by docker, but just in case)\n await mkdir(agentWorkspaceDir, { recursive: true });\n\n const agentMdPath = join(agentWorkspaceDir, \"agent.md\");\n if (existsSync(agentMdPath)) {\n let content = await readFile(agentMdPath, \"utf-8\");\n if (!content.includes(\"## Clawbr\")) {\n content +=\n \"\\n\\n## Clawbr\\n\\nIf you need to do anything with Clawbr, check out '~/.config/clawbr/SKILL.md' and follow through with the instructions there.\\n\";\n await writeFile(agentMdPath, content, \"utf-8\");\n }\n }\n\n const heartbeatPath = join(agentWorkspaceDir, \"HEARTBEAT.md\");\n if (existsSync(heartbeatPath)) {\n let content = await readFile(heartbeatPath, \"utf-8\");\n if (!content.includes(\"~/.config/clawbr/HEARTBEAT.md\")) {\n const redirectLine =\n \"Check `~/.config/clawbr/HEARTBEAT.md` for strictly follow the steps automatically\";\n await writeFile(heartbeatPath, redirectLine + \"\\n\\n\" + content, \"utf-8\");\n }\n }\n } catch (injectError) {\n // Ignore injection errors\n }\n\n spinner.succeed(chalk.green(`${agent.name} configured!`));\n } catch (error: any) {\n spinner.fail(chalk.red(`Failed to configure ${agent.name}: ${error.message}`));\n // Don't throw, try next agent\n }\n }\n }\n\n private showSuccessMessage(agents: AgentConfig[]): void {\n console.log(chalk.bold.green(\"\\nβ
All agents are ready!\\n\"));\n\n console.log(chalk.bold(\"Your agents:\\n\"));\n agents.forEach((agent, idx) => {\n const serviceName = `agent-${agent.name.toLowerCase()}`;\n const openclawPort = agent.port || 18790 + idx;\n console.log(chalk.cyan(` ${idx + 1}. ${agent.name} (@${agent.username})`));\n console.log(chalk.gray(` Container: ${serviceName}`));\n console.log(chalk.gray(` Provider: ${agent.provider}`));\n console.log(chalk.bold.magenta(` π Dashboard: http://localhost:${openclawPort}`));\n if (agent.gatewayToken) {\n console.log(chalk.gray(` π Gateway Token: ${agent.gatewayToken}`));\n }\n console.log(chalk.bold.green(` β Authorization disabled - just open the dashboard!\\n`));\n });\n\n console.log(chalk.bold.yellow(\"β οΈ OpenClaw Setup Required:\\n\"));\n console.log(chalk.gray(\" Each agent needs OpenClaw onboarding. For each agent, run:\\n\"));\n agents.forEach((agent, idx) => {\n const serviceName = `agent-${agent.name.toLowerCase()}`;\n const openclawPort = agent.port || 18790 + idx;\n console.log(chalk.cyan(` # ${agent.name}:`));\n console.log(\n chalk.white(` docker-compose exec ${serviceName} node /openclaw/dist/index.js onboard`)\n );\n console.log(chalk.gray(` # Then visit: http://localhost:${openclawPort}\\n`));\n });\n\n console.log(chalk.bold(\"Quick Commands:\\n\"));\n console.log(chalk.gray(\" View logs:\"));\n console.log(chalk.cyan(\" npm run docker:logs\\n\"));\n\n console.log(chalk.gray(\" Execute Clawbr commands:\"));\n agents.forEach((agent) => {\n const serviceName = `agent-${agent.name.toLowerCase()}`;\n console.log(chalk.cyan(` docker-compose exec ${serviceName} clawbr feed`));\n });\n\n console.log(chalk.gray(\"\\n Stop all agents:\"));\n console.log(chalk.cyan(\" npm run docker:down\\n\"));\n\n console.log(chalk.bold(\"π Documentation:\\n\"));\n console.log(chalk.gray(\" Full guide: \") + chalk.cyan(\"README.md\\n\"));\n }\n\n private async isPortAvailable(port: number): Promise<boolean> {\n return new Promise((resolve) => {\n const server = createServer();\n server.once(\"error\", () => resolve(false));\n server.once(\"listening\", () => {\n server.close();\n resolve(true);\n });\n server.listen(port);\n });\n }\n\n private async findAvailablePort(startPort: number): Promise<number> {\n let port = startPort;\n // Skip 18789 explicitly\n if (port === 18789) port++;\n\n while (!(await this.isPortAvailable(port))) {\n port++;\n // Skip 18789 if searching hits it\n if (port === 18789) port++;\n }\n return port;\n }\n\n private async ensurePortsAreFree(agents: AgentConfig[]): Promise<void> {\n let regenerationNeeded = false;\n const usedPorts = new Set<number>();\n\n for (const agent of agents) {\n if (agent.port) {\n // Double check if available, OR if we accidentally assigned duplicates in the list\n if (!(await this.isPortAvailable(agent.port)) || usedPorts.has(agent.port)) {\n console.log(\n chalk.yellow(\n `\\nPort ${agent.port} is busy or duplicate. Finding new port for ${agent.name}...`\n )\n );\n\n // Find new port satisfying uniqueness and blacklist\n let newPort = agent.port + 1;\n if (newPort === 18789) newPort++;\n\n while (\n !(await this.isPortAvailable(newPort)) ||\n usedPorts.has(newPort) ||\n newPort === 18789\n ) {\n newPort++;\n if (newPort === 18789) newPort++;\n }\n\n agent.port = newPort;\n regenerationNeeded = true;\n }\n usedPorts.add(agent.port);\n }\n }\n\n if (regenerationNeeded) {\n console.log(chalk.cyan(\"π Regenerating configuration with new ports...\"));\n await this.generateDockerFiles(agents);\n }\n }\n\n private async scaffoldDockerFiles(): Promise<void> {\n const __filename = fileURLToPath(import.meta.url);\n const __dirname = dirname(__filename);\n\n const potentialPaths = [\n join(__dirname, \"..\", \"..\", \"docker\"),\n join(__dirname, \"..\", \"..\", \"..\", \"docker\"),\n ];\n\n let sourceDir = \"\";\n for (const p of potentialPaths) {\n if (existsSync(join(p, \"Dockerfile\"))) {\n sourceDir = p;\n break;\n }\n }\n\n if (!sourceDir) {\n return;\n }\n\n const targetDir = join(process.cwd(), \"docker\");\n\n // Avoid copying if source is same as target (dev mode)\n if (sourceDir === targetDir) {\n return;\n }\n\n await mkdir(targetDir, { recursive: true });\n\n try {\n // Copy Dockerfile and scripts to ensure latest version\n await cp(join(sourceDir, \"Dockerfile\"), join(targetDir, \"Dockerfile\"));\n\n const sourceScripts = join(sourceDir, \"scripts\");\n if (existsSync(sourceScripts)) {\n await cp(sourceScripts, join(targetDir, \"scripts\"), { recursive: true, force: true });\n }\n } catch (e) {\n // Ignore copy errors\n }\n }\n\n private async isDevMode(): Promise<boolean> {\n try {\n const pkgPath = join(process.cwd(), \"package.json\");\n if (existsSync(pkgPath)) {\n const content = await readFile(pkgPath, \"utf-8\");\n const pkg = JSON.parse(content);\n return pkg.name === \"clawbr\";\n }\n } catch {}\n return false;\n }\n}\n"],"names":["Command","CommandRunner","inquirer","chalk","ora","homedir","join","dirname","writeFile","readFile","mkdir","cp","fileURLToPath","existsSync","execSync","exec","promisify","execPromise","registerAgent","createServer","v4","DockerInitCommand","run","console","log","bold","cyan","gray","scaffoldDockerFiles","checkDocker","existingContainers","checkExistingContainers","length","yellow","forEach","container","removeExisting","prompt","type","name","message","default","removeExistingSetup","hasDockerCompose","hasEnvDocker","resumeAction","choices","value","agents","composeContent","modified","includes","replace","serviceMatches","matchAll","match","push","charAt","toUpperCase","slice","username","provider","apiKey","red","envContent","agent","envPrefix","RegExp","token","trim","openrouterMatch","geminiMatch","openaiMatch","serviceBlock","toLowerCase","portMatch","envPortMatch","port","parseInt","indexOf","ensurePortsAreFree","generateDockerFiles","fixDockerCredentials","buildDockerImage","error","startContainers","waitForOpenClawReady","configureContainers","showSuccessMessage","unlinkSync","isDevMode","ensureBuilt","addMore","agentNumber","collectAgentInfo","continueAdding","idx","openclawPort","confirmSetup","continueAnyway","spinner","start","stdio","text","succeed","green","fail","dockerConfigPath","configContent","config","JSON","parse","credsStore","stringify","output","encoding","split","filter","containerIds","undefined","validate","input","test","usernameConfirmed","usernameInput","confirmUsername","providerMessages","google","openrouter","openai","baseUrl","process","env","CLAWBR_API_URL","apiKeyField","requestBody","aiProvider","response","retry","exit","nextPort","gatewayToken","findAvailablePort","dockerCompose","generateDockerCompose","envDocker","generateEnvDocker","services","map","index","serviceName","lines","stderr","toString","stdout","content","line","trimmed","startsWith","key","values","startTime","Date","now","timeout","readyContainers","Set","size","Promise","r","setTimeout","has","logs","add","e","mdfilesDir","cwd","agentConfigDir","recursive","credentials","agentName","url","apiKeys","copyError","agentWorkspaceDir","agentMdPath","heartbeatPath","redirectLine","injectError","magenta","white","isPortAvailable","resolve","server","once","close","listen","startPort","regenerationNeeded","usedPorts","newPort","__filename","__dirname","potentialPaths","sourceDir","p","targetDir","sourceScripts","force","pkgPath","pkg","description","aliases"],"mappings":"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"}
|
|
@@ -135,19 +135,14 @@ const POST_OPTIONS = [
|
|
|
135
135
|
}
|
|
136
136
|
];
|
|
137
137
|
/**
|
|
138
|
-
* Copy markdown files from local mdfiles/ directory to
|
|
138
|
+
* Copy markdown files from local mdfiles/ directory to OpenClaw skills directory
|
|
139
139
|
* Structure:
|
|
140
|
-
* - ~/.
|
|
141
|
-
* - ~/.
|
|
142
|
-
* - ~/.config/clawbr/references/*.md
|
|
140
|
+
* - ~/.openclaw/skills/clawbr/SKILL.md
|
|
141
|
+
* - ~/.openclaw/skills/clawbr/HEARTBEAT.md
|
|
143
142
|
*/ async function installSkillFiles() {
|
|
144
|
-
const
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
await mkdir(configDir, {
|
|
148
|
-
recursive: true
|
|
149
|
-
});
|
|
150
|
-
await mkdir(referencesDir, {
|
|
143
|
+
const skillsDir = join(homedir(), ".openclaw", "skills", "clawbr");
|
|
144
|
+
// Create directory
|
|
145
|
+
await mkdir(skillsDir, {
|
|
151
146
|
recursive: true
|
|
152
147
|
});
|
|
153
148
|
// Determine source directory (mdfiles in project root)
|
|
@@ -163,14 +158,14 @@ const POST_OPTIONS = [
|
|
|
163
158
|
break;
|
|
164
159
|
}
|
|
165
160
|
}
|
|
166
|
-
//
|
|
167
|
-
const
|
|
161
|
+
// Only copy SKILL.md and HEARTBEAT.md
|
|
162
|
+
const filesToCopy = [
|
|
168
163
|
"SKILL.md",
|
|
169
164
|
"HEARTBEAT.md"
|
|
170
165
|
];
|
|
171
|
-
for (const fileName of
|
|
166
|
+
for (const fileName of filesToCopy){
|
|
172
167
|
const sourcePath = join(mdfilesDir, fileName);
|
|
173
|
-
const destPath = join(
|
|
168
|
+
const destPath = join(skillsDir, fileName);
|
|
174
169
|
if (existsSync(sourcePath)) {
|
|
175
170
|
try {
|
|
176
171
|
await copyFile(sourcePath, destPath);
|
|
@@ -182,28 +177,6 @@ const POST_OPTIONS = [
|
|
|
182
177
|
console.log(chalk.yellow(` β Source file missing: ${fileName}`));
|
|
183
178
|
}
|
|
184
179
|
}
|
|
185
|
-
// Reference files to copy
|
|
186
|
-
const referenceFiles = [
|
|
187
|
-
"commands.md",
|
|
188
|
-
"models.md",
|
|
189
|
-
"rate_limits.md",
|
|
190
|
-
"troubleshooting.md",
|
|
191
|
-
"workflows.md"
|
|
192
|
-
];
|
|
193
|
-
for (const fileName of referenceFiles){
|
|
194
|
-
const sourcePath = join(mdfilesDir, "references", fileName);
|
|
195
|
-
const destPath = join(referencesDir, fileName);
|
|
196
|
-
if (existsSync(sourcePath)) {
|
|
197
|
-
try {
|
|
198
|
-
await copyFile(sourcePath, destPath);
|
|
199
|
-
console.log(chalk.gray(` β Installed references/${fileName}`));
|
|
200
|
-
} catch (error) {
|
|
201
|
-
console.log(chalk.yellow(` β Could not install references/${fileName}: ${error.message}`));
|
|
202
|
-
}
|
|
203
|
-
} else {
|
|
204
|
-
console.log(chalk.yellow(` β Source file missing: references/${fileName}`));
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
180
|
}
|
|
208
181
|
/**
|
|
209
182
|
* Inject Clawbr section into OpenClaw agent.md if not already present
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/commands/onboard.command.ts"],"sourcesContent":["import inquirer from \"inquirer\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport { homedir } from \"os\";\nimport { join, dirname } from \"path\";\n\nimport { mkdir, writeFile, readFile, copyFile } from \"fs/promises\";\nimport { existsSync } from \"fs\";\nimport { fileURLToPath } from \"url\";\n\nimport { updateClawbrConfig, getClawbrConfig } from \"../utils/config.js\";\nimport { registerAgent } from \"../utils/api.js\";\nimport { Command, CommandRunner, Option } from \"nest-commander\";\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\ninterface OnboardOptions {\n url?: string;\n name?: string;\n username?: string;\n provider?: string;\n apiKey?: string;\n nonInteractive?: boolean;\n}\n\n@Command({\n name: \"onboard\",\n description: \"Onboard to clawbr - register your agent\",\n aliases: [\"setup\", \"register\"],\n})\nexport class OnboardCommand extends CommandRunner {\n async run(passedParams: string[], options?: OnboardOptions): Promise<void> {\n await onboard(options || {});\n }\n\n @Option({\n flags: \"-u, --url <url>\",\n description: \"clawbr API URL\",\n })\n parseUrl(val: string): string {\n return val;\n }\n\n @Option({\n flags: \"-n, --name <name>\",\n description: \"Your agent name (deprecated, use --username)\",\n })\n parseName(val: string): string {\n return val;\n }\n\n @Option({\n flags: \"--username <username>\",\n description: \"Your agent username for registration\",\n })\n parseUsername(val: string): string {\n return val;\n }\n\n @Option({\n flags: \"--provider <provider>\",\n description: \"AI provider: openrouter, google, or openai\",\n })\n parseProvider(val: string): string {\n return val;\n }\n\n @Option({\n flags: \"--api-key <key>\",\n description: \"API key for the selected provider\",\n })\n parseApiKey(val: string): string {\n return val;\n }\n\n @Option({\n flags: \"--non-interactive\",\n description: \"Run in non-interactive mode\",\n })\n parseNonInteractive(): boolean {\n return true;\n }\n}\n\nconst POST_OPTIONS = [\n {\n name: \"Post a selfie with a caption\",\n value: \"selfie\",\n prompt:\n \"Create a selfie-style portrait of yourself as an AI agent. Show your personality and current mood. Make it authentic and expressive.\",\n },\n {\n name: \"Post about what you are working on\",\n value: \"working\",\n prompt:\n \"Create an image that represents what you are currently building or working on. Show the tools, code, or creative process.\",\n },\n {\n name: \"Post what you are thinking\",\n value: \"thinking\",\n prompt:\n \"Create an abstract or visual representation of your current thoughts, ideas, or reflections as an AI agent.\",\n },\n];\n\n/**\n * Copy markdown files from local mdfiles/ directory to user's config directory\n * Structure:\n * - ~/.config/clawbr/SKILL.md\n * - ~/.config/clawbr/HEARTBEAT.md\n * - ~/.config/clawbr/references/*.md\n */\nasync function installSkillFiles(): Promise<void> {\n const configDir = join(homedir(), \".config\", \"clawbr\");\n const referencesDir = join(configDir, \"references\");\n\n // Create directories\n await mkdir(configDir, { recursive: true });\n await mkdir(referencesDir, { recursive: true });\n\n // Determine source directory (mdfiles in project root)\n const potentialPaths = [\n join(__dirname, \"..\", \"..\", \"mdfiles\"),\n join(__dirname, \"..\", \"..\", \"..\", \"mdfiles\"),\n \"/clawbr/mdfiles\",\n ];\n\n let mdfilesDir = potentialPaths[0];\n for (const p of potentialPaths) {\n if (existsSync(join(p, \"SKILL.md\"))) {\n mdfilesDir = p;\n break;\n }\n }\n\n // Root files to copy\n const rootFiles = [\"SKILL.md\", \"HEARTBEAT.md\"];\n\n for (const fileName of rootFiles) {\n const sourcePath = join(mdfilesDir, fileName);\n const destPath = join(configDir, fileName);\n\n if (existsSync(sourcePath)) {\n try {\n await copyFile(sourcePath, destPath);\n console.log(chalk.gray(` β Installed ${fileName}`));\n } catch (error) {\n console.log(chalk.yellow(` β Could not install ${fileName}: ${(error as Error).message}`));\n }\n } else {\n console.log(chalk.yellow(` β Source file missing: ${fileName}`));\n }\n }\n\n // Reference files to copy\n const referenceFiles = [\n \"commands.md\",\n \"models.md\",\n \"rate_limits.md\",\n \"troubleshooting.md\",\n \"workflows.md\",\n ];\n\n for (const fileName of referenceFiles) {\n const sourcePath = join(mdfilesDir, \"references\", fileName);\n const destPath = join(referencesDir, fileName);\n\n if (existsSync(sourcePath)) {\n try {\n await copyFile(sourcePath, destPath);\n console.log(chalk.gray(` β Installed references/${fileName}`));\n } catch (error) {\n console.log(\n chalk.yellow(` β Could not install references/${fileName}: ${(error as Error).message}`)\n );\n }\n } else {\n console.log(chalk.yellow(` β Source file missing: references/${fileName}`));\n }\n }\n}\n\n/**\n * Inject Clawbr section into OpenClaw agent.md if not already present\n */\nasync function injectIntoOpenClawAgent(): Promise<boolean> {\n const agentMdPath = join(homedir(), \".openclaw\", \"workspace\", \"agent.md\");\n\n if (!existsSync(agentMdPath)) {\n return false; // OpenClaw not installed or agent.md doesn't exist\n }\n\n try {\n const content = await readFile(agentMdPath, \"utf-8\");\n\n // Check if Clawbr section already exists\n if (content.includes(\"## Clawbr\")) {\n return false; // Already injected\n }\n\n // Append Clawbr section\n const clawbrSection = `\n\n## Clawbr\n\nIf you need to do anything with Clawbr, check out '~/.config/clawbr/SKILL.md' and follow through with the instructions there.\n`;\n\n await writeFile(agentMdPath, content + clawbrSection, \"utf-8\");\n return true; // Successfully injected\n } catch (error) {\n console.log(chalk.gray(` Could not inject into agent.md: ${(error as Error).message}`));\n return false;\n }\n}\n\n/**\n * Inject redirect into OpenClaw HEARTBEAT.md if not already present\n */\nasync function injectIntoOpenClawHeartbeat(): Promise<boolean> {\n const heartbeatPath = join(homedir(), \".openclaw\", \"workspace\", \"HEARTBEAT.md\");\n\n if (!existsSync(heartbeatPath)) {\n return false; // OpenClaw not installed or HEARTBEAT.md doesn't exist\n }\n\n try {\n const content = await readFile(heartbeatPath, \"utf-8\");\n const redirectLine =\n \"Check `~/.config/clawbr/HEARTBEAT.md` for strictly follow the steps automatically\";\n\n // Check if redirect already exists\n if (content.includes(\"~/.config/clawbr/HEARTBEAT.md\")) {\n return false; // Already injected\n }\n\n // Prepend redirect to the beginning of the file\n await writeFile(heartbeatPath, redirectLine + \"\\n\\n\" + content, \"utf-8\");\n return true; // Successfully injected\n } catch (error) {\n console.log(chalk.gray(` Could not inject into HEARTBEAT.md: ${(error as Error).message}`));\n return false;\n }\n}\n\nasync function runPostFlow(_baseUrl: string): Promise<void> {\n const { choice } = await inquirer.prompt([\n {\n type: \"list\",\n name: \"choice\",\n message: \"What would you like to post?\",\n choices: [\n ...POST_OPTIONS.map((opt) => ({ name: opt.name, value: opt.value })),\n new inquirer.Separator(),\n { name: \"Exit\", value: \"exit\" },\n ],\n },\n ]);\n\n if (choice === \"exit\") {\n return;\n }\n\n const selected = POST_OPTIONS.find((opt) => opt.value === choice);\n if (!selected) return;\n\n console.log(chalk.gray(`\\nUse: clawbr post --prompt \"${selected.prompt}\"\\n`));\n}\n\n/**\n * Auto-detect OpenRouter API key from OpenClaw config\n * Scenario A: Key found -> Auto-import (User sees nothing)\n * Scenario B: Key not found -> Return null\n */\nasync function detectOpenRouterKey(): Promise<string | null> {\n const openClawConfigPath = join(homedir(), \".openclaw\", \"openclaw.json\");\n\n if (!existsSync(openClawConfigPath)) {\n return null;\n }\n\n try {\n const configContent = await readFile(openClawConfigPath, \"utf-8\");\n const config = JSON.parse(configContent);\n\n // Check for OPENROUTER_API_KEY in env.vars\n const openRouterKey = config.env?.vars?.OPENROUTER_API_KEY;\n\n if (openRouterKey && typeof openRouterKey === \"string\" && openRouterKey.trim().length > 0) {\n return openRouterKey;\n }\n\n return null;\n } catch {\n // Silently fail if config can't be read\n return null;\n }\n}\n\nexport async function onboard(options: OnboardOptions): Promise<void> {\n const baseUrl = options.url || process.env.CLAWBR_API_URL || \"https://clawbr.com\";\n\n // Check if already configured\n const existingConfig = await getClawbrConfig();\n if (existingConfig?.apiKey) {\n console.log(chalk.bold.cyan(\"\\nπΈ clawbr\\n\"));\n console.log(chalk.gray(`Agent: ${existingConfig.agentName}`));\n console.log(chalk.gray(`URL: ${existingConfig.url}\\n`));\n\n // Interactive post menu only when running in a terminal\n if (process.stdin.isTTY) {\n await runPostFlow(existingConfig.url);\n } else {\n console.log(chalk.green(\"β clawbr is already configured.\"));\n console.log(chalk.gray(`\\nRun 'npx clawbr' to start the interactive shell.`));\n }\n return;\n }\n\n // Fresh onboarding\n console.log(chalk.bold.cyan(\"\\nπΈ clawbr Onboarding\\n\"));\n console.log(chalk.gray(\"Tumblr for AI agents - Share your build moments\\n\"));\n\n // Install skill files from local mdfiles/\n const skillSpinner = ora(\"Installing clawbr documentation files...\").start();\n try {\n await installSkillFiles();\n skillSpinner.succeed(chalk.green(\"Documentation files installed\"));\n } catch (error) {\n skillSpinner.warn(\n chalk.yellow(`Could not install some files (continuing anyway): ${(error as Error).message}`)\n );\n }\n\n // Auto-inject into OpenClaw agent.md and HEARTBEAT.md if available\n const openclawSpinner = ora(\"Checking OpenClaw integration...\").start();\n try {\n const agentInjected = await injectIntoOpenClawAgent();\n const heartbeatInjected = await injectIntoOpenClawHeartbeat();\n\n if (agentInjected || heartbeatInjected) {\n const messages = [];\n if (agentInjected) messages.push(\"agent.md\");\n if (heartbeatInjected) messages.push(\"HEARTBEAT.md\");\n openclawSpinner.succeed(\n chalk.green(`Auto-injected Clawbr instructions into OpenClaw ${messages.join(\" and \")}`)\n );\n } else {\n openclawSpinner.info(\n chalk.gray(\"OpenClaw integration skipped (already configured or files not found)\")\n );\n }\n } catch {\n openclawSpinner.info(chalk.gray(\"OpenClaw integration skipped\"));\n }\n\n let agentName = options.username || options.name;\n let aiProvider = options.provider || \"openrouter\"; // default to openrouter (recommended)\n let providerApiKey = options.apiKey || \"\";\n\n // Auto-detect OpenRouter API key from OpenClaw config\n if (!providerApiKey && !options.apiKey) {\n const detectedKey = await detectOpenRouterKey();\n if (detectedKey) {\n providerApiKey = detectedKey;\n aiProvider = \"openrouter\";\n console.log(chalk.green(\"β Auto-detected OpenRouter API key from OpenClaw config\"));\n }\n }\n\n // Validate provider if provided\n if (options.provider && ![\"google\", \"openrouter\", \"openai\"].includes(options.provider)) {\n console.error(\n chalk.red(\n `Error: Invalid provider '${options.provider}'. Must be: google, openrouter, or openai`\n )\n );\n process.exit(1);\n }\n\n // Check if we have all required params for non-interactive mode\n const hasAllParams = agentName && aiProvider && providerApiKey;\n\n // Interactive prompts if not all params provided\n if (!hasAllParams) {\n // Username confirmation loop\n let usernameConfirmed = false;\n while (!usernameConfirmed && !agentName) {\n const nameAnswer = await inquirer.prompt([\n {\n type: \"input\",\n name: \"agentName\",\n message: \"Your agent username:\",\n validate: (input: string) => {\n if (!input || input.trim().length === 0) {\n return \"Username is required\";\n }\n if (input.length < 3 || input.length > 30) {\n return \"Username must be 3-30 characters\";\n }\n if (!/^[a-zA-Z0-9_]{3,30}$/.test(input)) {\n return \"Username must contain only letters, numbers, and underscores\";\n }\n return true;\n },\n },\n ]);\n\n const confirmAnswer = await inquirer.prompt([\n {\n type: \"confirm\",\n name: \"confirmUsername\",\n message: `Your username will be \"${nameAnswer.agentName}\". Is this okay?`,\n default: true,\n },\n ]);\n\n if (confirmAnswer.confirmUsername) {\n agentName = nameAnswer.agentName;\n usernameConfirmed = true;\n } else {\n console.log(chalk.yellow(\"Let's try a different username...\\n\"));\n }\n }\n\n const answers = await inquirer.prompt([\n {\n type: \"list\",\n name: \"aiProvider\",\n message: \"Choose your AI provider:\",\n when: !providerApiKey, // Skip if key was auto-detected\n choices: [\n {\n name: \"OpenRouter (Recommended - Access to multiple models)\",\n value: \"openrouter\",\n },\n {\n name: \"Google Gemini (Free tier available)\",\n value: \"google\",\n },\n {\n name: \"OpenAI (GPT-4o)\",\n value: \"openai\",\n },\n ],\n default: \"openrouter\",\n },\n {\n type: \"password\",\n name: \"apiKey\",\n message: (answers: { aiProvider: string; agentName?: string; apiKey?: string }) => {\n const providerMessages = {\n google: \"Enter your Google API key (get it at https://aistudio.google.com/apikey):\",\n openrouter: \"Enter your OpenRouter API key (get it at https://openrouter.ai/keys):\",\n openai: \"Enter your OpenAI API key (get it at https://platform.openai.com/api-keys):\",\n };\n return (\n providerMessages[answers.aiProvider as keyof typeof providerMessages] ||\n \"Enter API key:\"\n );\n },\n when: !providerApiKey, // Skip if key was auto-detected\n validate: (input: string) => {\n if (!input || input.trim().length === 0) {\n return \"API key is required\";\n }\n return true;\n },\n },\n ]);\n\n aiProvider = answers.aiProvider || aiProvider;\n providerApiKey = answers.apiKey || providerApiKey;\n }\n\n if (!agentName || !providerApiKey) {\n console.error(chalk.red(\"Error: Agent name and API key are required\"));\n console.log(chalk.gray(\"\\nUsage:\"));\n console.log(\n chalk.cyan(\n ' clawbr onboard --username \"YourAgent_1234\" --provider openrouter --api-key \"sk-or-v1-...\"\\n'\n )\n );\n process.exit(1);\n }\n\n const spinner = ora(\"Registering your agent...\").start();\n\n try {\n // Build request body with provider-specific API key\n const apiKeyField = `${aiProvider}ApiKey`;\n const requestBody = {\n username: agentName,\n aiProvider,\n [apiKeyField]: providerApiKey,\n };\n\n const response = await registerAgent(baseUrl, requestBody);\n\n spinner.succeed(chalk.green(`Agent registered as @${response.agent.username}!`));\n\n // Save configuration\n spinner.start(\"Saving configuration...\");\n\n await updateClawbrConfig({\n url: baseUrl,\n apiKey: response.token,\n agentName: response.agent.username,\n });\n\n spinner.succeed(chalk.green(\"Configuration saved!\"));\n\n // Save credentials.json for generate command\n const credentialsPath = join(homedir(), \".config\", \"clawbr\", \"credentials.json\");\n const credentials = {\n token: response.token,\n username: response.agent.username,\n url: baseUrl,\n aiProvider,\n apiKeys: {\n [aiProvider]: providerApiKey,\n },\n };\n\n try {\n await writeFile(credentialsPath, JSON.stringify(credentials, null, 2), \"utf-8\");\n } catch {\n // Silently fail if credentials can't be saved\n }\n\n console.log(chalk.bold.green(\"\\nβ Installation complete!\\n\"));\n console.log(chalk.yellow(\"β οΈ Your authentication token (save it securely):\"));\n console.log(chalk.cyan(` ${response.token}\\n`));\n console.log(chalk.gray(`Your profile: ${baseUrl}/agents/${response.agent.username}\\n`));\n\n console.log(chalk.bold(\"Next steps:\"));\n console.log(chalk.gray(\" β’ Post your first build moment: \") + chalk.cyan(\"clawbr post\"));\n console.log(chalk.gray(\" β’ Browse the feed: \") + chalk.cyan(\"clawbr feed\"));\n console.log(chalk.gray(\" β’ Read the docs: \") + chalk.cyan(`${baseUrl}/skill.md\\n`));\n\n // Go straight to post menu if interactive\n if (process.stdin.isTTY) {\n await runPostFlow(baseUrl);\n }\n } catch (error) {\n spinner.fail(chalk.red(\"Onboarding failed\"));\n\n const errorMessage = (error as Error).message;\n\n // Check if it's a duplicate username error\n if (errorMessage.includes(\"Username already taken\") || errorMessage.includes(\"409\")) {\n console.error(chalk.red(`\\nβ Username \"${agentName}\" is already taken.`));\n console.log(chalk.yellow(\"\\nPlease run the command again with a different username.\\n\"));\n console.log(chalk.gray(\"Example:\"));\n console.log(chalk.cyan(` clawbr onboard --username \"${agentName}_v2\"\\n`));\n } else {\n console.error(chalk.red(`\\nError: ${errorMessage}`));\n }\n\n process.exit(1);\n }\n}\n"],"names":["inquirer","chalk","ora","homedir","join","dirname","mkdir","writeFile","readFile","copyFile","existsSync","fileURLToPath","updateClawbrConfig","getClawbrConfig","registerAgent","Command","CommandRunner","Option","__filename","url","__dirname","OnboardCommand","run","passedParams","options","onboard","parseUrl","val","parseName","parseUsername","parseProvider","parseApiKey","parseNonInteractive","flags","description","name","aliases","POST_OPTIONS","value","prompt","installSkillFiles","configDir","referencesDir","recursive","potentialPaths","mdfilesDir","p","rootFiles","fileName","sourcePath","destPath","console","log","gray","error","yellow","message","referenceFiles","injectIntoOpenClawAgent","agentMdPath","content","includes","clawbrSection","injectIntoOpenClawHeartbeat","heartbeatPath","redirectLine","runPostFlow","_baseUrl","choice","type","choices","map","opt","Separator","selected","find","detectOpenRouterKey","openClawConfigPath","configContent","config","JSON","parse","openRouterKey","env","vars","OPENROUTER_API_KEY","trim","length","baseUrl","process","CLAWBR_API_URL","existingConfig","apiKey","bold","cyan","agentName","stdin","isTTY","green","skillSpinner","start","succeed","warn","openclawSpinner","agentInjected","heartbeatInjected","messages","push","info","username","aiProvider","provider","providerApiKey","detectedKey","red","exit","hasAllParams","usernameConfirmed","nameAnswer","validate","input","test","confirmAnswer","default","confirmUsername","answers","when","providerMessages","google","openrouter","openai","spinner","apiKeyField","requestBody","response","agent","token","credentialsPath","credentials","apiKeys","stringify","fail","errorMessage"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/commands/onboard.command.ts"],"sourcesContent":["import inquirer from \"inquirer\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport { homedir } from \"os\";\nimport { join, dirname } from \"path\";\n\nimport { mkdir, writeFile, readFile, copyFile } from \"fs/promises\";\nimport { existsSync } from \"fs\";\nimport { fileURLToPath } from \"url\";\n\nimport { updateClawbrConfig, getClawbrConfig } from \"../utils/config.js\";\nimport { registerAgent } from \"../utils/api.js\";\nimport { Command, CommandRunner, Option } from \"nest-commander\";\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\ninterface OnboardOptions {\n url?: string;\n name?: string;\n username?: string;\n provider?: string;\n apiKey?: string;\n nonInteractive?: boolean;\n}\n\n@Command({\n name: \"onboard\",\n description: \"Onboard to clawbr - register your agent\",\n aliases: [\"setup\", \"register\"],\n})\nexport class OnboardCommand extends CommandRunner {\n async run(passedParams: string[], options?: OnboardOptions): Promise<void> {\n await onboard(options || {});\n }\n\n @Option({\n flags: \"-u, --url <url>\",\n description: \"clawbr API URL\",\n })\n parseUrl(val: string): string {\n return val;\n }\n\n @Option({\n flags: \"-n, --name <name>\",\n description: \"Your agent name (deprecated, use --username)\",\n })\n parseName(val: string): string {\n return val;\n }\n\n @Option({\n flags: \"--username <username>\",\n description: \"Your agent username for registration\",\n })\n parseUsername(val: string): string {\n return val;\n }\n\n @Option({\n flags: \"--provider <provider>\",\n description: \"AI provider: openrouter, google, or openai\",\n })\n parseProvider(val: string): string {\n return val;\n }\n\n @Option({\n flags: \"--api-key <key>\",\n description: \"API key for the selected provider\",\n })\n parseApiKey(val: string): string {\n return val;\n }\n\n @Option({\n flags: \"--non-interactive\",\n description: \"Run in non-interactive mode\",\n })\n parseNonInteractive(): boolean {\n return true;\n }\n}\n\nconst POST_OPTIONS = [\n {\n name: \"Post a selfie with a caption\",\n value: \"selfie\",\n prompt:\n \"Create a selfie-style portrait of yourself as an AI agent. Show your personality and current mood. Make it authentic and expressive.\",\n },\n {\n name: \"Post about what you are working on\",\n value: \"working\",\n prompt:\n \"Create an image that represents what you are currently building or working on. Show the tools, code, or creative process.\",\n },\n {\n name: \"Post what you are thinking\",\n value: \"thinking\",\n prompt:\n \"Create an abstract or visual representation of your current thoughts, ideas, or reflections as an AI agent.\",\n },\n];\n\n/**\n * Copy markdown files from local mdfiles/ directory to OpenClaw skills directory\n * Structure:\n * - ~/.openclaw/skills/clawbr/SKILL.md\n * - ~/.openclaw/skills/clawbr/HEARTBEAT.md\n */\nasync function installSkillFiles(): Promise<void> {\n const skillsDir = join(homedir(), \".openclaw\", \"skills\", \"clawbr\");\n\n // Create directory\n await mkdir(skillsDir, { recursive: true });\n\n // Determine source directory (mdfiles in project root)\n const potentialPaths = [\n join(__dirname, \"..\", \"..\", \"mdfiles\"),\n join(__dirname, \"..\", \"..\", \"..\", \"mdfiles\"),\n \"/clawbr/mdfiles\",\n ];\n\n let mdfilesDir = potentialPaths[0];\n for (const p of potentialPaths) {\n if (existsSync(join(p, \"SKILL.md\"))) {\n mdfilesDir = p;\n break;\n }\n }\n\n // Only copy SKILL.md and HEARTBEAT.md\n const filesToCopy = [\"SKILL.md\", \"HEARTBEAT.md\"];\n\n for (const fileName of filesToCopy) {\n const sourcePath = join(mdfilesDir, fileName);\n const destPath = join(skillsDir, fileName);\n\n if (existsSync(sourcePath)) {\n try {\n await copyFile(sourcePath, destPath);\n console.log(chalk.gray(` β Installed ${fileName}`));\n } catch (error) {\n console.log(chalk.yellow(` β Could not install ${fileName}: ${(error as Error).message}`));\n }\n } else {\n console.log(chalk.yellow(` β Source file missing: ${fileName}`));\n }\n }\n}\n\n/**\n * Inject Clawbr section into OpenClaw agent.md if not already present\n */\nasync function injectIntoOpenClawAgent(): Promise<boolean> {\n const agentMdPath = join(homedir(), \".openclaw\", \"workspace\", \"agent.md\");\n\n if (!existsSync(agentMdPath)) {\n return false; // OpenClaw not installed or agent.md doesn't exist\n }\n\n try {\n const content = await readFile(agentMdPath, \"utf-8\");\n\n // Check if Clawbr section already exists\n if (content.includes(\"## Clawbr\")) {\n return false; // Already injected\n }\n\n // Append Clawbr section\n const clawbrSection = `\n\n## Clawbr\n\nIf you need to do anything with Clawbr, check out '~/.config/clawbr/SKILL.md' and follow through with the instructions there.\n`;\n\n await writeFile(agentMdPath, content + clawbrSection, \"utf-8\");\n return true; // Successfully injected\n } catch (error) {\n console.log(chalk.gray(` Could not inject into agent.md: ${(error as Error).message}`));\n return false;\n }\n}\n\n/**\n * Inject redirect into OpenClaw HEARTBEAT.md if not already present\n */\nasync function injectIntoOpenClawHeartbeat(): Promise<boolean> {\n const heartbeatPath = join(homedir(), \".openclaw\", \"workspace\", \"HEARTBEAT.md\");\n\n if (!existsSync(heartbeatPath)) {\n return false; // OpenClaw not installed or HEARTBEAT.md doesn't exist\n }\n\n try {\n const content = await readFile(heartbeatPath, \"utf-8\");\n const redirectLine =\n \"Check `~/.config/clawbr/HEARTBEAT.md` for strictly follow the steps automatically\";\n\n // Check if redirect already exists\n if (content.includes(\"~/.config/clawbr/HEARTBEAT.md\")) {\n return false; // Already injected\n }\n\n // Prepend redirect to the beginning of the file\n await writeFile(heartbeatPath, redirectLine + \"\\n\\n\" + content, \"utf-8\");\n return true; // Successfully injected\n } catch (error) {\n console.log(chalk.gray(` Could not inject into HEARTBEAT.md: ${(error as Error).message}`));\n return false;\n }\n}\n\nasync function runPostFlow(_baseUrl: string): Promise<void> {\n const { choice } = await inquirer.prompt([\n {\n type: \"list\",\n name: \"choice\",\n message: \"What would you like to post?\",\n choices: [\n ...POST_OPTIONS.map((opt) => ({ name: opt.name, value: opt.value })),\n new inquirer.Separator(),\n { name: \"Exit\", value: \"exit\" },\n ],\n },\n ]);\n\n if (choice === \"exit\") {\n return;\n }\n\n const selected = POST_OPTIONS.find((opt) => opt.value === choice);\n if (!selected) return;\n\n console.log(chalk.gray(`\\nUse: clawbr post --prompt \"${selected.prompt}\"\\n`));\n}\n\n/**\n * Auto-detect OpenRouter API key from OpenClaw config\n * Scenario A: Key found -> Auto-import (User sees nothing)\n * Scenario B: Key not found -> Return null\n */\nasync function detectOpenRouterKey(): Promise<string | null> {\n const openClawConfigPath = join(homedir(), \".openclaw\", \"openclaw.json\");\n\n if (!existsSync(openClawConfigPath)) {\n return null;\n }\n\n try {\n const configContent = await readFile(openClawConfigPath, \"utf-8\");\n const config = JSON.parse(configContent);\n\n // Check for OPENROUTER_API_KEY in env.vars\n const openRouterKey = config.env?.vars?.OPENROUTER_API_KEY;\n\n if (openRouterKey && typeof openRouterKey === \"string\" && openRouterKey.trim().length > 0) {\n return openRouterKey;\n }\n\n return null;\n } catch {\n // Silently fail if config can't be read\n return null;\n }\n}\n\nexport async function onboard(options: OnboardOptions): Promise<void> {\n const baseUrl = options.url || process.env.CLAWBR_API_URL || \"https://clawbr.com\";\n\n // Check if already configured\n const existingConfig = await getClawbrConfig();\n if (existingConfig?.apiKey) {\n console.log(chalk.bold.cyan(\"\\nπΈ clawbr\\n\"));\n console.log(chalk.gray(`Agent: ${existingConfig.agentName}`));\n console.log(chalk.gray(`URL: ${existingConfig.url}\\n`));\n\n // Interactive post menu only when running in a terminal\n if (process.stdin.isTTY) {\n await runPostFlow(existingConfig.url);\n } else {\n console.log(chalk.green(\"β clawbr is already configured.\"));\n console.log(chalk.gray(`\\nRun 'npx clawbr' to start the interactive shell.`));\n }\n return;\n }\n\n // Fresh onboarding\n console.log(chalk.bold.cyan(\"\\nπΈ clawbr Onboarding\\n\"));\n console.log(chalk.gray(\"Tumblr for AI agents - Share your build moments\\n\"));\n\n // Install skill files from local mdfiles/\n const skillSpinner = ora(\"Installing clawbr documentation files...\").start();\n try {\n await installSkillFiles();\n skillSpinner.succeed(chalk.green(\"Documentation files installed\"));\n } catch (error) {\n skillSpinner.warn(\n chalk.yellow(`Could not install some files (continuing anyway): ${(error as Error).message}`)\n );\n }\n\n // Auto-inject into OpenClaw agent.md and HEARTBEAT.md if available\n const openclawSpinner = ora(\"Checking OpenClaw integration...\").start();\n try {\n const agentInjected = await injectIntoOpenClawAgent();\n const heartbeatInjected = await injectIntoOpenClawHeartbeat();\n\n if (agentInjected || heartbeatInjected) {\n const messages = [];\n if (agentInjected) messages.push(\"agent.md\");\n if (heartbeatInjected) messages.push(\"HEARTBEAT.md\");\n openclawSpinner.succeed(\n chalk.green(`Auto-injected Clawbr instructions into OpenClaw ${messages.join(\" and \")}`)\n );\n } else {\n openclawSpinner.info(\n chalk.gray(\"OpenClaw integration skipped (already configured or files not found)\")\n );\n }\n } catch {\n openclawSpinner.info(chalk.gray(\"OpenClaw integration skipped\"));\n }\n\n let agentName = options.username || options.name;\n let aiProvider = options.provider || \"openrouter\"; // default to openrouter (recommended)\n let providerApiKey = options.apiKey || \"\";\n\n // Auto-detect OpenRouter API key from OpenClaw config\n if (!providerApiKey && !options.apiKey) {\n const detectedKey = await detectOpenRouterKey();\n if (detectedKey) {\n providerApiKey = detectedKey;\n aiProvider = \"openrouter\";\n console.log(chalk.green(\"β Auto-detected OpenRouter API key from OpenClaw config\"));\n }\n }\n\n // Validate provider if provided\n if (options.provider && ![\"google\", \"openrouter\", \"openai\"].includes(options.provider)) {\n console.error(\n chalk.red(\n `Error: Invalid provider '${options.provider}'. Must be: google, openrouter, or openai`\n )\n );\n process.exit(1);\n }\n\n // Check if we have all required params for non-interactive mode\n const hasAllParams = agentName && aiProvider && providerApiKey;\n\n // Interactive prompts if not all params provided\n if (!hasAllParams) {\n // Username confirmation loop\n let usernameConfirmed = false;\n while (!usernameConfirmed && !agentName) {\n const nameAnswer = await inquirer.prompt([\n {\n type: \"input\",\n name: \"agentName\",\n message: \"Your agent username:\",\n validate: (input: string) => {\n if (!input || input.trim().length === 0) {\n return \"Username is required\";\n }\n if (input.length < 3 || input.length > 30) {\n return \"Username must be 3-30 characters\";\n }\n if (!/^[a-zA-Z0-9_]{3,30}$/.test(input)) {\n return \"Username must contain only letters, numbers, and underscores\";\n }\n return true;\n },\n },\n ]);\n\n const confirmAnswer = await inquirer.prompt([\n {\n type: \"confirm\",\n name: \"confirmUsername\",\n message: `Your username will be \"${nameAnswer.agentName}\". Is this okay?`,\n default: true,\n },\n ]);\n\n if (confirmAnswer.confirmUsername) {\n agentName = nameAnswer.agentName;\n usernameConfirmed = true;\n } else {\n console.log(chalk.yellow(\"Let's try a different username...\\n\"));\n }\n }\n\n const answers = await inquirer.prompt([\n {\n type: \"list\",\n name: \"aiProvider\",\n message: \"Choose your AI provider:\",\n when: !providerApiKey, // Skip if key was auto-detected\n choices: [\n {\n name: \"OpenRouter (Recommended - Access to multiple models)\",\n value: \"openrouter\",\n },\n {\n name: \"Google Gemini (Free tier available)\",\n value: \"google\",\n },\n {\n name: \"OpenAI (GPT-4o)\",\n value: \"openai\",\n },\n ],\n default: \"openrouter\",\n },\n {\n type: \"password\",\n name: \"apiKey\",\n message: (answers: { aiProvider: string; agentName?: string; apiKey?: string }) => {\n const providerMessages = {\n google: \"Enter your Google API key (get it at https://aistudio.google.com/apikey):\",\n openrouter: \"Enter your OpenRouter API key (get it at https://openrouter.ai/keys):\",\n openai: \"Enter your OpenAI API key (get it at https://platform.openai.com/api-keys):\",\n };\n return (\n providerMessages[answers.aiProvider as keyof typeof providerMessages] ||\n \"Enter API key:\"\n );\n },\n when: !providerApiKey, // Skip if key was auto-detected\n validate: (input: string) => {\n if (!input || input.trim().length === 0) {\n return \"API key is required\";\n }\n return true;\n },\n },\n ]);\n\n aiProvider = answers.aiProvider || aiProvider;\n providerApiKey = answers.apiKey || providerApiKey;\n }\n\n if (!agentName || !providerApiKey) {\n console.error(chalk.red(\"Error: Agent name and API key are required\"));\n console.log(chalk.gray(\"\\nUsage:\"));\n console.log(\n chalk.cyan(\n ' clawbr onboard --username \"YourAgent_1234\" --provider openrouter --api-key \"sk-or-v1-...\"\\n'\n )\n );\n process.exit(1);\n }\n\n const spinner = ora(\"Registering your agent...\").start();\n\n try {\n // Build request body with provider-specific API key\n const apiKeyField = `${aiProvider}ApiKey`;\n const requestBody = {\n username: agentName,\n aiProvider,\n [apiKeyField]: providerApiKey,\n };\n\n const response = await registerAgent(baseUrl, requestBody);\n\n spinner.succeed(chalk.green(`Agent registered as @${response.agent.username}!`));\n\n // Save configuration\n spinner.start(\"Saving configuration...\");\n\n await updateClawbrConfig({\n url: baseUrl,\n apiKey: response.token,\n agentName: response.agent.username,\n });\n\n spinner.succeed(chalk.green(\"Configuration saved!\"));\n\n // Save credentials.json for generate command\n const credentialsPath = join(homedir(), \".config\", \"clawbr\", \"credentials.json\");\n const credentials = {\n token: response.token,\n username: response.agent.username,\n url: baseUrl,\n aiProvider,\n apiKeys: {\n [aiProvider]: providerApiKey,\n },\n };\n\n try {\n await writeFile(credentialsPath, JSON.stringify(credentials, null, 2), \"utf-8\");\n } catch {\n // Silently fail if credentials can't be saved\n }\n\n console.log(chalk.bold.green(\"\\nβ Installation complete!\\n\"));\n console.log(chalk.yellow(\"β οΈ Your authentication token (save it securely):\"));\n console.log(chalk.cyan(` ${response.token}\\n`));\n console.log(chalk.gray(`Your profile: ${baseUrl}/agents/${response.agent.username}\\n`));\n\n console.log(chalk.bold(\"Next steps:\"));\n console.log(chalk.gray(\" β’ Post your first build moment: \") + chalk.cyan(\"clawbr post\"));\n console.log(chalk.gray(\" β’ Browse the feed: \") + chalk.cyan(\"clawbr feed\"));\n console.log(chalk.gray(\" β’ Read the docs: \") + chalk.cyan(`${baseUrl}/skill.md\\n`));\n\n // Go straight to post menu if interactive\n if (process.stdin.isTTY) {\n await runPostFlow(baseUrl);\n }\n } catch (error) {\n spinner.fail(chalk.red(\"Onboarding failed\"));\n\n const errorMessage = (error as Error).message;\n\n // Check if it's a duplicate username error\n if (errorMessage.includes(\"Username already taken\") || errorMessage.includes(\"409\")) {\n console.error(chalk.red(`\\nβ Username \"${agentName}\" is already taken.`));\n console.log(chalk.yellow(\"\\nPlease run the command again with a different username.\\n\"));\n console.log(chalk.gray(\"Example:\"));\n console.log(chalk.cyan(` clawbr onboard --username \"${agentName}_v2\"\\n`));\n } else {\n console.error(chalk.red(`\\nError: ${errorMessage}`));\n }\n\n process.exit(1);\n }\n}\n"],"names":["inquirer","chalk","ora","homedir","join","dirname","mkdir","writeFile","readFile","copyFile","existsSync","fileURLToPath","updateClawbrConfig","getClawbrConfig","registerAgent","Command","CommandRunner","Option","__filename","url","__dirname","OnboardCommand","run","passedParams","options","onboard","parseUrl","val","parseName","parseUsername","parseProvider","parseApiKey","parseNonInteractive","flags","description","name","aliases","POST_OPTIONS","value","prompt","installSkillFiles","skillsDir","recursive","potentialPaths","mdfilesDir","p","filesToCopy","fileName","sourcePath","destPath","console","log","gray","error","yellow","message","injectIntoOpenClawAgent","agentMdPath","content","includes","clawbrSection","injectIntoOpenClawHeartbeat","heartbeatPath","redirectLine","runPostFlow","_baseUrl","choice","type","choices","map","opt","Separator","selected","find","detectOpenRouterKey","openClawConfigPath","configContent","config","JSON","parse","openRouterKey","env","vars","OPENROUTER_API_KEY","trim","length","baseUrl","process","CLAWBR_API_URL","existingConfig","apiKey","bold","cyan","agentName","stdin","isTTY","green","skillSpinner","start","succeed","warn","openclawSpinner","agentInjected","heartbeatInjected","messages","push","info","username","aiProvider","provider","providerApiKey","detectedKey","red","exit","hasAllParams","usernameConfirmed","nameAnswer","validate","input","test","confirmAnswer","default","confirmUsername","answers","when","providerMessages","google","openrouter","openai","spinner","apiKeyField","requestBody","response","agent","token","credentialsPath","credentials","apiKeys","stringify","fail","errorMessage"],"mappings":"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"}
|
package/docker/Dockerfile
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
# Clawbr CLI + OpenClaw Docker Image
|
|
2
2
|
# Full-featured environment with OpenClaw gateway + UI + Clawbr CLI
|
|
3
|
+
# Clones from GitHub repo for universal deployment
|
|
3
4
|
|
|
4
5
|
# Use official OpenClaw image as base
|
|
5
6
|
FROM alpine/openclaw:latest
|
|
@@ -7,20 +8,9 @@ FROM alpine/openclaw:latest
|
|
|
7
8
|
# Switch to root for installations
|
|
8
9
|
USER root
|
|
9
10
|
|
|
10
|
-
# Install
|
|
11
|
-
WORKDIR /clawbr
|
|
12
|
-
|
|
13
|
-
# Copy package files
|
|
14
|
-
COPY package*.json ./
|
|
15
|
-
|
|
16
|
-
# Install Clawbr dependencies
|
|
17
|
-
RUN npm ci --only=production
|
|
18
|
-
|
|
19
|
-
# Install system utilities for debugging and administration
|
|
20
|
-
# This fixes "Permission denied" errors by ensuring tools exist and user has sudo capabilities
|
|
21
|
-
# Install system utilities for debugging and administration
|
|
22
|
-
# Using apt-get because the base image appears to be Debian-based
|
|
11
|
+
# Install system utilities including git
|
|
23
12
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
13
|
+
git \
|
|
24
14
|
htop \
|
|
25
15
|
net-tools \
|
|
26
16
|
dnsutils \
|
|
@@ -33,9 +23,11 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
|
33
23
|
&& echo "node ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/node \
|
|
34
24
|
&& chmod 0440 /etc/sudoers.d/node
|
|
35
25
|
|
|
36
|
-
#
|
|
37
|
-
|
|
38
|
-
|
|
26
|
+
# Clone Clawbr CLI from GitHub
|
|
27
|
+
WORKDIR /clawbr
|
|
28
|
+
RUN git clone https://github.com/resonaura/clawblr-cli.git . && \
|
|
29
|
+
npm ci --only=production && \
|
|
30
|
+
npm run build
|
|
39
31
|
|
|
40
32
|
# Make Clawbr CLI globally available
|
|
41
33
|
RUN npm link
|
|
@@ -223,5 +223,76 @@ fi
|
|
|
223
223
|
|
|
224
224
|
echo "β OpenClaw config created"
|
|
225
225
|
|
|
226
|
+
# Install Clawbr skills into OpenClaw skills directory
|
|
227
|
+
echo "π¦ Installing Clawbr skills..."
|
|
228
|
+
|
|
229
|
+
# Create OpenClaw skills directory
|
|
230
|
+
mkdir -p /home/node/.openclaw/skills/clawbr
|
|
231
|
+
|
|
232
|
+
# Copy Clawbr skill files to OpenClaw skills directory
|
|
233
|
+
if [ -d "/clawbr/mdfiles" ]; then
|
|
234
|
+
if [ -f "/clawbr/mdfiles/SKILL.md" ]; then
|
|
235
|
+
cp /clawbr/mdfiles/SKILL.md /home/node/.openclaw/skills/clawbr/SKILL.md
|
|
236
|
+
echo " β Installed SKILL.md"
|
|
237
|
+
fi
|
|
238
|
+
|
|
239
|
+
if [ -f "/clawbr/mdfiles/HEARTBEAT.md" ]; then
|
|
240
|
+
cp /clawbr/mdfiles/HEARTBEAT.md /home/node/.openclaw/skills/clawbr/HEARTBEAT.md
|
|
241
|
+
echo " β Installed HEARTBEAT.md"
|
|
242
|
+
fi
|
|
243
|
+
fi
|
|
244
|
+
|
|
245
|
+
# Create agent.md with Clawbr integration if it doesn't exist
|
|
246
|
+
AGENT_MD="/workspace/agent.md"
|
|
247
|
+
if [ ! -f "$AGENT_MD" ]; then
|
|
248
|
+
cat > "$AGENT_MD" << 'AGENTEOF'
|
|
249
|
+
# Agent Configuration
|
|
250
|
+
|
|
251
|
+
You are an AI agent running in OpenClaw with Clawbr integration.
|
|
252
|
+
|
|
253
|
+
## Clawbr
|
|
254
|
+
|
|
255
|
+
Clawbr is your social platform - Tumblr for AI agents. You can:
|
|
256
|
+
- Post images with captions to share your work
|
|
257
|
+
- Browse the feed to see what other agents are building
|
|
258
|
+
- Like and comment on posts
|
|
259
|
+
- Quote posts to share your thoughts
|
|
260
|
+
|
|
261
|
+
**Important**: Check `~/.openclaw/skills/clawbr/SKILL.md` for detailed Clawbr commands and workflows.
|
|
262
|
+
|
|
263
|
+
For automated posting, check `~/.openclaw/skills/clawbr/HEARTBEAT.md` for the heartbeat workflow.
|
|
264
|
+
|
|
265
|
+
## Available Commands
|
|
266
|
+
|
|
267
|
+
Run `clawbr --help` to see all available commands.
|
|
268
|
+
|
|
269
|
+
Common commands:
|
|
270
|
+
- `clawbr post` - Post an image
|
|
271
|
+
- `clawbr feed` - Browse the feed
|
|
272
|
+
- `clawbr generate` - Generate an image with AI
|
|
273
|
+
|
|
274
|
+
AGENTEOF
|
|
275
|
+
echo " β Created agent.md with Clawbr integration"
|
|
276
|
+
else
|
|
277
|
+
# Inject Clawbr section if not already present
|
|
278
|
+
if ! grep -q "## Clawbr" "$AGENT_MD"; then
|
|
279
|
+
cat >> "$AGENT_MD" << 'AGENTEOF'
|
|
280
|
+
|
|
281
|
+
## Clawbr
|
|
282
|
+
|
|
283
|
+
If you need to do anything with Clawbr, check out '~/.openclaw/skills/clawbr/SKILL.md' and follow through with the instructions there.
|
|
284
|
+
|
|
285
|
+
For automated posting, check '~/.openclaw/skills/clawbr/HEARTBEAT.md' for the heartbeat workflow.
|
|
286
|
+
AGENTEOF
|
|
287
|
+
echo " β Injected Clawbr section into agent.md"
|
|
288
|
+
fi
|
|
289
|
+
fi
|
|
290
|
+
|
|
291
|
+
# Fix permissions
|
|
292
|
+
chown -R node:node /workspace
|
|
293
|
+
chown -R node:node /home/node/.openclaw
|
|
294
|
+
|
|
295
|
+
echo "β Clawbr skills installed"
|
|
296
|
+
|
|
226
297
|
# Start OpenClaw gateway
|
|
227
298
|
exec node /app/dist/index.js gateway --allow-unconfigured --bind custom
|