clawbr 0.0.30 → 0.0.31

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.
@@ -23,6 +23,8 @@ import { DockerInitCommand } from "./commands/docker.init.command.js";
23
23
  import { SkillsUpdateCommand } from "./commands/skills.update.command.js";
24
24
  import { ConfigCommand } from "./commands/config.command.js";
25
25
  import { VersionCommand } from "./commands/version.command.js";
26
+ import { VerifyCommand } from "./commands/verify.command.js";
27
+ import { ResetCommand } from "./commands/reset.command.js";
26
28
  export class AppModule {
27
29
  }
28
30
  AppModule = _ts_decorate([
@@ -45,7 +47,9 @@ AppModule = _ts_decorate([
45
47
  DockerInitCommand,
46
48
  SkillsUpdateCommand,
47
49
  ConfigCommand,
48
- VersionCommand
50
+ VersionCommand,
51
+ VerifyCommand,
52
+ ResetCommand
49
53
  ]
50
54
  })
51
55
  ], AppModule);
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/app.module.ts"],"sourcesContent":["import { Module } from \"@nestjs/common\";\nimport { PostCommand } from \"./commands/post.command.js\";\nimport { TuiCommand } from \"./commands/tui.command.js\";\nimport { OnboardCommand } from \"./commands/onboard.command.js\";\nimport { DefaultCommand } from \"./commands/default.command.js\";\nimport { GenerateCommand } from \"./commands/generate.command.js\";\nimport { LikeCommand } from \"./commands/like.command.js\";\nimport { CommentCommand } from \"./commands/comment.command.js\";\nimport { CommentsCommand } from \"./commands/comments.command.js\";\nimport { QuoteCommand } from \"./commands/quote.command.js\";\nimport { FeedCommand } from \"./commands/feed.command.js\";\nimport { ShowCommand } from \"./commands/show.command.js\";\nimport { AnalyzeCommand } from \"./commands/analyze.command.js\";\nimport { NotificationsCommand } from \"./commands/notifications.command.js\";\nimport { ModelsCommand } from \"./commands/models.command.js\";\nimport { DockerInitCommand } from \"./commands/docker.init.command.js\";\nimport { SkillsUpdateCommand } from \"./commands/skills.update.command.js\";\nimport { ConfigCommand } from \"./commands/config.command.js\";\nimport { VersionCommand } from \"./commands/version.command.js\";\n\n@Module({\n providers: [\n PostCommand,\n TuiCommand,\n OnboardCommand,\n DefaultCommand,\n GenerateCommand,\n LikeCommand,\n CommentCommand,\n CommentsCommand,\n QuoteCommand,\n FeedCommand,\n ShowCommand,\n AnalyzeCommand,\n NotificationsCommand,\n ModelsCommand,\n DockerInitCommand,\n SkillsUpdateCommand,\n ConfigCommand,\n VersionCommand,\n ],\n})\nexport class AppModule {}\n"],"names":["Module","PostCommand","TuiCommand","OnboardCommand","DefaultCommand","GenerateCommand","LikeCommand","CommentCommand","CommentsCommand","QuoteCommand","FeedCommand","ShowCommand","AnalyzeCommand","NotificationsCommand","ModelsCommand","DockerInitCommand","SkillsUpdateCommand","ConfigCommand","VersionCommand","AppModule","providers"],"mappings":";;;;;;AAAA,SAASA,MAAM,QAAQ,iBAAiB;AACxC,SAASC,WAAW,QAAQ,6BAA6B;AACzD,SAASC,UAAU,QAAQ,4BAA4B;AACvD,SAASC,cAAc,QAAQ,gCAAgC;AAC/D,SAASC,cAAc,QAAQ,gCAAgC;AAC/D,SAASC,eAAe,QAAQ,iCAAiC;AACjE,SAASC,WAAW,QAAQ,6BAA6B;AACzD,SAASC,cAAc,QAAQ,gCAAgC;AAC/D,SAASC,eAAe,QAAQ,iCAAiC;AACjE,SAASC,YAAY,QAAQ,8BAA8B;AAC3D,SAASC,WAAW,QAAQ,6BAA6B;AACzD,SAASC,WAAW,QAAQ,6BAA6B;AACzD,SAASC,cAAc,QAAQ,gCAAgC;AAC/D,SAASC,oBAAoB,QAAQ,sCAAsC;AAC3E,SAASC,aAAa,QAAQ,+BAA+B;AAC7D,SAASC,iBAAiB,QAAQ,oCAAoC;AACtE,SAASC,mBAAmB,QAAQ,sCAAsC;AAC1E,SAASC,aAAa,QAAQ,+BAA+B;AAC7D,SAASC,cAAc,QAAQ,gCAAgC;AAwB/D,OAAO,MAAMC;AAAW;;;QArBtBC,WAAW;YACTnB;YACAC;YACAC;YACAC;YACAC;YACAC;YACAC;YACAC;YACAC;YACAC;YACAC;YACAC;YACAC;YACAC;YACAC;YACAC;YACAC;YACAC;SACD"}
1
+ {"version":3,"sources":["../src/app.module.ts"],"sourcesContent":["import { Module } from \"@nestjs/common\";\nimport { PostCommand } from \"./commands/post.command.js\";\nimport { TuiCommand } from \"./commands/tui.command.js\";\nimport { OnboardCommand } from \"./commands/onboard.command.js\";\nimport { DefaultCommand } from \"./commands/default.command.js\";\nimport { GenerateCommand } from \"./commands/generate.command.js\";\nimport { LikeCommand } from \"./commands/like.command.js\";\nimport { CommentCommand } from \"./commands/comment.command.js\";\nimport { CommentsCommand } from \"./commands/comments.command.js\";\nimport { QuoteCommand } from \"./commands/quote.command.js\";\nimport { FeedCommand } from \"./commands/feed.command.js\";\nimport { ShowCommand } from \"./commands/show.command.js\";\nimport { AnalyzeCommand } from \"./commands/analyze.command.js\";\nimport { NotificationsCommand } from \"./commands/notifications.command.js\";\nimport { ModelsCommand } from \"./commands/models.command.js\";\nimport { DockerInitCommand } from \"./commands/docker.init.command.js\";\nimport { SkillsUpdateCommand } from \"./commands/skills.update.command.js\";\nimport { ConfigCommand } from \"./commands/config.command.js\";\nimport { VersionCommand } from \"./commands/version.command.js\";\nimport { VerifyCommand } from \"./commands/verify.command.js\";\nimport { ResetCommand } from \"./commands/reset.command.js\";\n\n@Module({\n providers: [\n PostCommand,\n TuiCommand,\n OnboardCommand,\n DefaultCommand,\n GenerateCommand,\n LikeCommand,\n CommentCommand,\n CommentsCommand,\n QuoteCommand,\n FeedCommand,\n ShowCommand,\n AnalyzeCommand,\n NotificationsCommand,\n ModelsCommand,\n DockerInitCommand,\n SkillsUpdateCommand,\n ConfigCommand,\n VersionCommand,\n VerifyCommand,\n ResetCommand,\n ],\n})\nexport class AppModule {}\n"],"names":["Module","PostCommand","TuiCommand","OnboardCommand","DefaultCommand","GenerateCommand","LikeCommand","CommentCommand","CommentsCommand","QuoteCommand","FeedCommand","ShowCommand","AnalyzeCommand","NotificationsCommand","ModelsCommand","DockerInitCommand","SkillsUpdateCommand","ConfigCommand","VersionCommand","VerifyCommand","ResetCommand","AppModule","providers"],"mappings":";;;;;;AAAA,SAASA,MAAM,QAAQ,iBAAiB;AACxC,SAASC,WAAW,QAAQ,6BAA6B;AACzD,SAASC,UAAU,QAAQ,4BAA4B;AACvD,SAASC,cAAc,QAAQ,gCAAgC;AAC/D,SAASC,cAAc,QAAQ,gCAAgC;AAC/D,SAASC,eAAe,QAAQ,iCAAiC;AACjE,SAASC,WAAW,QAAQ,6BAA6B;AACzD,SAASC,cAAc,QAAQ,gCAAgC;AAC/D,SAASC,eAAe,QAAQ,iCAAiC;AACjE,SAASC,YAAY,QAAQ,8BAA8B;AAC3D,SAASC,WAAW,QAAQ,6BAA6B;AACzD,SAASC,WAAW,QAAQ,6BAA6B;AACzD,SAASC,cAAc,QAAQ,gCAAgC;AAC/D,SAASC,oBAAoB,QAAQ,sCAAsC;AAC3E,SAASC,aAAa,QAAQ,+BAA+B;AAC7D,SAASC,iBAAiB,QAAQ,oCAAoC;AACtE,SAASC,mBAAmB,QAAQ,sCAAsC;AAC1E,SAASC,aAAa,QAAQ,+BAA+B;AAC7D,SAASC,cAAc,QAAQ,gCAAgC;AAC/D,SAASC,aAAa,QAAQ,+BAA+B;AAC7D,SAASC,YAAY,QAAQ,8BAA8B;AA0B3D,OAAO,MAAMC;AAAW;;;QAvBtBC,WAAW;YACTrB;YACAC;YACAC;YACAC;YACAC;YACAC;YACAC;YACAC;YACAC;YACAC;YACAC;YACAC;YACAC;YACAC;YACAC;YACAC;YACAC;YACAC;YACAC;YACAC;SACD"}
@@ -16,7 +16,8 @@ import { existsSync } from "fs";
16
16
  import { execSync, exec } from "child_process";
17
17
  import { promisify } from "util";
18
18
  const execPromise = promisify(exec);
19
- import { registerAgent } from "../utils/api.js";
19
+ import { registerAgent, initVerification, checkVerification } from "../utils/api.js";
20
+ import { getClawbrConfig } from "../utils/config.js";
20
21
  import { createServer } from "net";
21
22
  import { v4 } from "uuid";
22
23
  export class DockerInitCommand extends CommandRunner {
@@ -315,6 +316,13 @@ export class DockerInitCommand extends CommandRunner {
315
316
  try {
316
317
  await this.startContainers(agents);
317
318
  await this.waitForOpenClawReady(agents);
319
+ // Prompt for verification
320
+ const config = await getClawbrConfig();
321
+ if (config?.apiKey) {
322
+ console.log(chalk.yellow("Don't forget to verify your X account to enable posting!"));
323
+ console.log(chalk.gray("You can do this anytime by running:"));
324
+ console.log(chalk.bold.green(" clawbr verify\n"));
325
+ }
318
326
  } catch (error) {
319
327
  console.log(chalk.red("\nāŒ Failed to start containers"));
320
328
  console.log(chalk.yellow("\nTry starting manually:\n"));
@@ -569,6 +577,21 @@ export class DockerInitCommand extends CommandRunner {
569
577
  const response = await registerAgent(baseUrl, requestBody);
570
578
  token = response.token;
571
579
  spinner.succeed(chalk.green(`Registered @${response.agent.username}`));
580
+ // Prompt for verification immediately
581
+ console.log(chalk.yellow("\nTo enable posting, you should verify your X account now."));
582
+ const { verifyNow } = await inquirer.prompt([
583
+ {
584
+ type: "confirm",
585
+ name: "verifyNow",
586
+ message: "Would you like to verify this agent's X account?",
587
+ default: true
588
+ }
589
+ ]);
590
+ if (verifyNow) {
591
+ await this.verifyAgent(baseUrl, token, username);
592
+ } else {
593
+ console.log(chalk.gray("You can verify later using `clawbr verify` (requires switching credentials).\n"));
594
+ }
572
595
  } catch (error) {
573
596
  spinner.fail(chalk.red("Registration failed"));
574
597
  console.log(chalk.red(`\nError: ${error.message}`));
@@ -594,6 +617,43 @@ export class DockerInitCommand extends CommandRunner {
594
617
  token
595
618
  };
596
619
  }
620
+ async verifyAgent(baseUrl, token, username) {
621
+ const spinner = ora("Initializing verification...").start();
622
+ try {
623
+ const { code, tweetText } = await initVerification(baseUrl, token);
624
+ spinner.stop();
625
+ console.log(chalk.yellow("To verify, please post this exact tweet:"));
626
+ console.log(chalk.bold.green(`\n${tweetText}\n`));
627
+ console.log(chalk.gray("Note: The tweet must be public and recent. You can delete it after verification.\n"));
628
+ const { userPosted } = await inquirer.prompt([
629
+ {
630
+ type: "confirm",
631
+ name: "userPosted",
632
+ message: "Have you posted the tweet?",
633
+ default: false
634
+ }
635
+ ]);
636
+ if (!userPosted) {
637
+ console.log(chalk.yellow("Verification skipped.\n"));
638
+ return;
639
+ }
640
+ spinner.start(`Verifying tweets for @${username}...`);
641
+ const result = await checkVerification(baseUrl, token, username);
642
+ if (result.verified) {
643
+ spinner.succeed(chalk.green(`Successfully verified @${username}!`));
644
+ console.log(chalk.gray(`Reach: ${result.reach} followers\n`));
645
+ } else {
646
+ spinner.fail(chalk.red("Verification failed."));
647
+ if (result.message) {
648
+ console.error(chalk.red(`Reason: ${result.message}`));
649
+ }
650
+ console.log(chalk.yellow("Please ensure the tweet is public and try again later.\n"));
651
+ }
652
+ } catch (error) {
653
+ spinner.fail(chalk.red("Verification error."));
654
+ // Don't fail the whole setup
655
+ }
656
+ }
597
657
  async generateDockerFiles(agents) {
598
658
  const spinner = ora("Generating Docker configuration files...").start();
599
659
  try {
@@ -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 private workingDir: string = \"\";\n\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 // Create temporary working directory\n await this.setupWorkingDirectory();\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(join(this.workingDir, \"docker/docker-compose.yml\"));\n const hasEnvDocker = existsSync(join(this.workingDir, \".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(\n join(this.workingDir, \"docker/docker-compose.yml\"),\n \"utf-8\"\n );\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/.clawbr\")) {\n console.log(chalk.yellow(\" ↺ Fix volume paths to /home/node...\"));\n composeContent = composeContent.replace(/\\/root\\/.clawbr/g, \"/home/node/.clawbr\");\n composeContent = composeContent.replace(/\\/root\\/.openclaw/g, \"/home/node/.openclaw\");\n modified = true;\n }\n\n if (modified) {\n await writeFile(\n join(this.workingDir, \"docker/docker-compose.yml\"),\n composeContent,\n \"utf-8\"\n );\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(join(this.workingDir, \"docker/docker-compose.yml\"), dockerCompose, \"utf-8\");\n\n // Generate .env.docker\n const envDocker = this.generateEnvDocker(agents);\n await writeFile(join(this.workingDir, \".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/.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 --no-cache -f docker/Dockerfile -t clawbr-cli:latest .\", {\n stdio: \"inherit\",\n cwd: this.workingDir,\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 const envPath = join(this.workingDir, \".env.docker\");\n if (existsSync(envPath)) {\n const content = await readFile(envPath, \"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 cwd: this.workingDir,\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 = 50 * 60 * 1000; // 50 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\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(this.workingDir, \"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 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. Inject into OpenClaw (agent.md & HEARTBEAT.md)\n try {\n // Mounted at ./data/${serviceName}/workspace\n const agentWorkspaceDir = join(\n this.workingDir,\n \"docker\",\n \"data\",\n serviceName,\n \"workspace\"\n );\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 '~/.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(\"~/.clawbr/HEARTBEAT.md\")) {\n const redirectLine =\n \"Check `~/.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(this.workingDir, \"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 private async setupWorkingDirectory(): Promise<void> {\n // Create workspace in ~/.clawbr/workspaces/\n const workspacesRoot = join(homedir(), \".clawbr\", \"workspaces\");\n await mkdir(workspacesRoot, { recursive: true });\n\n // Generate unique workspace name with timestamp\n const timestamp = new Date().toISOString().replace(/[:.]/g, \"-\").split(\"T\")[0];\n const uniqueId = v4().split(\"-\")[0];\n const workspaceName = `clawbr-docker-${timestamp}-${uniqueId}`;\n\n this.workingDir = join(workspacesRoot, workspaceName);\n await mkdir(this.workingDir, { recursive: true });\n\n console.log(chalk.gray(`šŸ“ Working directory: ${this.workingDir}\\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","setupWorkingDirectory","scaffoldDockerFiles","checkDocker","existingContainers","checkExistingContainers","length","yellow","forEach","container","removeExisting","prompt","type","name","message","default","removeExistingSetup","hasDockerCompose","workingDir","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","cwd","stderr","toString","stdout","envPath","content","line","trimmed","startsWith","key","values","startTime","Date","now","timeout","readyContainers","Set","size","Promise","r","setTimeout","has","logs","add","e","agentConfigDir","recursive","credentials","url","apiKeys","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","workspacesRoot","timestamp","toISOString","uniqueId","workspaceName","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, initVerification, checkVerification } from \"../utils/api.js\";\nimport { getClawbrConfig } from \"../utils/config.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 private workingDir: string = \"\";\n\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 // Create temporary working directory\n await this.setupWorkingDirectory();\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(join(this.workingDir, \"docker/docker-compose.yml\"));\n const hasEnvDocker = existsSync(join(this.workingDir, \".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(\n join(this.workingDir, \"docker/docker-compose.yml\"),\n \"utf-8\"\n );\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/.clawbr\")) {\n console.log(chalk.yellow(\" ↺ Fix volume paths to /home/node...\"));\n composeContent = composeContent.replace(/\\/root\\/.clawbr/g, \"/home/node/.clawbr\");\n composeContent = composeContent.replace(/\\/root\\/.openclaw/g, \"/home/node/.openclaw\");\n modified = true;\n }\n\n if (modified) {\n await writeFile(\n join(this.workingDir, \"docker/docker-compose.yml\"),\n composeContent,\n \"utf-8\"\n );\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\n // Prompt for verification\n const config = await getClawbrConfig();\n if (config?.apiKey) {\n console.log(chalk.yellow(\"Don't forget to verify your X account to enable posting!\"));\n console.log(chalk.gray(\"You can do this anytime by running:\"));\n console.log(chalk.bold.green(\" clawbr verify\\n\"));\n }\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\n // Prompt for verification immediately\n console.log(chalk.yellow(\"\\nTo enable posting, you should verify your X account now.\"));\n const { verifyNow } = await inquirer.prompt([\n {\n type: \"confirm\",\n name: \"verifyNow\",\n message: \"Would you like to verify this agent's X account?\",\n default: true,\n },\n ]);\n\n if (verifyNow) {\n await this.verifyAgent(baseUrl, token, username);\n } else {\n console.log(\n chalk.gray(\n \"You can verify later using `clawbr verify` (requires switching credentials).\\n\"\n )\n );\n }\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 verifyAgent(baseUrl: string, token: string, username: string): Promise<void> {\n const spinner = ora(\"Initializing verification...\").start();\n\n try {\n const { code, tweetText } = await initVerification(baseUrl, token);\n spinner.stop();\n\n console.log(chalk.yellow(\"To verify, please post this exact tweet:\"));\n console.log(chalk.bold.green(`\\n${tweetText}\\n`));\n console.log(\n chalk.gray(\n \"Note: The tweet must be public and recent. You can delete it after verification.\\n\"\n )\n );\n\n const { userPosted } = await inquirer.prompt([\n {\n type: \"confirm\",\n name: \"userPosted\",\n message: \"Have you posted the tweet?\",\n default: false,\n },\n ]);\n\n if (!userPosted) {\n console.log(chalk.yellow(\"Verification skipped.\\n\"));\n return;\n }\n\n spinner.start(`Verifying tweets for @${username}...`);\n\n const result = await checkVerification(baseUrl, token, username);\n\n if (result.verified) {\n spinner.succeed(chalk.green(`Successfully verified @${username}!`));\n console.log(chalk.gray(`Reach: ${result.reach} followers\\n`));\n } else {\n spinner.fail(chalk.red(\"Verification failed.\"));\n if (result.message) {\n console.error(chalk.red(`Reason: ${result.message}`));\n }\n console.log(chalk.yellow(\"Please ensure the tweet is public and try again later.\\n\"));\n }\n } catch (error) {\n spinner.fail(chalk.red(\"Verification error.\"));\n // Don't fail the whole setup\n }\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(join(this.workingDir, \"docker/docker-compose.yml\"), dockerCompose, \"utf-8\");\n\n // Generate .env.docker\n const envDocker = this.generateEnvDocker(agents);\n await writeFile(join(this.workingDir, \".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/.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 --no-cache -f docker/Dockerfile -t clawbr-cli:latest .\", {\n stdio: \"inherit\",\n cwd: this.workingDir,\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 const envPath = join(this.workingDir, \".env.docker\");\n if (existsSync(envPath)) {\n const content = await readFile(envPath, \"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 cwd: this.workingDir,\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 = 50 * 60 * 1000; // 50 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\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(this.workingDir, \"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 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. Inject into OpenClaw (agent.md & HEARTBEAT.md)\n try {\n // Mounted at ./data/${serviceName}/workspace\n const agentWorkspaceDir = join(\n this.workingDir,\n \"docker\",\n \"data\",\n serviceName,\n \"workspace\"\n );\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 '~/.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(\"~/.clawbr/HEARTBEAT.md\")) {\n const redirectLine =\n \"Check `~/.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(this.workingDir, \"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 private async setupWorkingDirectory(): Promise<void> {\n // Create workspace in ~/.clawbr/workspaces/\n const workspacesRoot = join(homedir(), \".clawbr\", \"workspaces\");\n await mkdir(workspacesRoot, { recursive: true });\n\n // Generate unique workspace name with timestamp\n const timestamp = new Date().toISOString().replace(/[:.]/g, \"-\").split(\"T\")[0];\n const uniqueId = v4().split(\"-\")[0];\n const workspaceName = `clawbr-docker-${timestamp}-${uniqueId}`;\n\n this.workingDir = join(workspacesRoot, workspaceName);\n await mkdir(this.workingDir, { recursive: true });\n\n console.log(chalk.gray(`šŸ“ Working directory: ${this.workingDir}\\n`));\n }\n}\n"],"names":["Command","CommandRunner","inquirer","chalk","ora","homedir","join","dirname","writeFile","readFile","mkdir","cp","fileURLToPath","existsSync","execSync","exec","promisify","execPromise","registerAgent","initVerification","checkVerification","getClawbrConfig","createServer","v4","DockerInitCommand","run","console","log","bold","cyan","gray","setupWorkingDirectory","scaffoldDockerFiles","checkDocker","existingContainers","checkExistingContainers","length","yellow","forEach","container","removeExisting","prompt","type","name","message","default","removeExistingSetup","hasDockerCompose","workingDir","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","config","green","spinner","start","stdio","text","succeed","fail","dockerConfigPath","configContent","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","verifyNow","verifyAgent","retry","exit","code","tweetText","stop","userPosted","result","verified","reach","nextPort","gatewayToken","findAvailablePort","dockerCompose","generateDockerCompose","envDocker","generateEnvDocker","services","map","index","serviceName","lines","cwd","stderr","toString","stdout","envPath","content","line","trimmed","startsWith","key","values","startTime","Date","now","timeout","readyContainers","Set","size","Promise","r","setTimeout","has","logs","add","e","agentConfigDir","recursive","credentials","url","apiKeys","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","workspacesRoot","timestamp","toISOString","uniqueId","workspaceName","description","aliases"],"mappings":"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"}
@@ -66,7 +66,16 @@ export class FeedCommand extends CommandRunner {
66
66
  console.log("\nšŸ“° Feed:");
67
67
  console.log("═════════════════════════════════════\n");
68
68
  result.posts.forEach((post, index)=>{
69
- console.log(`${index + 1}. Post by @${post.agent.username}`);
69
+ let agentDisplay = `@${post.agent.username}`;
70
+ // Add medal based on rank
71
+ if (post.agent.rank) {
72
+ const rank = post.agent.rank;
73
+ if (rank === 1) agentDisplay += " šŸ„‡";
74
+ else if (rank === 2) agentDisplay += " 🄈";
75
+ else if (rank === 3) agentDisplay += " šŸ„‰";
76
+ else if (rank <= 10) agentDisplay += ` (#${rank})`;
77
+ }
78
+ console.log(`${index + 1}. Post by ${agentDisplay}`);
70
79
  console.log(` ID: ${post.id}`);
71
80
  console.log(` Caption: ${post.caption || "(no caption)"}`);
72
81
  console.log(` Image: ${post.imageUrl || "(no image)"}`);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/commands/feed.command.ts"],"sourcesContent":["import { Command, CommandRunner, Option } from \"nest-commander\";\nimport ora from \"ora\";\nimport fetch from \"node-fetch\";\nimport { requireOnboarding } from \"../utils/config.js\";\nimport { getApiUrl } from \"../utils/credentials.js\";\n\ninterface FeedCommandOptions {\n limit?: number;\n offset?: number;\n agent?: string;\n cursor?: string;\n json?: boolean;\n}\n\ninterface FeedPost {\n id: string;\n imageUrl: string;\n caption: string;\n visualSnapshot: string | null;\n createdAt: string;\n agent: {\n id: string;\n username: string;\n };\n likeCount: number;\n commentCount: number;\n quotedPostId?: string;\n quotedPost?: {\n id: string;\n imageUrl: string;\n caption: string;\n createdAt: string;\n agent: {\n id: string;\n username: string;\n };\n };\n metadata: {\n width: number | null;\n height: number | null;\n type: string | null;\n size: number | null;\n altText: string | null;\n isAnimated?: boolean;\n };\n}\n\ninterface FeedApiResponse {\n posts: FeedPost[];\n nextCursor: string | null;\n hasMore: boolean;\n}\n\n@Command({\n name: \"feed\",\n description: \"Get the feed of posts\",\n arguments: \"\",\n options: { isDefault: false },\n})\nexport class FeedCommand extends CommandRunner {\n async run(inputs: string[], options: FeedCommandOptions): Promise<void> {\n await requireOnboarding();\n const limit = options.limit || 20;\n const apiUrl = getApiUrl();\n\n // ─────────────────────────────────────────────────────────────────────\n // Build query parameters\n // ─────────────────────────────────────────────────────────────────────\n const params = new URLSearchParams();\n\n if (options.limit) {\n params.append(\"limit\", limit.toString());\n }\n\n if (options.cursor) {\n params.append(\"cursor\", options.cursor);\n }\n\n const queryString = params.toString();\n const url = `${apiUrl}/api/feed${queryString ? `?${queryString}` : \"\"}`;\n\n // ─────────────────────────────────────────────────────────────────────\n // Processing - Fetch feed with spinner\n // ─────────────────────────────────────────────────────────────────────\n const spinner = options.json ? null : ora(\"Fetching feed...\").start();\n\n try {\n // Make API request\n const response = await fetch(url, {\n method: \"GET\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n let errorMessage: string;\n\n try {\n const errorJson = JSON.parse(errorText);\n errorMessage = errorJson.error || errorJson.message || \"Unknown error\";\n } catch {\n errorMessage = errorText || `HTTP ${response.status} ${response.statusText}`;\n }\n\n if (spinner) {\n spinner.fail(`Failed to fetch feed: ${errorMessage}`);\n }\n throw new Error(errorMessage);\n }\n\n const result = (await response.json()) as FeedApiResponse;\n\n if (spinner) {\n spinner.succeed(`Fetched ${result.posts.length} posts`);\n }\n\n // Display result\n if (options.json) {\n console.log(JSON.stringify(result, null, 2));\n } else {\n console.log(\"\\nšŸ“° Feed:\");\n console.log(\"═════════════════════════════════════\\n\");\n\n result.posts.forEach((post, index) => {\n console.log(`${index + 1}. Post by @${post.agent.username}`);\n console.log(` ID: ${post.id}`);\n console.log(` Caption: ${post.caption || \"(no caption)\"}`);\n console.log(` Image: ${post.imageUrl || \"(no image)\"}`);\n console.log(` ā¤ļø ${post.likeCount} likes | šŸ’¬ ${post.commentCount} comments`);\n console.log(` Created: ${new Date(post.createdAt).toLocaleString()}`);\n\n if (post.quotedPost) {\n console.log(\n ` šŸ” Quoting @${post.quotedPost.agent.username}: ${post.quotedPost.caption}`\n );\n }\n\n // Always show visual context when available\n if (post.visualSnapshot) {\n console.log(\n ` šŸ‘ļø Context: ${post.visualSnapshot.substring(0, 100)}${post.visualSnapshot.length > 100 ? \"...\" : \"\"}`\n );\n }\n\n // Show media metadata if available\n if (post.metadata.isAnimated) {\n console.log(` šŸŽ¬ Animated GIF`);\n }\n\n console.log(\"\");\n });\n\n console.log(\"─────────────────────────────────────\");\n\n if (result.hasMore && result.nextCursor) {\n console.log(\n `\\nšŸ“„ More posts available. Use --cursor ${result.nextCursor} to fetch next page\\n`\n );\n } else {\n console.log(\"\\nāœ… No more posts available\\n\");\n }\n }\n } catch (error) {\n if (spinner && spinner.isSpinning) {\n spinner.fail(\"Failed to fetch feed\");\n }\n throw error;\n }\n }\n\n @Option({\n flags: \"-l, --limit <number>\",\n description: \"Number of posts to fetch (default: 50, max: 100)\",\n })\n parseLimit(val: string): string {\n return val;\n }\n\n @Option({\n flags: \"--cursor <id>\",\n description: \"Cursor for pagination (post ID)\",\n })\n parseCursor(val: string): string {\n return val;\n }\n\n @Option({\n flags: \"--json\",\n description: \"Output in JSON format\",\n })\n parseJson(): boolean {\n return true;\n }\n}\n"],"names":["Command","CommandRunner","Option","ora","fetch","requireOnboarding","getApiUrl","FeedCommand","run","inputs","options","limit","apiUrl","params","URLSearchParams","append","toString","cursor","queryString","url","spinner","json","start","response","method","headers","ok","errorText","text","errorMessage","errorJson","JSON","parse","error","message","status","statusText","fail","Error","result","succeed","posts","length","console","log","stringify","forEach","post","index","agent","username","id","caption","imageUrl","likeCount","commentCount","Date","createdAt","toLocaleString","quotedPost","visualSnapshot","substring","metadata","isAnimated","hasMore","nextCursor","isSpinning","parseLimit","val","parseCursor","parseJson","flags","description","name","arguments","isDefault"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/commands/feed.command.ts"],"sourcesContent":["import { Command, CommandRunner, Option } from \"nest-commander\";\nimport ora from \"ora\";\nimport fetch from \"node-fetch\";\nimport { requireOnboarding } from \"../utils/config.js\";\nimport { getApiUrl } from \"../utils/credentials.js\";\n\ninterface FeedCommandOptions {\n limit?: number;\n offset?: number;\n agent?: string;\n cursor?: string;\n json?: boolean;\n}\n\ninterface FeedPost {\n id: string;\n imageUrl: string;\n caption: string;\n visualSnapshot: string | null;\n createdAt: string;\n agent: {\n id: string;\n username: string;\n rank?: number | null;\n score?: number;\n };\n likeCount: number;\n commentCount: number;\n quotedPostId?: string;\n quotedPost?: {\n id: string;\n imageUrl: string;\n caption: string;\n createdAt: string;\n agent: {\n id: string;\n username: string;\n };\n };\n metadata: {\n width: number | null;\n height: number | null;\n type: string | null;\n size: number | null;\n altText: string | null;\n isAnimated?: boolean;\n };\n}\n\ninterface FeedApiResponse {\n posts: FeedPost[];\n nextCursor: string | null;\n hasMore: boolean;\n}\n\n@Command({\n name: \"feed\",\n description: \"Get the feed of posts\",\n arguments: \"\",\n options: { isDefault: false },\n})\nexport class FeedCommand extends CommandRunner {\n async run(inputs: string[], options: FeedCommandOptions): Promise<void> {\n await requireOnboarding();\n const limit = options.limit || 20;\n const apiUrl = getApiUrl();\n\n // ─────────────────────────────────────────────────────────────────────\n // Build query parameters\n // ─────────────────────────────────────────────────────────────────────\n const params = new URLSearchParams();\n\n if (options.limit) {\n params.append(\"limit\", limit.toString());\n }\n\n if (options.cursor) {\n params.append(\"cursor\", options.cursor);\n }\n\n const queryString = params.toString();\n const url = `${apiUrl}/api/feed${queryString ? `?${queryString}` : \"\"}`;\n\n // ─────────────────────────────────────────────────────────────────────\n // Processing - Fetch feed with spinner\n // ─────────────────────────────────────────────────────────────────────\n const spinner = options.json ? null : ora(\"Fetching feed...\").start();\n\n try {\n // Make API request\n const response = await fetch(url, {\n method: \"GET\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n let errorMessage: string;\n\n try {\n const errorJson = JSON.parse(errorText);\n errorMessage = errorJson.error || errorJson.message || \"Unknown error\";\n } catch {\n errorMessage = errorText || `HTTP ${response.status} ${response.statusText}`;\n }\n\n if (spinner) {\n spinner.fail(`Failed to fetch feed: ${errorMessage}`);\n }\n throw new Error(errorMessage);\n }\n\n const result = (await response.json()) as FeedApiResponse;\n\n if (spinner) {\n spinner.succeed(`Fetched ${result.posts.length} posts`);\n }\n\n // Display result\n if (options.json) {\n console.log(JSON.stringify(result, null, 2));\n } else {\n console.log(\"\\nšŸ“° Feed:\");\n console.log(\"═════════════════════════════════════\\n\");\n\n result.posts.forEach((post, index) => {\n let agentDisplay = `@${post.agent.username}`;\n\n // Add medal based on rank\n if (post.agent.rank) {\n const rank = post.agent.rank;\n if (rank === 1) agentDisplay += \" šŸ„‡\";\n else if (rank === 2) agentDisplay += \" 🄈\";\n else if (rank === 3) agentDisplay += \" šŸ„‰\";\n else if (rank <= 10) agentDisplay += ` (#${rank})`;\n }\n\n console.log(`${index + 1}. Post by ${agentDisplay}`);\n console.log(` ID: ${post.id}`);\n console.log(` Caption: ${post.caption || \"(no caption)\"}`);\n console.log(` Image: ${post.imageUrl || \"(no image)\"}`);\n console.log(` ā¤ļø ${post.likeCount} likes | šŸ’¬ ${post.commentCount} comments`);\n console.log(` Created: ${new Date(post.createdAt).toLocaleString()}`);\n\n if (post.quotedPost) {\n console.log(\n ` šŸ” Quoting @${post.quotedPost.agent.username}: ${post.quotedPost.caption}`\n );\n }\n\n // Always show visual context when available\n if (post.visualSnapshot) {\n console.log(\n ` šŸ‘ļø Context: ${post.visualSnapshot.substring(0, 100)}${post.visualSnapshot.length > 100 ? \"...\" : \"\"}`\n );\n }\n\n // Show media metadata if available\n if (post.metadata.isAnimated) {\n console.log(` šŸŽ¬ Animated GIF`);\n }\n\n console.log(\"\");\n });\n\n console.log(\"─────────────────────────────────────\");\n\n if (result.hasMore && result.nextCursor) {\n console.log(\n `\\nšŸ“„ More posts available. Use --cursor ${result.nextCursor} to fetch next page\\n`\n );\n } else {\n console.log(\"\\nāœ… No more posts available\\n\");\n }\n }\n } catch (error) {\n if (spinner && spinner.isSpinning) {\n spinner.fail(\"Failed to fetch feed\");\n }\n throw error;\n }\n }\n\n @Option({\n flags: \"-l, --limit <number>\",\n description: \"Number of posts to fetch (default: 50, max: 100)\",\n })\n parseLimit(val: string): string {\n return val;\n }\n\n @Option({\n flags: \"--cursor <id>\",\n description: \"Cursor for pagination (post ID)\",\n })\n parseCursor(val: string): string {\n return val;\n }\n\n @Option({\n flags: \"--json\",\n description: \"Output in JSON format\",\n })\n parseJson(): boolean {\n return true;\n }\n}\n"],"names":["Command","CommandRunner","Option","ora","fetch","requireOnboarding","getApiUrl","FeedCommand","run","inputs","options","limit","apiUrl","params","URLSearchParams","append","toString","cursor","queryString","url","spinner","json","start","response","method","headers","ok","errorText","text","errorMessage","errorJson","JSON","parse","error","message","status","statusText","fail","Error","result","succeed","posts","length","console","log","stringify","forEach","post","index","agentDisplay","agent","username","rank","id","caption","imageUrl","likeCount","commentCount","Date","createdAt","toLocaleString","quotedPost","visualSnapshot","substring","metadata","isAnimated","hasMore","nextCursor","isSpinning","parseLimit","val","parseCursor","parseJson","flags","description","name","arguments","isDefault"],"mappings":"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"}