@@ -524,75 +524,6 @@ const NPM_PREFIX_SETUP =
524524 'mkdir -p ~/.npm-global/bin; _NPM_G_FLAGS="--prefix $HOME/.npm-global"; fi; ' +
525525 'export PATH="$HOME/.npm-global/bin:$PATH"' ;
526526
527- // ─── Docker Image Extraction ──────────────────────────────────────────────────
528-
529- const DOCKER_IMAGE_PREFIX = "ghcr.io/openrouterteam/spawn-" ;
530-
531- /**
532- * Try to extract a pre-built agent from a Docker image pulled during cloud-init.
533- * Returns true if extraction succeeded, false if Docker/image unavailable.
534- *
535- * How it works:
536- * 1. Check if Docker is installed and the image was pulled
537- * 2. Create a temporary container from the image
538- * 3. Copy /root/. from the container to /root/ on the host
539- * 4. Remove the temporary container
540- *
541- * The agent then runs natively on the host (not in a container).
542- */
543- async function tryInstallFromDocker ( runner : CloudRunner , agentName : string , dockerImage : string ) : Promise < boolean > {
544- logStep ( `Checking for pre-built Docker image (${ agentName } )...` ) ;
545- const script = [
546- // Bail if Docker isn't installed
547- "command -v docker >/dev/null 2>&1 || { echo '==> Docker not installed'; exit 1; }" ,
548- // Poll for image availability — cloud-init started the pull in the background.
549- // We can't rely on pgrep because the docker CLI exits while dockerd continues pulling.
550- "_elapsed=0; _max=300" ,
551- `while ! docker images -q "${ dockerImage } " 2>/dev/null | grep -q .; do` ,
552- ` if [ $_elapsed -ge $_max ]; then echo "==> Timed out waiting for ${ dockerImage } "; exit 1; fi` ,
553- ' if [ $_elapsed -eq 0 ]; then echo "==> Waiting for Docker image pull to complete..."; fi' ,
554- " sleep 5; _elapsed=$((_elapsed + 5))" ,
555- "done" ,
556- // Create temp container, copy only known agent directories, clean up
557- `_cid=$(docker create "${ dockerImage } ")` ,
558- 'docker cp "$_cid":/root/.claude /root/ 2>/dev/null || true' ,
559- 'docker cp "$_cid":/root/.bun /root/ 2>/dev/null || true' ,
560- 'docker cp "$_cid":/root/.local /root/ 2>/dev/null || true' ,
561- 'docker cp "$_cid":/root/.npm /root/ 2>/dev/null || true' ,
562- 'docker cp "$_cid":/root/.cargo /root/ 2>/dev/null || true' ,
563- 'docker cp "$_cid":/root/.opencode /root/ 2>/dev/null || true' ,
564- 'docker rm "$_cid" >/dev/null' ,
565- 'echo "==> Agent extracted from Docker image"' ,
566- ] . join ( "\n" ) ;
567-
568- try {
569- await runner . runServer ( script , 600 ) ;
570- logInfo ( `${ agentName } extracted from Docker image` ) ;
571- return true ;
572- } catch {
573- logInfo ( "Docker image not available, falling back to normal install" ) ;
574- return false ;
575- }
576- }
577-
578- /**
579- * Wrap an agent's install function with Docker image extraction.
580- * Tries Docker first; falls back to the original install if unavailable.
581- */
582- function withDockerInstall (
583- runner : CloudRunner ,
584- agentName : string ,
585- dockerImage : string ,
586- originalInstall : ( ) => Promise < void > ,
587- ) : ( ) => Promise < void > {
588- return async ( ) => {
589- const extracted = await tryInstallFromDocker ( runner , agentName , dockerImage ) ;
590- if ( ! extracted ) {
591- await originalInstall ( ) ;
592- }
593- } ;
594- }
595-
596527// ─── Default Agent Definitions ───────────────────────────────────────────────
597528
598529const ZEROCLAW_INSTALL_URL =
@@ -603,7 +534,6 @@ function createAgents(runner: CloudRunner): Record<string, AgentConfig> {
603534 claude : {
604535 name : "Claude Code" ,
605536 cloudInitTier : "minimal" ,
606- dockerImage : `${ DOCKER_IMAGE_PREFIX } claude:latest` ,
607537 preProvision : promptGithubAuth ,
608538 install : ( ) => installClaudeCode ( runner ) ,
609539 envVars : ( apiKey ) => [
@@ -622,7 +552,6 @@ function createAgents(runner: CloudRunner): Record<string, AgentConfig> {
622552 codex : {
623553 name : "Codex CLI" ,
624554 cloudInitTier : "node" ,
625- dockerImage : `${ DOCKER_IMAGE_PREFIX } codex:latest` ,
626555 preProvision : promptGithubAuth ,
627556 install : ( ) =>
628557 installAgent (
@@ -642,20 +571,17 @@ function createAgents(runner: CloudRunner): Record<string, AgentConfig> {
642571 openclaw : {
643572 name : "OpenClaw" ,
644573 cloudInitTier : "full" ,
645- dockerImage : `${ DOCKER_IMAGE_PREFIX } openclaw:latest` ,
646- slowInstall : true ,
647574 preProvision : promptGithubAuth ,
648575 modelPrompt : true ,
649576 modelDefault : "openrouter/auto" ,
650- install : withDockerInstall ( runner , "OpenClaw" , ` ${ DOCKER_IMAGE_PREFIX } openclaw:latest` , ( ) =>
577+ install : ( ) =>
651578 installAgent (
652579 runner ,
653580 "openclaw" ,
654581 `source ~/.bashrc 2>/dev/null; ${ NPM_PREFIX_SETUP } && npm install -g \${_NPM_G_FLAGS} openclaw && ` +
655582 "{ grep -qF '.npm-global/bin' ~/.bashrc 2>/dev/null || echo 'export PATH=\"$HOME/.npm-global/bin:$PATH\"' >> ~/.bashrc; } && " +
656583 "{ [ ! -f ~/.zshrc ] || grep -qF '.npm-global/bin' ~/.zshrc 2>/dev/null || echo 'export PATH=\"$HOME/.npm-global/bin:$PATH\"' >> ~/.zshrc; }" ,
657584 ) ,
658- ) ,
659585 envVars : ( apiKey ) => [
660586 `OPENROUTER_API_KEY=${ apiKey } ` ,
661587 `ANTHROPIC_API_KEY=${ apiKey } ` ,
@@ -672,7 +598,6 @@ function createAgents(runner: CloudRunner): Record<string, AgentConfig> {
672598 opencode : {
673599 name : "OpenCode" ,
674600 cloudInitTier : "minimal" ,
675- dockerImage : `${ DOCKER_IMAGE_PREFIX } opencode:latest` ,
676601 preProvision : promptGithubAuth ,
677602 install : ( ) => installAgent ( runner , "OpenCode" , openCodeInstallCmd ( ) ) ,
678603 envVars : ( apiKey ) => [
@@ -684,7 +609,6 @@ function createAgents(runner: CloudRunner): Record<string, AgentConfig> {
684609 kilocode : {
685610 name : "Kilo Code" ,
686611 cloudInitTier : "node" ,
687- dockerImage : `${ DOCKER_IMAGE_PREFIX } kilocode:latest` ,
688612 preProvision : promptGithubAuth ,
689613 install : ( ) =>
690614 installAgent (
@@ -705,10 +629,8 @@ function createAgents(runner: CloudRunner): Record<string, AgentConfig> {
705629 zeroclaw : {
706630 name : "ZeroClaw" ,
707631 cloudInitTier : "minimal" ,
708- dockerImage : `${ DOCKER_IMAGE_PREFIX } zeroclaw:latest` ,
709- slowInstall : true ,
710632 preProvision : promptGithubAuth ,
711- install : withDockerInstall ( runner , "ZeroClaw" , ` ${ DOCKER_IMAGE_PREFIX } zeroclaw:latest` , async ( ) => {
633+ install : async ( ) => {
712634 // Add swap before building — low-memory instances (e.g., AWS nano 512 MB)
713635 // OOM during Rust compilation if --prefer-prebuilt falls back to source.
714636 await ensureSwapSpace ( runner ) ;
@@ -718,7 +640,7 @@ function createAgents(runner: CloudRunner): Record<string, AgentConfig> {
718640 `curl --proto '=https' -LsSf ${ ZEROCLAW_INSTALL_URL } | bash -s -- --install-rust --install-system-deps --prefer-prebuilt` ,
719641 600 , // 10 min: swap-backed compilation is slower than the 5-min default
720642 ) ;
721- } ) ,
643+ } ,
722644 envVars : ( apiKey ) => [
723645 `OPENROUTER_API_KEY=${ apiKey } ` ,
724646 "ZEROCLAW_PROVIDER=openrouter" ,
@@ -731,7 +653,6 @@ function createAgents(runner: CloudRunner): Record<string, AgentConfig> {
731653 hermes : {
732654 name : "Hermes Agent" ,
733655 cloudInitTier : "minimal" ,
734- dockerImage : `${ DOCKER_IMAGE_PREFIX } hermes:latest` ,
735656 preProvision : promptGithubAuth ,
736657 install : ( ) =>
737658 installAgent (
0 commit comments