@better-openclaw/core 1.0.26 → 1.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.
- package/README.md +67 -7
- package/dist/addon-stack.cjs +41 -28
- package/dist/addon-stack.cjs.map +1 -1
- package/dist/addon-stack.d.cts +1 -1
- package/dist/addon-stack.d.cts.map +1 -1
- package/dist/addon-stack.d.mts +1 -1
- package/dist/addon-stack.d.mts.map +1 -1
- package/dist/addon-stack.mjs +40 -27
- package/dist/addon-stack.mjs.map +1 -1
- package/dist/addon-stack.test.cjs +14 -14
- package/dist/addon-stack.test.cjs.map +1 -1
- package/dist/addon-stack.test.mjs +13 -13
- package/dist/addon-stack.test.mjs.map +1 -1
- package/dist/bare-metal-partition.d.cts +1 -1
- package/dist/bare-metal-partition.d.mts +1 -1
- package/dist/bare-metal-partition.test.cjs +1 -1
- package/dist/bare-metal-partition.test.mjs +1 -1
- package/dist/callback-sink-CdMKYayY.d.mts +15 -0
- package/dist/callback-sink-CdMKYayY.d.mts.map +1 -0
- package/dist/callback-sink-iNThWRnQ.d.cts +15 -0
- package/dist/callback-sink-iNThWRnQ.d.cts.map +1 -0
- package/dist/claude-code-fw-CrbAlzTM.d.mts +7 -0
- package/dist/claude-code-fw-CrbAlzTM.d.mts.map +1 -0
- package/dist/claude-code-fw-dKYH2prH.d.cts +7 -0
- package/dist/claude-code-fw-dKYH2prH.d.cts.map +1 -0
- package/dist/codex-fw-Ct8q4pzo.d.mts +7 -0
- package/dist/codex-fw-Ct8q4pzo.d.mts.map +1 -0
- package/dist/codex-fw-l7Ku8ZI8.d.cts +7 -0
- package/dist/codex-fw-l7Ku8ZI8.d.cts.map +1 -0
- package/dist/compose-validation.test.cjs +1 -1
- package/dist/composer.cjs +89 -129
- package/dist/composer.cjs.map +1 -1
- package/dist/composer.d.cts +3 -3
- package/dist/composer.d.cts.map +1 -1
- package/dist/composer.d.mts +3 -3
- package/dist/composer.d.mts.map +1 -1
- package/dist/composer.mjs +88 -128
- package/dist/composer.mjs.map +1 -1
- package/dist/composer.snapshot.test.cjs +1 -1
- package/dist/composer.snapshot.test.mjs +1 -1
- package/dist/composer.test.cjs +53 -2
- package/dist/composer.test.cjs.map +1 -1
- package/dist/composer.test.mjs +52 -1
- package/dist/composer.test.mjs.map +1 -1
- package/dist/console-sink-BHQpRyCt.d.cts +13 -0
- package/dist/console-sink-BHQpRyCt.d.cts.map +1 -0
- package/dist/console-sink-bouG_M1K.d.mts +13 -0
- package/dist/console-sink-bouG_M1K.d.mts.map +1 -0
- package/dist/{coolify-BVGGcMrT.d.mts → coolify-D5E0z01M.d.mts} +2 -2
- package/dist/{coolify-BVGGcMrT.d.mts.map → coolify-D5E0z01M.d.mts.map} +1 -1
- package/dist/{coolify-vlb1G9V2.d.cts → coolify-DjHecHCr.d.cts} +2 -2
- package/dist/{coolify-vlb1G9V2.d.cts.map → coolify-DjHecHCr.d.cts.map} +1 -1
- package/dist/copaw-BQyjioz7.d.cts +7 -0
- package/dist/copaw-BQyjioz7.d.cts.map +1 -0
- package/dist/copaw-C_3N7eQu.d.mts +7 -0
- package/dist/copaw-C_3N7eQu.d.mts.map +1 -0
- package/dist/deployers/coolify.cjs +25 -0
- package/dist/deployers/coolify.cjs.map +1 -1
- package/dist/deployers/coolify.d.cts +1 -1
- package/dist/deployers/coolify.d.mts +1 -1
- package/dist/deployers/coolify.mjs +25 -0
- package/dist/deployers/coolify.mjs.map +1 -1
- package/dist/deployers/coolify.test.cjs +156 -0
- package/dist/deployers/coolify.test.cjs.map +1 -0
- package/dist/deployers/coolify.test.d.cts +1 -0
- package/dist/deployers/coolify.test.d.mts +1 -0
- package/dist/deployers/coolify.test.mjs +157 -0
- package/dist/deployers/coolify.test.mjs.map +1 -0
- package/dist/deployers/dokploy.cjs +25 -0
- package/dist/deployers/dokploy.cjs.map +1 -1
- package/dist/deployers/dokploy.d.cts +1 -1
- package/dist/deployers/dokploy.d.mts +1 -1
- package/dist/deployers/dokploy.mjs +25 -0
- package/dist/deployers/dokploy.mjs.map +1 -1
- package/dist/deployers/dokploy.test.cjs +108 -0
- package/dist/deployers/dokploy.test.cjs.map +1 -0
- package/dist/deployers/dokploy.test.d.cts +1 -0
- package/dist/deployers/dokploy.test.d.mts +1 -0
- package/dist/deployers/dokploy.test.mjs +109 -0
- package/dist/deployers/dokploy.test.mjs.map +1 -0
- package/dist/deployers/index.d.cts +3 -3
- package/dist/deployers/index.d.mts +3 -3
- package/dist/deployers/strip-host-ports.cjs +1 -1
- package/dist/deployers/strip-host-ports.test.cjs +1 -1
- package/dist/deployers/strip-host-ports.test.mjs +1 -1
- package/dist/deployers/types.d.cts +1 -1
- package/dist/deployers/types.d.mts +1 -1
- package/dist/{dokploy-8cbrxUun.d.cts → dokploy-BnVDjWCV.d.cts} +2 -2
- package/dist/{dokploy-8cbrxUun.d.cts.map → dokploy-BnVDjWCV.d.cts.map} +1 -1
- package/dist/{dokploy-BTflLhTM.d.mts → dokploy-BqLdCfyR.d.mts} +2 -2
- package/dist/{dokploy-BTflLhTM.d.mts.map → dokploy-BqLdCfyR.d.mts.map} +1 -1
- package/dist/frameworks/claude-code-fw.cjs +79 -0
- package/dist/frameworks/claude-code-fw.cjs.map +1 -0
- package/dist/frameworks/claude-code-fw.d.cts +2 -0
- package/dist/frameworks/claude-code-fw.d.mts +2 -0
- package/dist/frameworks/claude-code-fw.mjs +78 -0
- package/dist/frameworks/claude-code-fw.mjs.map +1 -0
- package/dist/frameworks/codex-fw.cjs +67 -0
- package/dist/frameworks/codex-fw.cjs.map +1 -0
- package/dist/frameworks/codex-fw.d.cts +2 -0
- package/dist/frameworks/codex-fw.d.mts +2 -0
- package/dist/frameworks/codex-fw.mjs +66 -0
- package/dist/frameworks/codex-fw.mjs.map +1 -0
- package/dist/frameworks/copaw.cjs +118 -0
- package/dist/frameworks/copaw.cjs.map +1 -0
- package/dist/frameworks/copaw.d.cts +2 -0
- package/dist/frameworks/copaw.d.mts +2 -0
- package/dist/frameworks/copaw.mjs +117 -0
- package/dist/frameworks/copaw.mjs.map +1 -0
- package/dist/frameworks/frameworks.test.cjs +94 -0
- package/dist/frameworks/frameworks.test.cjs.map +1 -0
- package/dist/frameworks/frameworks.test.d.cts +1 -0
- package/dist/frameworks/frameworks.test.d.mts +1 -0
- package/dist/frameworks/frameworks.test.mjs +94 -0
- package/dist/frameworks/frameworks.test.mjs.map +1 -0
- package/dist/frameworks/index.cjs +35 -0
- package/dist/frameworks/index.cjs.map +1 -0
- package/dist/frameworks/index.d.cts +11 -0
- package/dist/frameworks/index.d.mts +11 -0
- package/dist/frameworks/index.mjs +22 -0
- package/dist/frameworks/index.mjs.map +1 -0
- package/dist/frameworks/memu.cjs +118 -0
- package/dist/frameworks/memu.cjs.map +1 -0
- package/dist/frameworks/memu.d.cts +2 -0
- package/dist/frameworks/memu.d.mts +2 -0
- package/dist/frameworks/memu.mjs +117 -0
- package/dist/frameworks/memu.mjs.map +1 -0
- package/dist/frameworks/nanobot.cjs +126 -0
- package/dist/frameworks/nanobot.cjs.map +1 -0
- package/dist/frameworks/nanobot.d.cts +2 -0
- package/dist/frameworks/nanobot.d.mts +2 -0
- package/dist/frameworks/nanobot.mjs +125 -0
- package/dist/frameworks/nanobot.mjs.map +1 -0
- package/dist/frameworks/nanoclaw.cjs +99 -0
- package/dist/frameworks/nanoclaw.cjs.map +1 -0
- package/dist/frameworks/nanoclaw.d.cts +2 -0
- package/dist/frameworks/nanoclaw.d.mts +2 -0
- package/dist/frameworks/nanoclaw.mjs +98 -0
- package/dist/frameworks/nanoclaw.mjs.map +1 -0
- package/dist/frameworks/openclaw.cjs +253 -0
- package/dist/frameworks/openclaw.cjs.map +1 -0
- package/dist/frameworks/openclaw.d.cts +2 -0
- package/dist/frameworks/openclaw.d.mts +2 -0
- package/dist/frameworks/openclaw.mjs +251 -0
- package/dist/frameworks/openclaw.mjs.map +1 -0
- package/dist/frameworks/registry.cjs +31 -0
- package/dist/frameworks/registry.cjs.map +1 -0
- package/dist/frameworks/registry.d.cts +2 -0
- package/dist/frameworks/registry.d.mts +2 -0
- package/dist/frameworks/registry.mjs +26 -0
- package/dist/frameworks/registry.mjs.map +1 -0
- package/dist/frameworks/registry.test.cjs +110 -0
- package/dist/frameworks/registry.test.cjs.map +1 -0
- package/dist/frameworks/registry.test.d.cts +1 -0
- package/dist/frameworks/registry.test.d.mts +1 -0
- package/dist/frameworks/registry.test.mjs +111 -0
- package/dist/frameworks/registry.test.mjs.map +1 -0
- package/dist/frameworks/types.cjs +0 -0
- package/dist/frameworks/types.d.cts +2 -0
- package/dist/frameworks/types.d.mts +2 -0
- package/dist/frameworks/types.mjs +1 -0
- package/dist/frameworks/zeroclaw.cjs +123 -0
- package/dist/frameworks/zeroclaw.cjs.map +1 -0
- package/dist/frameworks/zeroclaw.d.cts +2 -0
- package/dist/frameworks/zeroclaw.d.mts +2 -0
- package/dist/frameworks/zeroclaw.mjs +122 -0
- package/dist/frameworks/zeroclaw.mjs.map +1 -0
- package/dist/generate.cjs +64 -13
- package/dist/generate.cjs.map +1 -1
- package/dist/generate.d.cts +5 -2
- package/dist/generate.d.cts.map +1 -1
- package/dist/generate.d.mts +5 -2
- package/dist/generate.d.mts.map +1 -1
- package/dist/generate.mjs +63 -12
- package/dist/generate.mjs.map +1 -1
- package/dist/generate.test.cjs +42 -6
- package/dist/generate.test.cjs.map +1 -1
- package/dist/generate.test.mjs +41 -5
- package/dist/generate.test.mjs.map +1 -1
- package/dist/generators/bare-metal-install.d.cts +1 -1
- package/dist/generators/bare-metal-install.d.mts +1 -1
- package/dist/generators/bare-metal-install.test.cjs +1 -1
- package/dist/generators/bare-metal-install.test.mjs +1 -1
- package/dist/generators/caddy.cjs +9 -3
- package/dist/generators/caddy.cjs.map +1 -1
- package/dist/generators/caddy.d.cts +1 -1
- package/dist/generators/caddy.d.mts +1 -1
- package/dist/generators/caddy.mjs +9 -3
- package/dist/generators/caddy.mjs.map +1 -1
- package/dist/generators/caddy.test.cjs +30 -2
- package/dist/generators/caddy.test.cjs.map +1 -1
- package/dist/generators/caddy.test.mjs +30 -2
- package/dist/generators/caddy.test.mjs.map +1 -1
- package/dist/generators/clone-repos.cjs.map +1 -1
- package/dist/generators/clone-repos.d.cts +1 -1
- package/dist/generators/clone-repos.d.mts +1 -1
- package/dist/generators/clone-repos.mjs.map +1 -1
- package/dist/generators/clone-repos.test.cjs +1 -1
- package/dist/generators/clone-repos.test.cjs.map +1 -1
- package/dist/generators/clone-repos.test.mjs +1 -1
- package/dist/generators/clone-repos.test.mjs.map +1 -1
- package/dist/generators/cloud-init.test.cjs +58 -0
- package/dist/generators/cloud-init.test.cjs.map +1 -0
- package/dist/generators/cloud-init.test.d.cts +1 -0
- package/dist/generators/cloud-init.test.d.mts +1 -0
- package/dist/generators/cloud-init.test.mjs +59 -0
- package/dist/generators/cloud-init.test.mjs.map +1 -0
- package/dist/generators/env.cjs +28 -103
- package/dist/generators/env.cjs.map +1 -1
- package/dist/generators/env.d.cts +4 -1
- package/dist/generators/env.d.cts.map +1 -1
- package/dist/generators/env.d.mts +4 -1
- package/dist/generators/env.d.mts.map +1 -1
- package/dist/generators/env.mjs +27 -102
- package/dist/generators/env.mjs.map +1 -1
- package/dist/generators/env.test.cjs +3 -3
- package/dist/generators/env.test.cjs.map +1 -1
- package/dist/generators/env.test.mjs +3 -3
- package/dist/generators/env.test.mjs.map +1 -1
- package/dist/generators/get-shit-done.d.cts +1 -1
- package/dist/generators/get-shit-done.d.mts +1 -1
- package/dist/generators/get-shit-done.test.cjs +48 -0
- package/dist/generators/get-shit-done.test.cjs.map +1 -0
- package/dist/generators/get-shit-done.test.d.cts +1 -0
- package/dist/generators/get-shit-done.test.d.mts +1 -0
- package/dist/generators/get-shit-done.test.mjs +49 -0
- package/dist/generators/get-shit-done.test.mjs.map +1 -0
- package/dist/generators/grafana.test.cjs +74 -0
- package/dist/generators/grafana.test.cjs.map +1 -0
- package/dist/generators/grafana.test.d.cts +1 -0
- package/dist/generators/grafana.test.d.mts +1 -0
- package/dist/generators/grafana.test.mjs +74 -0
- package/dist/generators/grafana.test.mjs.map +1 -0
- package/dist/generators/health-check.cjs +6 -6
- package/dist/generators/health-check.cjs.map +1 -1
- package/dist/generators/health-check.d.cts +1 -1
- package/dist/generators/health-check.d.mts +1 -1
- package/dist/generators/health-check.mjs +6 -6
- package/dist/generators/health-check.mjs.map +1 -1
- package/dist/generators/health-check.test.cjs +1 -1
- package/dist/generators/health-check.test.mjs +1 -1
- package/dist/generators/n8n-workflows.d.cts +1 -1
- package/dist/generators/n8n-workflows.d.mts +1 -1
- package/dist/generators/n8n-workflows.test.cjs +75 -0
- package/dist/generators/n8n-workflows.test.cjs.map +1 -0
- package/dist/generators/n8n-workflows.test.d.cts +1 -0
- package/dist/generators/n8n-workflows.test.d.mts +1 -0
- package/dist/generators/n8n-workflows.test.mjs +76 -0
- package/dist/generators/n8n-workflows.test.mjs.map +1 -0
- package/dist/generators/native-services.d.cts +1 -1
- package/dist/generators/native-services.d.mts +1 -1
- package/dist/generators/openclaw-install-script.test.cjs +35 -0
- package/dist/generators/openclaw-install-script.test.cjs.map +1 -0
- package/dist/generators/openclaw-install-script.test.d.cts +1 -0
- package/dist/generators/openclaw-install-script.test.d.mts +1 -0
- package/dist/generators/openclaw-install-script.test.mjs +36 -0
- package/dist/generators/openclaw-install-script.test.mjs.map +1 -0
- package/dist/generators/openclaw-json.cjs +60 -4
- package/dist/generators/openclaw-json.cjs.map +1 -1
- package/dist/generators/openclaw-json.d.cts +1 -5
- package/dist/generators/openclaw-json.d.cts.map +1 -1
- package/dist/generators/openclaw-json.d.mts +1 -5
- package/dist/generators/openclaw-json.d.mts.map +1 -1
- package/dist/generators/openclaw-json.mjs +60 -4
- package/dist/generators/openclaw-json.mjs.map +1 -1
- package/dist/generators/postgres-init.cjs +20 -0
- package/dist/generators/postgres-init.cjs.map +1 -1
- package/dist/generators/postgres-init.d.cts +1 -1
- package/dist/generators/postgres-init.d.cts.map +1 -1
- package/dist/generators/postgres-init.d.mts +1 -1
- package/dist/generators/postgres-init.d.mts.map +1 -1
- package/dist/generators/postgres-init.mjs +20 -0
- package/dist/generators/postgres-init.mjs.map +1 -1
- package/dist/generators/postgres-init.test.cjs +111 -0
- package/dist/generators/postgres-init.test.cjs.map +1 -0
- package/dist/generators/postgres-init.test.d.cts +1 -0
- package/dist/generators/postgres-init.test.d.mts +1 -0
- package/dist/generators/postgres-init.test.mjs +112 -0
- package/dist/generators/postgres-init.test.mjs.map +1 -0
- package/dist/generators/prometheus.d.cts +1 -1
- package/dist/generators/prometheus.d.mts +1 -1
- package/dist/generators/prometheus.test.cjs +99 -0
- package/dist/generators/prometheus.test.cjs.map +1 -0
- package/dist/generators/prometheus.test.d.cts +1 -0
- package/dist/generators/prometheus.test.d.mts +1 -0
- package/dist/generators/prometheus.test.mjs +99 -0
- package/dist/generators/prometheus.test.mjs.map +1 -0
- package/dist/generators/readme.cjs +50 -7
- package/dist/generators/readme.cjs.map +1 -1
- package/dist/generators/readme.d.cts +3 -1
- package/dist/generators/readme.d.cts.map +1 -1
- package/dist/generators/readme.d.mts +3 -1
- package/dist/generators/readme.d.mts.map +1 -1
- package/dist/generators/readme.mjs +50 -7
- package/dist/generators/readme.mjs.map +1 -1
- package/dist/generators/scripts.test.cjs +2 -2
- package/dist/generators/scripts.test.cjs.map +1 -1
- package/dist/generators/scripts.test.mjs +2 -2
- package/dist/generators/scripts.test.mjs.map +1 -1
- package/dist/generators/skills.cjs +1 -1
- package/dist/generators/skills.d.cts +1 -1
- package/dist/generators/skills.d.cts.map +1 -1
- package/dist/generators/skills.d.mts +1 -1
- package/dist/generators/skills.d.mts.map +1 -1
- package/dist/generators/skills.mjs +310 -0
- package/dist/generators/skills.mjs.map +1 -1
- package/dist/generators/stack-manifest.d.cts +1 -1
- package/dist/generators/stack-manifest.d.mts +1 -1
- package/dist/generators/stack-manifest.test.cjs +97 -0
- package/dist/generators/stack-manifest.test.cjs.map +1 -0
- package/dist/generators/stack-manifest.test.d.cts +1 -0
- package/dist/generators/stack-manifest.test.d.mts +1 -0
- package/dist/generators/stack-manifest.test.mjs +98 -0
- package/dist/generators/stack-manifest.test.mjs.map +1 -0
- package/dist/generators/traefik.d.cts +1 -1
- package/dist/generators/traefik.d.mts +1 -1
- package/dist/generators/traefik.test.cjs +12 -12
- package/dist/generators/traefik.test.cjs.map +1 -1
- package/dist/generators/traefik.test.mjs +12 -12
- package/dist/generators/traefik.test.mjs.map +1 -1
- package/dist/index.cjs +18 -2
- package/dist/index.d.cts +13 -7
- package/dist/index.d.mts +13 -7
- package/dist/index.mjs +9 -3
- package/dist/logger/__tests__/logger.test.cjs +308 -0
- package/dist/logger/__tests__/logger.test.cjs.map +1 -0
- package/dist/logger/__tests__/logger.test.d.cts +1 -0
- package/dist/logger/__tests__/logger.test.d.mts +1 -0
- package/dist/logger/__tests__/logger.test.mjs +308 -0
- package/dist/logger/__tests__/logger.test.mjs.map +1 -0
- package/dist/logger/index.cjs +8 -0
- package/dist/logger/index.d.cts +5 -0
- package/dist/logger/index.d.mts +5 -0
- package/dist/logger/index.mjs +4 -0
- package/dist/logger/logger.cjs +270 -0
- package/dist/logger/logger.cjs.map +1 -0
- package/dist/logger/logger.d.cts +2 -0
- package/dist/logger/logger.d.mts +2 -0
- package/dist/logger/logger.mjs +267 -0
- package/dist/logger/logger.mjs.map +1 -0
- package/dist/logger/sinks/callback-sink.cjs +18 -0
- package/dist/logger/sinks/callback-sink.cjs.map +1 -0
- package/dist/logger/sinks/callback-sink.d.cts +2 -0
- package/dist/logger/sinks/callback-sink.d.mts +2 -0
- package/dist/logger/sinks/callback-sink.mjs +17 -0
- package/dist/logger/sinks/callback-sink.mjs.map +1 -0
- package/dist/logger/sinks/console-sink.cjs +39 -0
- package/dist/logger/sinks/console-sink.cjs.map +1 -0
- package/dist/logger/sinks/console-sink.d.cts +2 -0
- package/dist/logger/sinks/console-sink.d.mts +2 -0
- package/dist/logger/sinks/console-sink.mjs +38 -0
- package/dist/logger/sinks/console-sink.mjs.map +1 -0
- package/dist/logger/sinks/file-sink.cjs +72 -0
- package/dist/logger/sinks/file-sink.cjs.map +1 -0
- package/dist/logger/sinks/file-sink.d.cts +36 -0
- package/dist/logger/sinks/file-sink.d.cts.map +1 -0
- package/dist/logger/sinks/file-sink.d.mts +36 -0
- package/dist/logger/sinks/file-sink.d.mts.map +1 -0
- package/dist/logger/sinks/file-sink.mjs +70 -0
- package/dist/logger/sinks/file-sink.mjs.map +1 -0
- package/dist/logger/types.cjs +0 -0
- package/dist/logger/types.d.cts +2 -0
- package/dist/logger/types.d.mts +2 -0
- package/dist/logger/types.mjs +1 -0
- package/dist/logger-CZ0Qnyiu.d.mts +66 -0
- package/dist/logger-CZ0Qnyiu.d.mts.map +1 -0
- package/dist/logger-DDfwai-A.d.cts +66 -0
- package/dist/logger-DDfwai-A.d.cts.map +1 -0
- package/dist/memu-BfRXtwmL.d.cts +7 -0
- package/dist/memu-BfRXtwmL.d.cts.map +1 -0
- package/dist/memu-C-fXbWr-.d.mts +7 -0
- package/dist/memu-C-fXbWr-.d.mts.map +1 -0
- package/dist/migrations.cjs +17 -9
- package/dist/migrations.cjs.map +1 -1
- package/dist/migrations.d.cts +1 -1
- package/dist/migrations.d.cts.map +1 -1
- package/dist/migrations.d.mts +1 -1
- package/dist/migrations.d.mts.map +1 -1
- package/dist/migrations.mjs +17 -9
- package/dist/migrations.mjs.map +1 -1
- package/dist/migrations.test.cjs +4 -4
- package/dist/migrations.test.mjs +4 -4
- package/dist/nanobot-2c0bS4lu.d.cts +7 -0
- package/dist/nanobot-2c0bS4lu.d.cts.map +1 -0
- package/dist/nanobot-BUO6pVQc.d.mts +7 -0
- package/dist/nanobot-BUO6pVQc.d.mts.map +1 -0
- package/dist/nanoclaw-CgHubEig.d.mts +7 -0
- package/dist/nanoclaw-CgHubEig.d.mts.map +1 -0
- package/dist/nanoclaw-Dvz0ef6J.d.cts +7 -0
- package/dist/nanoclaw-Dvz0ef6J.d.cts.map +1 -0
- package/dist/openclaw-D8lVecjC.d.mts +7 -0
- package/dist/openclaw-D8lVecjC.d.mts.map +1 -0
- package/dist/openclaw-DThj8i3N.d.cts +7 -0
- package/dist/openclaw-DThj8i3N.d.cts.map +1 -0
- package/dist/port-scanner.d.cts +1 -1
- package/dist/port-scanner.d.mts +1 -1
- package/dist/port-scanner.test.cjs +155 -0
- package/dist/port-scanner.test.cjs.map +1 -0
- package/dist/port-scanner.test.d.cts +1 -0
- package/dist/port-scanner.test.d.mts +1 -0
- package/dist/port-scanner.test.mjs +156 -0
- package/dist/port-scanner.test.mjs.map +1 -0
- package/dist/presets/presets.test.cjs +5 -5
- package/dist/presets/presets.test.cjs.map +1 -1
- package/dist/presets/presets.test.mjs +4 -4
- package/dist/presets/presets.test.mjs.map +1 -1
- package/dist/presets/registry.d.cts +1 -1
- package/dist/presets/registry.d.mts +1 -1
- package/dist/presets/registry.test.cjs +7 -7
- package/dist/presets/registry.test.cjs.map +1 -1
- package/dist/presets/registry.test.mjs +7 -7
- package/dist/presets/registry.test.mjs.map +1 -1
- package/dist/registry-DHX7vnVo.d.cts +16 -0
- package/dist/registry-DHX7vnVo.d.cts.map +1 -0
- package/dist/registry-DTAILnga.d.mts +16 -0
- package/dist/registry-DTAILnga.d.mts.map +1 -0
- package/dist/resolver.cjs +13 -3
- package/dist/resolver.cjs.map +1 -1
- package/dist/resolver.d.cts +1 -1
- package/dist/resolver.d.cts.map +1 -1
- package/dist/resolver.d.mts +1 -1
- package/dist/resolver.d.mts.map +1 -1
- package/dist/resolver.mjs +13 -3
- package/dist/resolver.mjs.map +1 -1
- package/dist/resolver.test.cjs +35 -3
- package/dist/resolver.test.cjs.map +1 -1
- package/dist/resolver.test.mjs +35 -3
- package/dist/resolver.test.mjs.map +1 -1
- package/dist/{schema-BQnZrcw8.d.cts → schema-BSl9wiFe.d.mts} +134 -2
- package/dist/schema-BSl9wiFe.d.mts.map +1 -0
- package/dist/{schema-SBpL0bdI.d.mts → schema-Bd9l2r7p.d.cts} +134 -2
- package/dist/schema-Bd9l2r7p.d.cts.map +1 -0
- package/dist/schema.cjs +28 -4
- package/dist/schema.cjs.map +1 -1
- package/dist/schema.d.cts +2 -2
- package/dist/schema.d.mts +2 -2
- package/dist/schema.mjs +27 -4
- package/dist/schema.mjs.map +1 -1
- package/dist/schema.test.cjs +3 -3
- package/dist/schema.test.cjs.map +1 -1
- package/dist/schema.test.mjs +3 -3
- package/dist/schema.test.mjs.map +1 -1
- package/dist/services/definitions/adguard-home.d.cts +1 -1
- package/dist/services/definitions/adguard-home.d.mts +1 -1
- package/dist/services/definitions/agent-browser.cjs +161 -0
- package/dist/services/definitions/agent-browser.cjs.map +1 -0
- package/dist/services/definitions/agent-browser.d.cts +7 -0
- package/dist/services/definitions/agent-browser.d.cts.map +1 -0
- package/dist/services/definitions/agent-browser.d.mts +7 -0
- package/dist/services/definitions/agent-browser.d.mts.map +1 -0
- package/dist/services/definitions/agent-browser.mjs +160 -0
- package/dist/services/definitions/agent-browser.mjs.map +1 -0
- package/dist/services/definitions/airbyte.d.cts +1 -1
- package/dist/services/definitions/airbyte.d.mts +1 -1
- package/dist/services/definitions/airflow.d.cts +1 -1
- package/dist/services/definitions/airflow.d.mts +1 -1
- package/dist/services/definitions/anything-llm.d.cts +1 -1
- package/dist/services/definitions/anything-llm.d.mts +1 -1
- package/dist/services/definitions/appflowy.d.cts +1 -1
- package/dist/services/definitions/appflowy.d.mts +1 -1
- package/dist/services/definitions/apptension-saas.cjs.map +1 -1
- package/dist/services/definitions/apptension-saas.d.cts +1 -1
- package/dist/services/definitions/apptension-saas.d.mts +1 -1
- package/dist/services/definitions/apptension-saas.mjs.map +1 -1
- package/dist/services/definitions/appwrite.d.cts +1 -1
- package/dist/services/definitions/appwrite.d.mts +1 -1
- package/dist/services/definitions/audiobookshelf.d.cts +1 -1
- package/dist/services/definitions/audiobookshelf.d.mts +1 -1
- package/dist/services/definitions/authelia.d.cts +1 -1
- package/dist/services/definitions/authelia.d.mts +1 -1
- package/dist/services/definitions/authentik.d.cts +1 -1
- package/dist/services/definitions/authentik.d.mts +1 -1
- package/dist/services/definitions/axolotl.d.cts +1 -1
- package/dist/services/definitions/axolotl.d.mts +1 -1
- package/dist/services/definitions/baserow.d.cts +1 -1
- package/dist/services/definitions/baserow.d.mts +1 -1
- package/dist/services/definitions/beszel.d.cts +1 -1
- package/dist/services/definitions/beszel.d.mts +1 -1
- package/dist/services/definitions/boxyhq-saas.d.cts +1 -1
- package/dist/services/definitions/boxyhq-saas.d.mts +1 -1
- package/dist/services/definitions/browserless.d.cts +1 -1
- package/dist/services/definitions/browserless.d.mts +1 -1
- package/dist/services/definitions/burnlink.d.cts +1 -1
- package/dist/services/definitions/burnlink.d.mts +1 -1
- package/dist/services/definitions/caddy.d.cts +1 -1
- package/dist/services/definitions/caddy.d.mts +1 -1
- package/dist/services/definitions/cal-com.d.cts +1 -1
- package/dist/services/definitions/cal-com.d.mts +1 -1
- package/dist/services/definitions/calibre-web.d.cts +1 -1
- package/dist/services/definitions/calibre-web.d.mts +1 -1
- package/dist/services/definitions/chatwoot-worker.d.cts +1 -1
- package/dist/services/definitions/chatwoot-worker.d.mts +1 -1
- package/dist/services/definitions/chatwoot.d.cts +1 -1
- package/dist/services/definitions/chatwoot.d.mts +1 -1
- package/dist/services/definitions/chromadb.cjs +4 -1
- package/dist/services/definitions/chromadb.cjs.map +1 -1
- package/dist/services/definitions/chromadb.d.cts +1 -1
- package/dist/services/definitions/chromadb.d.mts +1 -1
- package/dist/services/definitions/chromadb.mjs +4 -1
- package/dist/services/definitions/chromadb.mjs.map +1 -1
- package/dist/services/definitions/claude-code.cjs +1 -1
- package/dist/services/definitions/claude-code.cjs.map +1 -1
- package/dist/services/definitions/claude-code.d.cts +1 -1
- package/dist/services/definitions/claude-code.d.mts +1 -1
- package/dist/services/definitions/claude-code.mjs +1 -1
- package/dist/services/definitions/claude-code.mjs.map +1 -1
- package/dist/services/definitions/clawrouter.cjs +138 -0
- package/dist/services/definitions/clawrouter.cjs.map +1 -0
- package/dist/services/definitions/clawrouter.d.cts +7 -0
- package/dist/services/definitions/clawrouter.d.cts.map +1 -0
- package/dist/services/definitions/clawrouter.d.mts +7 -0
- package/dist/services/definitions/clawrouter.d.mts.map +1 -0
- package/dist/services/definitions/clawrouter.mjs +137 -0
- package/dist/services/definitions/clawrouter.mjs.map +1 -0
- package/dist/services/definitions/clickhouse.d.cts +1 -1
- package/dist/services/definitions/clickhouse.d.mts +1 -1
- package/dist/services/definitions/cloudflared.d.cts +1 -1
- package/dist/services/definitions/cloudflared.d.mts +1 -1
- package/dist/services/definitions/cmsaas-starter.d.cts +1 -1
- package/dist/services/definitions/cmsaas-starter.d.mts +1 -1
- package/dist/services/definitions/cockroachdb.d.cts +1 -1
- package/dist/services/definitions/cockroachdb.d.mts +1 -1
- package/dist/services/definitions/code-server.d.cts +1 -1
- package/dist/services/definitions/code-server.d.mts +1 -1
- package/dist/services/definitions/coder.d.cts +1 -1
- package/dist/services/definitions/coder.d.mts +1 -1
- package/dist/services/definitions/codex.cjs +1 -1
- package/dist/services/definitions/codex.cjs.map +1 -1
- package/dist/services/definitions/codex.d.cts +1 -1
- package/dist/services/definitions/codex.d.mts +1 -1
- package/dist/services/definitions/codex.mjs +1 -1
- package/dist/services/definitions/codex.mjs.map +1 -1
- package/dist/services/definitions/comfyui.d.cts +1 -1
- package/dist/services/definitions/comfyui.d.mts +1 -1
- package/dist/services/definitions/convex-dashboard.d.cts +1 -1
- package/dist/services/definitions/convex-dashboard.d.mts +1 -1
- package/dist/services/definitions/convex.cjs.map +1 -1
- package/dist/services/definitions/convex.d.cts +1 -1
- package/dist/services/definitions/convex.d.mts +1 -1
- package/dist/services/definitions/convex.mjs.map +1 -1
- package/dist/services/definitions/coolify.d.cts +1 -1
- package/dist/services/definitions/coolify.d.mts +1 -1
- package/dist/services/definitions/copaw.cjs +97 -0
- package/dist/services/definitions/copaw.cjs.map +1 -0
- package/dist/services/definitions/copaw.d.cts +7 -0
- package/dist/services/definitions/copaw.d.cts.map +1 -0
- package/dist/services/definitions/copaw.d.mts +7 -0
- package/dist/services/definitions/copaw.d.mts.map +1 -0
- package/dist/services/definitions/copaw.mjs +96 -0
- package/dist/services/definitions/copaw.mjs.map +1 -0
- package/dist/services/definitions/crowdsec.d.cts +1 -1
- package/dist/services/definitions/crowdsec.d.mts +1 -1
- package/dist/services/definitions/dagster.d.cts +1 -1
- package/dist/services/definitions/dagster.d.mts +1 -1
- package/dist/services/definitions/desktop-environment.cjs +2 -1
- package/dist/services/definitions/desktop-environment.cjs.map +1 -1
- package/dist/services/definitions/desktop-environment.d.cts +1 -1
- package/dist/services/definitions/desktop-environment.d.mts +1 -1
- package/dist/services/definitions/desktop-environment.mjs +2 -1
- package/dist/services/definitions/desktop-environment.mjs.map +1 -1
- package/dist/services/definitions/dify.d.cts +1 -1
- package/dist/services/definitions/dify.d.mts +1 -1
- package/dist/services/definitions/directus.d.cts +1 -1
- package/dist/services/definitions/directus.d.mts +1 -1
- package/dist/services/definitions/docsgpt.d.cts +1 -1
- package/dist/services/definitions/docsgpt.d.mts +1 -1
- package/dist/services/definitions/dokploy.d.cts +1 -1
- package/dist/services/definitions/dokploy.d.mts +1 -1
- package/dist/services/definitions/dozzle.d.cts +1 -1
- package/dist/services/definitions/dozzle.d.mts +1 -1
- package/dist/services/definitions/dragonfly.d.cts +1 -1
- package/dist/services/definitions/dragonfly.d.mts +1 -1
- package/dist/services/definitions/drone-ci.d.cts +1 -1
- package/dist/services/definitions/drone-ci.d.mts +1 -1
- package/dist/services/definitions/duplicati.d.cts +1 -1
- package/dist/services/definitions/duplicati.d.mts +1 -1
- package/dist/services/definitions/element-web.d.cts +1 -1
- package/dist/services/definitions/element-web.d.mts +1 -1
- package/dist/services/definitions/excalidraw.d.cts +1 -1
- package/dist/services/definitions/excalidraw.d.mts +1 -1
- package/dist/services/definitions/ffmpeg.d.cts +1 -1
- package/dist/services/definitions/ffmpeg.d.mts +1 -1
- package/dist/services/definitions/firecrawl-playwright.d.cts +1 -1
- package/dist/services/definitions/firecrawl-playwright.d.mts +1 -1
- package/dist/services/definitions/firecrawl.d.cts +1 -1
- package/dist/services/definitions/firecrawl.d.mts +1 -1
- package/dist/services/definitions/flagsmith.d.cts +1 -1
- package/dist/services/definitions/flagsmith.d.mts +1 -1
- package/dist/services/definitions/flowise.d.cts +1 -1
- package/dist/services/definitions/flowise.d.mts +1 -1
- package/dist/services/definitions/focalboard.d.cts +1 -1
- package/dist/services/definitions/focalboard.d.mts +1 -1
- package/dist/services/definitions/fonoster.d.cts +1 -1
- package/dist/services/definitions/fonoster.d.mts +1 -1
- package/dist/services/definitions/forgejo.d.cts +1 -1
- package/dist/services/definitions/forgejo.d.mts +1 -1
- package/dist/services/definitions/formbricks.d.cts +1 -1
- package/dist/services/definitions/formbricks.d.mts +1 -1
- package/dist/services/definitions/gemini-cli.d.cts +1 -1
- package/dist/services/definitions/gemini-cli.d.mts +1 -1
- package/dist/services/definitions/ghost.d.cts +1 -1
- package/dist/services/definitions/ghost.d.mts +1 -1
- package/dist/services/definitions/gitea.d.cts +1 -1
- package/dist/services/definitions/gitea.d.mts +1 -1
- package/dist/services/definitions/gotify.d.cts +1 -1
- package/dist/services/definitions/gotify.d.mts +1 -1
- package/dist/services/definitions/grafana.d.cts +1 -1
- package/dist/services/definitions/grafana.d.mts +1 -1
- package/dist/services/definitions/graylog.d.cts +1 -1
- package/dist/services/definitions/graylog.d.mts +1 -1
- package/dist/services/definitions/headscale.d.cts +1 -1
- package/dist/services/definitions/headscale.d.mts +1 -1
- package/dist/services/definitions/hedgedoc.d.cts +1 -1
- package/dist/services/definitions/hedgedoc.d.mts +1 -1
- package/dist/services/definitions/hexstrike.d.cts +1 -1
- package/dist/services/definitions/hexstrike.d.mts +1 -1
- package/dist/services/definitions/heyform.d.cts +1 -1
- package/dist/services/definitions/heyform.d.mts +1 -1
- package/dist/services/definitions/hindsight.cjs +4 -1
- package/dist/services/definitions/hindsight.cjs.map +1 -1
- package/dist/services/definitions/hindsight.d.cts +1 -1
- package/dist/services/definitions/hindsight.d.mts +1 -1
- package/dist/services/definitions/hindsight.mjs +4 -1
- package/dist/services/definitions/hindsight.mjs.map +1 -1
- package/dist/services/definitions/homeassistant.d.cts +1 -1
- package/dist/services/definitions/homeassistant.d.mts +1 -1
- package/dist/services/definitions/hoppscotch.d.cts +1 -1
- package/dist/services/definitions/hoppscotch.d.mts +1 -1
- package/dist/services/definitions/immich.d.cts +1 -1
- package/dist/services/definitions/immich.d.mts +1 -1
- package/dist/services/definitions/index.cjs +42 -6
- package/dist/services/definitions/index.cjs.map +1 -1
- package/dist/services/definitions/index.d.cts +16 -4
- package/dist/services/definitions/index.d.cts.map +1 -1
- package/dist/services/definitions/index.d.mts +16 -4
- package/dist/services/definitions/index.d.mts.map +1 -1
- package/dist/services/definitions/index.mjs +31 -7
- package/dist/services/definitions/index.mjs.map +1 -1
- package/dist/services/definitions/infisical.d.cts +1 -1
- package/dist/services/definitions/infisical.d.mts +1 -1
- package/dist/services/definitions/influxdb.d.cts +1 -1
- package/dist/services/definitions/influxdb.d.mts +1 -1
- package/dist/services/definitions/invoke-ai.d.cts +1 -1
- package/dist/services/definitions/invoke-ai.d.mts +1 -1
- package/dist/services/definitions/ixartz-saas.d.cts +1 -1
- package/dist/services/definitions/ixartz-saas.d.mts +1 -1
- package/dist/services/definitions/jaeger.d.cts +1 -1
- package/dist/services/definitions/jaeger.d.mts +1 -1
- package/dist/services/definitions/jan.d.cts +1 -1
- package/dist/services/definitions/jan.d.mts +1 -1
- package/dist/services/definitions/jellyfin.d.cts +1 -1
- package/dist/services/definitions/jellyfin.d.mts +1 -1
- package/dist/services/definitions/jenkins.d.cts +1 -1
- package/dist/services/definitions/jenkins.d.mts +1 -1
- package/dist/services/definitions/jitsi-meet.d.cts +1 -1
- package/dist/services/definitions/jitsi-meet.d.mts +1 -1
- package/dist/services/definitions/keycloak.d.cts +1 -1
- package/dist/services/definitions/keycloak.d.mts +1 -1
- package/dist/services/definitions/kimi.d.cts +1 -1
- package/dist/services/definitions/kimi.d.mts +1 -1
- package/dist/services/definitions/kong.d.cts +1 -1
- package/dist/services/definitions/kong.d.mts +1 -1
- package/dist/services/definitions/lago.d.cts +1 -1
- package/dist/services/definitions/lago.d.mts +1 -1
- package/dist/services/definitions/langflow.d.cts +1 -1
- package/dist/services/definitions/langflow.d.mts +1 -1
- package/dist/services/definitions/langfuse.d.cts +1 -1
- package/dist/services/definitions/langfuse.d.mts +1 -1
- package/dist/services/definitions/lasuite-meet-agents.d.cts +1 -1
- package/dist/services/definitions/lasuite-meet-agents.d.mts +1 -1
- package/dist/services/definitions/lasuite-meet-backend.d.cts +1 -1
- package/dist/services/definitions/lasuite-meet-backend.d.mts +1 -1
- package/dist/services/definitions/lasuite-meet-frontend.d.cts +1 -1
- package/dist/services/definitions/lasuite-meet-frontend.d.mts +1 -1
- package/dist/services/definitions/librechat.d.cts +1 -1
- package/dist/services/definitions/librechat.d.mts +1 -1
- package/dist/services/definitions/lightpanda.d.cts +1 -1
- package/dist/services/definitions/lightpanda.d.mts +1 -1
- package/dist/services/definitions/listmonk.d.cts +1 -1
- package/dist/services/definitions/listmonk.d.mts +1 -1
- package/dist/services/definitions/litellm.d.cts +1 -1
- package/dist/services/definitions/litellm.d.mts +1 -1
- package/dist/services/definitions/livekit.d.cts +1 -1
- package/dist/services/definitions/livekit.d.mts +1 -1
- package/dist/services/definitions/local-ai.d.cts +1 -1
- package/dist/services/definitions/local-ai.d.mts +1 -1
- package/dist/services/definitions/loki.d.cts +1 -1
- package/dist/services/definitions/loki.d.mts +1 -1
- package/dist/services/definitions/mariadb.d.cts +1 -1
- package/dist/services/definitions/mariadb.d.mts +1 -1
- package/dist/services/definitions/matomo.d.cts +1 -1
- package/dist/services/definitions/matomo.d.mts +1 -1
- package/dist/services/definitions/matrix-synapse.d.cts +1 -1
- package/dist/services/definitions/matrix-synapse.d.mts +1 -1
- package/dist/services/definitions/mattermost.d.cts +1 -1
- package/dist/services/definitions/mattermost.d.mts +1 -1
- package/dist/services/definitions/mautic.d.cts +1 -1
- package/dist/services/definitions/mautic.d.mts +1 -1
- package/dist/services/definitions/medusa.d.cts +1 -1
- package/dist/services/definitions/medusa.d.mts +1 -1
- package/dist/services/definitions/meilisearch.d.cts +1 -1
- package/dist/services/definitions/meilisearch.d.mts +1 -1
- package/dist/services/definitions/mem0.cjs +133 -0
- package/dist/services/definitions/mem0.cjs.map +1 -0
- package/dist/services/definitions/mem0.d.cts +7 -0
- package/dist/services/definitions/mem0.d.cts.map +1 -0
- package/dist/services/definitions/mem0.d.mts +7 -0
- package/dist/services/definitions/mem0.d.mts.map +1 -0
- package/dist/services/definitions/mem0.mjs +132 -0
- package/dist/services/definitions/mem0.mjs.map +1 -0
- package/dist/services/definitions/memu.cjs +96 -0
- package/dist/services/definitions/memu.cjs.map +1 -0
- package/dist/services/definitions/memu.d.cts +7 -0
- package/dist/services/definitions/memu.d.cts.map +1 -0
- package/dist/services/definitions/memu.d.mts +7 -0
- package/dist/services/definitions/memu.d.mts.map +1 -0
- package/dist/services/definitions/memu.mjs +95 -0
- package/dist/services/definitions/memu.mjs.map +1 -0
- package/dist/services/definitions/metabase.d.cts +1 -1
- package/dist/services/definitions/metabase.d.mts +1 -1
- package/dist/services/definitions/milvus.cjs +4 -1
- package/dist/services/definitions/milvus.cjs.map +1 -1
- package/dist/services/definitions/milvus.d.cts +1 -1
- package/dist/services/definitions/milvus.d.mts +1 -1
- package/dist/services/definitions/milvus.mjs +4 -1
- package/dist/services/definitions/milvus.mjs.map +1 -1
- package/dist/services/definitions/minio.d.cts +1 -1
- package/dist/services/definitions/minio.d.mts +1 -1
- package/dist/services/definitions/mission-control.d.cts +1 -1
- package/dist/services/definitions/mission-control.d.mts +1 -1
- package/dist/services/definitions/mixpost.d.cts +1 -1
- package/dist/services/definitions/mixpost.d.mts +1 -1
- package/dist/services/definitions/mosquitto.d.cts +1 -1
- package/dist/services/definitions/mosquitto.d.mts +1 -1
- package/dist/services/definitions/motion-canvas.d.cts +1 -1
- package/dist/services/definitions/motion-canvas.d.mts +1 -1
- package/dist/services/definitions/mysql.d.cts +1 -1
- package/dist/services/definitions/mysql.d.mts +1 -1
- package/dist/services/definitions/n8n.d.cts +1 -1
- package/dist/services/definitions/n8n.d.mts +1 -1
- package/dist/services/definitions/nanobot.cjs +86 -0
- package/dist/services/definitions/nanobot.cjs.map +1 -0
- package/dist/services/definitions/nanobot.d.cts +7 -0
- package/dist/services/definitions/nanobot.d.cts.map +1 -0
- package/dist/services/definitions/nanobot.d.mts +7 -0
- package/dist/services/definitions/nanobot.d.mts.map +1 -0
- package/dist/services/definitions/nanobot.mjs +85 -0
- package/dist/services/definitions/nanobot.mjs.map +1 -0
- package/dist/services/definitions/nanoclaw.cjs +79 -0
- package/dist/services/definitions/nanoclaw.cjs.map +1 -0
- package/dist/services/definitions/nanoclaw.d.cts +7 -0
- package/dist/services/definitions/nanoclaw.d.cts.map +1 -0
- package/dist/services/definitions/nanoclaw.d.mts +7 -0
- package/dist/services/definitions/nanoclaw.d.mts.map +1 -0
- package/dist/services/definitions/nanoclaw.mjs +78 -0
- package/dist/services/definitions/nanoclaw.mjs.map +1 -0
- package/dist/services/definitions/navidrome.d.cts +1 -1
- package/dist/services/definitions/navidrome.d.mts +1 -1
- package/dist/services/definitions/neo4j.d.cts +1 -1
- package/dist/services/definitions/neo4j.d.mts +1 -1
- package/dist/services/definitions/nextcloud.d.cts +1 -1
- package/dist/services/definitions/nextcloud.d.mts +1 -1
- package/dist/services/definitions/nginx-proxy-manager.d.cts +1 -1
- package/dist/services/definitions/nginx-proxy-manager.d.mts +1 -1
- package/dist/services/definitions/nocodb.d.cts +1 -1
- package/dist/services/definitions/nocodb.d.mts +1 -1
- package/dist/services/definitions/node-red.d.cts +1 -1
- package/dist/services/definitions/node-red.d.mts +1 -1
- package/dist/services/definitions/ntfy.d.cts +1 -1
- package/dist/services/definitions/ntfy.d.mts +1 -1
- package/dist/services/definitions/ollama.d.cts +1 -1
- package/dist/services/definitions/ollama.d.mts +1 -1
- package/dist/services/definitions/open-saas.d.cts +1 -1
- package/dist/services/definitions/open-saas.d.mts +1 -1
- package/dist/services/definitions/open-webui.d.cts +1 -1
- package/dist/services/definitions/open-webui.d.mts +1 -1
- package/dist/services/definitions/opencode.d.cts +1 -1
- package/dist/services/definitions/opencode.d.mts +1 -1
- package/dist/services/definitions/openhands.d.cts +1 -1
- package/dist/services/definitions/openhands.d.mts +1 -1
- package/dist/services/definitions/openpanel.d.cts +1 -1
- package/dist/services/definitions/openpanel.d.mts +1 -1
- package/dist/services/definitions/opensandbox.cjs +2 -1
- package/dist/services/definitions/opensandbox.cjs.map +1 -1
- package/dist/services/definitions/opensandbox.d.cts +1 -1
- package/dist/services/definitions/opensandbox.d.mts +1 -1
- package/dist/services/definitions/opensandbox.mjs +2 -1
- package/dist/services/definitions/opensandbox.mjs.map +1 -1
- package/dist/services/definitions/opensearch.d.cts +1 -1
- package/dist/services/definitions/opensearch.d.mts +1 -1
- package/dist/services/definitions/outline.d.cts +1 -1
- package/dist/services/definitions/outline.d.mts +1 -1
- package/dist/services/definitions/paperless-ngx.d.cts +1 -1
- package/dist/services/definitions/paperless-ngx.d.mts +1 -1
- package/dist/services/definitions/pentagi.d.cts +1 -1
- package/dist/services/definitions/pentagi.d.mts +1 -1
- package/dist/services/definitions/pentestagent.d.cts +1 -1
- package/dist/services/definitions/pentestagent.d.mts +1 -1
- package/dist/services/definitions/photoprism.d.cts +1 -1
- package/dist/services/definitions/photoprism.d.mts +1 -1
- package/dist/services/definitions/pihole.d.cts +1 -1
- package/dist/services/definitions/pihole.d.mts +1 -1
- package/dist/services/definitions/piper-tts.d.cts +1 -1
- package/dist/services/definitions/piper-tts.d.mts +1 -1
- package/dist/services/definitions/plane.d.cts +1 -1
- package/dist/services/definitions/plane.d.mts +1 -1
- package/dist/services/definitions/plausible.d.cts +1 -1
- package/dist/services/definitions/plausible.d.mts +1 -1
- package/dist/services/definitions/playwright-server.d.cts +1 -1
- package/dist/services/definitions/playwright-server.d.mts +1 -1
- package/dist/services/definitions/pocket-id.d.cts +1 -1
- package/dist/services/definitions/pocket-id.d.mts +1 -1
- package/dist/services/definitions/pocketbase.d.cts +1 -1
- package/dist/services/definitions/pocketbase.d.mts +1 -1
- package/dist/services/definitions/portainer.d.cts +1 -1
- package/dist/services/definitions/portainer.d.mts +1 -1
- package/dist/services/definitions/postgresql.d.cts +1 -1
- package/dist/services/definitions/postgresql.d.mts +1 -1
- package/dist/services/definitions/posthog.d.cts +1 -1
- package/dist/services/definitions/posthog.d.mts +1 -1
- package/dist/services/definitions/postiz.d.cts +1 -1
- package/dist/services/definitions/postiz.d.mts +1 -1
- package/dist/services/definitions/prometheus.d.cts +1 -1
- package/dist/services/definitions/prometheus.d.mts +1 -1
- package/dist/services/definitions/qdrant.d.cts +1 -1
- package/dist/services/definitions/qdrant.d.mts +1 -1
- package/dist/services/definitions/rabbitmq.d.cts +1 -1
- package/dist/services/definitions/rabbitmq.d.mts +1 -1
- package/dist/services/definitions/ragflow.d.cts +1 -1
- package/dist/services/definitions/ragflow.d.mts +1 -1
- package/dist/services/definitions/redis.d.cts +1 -1
- package/dist/services/definitions/redis.d.mts +1 -1
- package/dist/services/definitions/relaticle-horizon.cjs +48 -0
- package/dist/services/definitions/relaticle-horizon.cjs.map +1 -0
- package/dist/services/definitions/relaticle-horizon.d.cts +7 -0
- package/dist/services/definitions/relaticle-horizon.d.cts.map +1 -0
- package/dist/services/definitions/relaticle-horizon.d.mts +7 -0
- package/dist/services/definitions/relaticle-horizon.d.mts.map +1 -0
- package/dist/services/definitions/relaticle-horizon.mjs +48 -0
- package/dist/services/definitions/relaticle-horizon.mjs.map +1 -0
- package/dist/services/definitions/relaticle-scheduler.cjs +44 -0
- package/dist/services/definitions/relaticle-scheduler.cjs.map +1 -0
- package/dist/services/definitions/relaticle-scheduler.d.cts +7 -0
- package/dist/services/definitions/relaticle-scheduler.d.cts.map +1 -0
- package/dist/services/definitions/relaticle-scheduler.d.mts +7 -0
- package/dist/services/definitions/relaticle-scheduler.d.mts.map +1 -0
- package/dist/services/definitions/relaticle-scheduler.mjs +44 -0
- package/dist/services/definitions/relaticle-scheduler.mjs.map +1 -0
- package/dist/services/definitions/relaticle.cjs +151 -0
- package/dist/services/definitions/relaticle.cjs.map +1 -0
- package/dist/services/definitions/relaticle.d.cts +80 -0
- package/dist/services/definitions/relaticle.d.cts.map +1 -0
- package/dist/services/definitions/relaticle.d.mts +80 -0
- package/dist/services/definitions/relaticle.d.mts.map +1 -0
- package/dist/services/definitions/relaticle.mjs +149 -0
- package/dist/services/definitions/relaticle.mjs.map +1 -0
- package/dist/services/definitions/remotion.d.cts +1 -1
- package/dist/services/definitions/remotion.d.mts +1 -1
- package/dist/services/definitions/restic.d.cts +1 -1
- package/dist/services/definitions/restic.d.mts +1 -1
- package/dist/services/definitions/revolt.d.cts +1 -1
- package/dist/services/definitions/revolt.d.mts +1 -1
- package/dist/services/definitions/rocketchat.d.cts +1 -1
- package/dist/services/definitions/rocketchat.d.mts +1 -1
- package/dist/services/definitions/saleor.d.cts +1 -1
- package/dist/services/definitions/saleor.d.mts +1 -1
- package/dist/services/definitions/scrapling.d.cts +1 -1
- package/dist/services/definitions/scrapling.d.mts +1 -1
- package/dist/services/definitions/searxng.d.cts +1 -1
- package/dist/services/definitions/searxng.d.mts +1 -1
- package/dist/services/definitions/sentry.d.cts +1 -1
- package/dist/services/definitions/sentry.d.mts +1 -1
- package/dist/services/definitions/signoz.d.cts +1 -1
- package/dist/services/definitions/signoz.d.mts +1 -1
- package/dist/services/definitions/solidityguard.d.cts +1 -1
- package/dist/services/definitions/solidityguard.d.mts +1 -1
- package/dist/services/definitions/sonarqube.d.cts +1 -1
- package/dist/services/definitions/sonarqube.d.mts +1 -1
- package/dist/services/definitions/stable-diffusion.d.cts +1 -1
- package/dist/services/definitions/stable-diffusion.d.mts +1 -1
- package/dist/services/definitions/steel-browser.d.cts +1 -1
- package/dist/services/definitions/steel-browser.d.mts +1 -1
- package/dist/services/definitions/stirling-pdf.d.cts +1 -1
- package/dist/services/definitions/stirling-pdf.d.mts +1 -1
- package/dist/services/definitions/strapi.d.cts +1 -1
- package/dist/services/definitions/strapi.d.mts +1 -1
- package/dist/services/definitions/stream-gateway.d.cts +1 -1
- package/dist/services/definitions/stream-gateway.d.mts +1 -1
- package/dist/services/definitions/supabase.d.cts +1 -1
- package/dist/services/definitions/supabase.d.mts +1 -1
- package/dist/services/definitions/superset.d.cts +1 -1
- package/dist/services/definitions/superset.d.mts +1 -1
- package/dist/services/definitions/surrealdb.d.cts +1 -1
- package/dist/services/definitions/surrealdb.d.mts +1 -1
- package/dist/services/definitions/tabby-ml.d.cts +1 -1
- package/dist/services/definitions/tabby-ml.d.mts +1 -1
- package/dist/services/definitions/tailscale.d.cts +1 -1
- package/dist/services/definitions/tailscale.d.mts +1 -1
- package/dist/services/definitions/tempo.d.cts +1 -1
- package/dist/services/definitions/tempo.d.mts +1 -1
- package/dist/services/definitions/temporal.d.cts +1 -1
- package/dist/services/definitions/temporal.d.mts +1 -1
- package/dist/services/definitions/text-gen-webui.d.cts +1 -1
- package/dist/services/definitions/text-gen-webui.d.mts +1 -1
- package/dist/services/definitions/timescaledb.d.cts +1 -1
- package/dist/services/definitions/timescaledb.d.mts +1 -1
- package/dist/services/definitions/traefik.d.cts +1 -1
- package/dist/services/definitions/traefik.d.mts +1 -1
- package/dist/services/definitions/twenty-worker.cjs +73 -0
- package/dist/services/definitions/twenty-worker.cjs.map +1 -0
- package/dist/services/definitions/twenty-worker.d.cts +7 -0
- package/dist/services/definitions/twenty-worker.d.cts.map +1 -0
- package/dist/services/definitions/twenty-worker.d.mts +7 -0
- package/dist/services/definitions/twenty-worker.d.mts.map +1 -0
- package/dist/services/definitions/twenty-worker.mjs +72 -0
- package/dist/services/definitions/twenty-worker.mjs.map +1 -0
- package/dist/services/definitions/twenty.cjs +24 -2
- package/dist/services/definitions/twenty.cjs.map +1 -1
- package/dist/services/definitions/twenty.d.cts +1 -1
- package/dist/services/definitions/twenty.d.mts +1 -1
- package/dist/services/definitions/twenty.mjs +24 -2
- package/dist/services/definitions/twenty.mjs.map +1 -1
- package/dist/services/definitions/umami.d.cts +1 -1
- package/dist/services/definitions/umami.d.mts +1 -1
- package/dist/services/definitions/uptime-kuma.d.cts +1 -1
- package/dist/services/definitions/uptime-kuma.d.mts +1 -1
- package/dist/services/definitions/usesend.d.cts +1 -1
- package/dist/services/definitions/usesend.d.mts +1 -1
- package/dist/services/definitions/valkey.d.cts +1 -1
- package/dist/services/definitions/valkey.d.mts +1 -1
- package/dist/services/definitions/vault.d.cts +1 -1
- package/dist/services/definitions/vault.d.mts +1 -1
- package/dist/services/definitions/vaultwarden.d.cts +1 -1
- package/dist/services/definitions/vaultwarden.d.mts +1 -1
- package/dist/services/definitions/vector-log.d.cts +1 -1
- package/dist/services/definitions/vector-log.d.mts +1 -1
- package/dist/services/definitions/vikunja.d.cts +1 -1
- package/dist/services/definitions/vikunja.d.mts +1 -1
- package/dist/services/definitions/watchtower.d.cts +1 -1
- package/dist/services/definitions/watchtower.d.mts +1 -1
- package/dist/services/definitions/weaviate.cjs +4 -1
- package/dist/services/definitions/weaviate.cjs.map +1 -1
- package/dist/services/definitions/weaviate.d.cts +1 -1
- package/dist/services/definitions/weaviate.d.mts +1 -1
- package/dist/services/definitions/weaviate.mjs +4 -1
- package/dist/services/definitions/weaviate.mjs.map +1 -1
- package/dist/services/definitions/whisper.d.cts +1 -1
- package/dist/services/definitions/whisper.d.mts +1 -1
- package/dist/services/definitions/wireguard.d.cts +1 -1
- package/dist/services/definitions/wireguard.d.mts +1 -1
- package/dist/services/definitions/woodpecker-ci.d.cts +1 -1
- package/dist/services/definitions/woodpecker-ci.d.mts +1 -1
- package/dist/services/definitions/xyops.d.cts +1 -1
- package/dist/services/definitions/xyops.d.mts +1 -1
- package/dist/services/definitions/zeroclaw.cjs +103 -0
- package/dist/services/definitions/zeroclaw.cjs.map +1 -0
- package/dist/services/definitions/zeroclaw.d.cts +7 -0
- package/dist/services/definitions/zeroclaw.d.cts.map +1 -0
- package/dist/services/definitions/zeroclaw.d.mts +7 -0
- package/dist/services/definitions/zeroclaw.d.mts.map +1 -0
- package/dist/services/definitions/zeroclaw.mjs +102 -0
- package/dist/services/definitions/zeroclaw.mjs.map +1 -0
- package/dist/services/definitions/zulip.d.cts +1 -1
- package/dist/services/definitions/zulip.d.mts +1 -1
- package/dist/services/registry.d.cts +1 -1
- package/dist/services/registry.d.mts +1 -1
- package/dist/services/registry.test.cjs +8 -8
- package/dist/services/registry.test.cjs.map +1 -1
- package/dist/services/registry.test.mjs +8 -8
- package/dist/services/registry.test.mjs.map +1 -1
- package/dist/skills/registry.cjs +19 -0
- package/dist/skills/registry.cjs.map +1 -1
- package/dist/skills/registry.d.cts +1 -1
- package/dist/skills/registry.d.cts.map +1 -1
- package/dist/skills/registry.d.mts +1 -1
- package/dist/skills/registry.d.mts.map +1 -1
- package/dist/skills/registry.mjs +19 -0
- package/dist/skills/registry.mjs.map +1 -1
- package/dist/{skills-BSF7iNa4.cjs → skills-uPxJVmKk.cjs} +311 -1
- package/dist/skills-uPxJVmKk.cjs.map +1 -0
- package/dist/{test.CTcmp4Su-ClCHJ3FA.mjs → test.CTcmp4Su-BRa7-bTj.mjs} +2 -2
- package/dist/{test.CTcmp4Su-ClCHJ3FA.mjs.map → test.CTcmp4Su-BRa7-bTj.mjs.map} +1 -1
- package/dist/{test.CTcmp4Su-DlzTarwH.cjs → test.CTcmp4Su-BWSPM8ZQ.cjs} +19 -1
- package/dist/{test.CTcmp4Su-DlzTarwH.cjs.map → test.CTcmp4Su-BWSPM8ZQ.cjs.map} +1 -1
- package/dist/track-analytics.d.cts +1 -1
- package/dist/track-analytics.d.mts +1 -1
- package/dist/track-analytics.test.cjs +1 -1
- package/dist/track-analytics.test.mjs +1 -1
- package/dist/types-BREUfzzq.d.mts +77 -0
- package/dist/types-BREUfzzq.d.mts.map +1 -0
- package/dist/types-Bsn0XzSP.d.cts +95 -0
- package/dist/types-Bsn0XzSP.d.cts.map +1 -0
- package/dist/types-CyZ5mn6w.d.cts +77 -0
- package/dist/types-CyZ5mn6w.d.cts.map +1 -0
- package/dist/types-DIsPc-hb.d.cts +100 -0
- package/dist/types-DIsPc-hb.d.cts.map +1 -0
- package/dist/types-DbXajvYq.d.mts +100 -0
- package/dist/types-DbXajvYq.d.mts.map +1 -0
- package/dist/types-DwTKyCZ9.d.mts +95 -0
- package/dist/types-DwTKyCZ9.d.mts.map +1 -0
- package/dist/{types-CR83OJiq.d.cts → types-dyBnrHm9.d.cts} +5 -1
- package/dist/types-dyBnrHm9.d.cts.map +1 -0
- package/dist/{types-zYjGTuyn.d.mts → types-fRSnaZTX.d.mts} +5 -1
- package/dist/types-fRSnaZTX.d.mts.map +1 -0
- package/dist/types.cjs +7 -0
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.cts +2 -93
- package/dist/types.d.mts +2 -93
- package/dist/types.mjs +7 -0
- package/dist/types.mjs.map +1 -1
- package/dist/validator.cjs +1 -1
- package/dist/validator.d.cts +1 -1
- package/dist/validator.d.mts +1 -1
- package/dist/validator.test.cjs +1 -1
- package/dist/validator.test.mjs +1 -1
- package/dist/version-manager.d.cts +1 -1
- package/dist/version-manager.d.mts +1 -1
- package/dist/version-manager.test.cjs +3 -3
- package/dist/version-manager.test.cjs.map +1 -1
- package/dist/version-manager.test.mjs +3 -3
- package/dist/version-manager.test.mjs.map +1 -1
- package/dist/zeroclaw-B-0TuOfZ.d.mts +7 -0
- package/dist/zeroclaw-B-0TuOfZ.d.mts.map +1 -0
- package/dist/zeroclaw-BvKpDHKe.d.cts +7 -0
- package/dist/zeroclaw-BvKpDHKe.d.cts.map +1 -0
- package/package.json +6 -2
- package/src/addon-stack.test.ts +19 -23
- package/src/addon-stack.ts +67 -44
- package/src/composer.test.ts +59 -0
- package/src/composer.ts +135 -194
- package/src/deployers/coolify.test.ts +180 -0
- package/src/deployers/coolify.ts +38 -0
- package/src/deployers/dokploy.test.ts +120 -0
- package/src/deployers/dokploy.ts +38 -0
- package/src/deployers/types.ts +2 -0
- package/src/frameworks/claude-code-fw.ts +118 -0
- package/src/frameworks/codex-fw.ts +102 -0
- package/src/frameworks/copaw.ts +154 -0
- package/src/frameworks/frameworks.test.ts +119 -0
- package/src/frameworks/index.ts +46 -0
- package/src/frameworks/memu.ts +149 -0
- package/src/frameworks/nanobot.ts +156 -0
- package/src/frameworks/nanoclaw.ts +126 -0
- package/src/frameworks/openclaw.ts +325 -0
- package/src/frameworks/registry.test.ts +131 -0
- package/src/frameworks/registry.ts +28 -0
- package/src/frameworks/types.ts +146 -0
- package/src/frameworks/zeroclaw.ts +148 -0
- package/src/generate.test.ts +55 -4
- package/src/generate.ts +67 -14
- package/src/generators/caddy.test.ts +41 -1
- package/src/generators/caddy.ts +16 -2
- package/src/generators/clone-repos.test.ts +1 -1
- package/src/generators/clone-repos.ts +7 -2
- package/src/generators/cloud-init.test.ts +70 -0
- package/src/generators/env.test.ts +2 -2
- package/src/generators/env.ts +30 -180
- package/src/generators/get-shit-done.test.ts +54 -0
- package/src/generators/grafana.test.ts +90 -0
- package/src/generators/health-check.ts +4 -4
- package/src/generators/n8n-workflows.test.ts +80 -0
- package/src/generators/openclaw-install-script.test.ts +42 -0
- package/src/generators/openclaw-json.ts +57 -5
- package/src/generators/postgres-init.test.ts +116 -0
- package/src/generators/postgres-init.ts +9 -0
- package/src/generators/prometheus.test.ts +108 -0
- package/src/generators/readme.ts +75 -9
- package/src/generators/scripts.test.ts +1 -1
- package/src/generators/skills.ts +316 -0
- package/src/generators/stack-manifest.test.ts +104 -0
- package/src/generators/traefik.test.ts +13 -13
- package/src/index.ts +47 -7
- package/src/logger/__tests__/logger.test.ts +388 -0
- package/src/logger/index.ts +15 -0
- package/src/logger/logger.ts +326 -0
- package/src/logger/sinks/callback-sink.ts +13 -0
- package/src/logger/sinks/console-sink.ts +51 -0
- package/src/logger/sinks/file-sink.ts +121 -0
- package/src/logger/types.ts +90 -0
- package/src/migrations.ts +8 -1
- package/src/port-scanner.test.ts +167 -0
- package/src/presets/presets.test.ts +4 -4
- package/src/presets/registry.test.ts +6 -6
- package/src/resolver.test.ts +31 -3
- package/src/resolver.ts +19 -3
- package/src/schema.test.ts +2 -2
- package/src/schema.ts +58 -17
- package/src/services/definitions/agent-browser.ts +177 -0
- package/src/services/definitions/apptension-saas.ts +2 -1
- package/src/services/definitions/chromadb.ts +1 -1
- package/src/services/definitions/claude-code.ts +1 -1
- package/src/services/definitions/clawrouter.ts +141 -0
- package/src/services/definitions/codex.ts +1 -1
- package/src/services/definitions/convex.ts +1 -2
- package/src/services/definitions/copaw.ts +101 -0
- package/src/services/definitions/desktop-environment.ts +1 -0
- package/src/services/definitions/hindsight.ts +3 -2
- package/src/services/definitions/index.ts +53 -16
- package/src/services/definitions/mem0.ts +132 -0
- package/src/services/definitions/memu.ts +96 -0
- package/src/services/definitions/milvus.ts +1 -1
- package/src/services/definitions/nanobot.ts +89 -0
- package/src/services/definitions/nanoclaw.ts +78 -0
- package/src/services/definitions/opensandbox.ts +6 -15
- package/src/services/definitions/relaticle-horizon.ts +48 -0
- package/src/services/definitions/relaticle-scheduler.ts +42 -0
- package/src/services/definitions/relaticle.ts +142 -0
- package/src/services/definitions/twenty-worker.ts +70 -0
- package/src/services/definitions/twenty.ts +16 -2
- package/src/services/definitions/weaviate.ts +1 -1
- package/src/services/definitions/zeroclaw.ts +102 -0
- package/src/services/registry.test.ts +7 -7
- package/src/skills/registry.ts +10 -0
- package/src/types.ts +11 -1
- package/src/version-manager.test.ts +2 -2
- package/dist/schema-BQnZrcw8.d.cts.map +0 -1
- package/dist/schema-SBpL0bdI.d.mts.map +0 -1
- package/dist/skills-BSF7iNa4.cjs.map +0 -1
- package/dist/types-CR83OJiq.d.cts.map +0 -1
- package/dist/types-zYjGTuyn.d.mts.map +0 -1
- package/dist/types.d.cts.map +0 -1
- package/dist/types.d.mts.map +0 -1
package/README.md
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
# @better-openclaw/core
|
|
2
2
|
|
|
3
|
-
The core engine responsible for parsing configurations, resolving dependencies, formatting outputs, and generating production-ready
|
|
3
|
+
The core engine responsible for parsing configurations, resolving dependencies, formatting outputs, and generating production-ready AI agent Docker Compose stacks with support for 8 agent frameworks.
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
|
-
- **
|
|
8
|
-
- **
|
|
7
|
+
- **Multi-Agent Framework Registry:** Choose from 8 pluggable agent frameworks (OpenClaw, CoPaw, NanoClaw, NanoBot, ZeroClaw, MemU, Claude Code, Codex) as primary orchestrator, with optional companion frameworks for hybrid stacks. Framework definitions live in `src/frameworks/` and use a registry pattern.
|
|
8
|
+
- **Service Registry:** A unified, expandable catalog of 94+ pre-configured Docker services (e.g., Traefik, PostgreSQL, Qdrant, Ollama, N8N, SearXNG, Scrapling, etc.) categorized by function (databases, models, scrapers, tools).
|
|
9
|
+
- **Dependency Resolution Engine:** Automatically detects and resolves required services. Framework-specific mandatory services are injected automatically (e.g., MemU requires PostgreSQL, non-OpenClaw frameworks skip Convex/Mission-Control/Tailscale).
|
|
9
10
|
- **Skill Injection (`SKILL.md`):** Deep integration with AI agent workflows. Packages specialized `SKILL.md` instructions into volume mounts for AI tools like the `browser` integration or `tinyfish`.
|
|
10
|
-
- **Intelligent Networking & Proxies:** Fully integrated reverse proxy generation (Caddy and Traefik)
|
|
11
|
+
- **Intelligent Networking & Proxies:** Fully integrated reverse proxy generation (Caddy and Traefik) with auto-SSL domain generation and WebSocket streaming support (`flush_interval -1`) for noVNC/KasmVNC desktop sandbox services.
|
|
11
12
|
- **Cross-Platform & Heterogeneous Topologies:** Supports generating stacks for `local` (Docker Desktop), `vps` (cloud), and `homelab` deployments. It explicitly supports a hybrid native-docker model via `deploymentType: "bare-metal"`.
|
|
12
13
|
- **GPU Passthrough Support:** Automatically injects NVIDIA or AMD runtime flags to AI services if the `gpuRequired` flag is detected on the requested service and enabled by the user.
|
|
13
14
|
|
|
@@ -19,9 +20,9 @@ You can use the generation engine programmatically within any Node.js or TypeScr
|
|
|
19
20
|
import { generate, type GenerationInput } from "@better-openclaw/core";
|
|
20
21
|
|
|
21
22
|
const input: GenerationInput = {
|
|
22
|
-
projectName: "my-
|
|
23
|
-
services: ["
|
|
24
|
-
skillPacks: ["
|
|
23
|
+
projectName: "my-agent-stack",
|
|
24
|
+
services: ["postgresql", "ollama", "n8n"],
|
|
25
|
+
skillPacks: ["local-ai"],
|
|
25
26
|
proxy: "caddy",
|
|
26
27
|
domain: "my-ai.example.com",
|
|
27
28
|
gpu: true,
|
|
@@ -31,6 +32,8 @@ const input: GenerationInput = {
|
|
|
31
32
|
generateSecrets: true,
|
|
32
33
|
openclawVersion: "latest",
|
|
33
34
|
monitoring: true,
|
|
35
|
+
primaryFramework: "zeroclaw", // Choose from 8 agent frameworks
|
|
36
|
+
companionFrameworks: ["copaw"], // Optional companion frameworks
|
|
34
37
|
};
|
|
35
38
|
|
|
36
39
|
// Generates the Compose YAML, configs, skills, and .env securely.
|
|
@@ -88,6 +91,63 @@ const result = await deployer.deploy({
|
|
|
88
91
|
});
|
|
89
92
|
```
|
|
90
93
|
|
|
94
|
+
## Operations Logger
|
|
95
|
+
|
|
96
|
+
The core ships a centralized `OperationsLogger` used by all packages (CLI, API, MCP) to produce structured, NDJSON log files tracking every significant operation — generation pipelines, deployments, file writes, API requests, and MCP tool calls.
|
|
97
|
+
|
|
98
|
+
### Programmatic Usage
|
|
99
|
+
|
|
100
|
+
```typescript
|
|
101
|
+
import { OperationsLogger, ConsoleSink, CallbackSink } from "@better-openclaw/core";
|
|
102
|
+
import { FileSink } from "@better-openclaw/core/logger/sinks/file-sink";
|
|
103
|
+
|
|
104
|
+
const logger = new OperationsLogger({
|
|
105
|
+
source: "cli", // "cli" | "api" | "mcp" | "web" | "core"
|
|
106
|
+
sinks: [
|
|
107
|
+
new ConsoleSink(), // Human-readable terminal output
|
|
108
|
+
new FileSink(), // NDJSON file (~/.better-openclaw/logs/operations.log)
|
|
109
|
+
],
|
|
110
|
+
minLevel: "info", // "debug" | "info" | "warn" | "error"
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
// Basic logging
|
|
114
|
+
logger.info("generation", "Starting stack generation", { projectName: "my-stack" });
|
|
115
|
+
logger.warn("validation", "Port conflict detected", { port: 8080 });
|
|
116
|
+
logger.error("deployment", "Deploy failed", new Error("timeout"), { provider: "dokploy" });
|
|
117
|
+
|
|
118
|
+
// Timed operations (auto-logs duration + outcome)
|
|
119
|
+
const result = await logger.timed("deployment", "Deploying to Dokploy", async () => {
|
|
120
|
+
return await deployer.deploy(input);
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
// Child loggers (inherit correlationId)
|
|
124
|
+
const childLogger = logger.child({ source: "core" });
|
|
125
|
+
|
|
126
|
+
// Pass to generate()
|
|
127
|
+
const output = generate(input, { logger });
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### Log File Location
|
|
131
|
+
|
|
132
|
+
| Default | `~/.better-openclaw/logs/operations.log` |
|
|
133
|
+
|---------|------------------------------------------|
|
|
134
|
+
| Override | `OPENCLAW_LOG_DIR` env var |
|
|
135
|
+
| Format | NDJSON (one JSON object per line, `jq`-friendly) |
|
|
136
|
+
| Rotation | 10 MB per file, 5 rotated files (~60 MB total) |
|
|
137
|
+
|
|
138
|
+
### Environment Variables
|
|
139
|
+
|
|
140
|
+
| Variable | Default | Description |
|
|
141
|
+
|----------|---------|-------------|
|
|
142
|
+
| `OPENCLAW_LOG_DIR` | `~/.better-openclaw/logs/` | Log directory path |
|
|
143
|
+
| `OPENCLAW_LOG_LEVEL` | `info` | Minimum log level |
|
|
144
|
+
| `OPENCLAW_LOG_MAX_SIZE` | `10485760` (10 MB) | Max file size before rotation |
|
|
145
|
+
| `OPENCLAW_LOG_MAX_FILES` | `5` | Number of rotated files to keep |
|
|
146
|
+
|
|
147
|
+
### Sensitive Data
|
|
148
|
+
|
|
149
|
+
The logger automatically redacts known sensitive keys (`apiKey`, `password`, `token`, `secret`, `authorization`, `credentials`, `private_key`) from context before writing to any sink.
|
|
150
|
+
|
|
91
151
|
## Development
|
|
92
152
|
|
|
93
153
|
```bash
|
package/dist/addon-stack.cjs
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_skills = require("./skills-
|
|
2
|
+
const require_skills = require("./skills-uPxJVmKk.cjs");
|
|
3
|
+
const require_frameworks_registry = require("./frameworks/registry.cjs");
|
|
4
|
+
require("./frameworks/index.cjs");
|
|
3
5
|
const require_generators_postgres_init = require("./generators/postgres-init.cjs");
|
|
4
6
|
const require_composer = require("./composer.cjs");
|
|
5
7
|
const require_services_registry = require("./services/registry.cjs");
|
|
@@ -8,31 +10,28 @@ const require_schema = require("./schema.cjs");
|
|
|
8
10
|
let yaml = require("yaml");
|
|
9
11
|
let node_crypto = require("node:crypto");
|
|
10
12
|
//#region src/addon-stack.ts
|
|
11
|
-
/**
|
|
12
|
-
const
|
|
13
|
-
"openclaw-gateway",
|
|
14
|
-
"openclaw-cli",
|
|
13
|
+
/** Base infrastructure service IDs that Clawexa's cloud-init provisions. */
|
|
14
|
+
const BASE_INFRA_SERVICE_IDS = [
|
|
15
15
|
"redis",
|
|
16
16
|
"postgresql",
|
|
17
17
|
"open-webui",
|
|
18
18
|
"caddy",
|
|
19
19
|
"traefik",
|
|
20
|
-
"postgres-setup"
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
20
|
+
"postgres-setup"
|
|
21
|
+
];
|
|
22
|
+
/** Build the full set of infra IDs for a given framework. */
|
|
23
|
+
function getInfraServiceIds(framework) {
|
|
24
|
+
return new Set([
|
|
25
|
+
`${framework.id}-gateway`,
|
|
26
|
+
`${framework.id}-cli`,
|
|
27
|
+
...BASE_INFRA_SERVICE_IDS,
|
|
28
|
+
...framework.getMandatoryServices()
|
|
29
|
+
]);
|
|
30
|
+
}
|
|
25
31
|
/** Env keys managed by Clawexa's cloud-init — never include in addon env output. */
|
|
26
32
|
const CLAWEXA_MANAGED_ENV_KEYS = new Set([
|
|
27
33
|
"COMPOSE_FILE",
|
|
28
34
|
"COMPOSE_PROFILES",
|
|
29
|
-
"OPENCLAW_VERSION",
|
|
30
|
-
"OPENCLAW_GATEWAY_TOKEN",
|
|
31
|
-
"OPENCLAW_GATEWAY_PORT",
|
|
32
|
-
"OPENCLAW_BRIDGE_PORT",
|
|
33
|
-
"OPENCLAW_GATEWAY_BIND",
|
|
34
|
-
"OPENCLAW_CONFIG_DIR",
|
|
35
|
-
"OPENCLAW_WORKSPACE_DIR",
|
|
36
35
|
"REDIS_PASSWORD",
|
|
37
36
|
"REDIS_HOST",
|
|
38
37
|
"REDIS_PORT",
|
|
@@ -42,6 +41,16 @@ const CLAWEXA_MANAGED_ENV_KEYS = new Set([
|
|
|
42
41
|
"POSTGRES_HOST",
|
|
43
42
|
"POSTGRES_PORT"
|
|
44
43
|
]);
|
|
44
|
+
/** Build the full set of managed env keys for a given framework. */
|
|
45
|
+
function getManagedEnvKeys(framework) {
|
|
46
|
+
const keys = new Set(CLAWEXA_MANAGED_ENV_KEYS);
|
|
47
|
+
for (const envLine of framework.getBaseEnvVars({
|
|
48
|
+
generateSecrets: false,
|
|
49
|
+
frameworkVersion: "latest",
|
|
50
|
+
frameworkImageVariant: "official"
|
|
51
|
+
})) keys.add(envLine.key);
|
|
52
|
+
return keys;
|
|
53
|
+
}
|
|
45
54
|
/** Sanitize instanceId into a valid Docker Compose project name. */
|
|
46
55
|
function sanitizeProjectName(instanceId) {
|
|
47
56
|
return instanceId.toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/^-+|-+$/g, "").replace(/-{2,}/g, "-").slice(0, 64) || "addon";
|
|
@@ -156,7 +165,7 @@ function resolvePortConflicts(addonServices, reservedPorts, portOverrides) {
|
|
|
156
165
|
if (userOverride) {
|
|
157
166
|
usedPorts.add(userOverride);
|
|
158
167
|
assignments[`${def.id}:${port.container}`] = userOverride;
|
|
159
|
-
|
|
168
|
+
overrides[def.id] ??= {};
|
|
160
169
|
overrides[def.id][String(port.host)] = userOverride;
|
|
161
170
|
continue;
|
|
162
171
|
}
|
|
@@ -164,7 +173,7 @@ function resolvePortConflicts(addonServices, reservedPorts, portOverrides) {
|
|
|
164
173
|
if (usedPorts.has(assignedPort)) {
|
|
165
174
|
assignedPort = port.host + 1e3;
|
|
166
175
|
while (usedPorts.has(assignedPort)) assignedPort++;
|
|
167
|
-
|
|
176
|
+
overrides[def.id] ??= {};
|
|
168
177
|
overrides[def.id][String(port.host)] = assignedPort;
|
|
169
178
|
}
|
|
170
179
|
usedPorts.add(assignedPort);
|
|
@@ -195,8 +204,11 @@ function generateAddonStack(rawInput) {
|
|
|
195
204
|
return emptyResult(`Invalid input: ${err instanceof Error ? err.message : String(err)}`);
|
|
196
205
|
}
|
|
197
206
|
const projectName = sanitizeProjectName(input.instanceId);
|
|
207
|
+
const framework = require_frameworks_registry.getFrameworkById("openclaw");
|
|
208
|
+
const infraIds = getInfraServiceIds(framework);
|
|
209
|
+
const managedKeys = getManagedEnvKeys(framework);
|
|
198
210
|
const addonServiceIds = input.services.filter((id) => {
|
|
199
|
-
if (
|
|
211
|
+
if (infraIds.has(id)) {
|
|
200
212
|
warnings.push(`Service "${id}" is managed by Clawexa infrastructure and was excluded.`);
|
|
201
213
|
return false;
|
|
202
214
|
}
|
|
@@ -239,7 +251,7 @@ function generateAddonStack(rawInput) {
|
|
|
239
251
|
for (const w of resolved.warnings) warnings.push(w.message);
|
|
240
252
|
const addonResolved = [];
|
|
241
253
|
for (const svc of resolved.services) {
|
|
242
|
-
if (
|
|
254
|
+
if (infraIds.has(svc.definition.id)) continue;
|
|
243
255
|
addonResolved.push(svc);
|
|
244
256
|
}
|
|
245
257
|
const deployableServices = [];
|
|
@@ -329,7 +341,7 @@ function generateAddonStack(rawInput) {
|
|
|
329
341
|
delete entry.profiles;
|
|
330
342
|
if (entry.depends_on) {
|
|
331
343
|
const deps = entry.depends_on;
|
|
332
|
-
for (const depId of Object.keys(deps)) if (
|
|
344
|
+
for (const depId of Object.keys(deps)) if (infraIds.has(depId)) delete deps[depId];
|
|
333
345
|
if (Object.keys(deps).length === 0) delete entry.depends_on;
|
|
334
346
|
}
|
|
335
347
|
services[def.id] = entry;
|
|
@@ -370,7 +382,7 @@ function generateAddonStack(rawInput) {
|
|
|
370
382
|
entrypoint: ["/bin/sh", "-c"],
|
|
371
383
|
command: [scriptLines.join("\n")],
|
|
372
384
|
restart: require_composer.quotedStr("no"),
|
|
373
|
-
networks: [
|
|
385
|
+
networks: [framework.networkName]
|
|
374
386
|
};
|
|
375
387
|
for (const req of dbReqs) {
|
|
376
388
|
const svcEntry = services[req.serviceId];
|
|
@@ -400,7 +412,7 @@ function generateAddonStack(rawInput) {
|
|
|
400
412
|
envLines.push("");
|
|
401
413
|
}
|
|
402
414
|
}
|
|
403
|
-
const seenKeys = new Set([...
|
|
415
|
+
const seenKeys = new Set([...managedKeys, ...dbReqs.map((r) => r.passwordEnvVar)]);
|
|
404
416
|
const envVarGroups = [];
|
|
405
417
|
for (const svc of deployableServices) {
|
|
406
418
|
const def = svc.definition;
|
|
@@ -456,7 +468,7 @@ function generateAddonStack(rawInput) {
|
|
|
456
468
|
else finalEnvLines.push(line);
|
|
457
469
|
} else finalEnvLines.push(line);
|
|
458
470
|
}
|
|
459
|
-
for (const [key, value] of envValues) if (!quirkedKeys.has(key) && !seenKeys.has(key) && !
|
|
471
|
+
for (const [key, value] of envValues) if (!quirkedKeys.has(key) && !seenKeys.has(key) && !managedKeys.has(key)) {
|
|
460
472
|
finalEnvLines.push(`# Synced by env quirk`);
|
|
461
473
|
finalEnvLines.push(`${key}=${value}`);
|
|
462
474
|
finalEnvLines.push("");
|
|
@@ -522,7 +534,7 @@ function generateAddonStack(rawInput) {
|
|
|
522
534
|
for (const v of allVolumes) volumeMap[v] = null;
|
|
523
535
|
const composeDoc = { services };
|
|
524
536
|
if (Object.keys(volumeMap).length > 0) composeDoc.volumes = volumeMap;
|
|
525
|
-
composeDoc.networks = {
|
|
537
|
+
composeDoc.networks = { [framework.networkName]: { external: true } };
|
|
526
538
|
return {
|
|
527
539
|
composeOverride: (0, yaml.stringify)(composeDoc, require_composer.YAML_OPTIONS),
|
|
528
540
|
envFile,
|
|
@@ -572,7 +584,6 @@ function updateAddonStack(rawInput) {
|
|
|
572
584
|
const eqIdx = trimmed.indexOf("=");
|
|
573
585
|
if (eqIdx > 0) existingEnvMap.set(trimmed.slice(0, eqIdx), trimmed.slice(eqIdx + 1));
|
|
574
586
|
}
|
|
575
|
-
new Set(input.addServices);
|
|
576
587
|
const removeSet = new Set(input.removeServices);
|
|
577
588
|
const desiredServiceIds = [...currentServiceIds.filter((id) => !removeSet.has(id)), ...input.addServices.filter((id) => !currentServiceIds.includes(id))];
|
|
578
589
|
const targetResult = generateAddonStack({
|
|
@@ -581,10 +592,12 @@ function updateAddonStack(rawInput) {
|
|
|
581
592
|
skillPacks: [],
|
|
582
593
|
platform: input.platform,
|
|
583
594
|
openclawVersion: input.openclawVersion,
|
|
595
|
+
existingServices: input.existingServices,
|
|
584
596
|
reservedPorts: input.reservedPorts,
|
|
585
597
|
generateSecrets: input.generateSecrets,
|
|
586
598
|
credentials: input.credentials,
|
|
587
599
|
portOverrides: input.portOverrides,
|
|
600
|
+
gpu: input.gpu,
|
|
588
601
|
aiProviders: input.aiProviders,
|
|
589
602
|
prebuiltImages: input.prebuiltImages
|
|
590
603
|
});
|
|
@@ -614,7 +627,7 @@ function updateAddonStack(rawInput) {
|
|
|
614
627
|
if (!def) continue;
|
|
615
628
|
for (const skill of def.skills) {
|
|
616
629
|
const skillPath = Object.keys(targetResult.skillFiles).find((path) => path.includes(skill.skillId));
|
|
617
|
-
if (skillPath) newSkillFiles[skillPath] = targetResult.skillFiles[skillPath];
|
|
630
|
+
if (skillPath && targetResult.skillFiles[skillPath]) newSkillFiles[skillPath] = targetResult.skillFiles[skillPath];
|
|
618
631
|
}
|
|
619
632
|
}
|
|
620
633
|
for (const id of removed) {
|
package/dist/addon-stack.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"addon-stack.cjs","names":["AddonStackInputSchema","getServiceById","resolve","buildCompanionService","getDbRequirements","quotedStr","generateSkillFiles","YAML_OPTIONS","AddonStackUpdateInputSchema"],"sources":["../src/addon-stack.ts"],"sourcesContent":["import { randomBytes } from \"node:crypto\";\nimport { stringify } from \"yaml\";\nimport { parse as parseYaml } from \"yaml\";\nimport { buildCompanionService, buildPostgresSetup, quotedStr, YAML_OPTIONS } from \"./composer.js\";\nimport { getDbRequirements } from \"./generators/postgres-init.js\";\nimport { generateSkillFiles } from \"./generators/skills.js\";\nimport { resolve } from \"./resolver.js\";\nimport { AddonStackInputSchema, AddonStackUpdateInputSchema } from \"./schema.js\";\nimport { getServiceById } from \"./services/registry.js\";\nimport type {\n\tAddonStackInput,\n\tAddonStackResult,\n\tAddonStackUpdateInput,\n\tAddonStackUpdateResult,\n\tComposeOptions,\n\tProxyRoute,\n\tResolvedService,\n\tResolverOutput,\n\tServiceDefinition,\n\tSkippedService,\n} from \"./types.js\";\n\n// ── Constants ────────────────────────────────────────────────────────────────\n\n/** Services that Clawexa's cloud-init already provisions (or are mandatory platform services). */\nconst INFRA_SERVICE_IDS = new Set([\n\t\"openclaw-gateway\",\n\t\"openclaw-cli\",\n\t\"redis\",\n\t\"postgresql\",\n\t\"open-webui\",\n\t\"caddy\",\n\t\"traefik\",\n\t\"postgres-setup\",\n\t// Mandatory platform services provisioned by Clawexa cloud-init\n\t\"convex\",\n\t\"convex-dashboard\",\n\t\"mission-control\",\n]);\n\n/** Env keys managed by Clawexa's cloud-init — never include in addon env output. */\nconst CLAWEXA_MANAGED_ENV_KEYS = new Set([\n\t\"COMPOSE_FILE\",\n\t\"COMPOSE_PROFILES\",\n\t\"OPENCLAW_VERSION\",\n\t\"OPENCLAW_GATEWAY_TOKEN\",\n\t\"OPENCLAW_GATEWAY_PORT\",\n\t\"OPENCLAW_BRIDGE_PORT\",\n\t\"OPENCLAW_GATEWAY_BIND\",\n\t\"OPENCLAW_CONFIG_DIR\",\n\t\"OPENCLAW_WORKSPACE_DIR\",\n\t\"REDIS_PASSWORD\",\n\t\"REDIS_HOST\",\n\t\"REDIS_PORT\",\n\t\"POSTGRES_USER\",\n\t\"POSTGRES_PASSWORD\",\n\t\"POSTGRES_DB\",\n\t\"POSTGRES_HOST\",\n\t\"POSTGRES_PORT\",\n]);\n\n// ── Helpers ──────────────────────────────────────────────────────────────────\n\n/** Sanitize instanceId into a valid Docker Compose project name. */\nfunction sanitizeProjectName(instanceId: string): string {\n\treturn instanceId\n\t\t.toLowerCase()\n\t\t.replace(/[^a-z0-9-]/g, \"-\")\n\t\t.replace(/^-+|-+$/g, \"\")\n\t\t.replace(/-{2,}/g, \"-\")\n\t\t.slice(0, 64) || \"addon\";\n}\n\n/** Generate a cryptographically secure hex secret of the given byte length. */\nfunction generateHexSecret(bytes: number): string {\n\treturn randomBytes(bytes).toString(\"hex\");\n}\n\n/** Generate a cryptographically secure base64url secret of the given byte length. */\nfunction generateBase64UrlSecret(bytes: number): string {\n\treturn randomBytes(bytes).toString(\"base64url\");\n}\n\n/**\n * Check if a service requires user-provided credentials that are missing.\n * Returns the list of missing credential keys, or empty if all are satisfied.\n *\n * When `generateSecrets` is true, empty-default secrets are auto-generated\n * (passwords, tokens, etc.) and are NOT considered missing. Only secrets\n * with `validation` regex patterns (indicating specific format like API keys)\n * are flagged as missing when not provided by the user.\n */\nfunction getMissingCredentials(\n\tdef: ServiceDefinition,\n\tuserCredentials: Record<string, string> | undefined,\n\tgenerateSecrets: boolean,\n): string[] {\n\tconst missing: string[] = [];\n\tfor (const env of def.environment) {\n\t\t// Skip if not required or not a secret\n\t\tif (!env.required || !env.secret) continue;\n\t\t// Skip if it has a non-empty default value or is a reference\n\t\tif (env.defaultValue && env.defaultValue.length > 0) continue;\n\t\t// Skip if user provided the credential\n\t\tif (userCredentials?.[env.key]) continue;\n\t\t// When generateSecrets is true, empty secrets are auto-generated\n\t\t// Only flag as missing if the env var has a validation pattern\n\t\t// (indicating it needs a specific format like an API key)\n\t\tif (generateSecrets && !env.validation) continue;\n\n\t\tmissing.push(env.key);\n\t}\n\treturn missing;\n}\n\n/**\n * Apply env quirks (from service definition) to the generated env values.\n * Handles: empty_string_crashes → set fixed value, min_length → generate longer secret,\n * must_sync → ensure two keys have the same value.\n */\nfunction applyEnvQuirks(\n\tdef: ServiceDefinition,\n\tenvValues: Map<string, string>,\n\tgenerateSecrets: boolean,\n): void {\n\tif (!def.envQuirks) return;\n\n\tfor (const quirk of def.envQuirks) {\n\t\tswitch (quirk.issue) {\n\t\t\tcase \"empty_string_crashes\": {\n\t\t\t\tif (quirk.fix.type === \"set_value\" && quirk.fix.value !== undefined) {\n\t\t\t\t\tenvValues.set(quirk.key, quirk.fix.value);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"min_length\": {\n\t\t\t\tif (!generateSecrets) break;\n\t\t\t\tconst current = envValues.get(quirk.key) || \"\";\n\t\t\t\tconst minBytes = quirk.fix.minBytes || 24;\n\t\t\t\tconst minHexLen = minBytes * 2;\n\t\t\t\tif (current.length < minHexLen) {\n\t\t\t\t\tif (quirk.fix.type === \"generate_hex\") {\n\t\t\t\t\t\tenvValues.set(quirk.key, generateHexSecret(minBytes));\n\t\t\t\t\t} else if (quirk.fix.type === \"generate_base64url\") {\n\t\t\t\t\t\tenvValues.set(quirk.key, generateBase64UrlSecret(minBytes));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"must_sync\": {\n\t\t\t\tif (quirk.fix.type === \"sync_with\" && quirk.fix.syncKey) {\n\t\t\t\t\tconst sourceValue = envValues.get(quirk.key) || envValues.get(quirk.fix.syncKey);\n\t\t\t\t\tif (sourceValue) {\n\t\t\t\t\t\tenvValues.set(quirk.key, sourceValue);\n\t\t\t\t\t\tenvValues.set(quirk.fix.syncKey, sourceValue);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Build proxy routes from resolved addon services.\n */\nfunction buildProxyRoutes(services: ResolvedService[]): ProxyRoute[] {\n\tconst routes: ProxyRoute[] = [];\n\tfor (const { definition: def } of services) {\n\t\tconst exposedPort = def.ports.find((p) => p.exposed);\n\t\tif (!exposedPort) continue;\n\n\t\troutes.push({\n\t\t\tserviceId: def.id,\n\t\t\tpath: def.proxyPath || `/${def.id}`,\n\t\t\tport: exposedPort.container,\n\t\t\tprotocol: \"http\",\n\t\t\tstripPrefix: true,\n\t\t});\n\t}\n\treturn routes;\n}\n\n/**\n * Build a minimal ComposeOptions suitable for addon stack generation.\n * No proxy, no gateway, no hardening by default.\n */\nfunction buildAddonComposeOptions(projectName: string, input: AddonStackInput): ComposeOptions {\n\treturn {\n\t\tprojectName,\n\t\tproxy: \"none\",\n\t\tgpu: false,\n\t\tplatform: input.platform ?? \"linux/amd64\",\n\t\tdeployment: \"clawexa\",\n\t\topenclawVersion: input.openclawVersion ?? \"latest\",\n\t\topenclawImage: \"official\",\n\t\thardened: false, // Clawexa default: no cap_drop/security_opt\n\t\topenclawInstallMethod: \"docker\",\n\t};\n}\n\n/**\n * Resolve port conflicts between addon services and reserved ports.\n * Returns a map of serviceId → { originalPort → assignedPort }.\n */\nfunction resolvePortConflicts(\n\taddonServices: ResolvedService[],\n\treservedPorts: number[],\n\tportOverrides?: Record<string, Record<string, number>>,\n): { assignments: Record<string, number>; overrides: Record<string, Record<string, number>> } {\n\tconst usedPorts = new Set(reservedPorts);\n\tconst assignments: Record<string, number> = {};\n\tconst overrides: Record<string, Record<string, number>> = {};\n\n\tfor (const { definition: def } of addonServices) {\n\t\tfor (const port of def.ports) {\n\t\t\tif (!port.exposed) continue;\n\n\t\t\t// Check for user-specified override\n\t\t\tconst userOverride = portOverrides?.[def.id]?.[String(port.host)];\n\t\t\tif (userOverride) {\n\t\t\t\tusedPorts.add(userOverride);\n\t\t\t\tassignments[`${def.id}:${port.container}`] = userOverride;\n\t\t\t\tif (!overrides[def.id]) overrides[def.id] = {};\n\t\t\t\toverrides[def.id][String(port.host)] = userOverride;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tlet assignedPort = port.host;\n\t\t\tif (usedPorts.has(assignedPort)) {\n\t\t\t\t// Auto-reassign to port+1000 range\n\t\t\t\tassignedPort = port.host + 1000;\n\t\t\t\twhile (usedPorts.has(assignedPort)) {\n\t\t\t\t\tassignedPort++;\n\t\t\t\t}\n\t\t\t\tif (!overrides[def.id]) overrides[def.id] = {};\n\t\t\t\toverrides[def.id][String(port.host)] = assignedPort;\n\t\t\t}\n\t\t\tusedPorts.add(assignedPort);\n\t\t\tassignments[`${def.id}:${port.container}`] = assignedPort;\n\t\t}\n\t}\n\n\treturn { assignments, overrides };\n}\n\n// ── Main: generateAddonStack ─────────────────────────────────────────────────\n\n/**\n * Generates a Docker Compose override stack containing only addon services\n * for Clawexa managed instances. Infrastructure services (gateway, redis,\n * postgres, open-webui, caddy) are excluded since Clawexa's cloud-init\n * already provisions them.\n *\n * This function never throws. Errors are reported via `warnings` and\n * `metadata.skippedServices`.\n */\nexport function generateAddonStack(rawInput: AddonStackInput): AddonStackResult {\n\tconst warnings: string[] = [];\n\tconst skippedServices: SkippedService[] = [];\n\tconst generatedSecretKeys: string[] = [];\n\n\t// 1. Parse & validate input\n\tlet input: AddonStackInput;\n\ttry {\n\t\tinput = AddonStackInputSchema.parse(rawInput);\n\t} catch (err) {\n\t\treturn emptyResult(`Invalid input: ${err instanceof Error ? err.message : String(err)}`);\n\t}\n\n\tconst projectName = sanitizeProjectName(input.instanceId);\n\n\t// 2. Filter out infrastructure service IDs from request\n\tconst addonServiceIds = input.services.filter((id) => {\n\t\tif (INFRA_SERVICE_IDS.has(id)) {\n\t\t\twarnings.push(`Service \"${id}\" is managed by Clawexa infrastructure and was excluded.`);\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t});\n\n\tif (addonServiceIds.length === 0) {\n\t\treturn emptyResult(\"No addon services requested (all were infrastructure services).\");\n\t}\n\n\t// 3. Validate all service IDs exist in registry\n\tconst validServiceIds: string[] = [];\n\tfor (const id of addonServiceIds) {\n\t\tconst svc = getServiceById(id);\n\t\tif (!svc) {\n\t\t\tskippedServices.push({\n\t\t\t\tserviceId: id,\n\t\t\t\treason: \"unknown_service\",\n\t\t\t\tdetails: `Service \"${id}\" does not exist in the registry.`,\n\t\t\t});\n\t\t} else {\n\t\t\tvalidServiceIds.push(id);\n\t\t}\n\t}\n\n\tif (validServiceIds.length === 0) {\n\t\treturn {\n\t\t\t...emptyResultBase(),\n\t\t\tmetadata: {\n\t\t\t\t...emptyResultBase().metadata,\n\t\t\t\tskippedServices,\n\t\t\t},\n\t\t\twarnings: [...warnings, \"No valid addon services to deploy.\"],\n\t\t};\n\t}\n\n\t// 4. Resolve dependencies\n\tlet resolved: ResolverOutput;\n\ttry {\n\t\tresolved = resolve({\n\t\t\tservices: validServiceIds,\n\t\t\tskillPacks: input.skillPacks,\n\t\t\taiProviders: input.aiProviders,\n\t\t\tplatform: input.platform ?? \"linux/amd64\",\n\t\t});\n\t} catch (err) {\n\t\treturn {\n\t\t\t...emptyResultBase(),\n\t\t\tmetadata: {\n\t\t\t\t...emptyResultBase().metadata,\n\t\t\t\tskippedServices,\n\t\t\t},\n\t\t\twarnings: [\n\t\t\t\t...warnings,\n\t\t\t\t`Dependency resolution failed: ${err instanceof Error ? err.message : String(err)}`,\n\t\t\t],\n\t\t};\n\t}\n\n\t// Forward resolver warnings\n\tfor (const w of resolved.warnings) {\n\t\twarnings.push(w.message);\n\t}\n\n\t// 5. Filter resolved services: keep only addon services (not infra)\n\tconst addonResolved: ResolvedService[] = [];\n\tfor (const svc of resolved.services) {\n\t\tif (INFRA_SERVICE_IDS.has(svc.definition.id)) continue;\n\t\taddonResolved.push(svc);\n\t}\n\n\t// 6. Check credentials, images, platform, GPU for each addon service\n\tconst deployableServices: ResolvedService[] = [];\n\tfor (const svc of addonResolved) {\n\t\tconst def = svc.definition;\n\n\t\t// Check for git-based services without prebuilt image\n\t\tif (def.gitSource && def.buildContext && !def.image) {\n\t\t\tconst prebuilt = def.prebuiltImage || input.prebuiltImages[def.id];\n\t\t\tif (!prebuilt) {\n\t\t\t\tskippedServices.push({\n\t\t\t\t\tserviceId: def.id,\n\t\t\t\t\treason: \"no_image\",\n\t\t\t\t\tdetails: `Service \"${def.name}\" requires building from source but no pre-built image is available.`,\n\t\t\t\t});\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\n\t\t// Check GPU requirement — skip if host has no GPU support\n\t\tif (def.gpuRequired && !input.gpu) {\n\t\t\tskippedServices.push({\n\t\t\t\tserviceId: def.id,\n\t\t\t\treason: \"gpu_required\",\n\t\t\t\tdetails: `Service \"${def.name}\" requires a GPU but the host does not have GPU support.`,\n\t\t\t});\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Check user-provided credentials\n\t\tconst userCreds = input.credentials[def.id];\n\t\tconst missing = getMissingCredentials(def, userCreds, input.generateSecrets);\n\t\tif (missing.length > 0) {\n\t\t\tskippedServices.push({\n\t\t\t\tserviceId: def.id,\n\t\t\t\treason: \"missing_credentials\",\n\t\t\t\tdetails: `Service \"${def.name}\" requires credentials: ${missing.join(\", \")}`,\n\t\t\t\trequiredCredentials: missing,\n\t\t\t});\n\t\t\tcontinue;\n\t\t}\n\n\t\tdeployableServices.push(svc);\n\t}\n\n\tif (deployableServices.length === 0) {\n\t\treturn {\n\t\t\t...emptyResultBase(),\n\t\t\tmetadata: {\n\t\t\t\t...emptyResultBase().metadata,\n\t\t\t\tskippedServices,\n\t\t\t},\n\t\t\twarnings: [...warnings, \"No deployable addon services after filtering.\"],\n\t\t};\n\t}\n\n\t// 7. Resolve port conflicts (include ports from existingServices)\n\tconst allReservedPorts = [...input.reservedPorts];\n\tfor (const existingId of input.existingServices) {\n\t\tconst existingDef = getServiceById(existingId);\n\t\tif (existingDef) {\n\t\t\tfor (const port of existingDef.ports) {\n\t\t\t\tif (port.exposed) allReservedPorts.push(port.host);\n\t\t\t}\n\t\t}\n\t}\n\tconst portConflicts = resolvePortConflicts(\n\t\tdeployableServices,\n\t\tallReservedPorts,\n\t\tinput.portOverrides,\n\t);\n\n\t// Build a fake \"full\" resolved output for buildCompanionService\n\t// It needs to see all services to resolve depends_on references\n\tconst addonResolvedOutput: ResolverOutput = {\n\t\tservices: deployableServices,\n\t\taddedDependencies: resolved.addedDependencies,\n\t\tremovedConflicts: resolved.removedConflicts,\n\t\twarnings: resolved.warnings,\n\t\terrors: [],\n\t\tisValid: true,\n\t\testimatedMemoryMB: deployableServices.reduce(\n\t\t\t(sum, s) => sum + (s.definition.minMemoryMB ?? 128),\n\t\t\t0,\n\t\t),\n\t\taiProviders: input.aiProviders ?? [],\n\t\tgsdRuntimes: [],\n\t};\n\n\t// 8. Build compose options (no hardening for Clawexa)\n\tconst composeOptions = buildAddonComposeOptions(projectName, input);\n\tif (Object.keys(portConflicts.overrides).length > 0) {\n\t\tcomposeOptions.portOverrides = portConflicts.overrides;\n\t}\n\n\t// 9. Build per-service entries\n\tconst services: Record<string, Record<string, unknown>> = {};\n\tconst allVolumes = new Set<string>();\n\tconst envValues = new Map<string, string>();\n\n\tfor (const svc of deployableServices) {\n\t\tconst def = svc.definition;\n\t\ttry {\n\t\t\t// Handle prebuilt image substitution for git-based services\n\t\t\tlet effectiveDef = def;\n\t\t\tif (def.gitSource && def.buildContext && !def.image) {\n\t\t\t\tconst prebuiltImage = def.prebuiltImage || input.prebuiltImages[def.id];\n\t\t\t\tif (prebuiltImage) {\n\t\t\t\t\tconst [img, tag] = prebuiltImage.includes(\":\")\n\t\t\t\t\t\t? prebuiltImage.split(\":\")\n\t\t\t\t\t\t: [prebuiltImage, \"latest\"];\n\t\t\t\t\teffectiveDef = {\n\t\t\t\t\t\t...def,\n\t\t\t\t\t\timage: img,\n\t\t\t\t\t\timageTag: tag,\n\t\t\t\t\t\tgitSource: undefined,\n\t\t\t\t\t\tbuildContext: undefined,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst { entry, volumeNames } = buildCompanionService(\n\t\t\t\teffectiveDef,\n\t\t\t\taddonResolvedOutput,\n\t\t\t\tcomposeOptions,\n\t\t\t\tallVolumes,\n\t\t\t);\n\n\t\t\t// Remove profiles from the service entry\n\t\t\tdelete (entry as Record<string, unknown>).profiles;\n\n\t\t\t// Remove depends_on references to infrastructure services\n\t\t\tif (entry.depends_on) {\n\t\t\t\tconst deps = entry.depends_on as Record<string, { condition: string }>;\n\t\t\t\tfor (const depId of Object.keys(deps)) {\n\t\t\t\t\tif (INFRA_SERVICE_IDS.has(depId)) {\n\t\t\t\t\t\tdelete deps[depId];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (Object.keys(deps).length === 0) {\n\t\t\t\t\tdelete entry.depends_on;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tservices[def.id] = entry;\n\t\t\tfor (const v of volumeNames) allVolumes.add(v);\n\n\t\t\t// Inject user-provided credentials into env\n\t\t\tconst userCreds = input.credentials[def.id];\n\t\t\tif (userCreds) {\n\t\t\t\tfor (const [key, value] of Object.entries(userCreds)) {\n\t\t\t\t\tenvValues.set(key, value);\n\t\t\t\t}\n\t\t\t\t// Sync referenced keys: if a user provides e.g. DB_POSTGRESDB_PASSWORD\n\t\t\t\t// and the env var's defaultValue is \"${N8N_DB_PASSWORD}\", sync the ref key\n\t\t\t\t// so postgres-setup uses the same password.\n\t\t\t\tfor (const envVar of def.environment) {\n\t\t\t\t\tif (\n\t\t\t\t\t\tuserCreds[envVar.key] &&\n\t\t\t\t\t\tenvVar.defaultValue?.startsWith(\"${\") &&\n\t\t\t\t\t\tenvVar.defaultValue?.endsWith(\"}\")\n\t\t\t\t\t) {\n\t\t\t\t\t\tconst refKey = envVar.defaultValue.slice(2, -1);\n\t\t\t\t\t\tenvValues.set(refKey, userCreds[envVar.key]);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (err) {\n\t\t\tskippedServices.push({\n\t\t\t\tserviceId: def.id,\n\t\t\t\treason: \"resolution_error\",\n\t\t\t\tdetails: `Failed to build compose entry: ${err instanceof Error ? err.message : String(err)}`,\n\t\t\t});\n\t\t\twarnings.push(`Failed to process service \"${def.name}\": ${err instanceof Error ? err.message : String(err)}`);\n\t\t}\n\t}\n\n\t// 10. Build postgres-setup if any addon needs a DB\n\t// We need to check if any of our deployable services require DB setup\n\t// and if postgresql is in the infrastructure (it is for Clawexa)\n\tconst dbReqs = getDbRequirements(addonResolvedOutput);\n\tif (dbReqs.length > 0) {\n\t\t// Build a custom postgres-setup that references the existing PostgreSQL\n\t\t// We can't use buildPostgresSetup directly because it checks for postgresql\n\t\t// in the resolved services. Instead, build it manually.\n\t\tconst scriptLines = [\"echo '=== PostgreSQL database setup (addon) ==='\", \"FAILED=0\"];\n\n\t\tfor (const req of dbReqs) {\n\t\t\tscriptLines.push(\n\t\t\t\t`echo \"Setting up database '${req.dbName}' with user '${req.dbUser}'...\"`,\n\t\t\t\t`psql -c \"SELECT 1 FROM pg_roles WHERE rolname='${req.dbUser}'\" | grep -q 1 || psql -c \"CREATE ROLE ${req.dbUser} WITH LOGIN PASSWORD '$$${req.passwordEnvVar}'\"`,\n\t\t\t\t`psql -c \"ALTER ROLE ${req.dbUser} WITH LOGIN PASSWORD '$$${req.passwordEnvVar}'\"`,\n\t\t\t\t`psql -tc \"SELECT 1 FROM pg_database WHERE datname='${req.dbName}'\" | grep -q 1 || psql -c \"CREATE DATABASE ${req.dbName} OWNER ${req.dbUser}\"`,\n\t\t\t\t`psql -c \"GRANT ALL PRIVILEGES ON DATABASE ${req.dbName} TO ${req.dbUser}\" || FAILED=1`,\n\t\t\t\t`echo \" Done: ${req.dbName}\"`,\n\t\t\t);\n\t\t}\n\t\tscriptLines.push(\"echo '=== All databases ready ==='\", \"exit $$FAILED\");\n\n\t\tconst dbEnv: Record<string, string> = {\n\t\t\tPGHOST: \"postgresql\",\n\t\t\tPGUSER: \"${POSTGRES_USER:-openclaw}\",\n\t\t\tPGDATABASE: \"${POSTGRES_DB:-openclaw}\",\n\t\t\tPGPASSWORD: \"${POSTGRES_PASSWORD}\",\n\t\t};\n\t\tfor (const req of dbReqs) {\n\t\t\tdbEnv[req.passwordEnvVar] = `\\${${req.passwordEnvVar}}`;\n\t\t}\n\n\t\tservices[\"postgres-setup\"] = {\n\t\t\timage: \"postgres:17-alpine\",\n\t\t\tdepends_on: {\n\t\t\t\tpostgresql: { condition: \"service_healthy\" },\n\t\t\t},\n\t\t\tenvironment: dbEnv,\n\t\t\tentrypoint: [\"/bin/sh\", \"-c\"],\n\t\t\tcommand: [scriptLines.join(\"\\n\")],\n\t\t\trestart: quotedStr(\"no\"),\n\t\t\tnetworks: [\"openclaw-network\"],\n\t\t};\n\n\t\t// Update addon services that need DB to depend on postgres-setup\n\t\tfor (const req of dbReqs) {\n\t\t\tconst svcEntry = services[req.serviceId];\n\t\t\tif (svcEntry) {\n\t\t\t\tconst deps = (svcEntry.depends_on as Record<string, { condition: string }>) || {};\n\t\t\t\tdeps[\"postgres-setup\"] = { condition: \"service_completed_successfully\" };\n\t\t\t\tsvcEntry.depends_on = deps;\n\t\t\t}\n\t\t}\n\t}\n\n\t// 11. Generate secrets and env file\n\tconst envLines: string[] = [\n\t\t\"# ═══════════════════════════════════════════════════════════════════════════════\",\n\t\t\"# OpenClaw Addon Stack Environment\",\n\t\t`# Instance: ${input.instanceId}`,\n\t\t`# Generated at ${new Date().toISOString()}`,\n\t\t\"# ═══════════════════════════════════════════════════════════════════════════════\",\n\t\t\"\",\n\t];\n\n\t// DB passwords first\n\tif (dbReqs.length > 0) {\n\t\tenvLines.push(\"# ── Per-Service Database Passwords ──────────────────────────────────────\");\n\t\tfor (const req of dbReqs) {\n\t\t\tconst secretValue = input.generateSecrets ? generateHexSecret(24) : \"\";\n\t\t\tenvValues.set(req.passwordEnvVar, secretValue);\n\t\t\tif (secretValue) generatedSecretKeys.push(req.passwordEnvVar);\n\t\t\tenvLines.push(`# PostgreSQL password for ${req.serviceName} (db: ${req.dbName}, user: ${req.dbUser})`);\n\t\t\tenvLines.push(`${req.passwordEnvVar}=${secretValue}`);\n\t\t\tenvLines.push(\"\");\n\t\t}\n\t}\n\n\t// Per-service env vars\n\tconst seenKeys = new Set<string>([...CLAWEXA_MANAGED_ENV_KEYS, ...dbReqs.map((r) => r.passwordEnvVar)]);\n\tconst envVarGroups: AddonStackResult[\"envVars\"] = [];\n\n\tfor (const svc of deployableServices) {\n\t\tconst def = svc.definition;\n\t\tconst allEnvVars = [...def.environment, ...def.openclawEnvVars];\n\t\tif (allEnvVars.length === 0) continue;\n\n\t\tconst groupVars: AddonStackResult[\"envVars\"][number][\"vars\"] = [];\n\n\t\tenvLines.push(`# ── ${def.icon} ${def.name} ──────────────────────────────────────`);\n\n\t\tfor (const envVar of allEnvVars) {\n\t\t\tif (seenKeys.has(envVar.key)) continue;\n\t\t\tseenKeys.add(envVar.key);\n\n\t\t\t// Check if user provided this credential\n\t\t\tconst userValue = input.credentials[def.id]?.[envVar.key];\n\t\t\tlet actualValue: string;\n\n\t\t\tif (userValue !== undefined) {\n\t\t\t\tactualValue = userValue;\n\t\t\t} else if (envVar.secret) {\n\t\t\t\t// Resolve references like ${N8N_DB_PASSWORD}\n\t\t\t\tif (envVar.defaultValue.startsWith(\"${\") && envVar.defaultValue.endsWith(\"}\")) {\n\t\t\t\t\tconst refKey = envVar.defaultValue.slice(2, -1);\n\t\t\t\t\tactualValue = envValues.get(refKey) || envVar.defaultValue;\n\t\t\t\t} else if (input.generateSecrets) {\n\t\t\t\t\tactualValue = generateHexSecret(24);\n\t\t\t\t\tgeneratedSecretKeys.push(envVar.key);\n\t\t\t\t} else {\n\t\t\t\t\tactualValue = envVar.defaultValue;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tactualValue = envVar.defaultValue;\n\t\t\t}\n\n\t\t\tenvValues.set(envVar.key, actualValue);\n\n\t\t\tenvLines.push(`# ${envVar.description}`);\n\t\t\tenvLines.push(`${envVar.key}=${actualValue}`);\n\t\t\tenvLines.push(\"\");\n\n\t\t\tgroupVars.push({\n\t\t\t\tkey: envVar.key,\n\t\t\t\tdescription: envVar.description,\n\t\t\t\tvalue: actualValue,\n\t\t\t\tsecret: envVar.secret,\n\t\t\t});\n\t\t}\n\n\t\tif (groupVars.length > 0) {\n\t\t\tenvVarGroups.push({\n\t\t\t\tserviceName: def.name,\n\t\t\t\tvars: groupVars,\n\t\t\t});\n\t\t}\n\t}\n\n\t// Apply env quirks after all values are generated\n\tfor (const svc of deployableServices) {\n\t\tapplyEnvQuirks(svc.definition, envValues, input.generateSecrets);\n\t}\n\n\t// Rebuild env lines from envValues (quirks may have modified values or introduced new keys)\n\tconst quirkedKeys = new Set<string>();\n\tconst finalEnvLines: string[] = [];\n\tfor (const line of envLines) {\n\t\tconst trimmed = line.trim();\n\t\tif (!trimmed || trimmed.startsWith(\"#\")) {\n\t\t\tfinalEnvLines.push(line);\n\t\t\tcontinue;\n\t\t}\n\t\tconst eqIdx = trimmed.indexOf(\"=\");\n\t\tif (eqIdx > 0) {\n\t\t\tconst key = trimmed.slice(0, eqIdx);\n\t\t\tquirkedKeys.add(key);\n\t\t\tconst fixedValue = envValues.get(key);\n\t\t\tif (fixedValue !== undefined) {\n\t\t\t\tfinalEnvLines.push(`${key}=${fixedValue}`);\n\t\t\t} else {\n\t\t\t\tfinalEnvLines.push(line);\n\t\t\t}\n\t\t} else {\n\t\t\tfinalEnvLines.push(line);\n\t\t}\n\t}\n\t// Append any new keys introduced by quirks (e.g., must_sync creating a new key)\n\tfor (const [key, value] of envValues) {\n\t\tif (!quirkedKeys.has(key) && !seenKeys.has(key) && !CLAWEXA_MANAGED_ENV_KEYS.has(key)) {\n\t\t\tfinalEnvLines.push(`# Synced by env quirk`);\n\t\t\tfinalEnvLines.push(`${key}=${value}`);\n\t\t\tfinalEnvLines.push(\"\");\n\t\t}\n\t}\n\tconst envFile = finalEnvLines.join(\"\\n\");\n\n\t// 12. Generate skill files\n\tconst skillFiles = generateSkillFiles(addonResolvedOutput);\n\n\t// 13. Build openclaw config patch\n\tconst skillEntries: Record<string, { enabled: boolean }> = {};\n\tlet skillCount = 0;\n\tfor (const svc of deployableServices) {\n\t\tfor (const skill of svc.definition.skills) {\n\t\t\tif (skill.autoInstall) {\n\t\t\t\tskillEntries[skill.skillId] = { enabled: true };\n\t\t\t\tskillCount++;\n\t\t\t}\n\t\t}\n\t}\n\n\t// 14. Build proxy routes\n\tconst proxyRoutes = buildProxyRoutes(deployableServices);\n\n\t// 14b. Build additional files (e.g. sandbox.toml for opensandbox)\n\tconst additionalFiles: Record<string, string> = {};\n\tif (deployableServices.some((s) => s.definition.id === \"opensandbox\")) {\n\t\tadditionalFiles[\"sandbox.toml\"] = [\n\t\t\t\"[server]\",\n\t\t\t'host = \"0.0.0.0\"',\n\t\t\t\"port = 8080\",\n\t\t\t'log_level = \"INFO\"',\n\t\t\t'api_key = \"${OPEN_SANDBOX_API_KEY}\"',\n\t\t\t\"\",\n\t\t\t\"[runtime]\",\n\t\t\t'type = \"docker\"',\n\t\t\t'execd_image = \"opensandbox/execd:v1.0.6\"',\n\t\t\t\"\",\n\t\t\t\"[docker]\",\n\t\t\t\"network_mode = \\\"bridge\\\"\",\n\t\t\t'drop_capabilities = [\"NET_ADMIN\", \"SYS_ADMIN\", \"SYS_PTRACE\", \"MKNOD\", \"NET_RAW\", \"SYS_RAWIO\"]',\n\t\t\t\"no_new_privileges = true\",\n\t\t\t\"pids_limit = 512\",\n\t\t\t\"\",\n\t\t\t\"[secure_runtime]\",\n\t\t\t'type = \"gvisor\"',\n\t\t\t\"\",\n\t\t].join(\"\\n\");\n\t}\n\n\t// 14c. Build pre-pull images list\n\tconst prePullImages: Array<{ image: string; priority: 1 | 2 | 3 }> = [];\n\tif (deployableServices.some((s) => s.definition.id === \"opensandbox\")) {\n\t\tprePullImages.push(\n\t\t\t// Priority 1: always pulled (core + Homespace)\n\t\t\t{ image: \"opensandbox/server:v1.0.6\", priority: 1 },\n\t\t\t{ image: \"opensandbox/execd:v1.0.6\", priority: 1 },\n\t\t\t{ image: \"opensandbox/desktop:latest\", priority: 1 },\n\t\t\t{ image: \"opensandbox/chrome:latest\", priority: 1 },\n\t\t\t// Priority 2: recommended (common languages)\n\t\t\t{ image: \"opensandbox/code-interpreter:python\", priority: 2 },\n\t\t\t{ image: \"opensandbox/code-interpreter:node\", priority: 2 },\n\t\t\t// Priority 3: optional (full multi-lang and IDE)\n\t\t\t{ image: \"opensandbox/code-interpreter:latest\", priority: 3 },\n\t\t\t{ image: \"opensandbox/vscode:latest\", priority: 3 },\n\t\t);\n\t}\n\n\t// 15. Compose single YAML\n\tconst volumeMap: Record<string, null> = {};\n\tfor (const v of allVolumes) {\n\t\tvolumeMap[v] = null;\n\t}\n\n\tconst composeDoc: Record<string, unknown> = {\n\t\tservices,\n\t};\n\n\tif (Object.keys(volumeMap).length > 0) {\n\t\tcomposeDoc.volumes = volumeMap;\n\t}\n\n\tcomposeDoc.networks = {\n\t\t\"openclaw-network\": {\n\t\t\texternal: true,\n\t\t},\n\t};\n\n\tconst composeOverride = stringify(composeDoc, YAML_OPTIONS);\n\n\t// 16. Return result\n\treturn {\n\t\tcomposeOverride,\n\t\tenvFile,\n\t\tenvVars: envVarGroups,\n\t\tskillFiles,\n\t\topenclawConfigPatch: {\n\t\t\tskills: { entries: skillEntries },\n\t\t},\n\t\tproxyRoutes,\n\t\tadditionalFiles,\n\t\tmetadata: {\n\t\t\tserviceCount: Object.keys(services).length,\n\t\t\tskillCount,\n\t\t\testimatedMemoryMB: addonResolvedOutput.estimatedMemoryMB,\n\t\t\tresolvedServices: deployableServices.map((s) => s.definition.id),\n\t\t\tskippedServices,\n\t\t\tgeneratedSecretKeys,\n\t\t\tportAssignments: portConflicts.assignments,\n\t\t\tprePullImages,\n\t\t},\n\t\twarnings,\n\t};\n}\n\n// ── Main: updateAddonStack ───────────────────────────────────────────────────\n\n/**\n * Incrementally updates an existing addon stack by adding or removing services.\n * Preserves existing env values (never overwrites user-customized values).\n *\n * This function never throws.\n */\nexport function updateAddonStack(rawInput: AddonStackUpdateInput): AddonStackUpdateResult {\n\tconst warnings: string[] = [];\n\n\t// 1. Parse & validate\n\tlet input: AddonStackUpdateInput;\n\ttry {\n\t\tinput = AddonStackUpdateInputSchema.parse(rawInput);\n\t} catch (err) {\n\t\treturn emptyUpdateResult(`Invalid input: ${err instanceof Error ? err.message : String(err)}`);\n\t}\n\n\t// 2. Parse existing compose YAML to extract current service list\n\tlet currentServiceIds: string[] = [];\n\ttry {\n\t\tconst existingCompose = parseYaml(input.currentCompose);\n\t\tif (existingCompose?.services && typeof existingCompose.services === \"object\") {\n\t\t\tcurrentServiceIds = Object.keys(existingCompose.services).filter(\n\t\t\t\t(id) => id !== \"postgres-setup\",\n\t\t\t);\n\t\t}\n\t} catch (err) {\n\t\twarnings.push(\n\t\t\t`Failed to parse existing compose YAML: ${err instanceof Error ? err.message : String(err)}`,\n\t\t);\n\t}\n\n\t// 3. Parse existing env into a map\n\tconst existingEnvMap = new Map<string, string>();\n\tfor (const line of input.currentEnv.split(\"\\n\")) {\n\t\tconst trimmed = line.trim();\n\t\tif (!trimmed || trimmed.startsWith(\"#\")) continue;\n\t\tconst eqIdx = trimmed.indexOf(\"=\");\n\t\tif (eqIdx > 0) {\n\t\t\texistingEnvMap.set(trimmed.slice(0, eqIdx), trimmed.slice(eqIdx + 1));\n\t\t}\n\t}\n\n\t// 4. Compute desired service list\n\tconst addSet = new Set(input.addServices);\n\tconst removeSet = new Set(input.removeServices);\n\tconst desiredServiceIds = [\n\t\t...currentServiceIds.filter((id) => !removeSet.has(id)),\n\t\t...input.addServices.filter((id) => !currentServiceIds.includes(id)),\n\t];\n\n\t// 5. Generate the full target state\n\tconst targetResult = generateAddonStack({\n\t\tinstanceId: input.instanceId,\n\t\tservices: desiredServiceIds,\n\t\tskillPacks: [],\n\t\tplatform: input.platform,\n\t\topenclawVersion: input.openclawVersion,\n\t\treservedPorts: input.reservedPorts,\n\t\tgenerateSecrets: input.generateSecrets,\n\t\tcredentials: input.credentials,\n\t\tportOverrides: input.portOverrides,\n\t\taiProviders: input.aiProviders,\n\t\tprebuiltImages: input.prebuiltImages,\n\t});\n\n\t// 6. Merge env: preserve existing values, only add new ones\n\tconst mergedEnvLines: string[] = [];\n\tfor (const line of targetResult.envFile.split(\"\\n\")) {\n\t\tconst trimmed = line.trim();\n\t\tif (!trimmed || trimmed.startsWith(\"#\")) {\n\t\t\tmergedEnvLines.push(line);\n\t\t\tcontinue;\n\t\t}\n\t\tconst eqIdx = trimmed.indexOf(\"=\");\n\t\tif (eqIdx > 0) {\n\t\t\tconst key = trimmed.slice(0, eqIdx);\n\t\t\tif (existingEnvMap.has(key)) {\n\t\t\t\t// Preserve existing value\n\t\t\t\tmergedEnvLines.push(`${key}=${existingEnvMap.get(key)}`);\n\t\t\t} else {\n\t\t\t\tmergedEnvLines.push(line);\n\t\t\t}\n\t\t} else {\n\t\t\tmergedEnvLines.push(line);\n\t\t}\n\t}\n\n\t// 7. Compute diffs\n\tconst currentSet = new Set(currentServiceIds);\n\tconst targetSet = new Set(targetResult.metadata.resolvedServices);\n\tconst added = [...targetSet].filter((id) => !currentSet.has(id));\n\tconst removed = [...currentSet].filter((id) => !targetSet.has(id));\n\tconst unchanged = [...currentSet].filter((id) => targetSet.has(id));\n\n\t// 8. Compute skill diffs\n\tconst newSkillFiles: Record<string, string> = {};\n\tconst removedSkillSlugs: string[] = [];\n\n\t// New skills from added services\n\tfor (const id of added) {\n\t\tconst def = getServiceById(id);\n\t\tif (!def) continue;\n\t\tfor (const skill of def.skills) {\n\t\t\tconst skillPath = Object.keys(targetResult.skillFiles).find(\n\t\t\t\t(path) => path.includes(skill.skillId),\n\t\t\t);\n\t\t\tif (skillPath) {\n\t\t\t\tnewSkillFiles[skillPath] = targetResult.skillFiles[skillPath];\n\t\t\t}\n\t\t}\n\t}\n\n\t// Removed skills from removed services\n\tfor (const id of removed) {\n\t\tconst def = getServiceById(id);\n\t\tif (!def) continue;\n\t\tfor (const skill of def.skills) {\n\t\t\tremovedSkillSlugs.push(skill.skillId);\n\t\t}\n\t}\n\n\t// 9. Proxy route diffs\n\tconst addProxyRoutes = targetResult.proxyRoutes.filter((r) => added.includes(r.serviceId));\n\tconst removeProxyRoutes = removed;\n\n\t// 10. Images to pull for new services\n\tconst imagesToPull: string[] = [];\n\tfor (const id of added) {\n\t\tconst def = getServiceById(id);\n\t\tif (def?.image && def?.imageTag) {\n\t\t\timagesToPull.push(`${def.image}:${def.imageTag}`);\n\t\t} else if (def?.prebuiltImage) {\n\t\t\timagesToPull.push(def.prebuiltImage);\n\t\t}\n\t}\n\n\t// 11. Estimate memory delta\n\tlet memoryDelta = 0;\n\tfor (const id of added) {\n\t\tconst def = getServiceById(id);\n\t\tmemoryDelta += def?.minMemoryMB ?? 128;\n\t}\n\tfor (const id of removed) {\n\t\tconst def = getServiceById(id);\n\t\tmemoryDelta -= def?.minMemoryMB ?? 128;\n\t}\n\n\t// Add existing skills to the config patch\n\tconst addSkillEntries: Record<string, { enabled: boolean }> = {};\n\tfor (const id of added) {\n\t\tconst def = getServiceById(id);\n\t\tif (!def) continue;\n\t\tfor (const skill of def.skills) {\n\t\t\tif (skill.autoInstall) {\n\t\t\t\taddSkillEntries[skill.skillId] = { enabled: true };\n\t\t\t}\n\t\t}\n\t}\n\n\treturn {\n\t\tcomposeOverride: targetResult.composeOverride,\n\t\tenvFile: mergedEnvLines.join(\"\\n\"),\n\t\tnewSkillFiles,\n\t\tremovedSkillSlugs,\n\t\topenclawConfigPatch: {\n\t\t\tskills: {\n\t\t\t\tadd: addSkillEntries,\n\t\t\t\tremove: removedSkillSlugs,\n\t\t\t},\n\t\t},\n\t\taddProxyRoutes,\n\t\tremoveProxyRoutes,\n\t\timagesToPull,\n\t\trestartRequired: added, // New services need starting, not restarting\n\t\tmetadata: {\n\t\t\tadded,\n\t\t\tremoved,\n\t\t\tunchanged,\n\t\t\testimatedMemoryDelta: memoryDelta,\n\t\t},\n\t\twarnings: [...warnings, ...targetResult.warnings],\n\t};\n}\n\n// ── Empty Result Helpers ─────────────────────────────────────────────────────\n\nfunction emptyResultBase(): AddonStackResult {\n\treturn {\n\t\tcomposeOverride: \"services: {}\\n\",\n\t\tenvFile: \"\",\n\t\tenvVars: [],\n\t\tskillFiles: {},\n\t\topenclawConfigPatch: { skills: { entries: {} } },\n\t\tproxyRoutes: [],\n\t\tadditionalFiles: {},\n\t\tmetadata: {\n\t\t\tserviceCount: 0,\n\t\t\tskillCount: 0,\n\t\t\testimatedMemoryMB: 0,\n\t\t\tresolvedServices: [],\n\t\t\tskippedServices: [],\n\t\t\tgeneratedSecretKeys: [],\n\t\t\tportAssignments: {},\n\t\t\tprePullImages: [],\n\t\t},\n\t\twarnings: [],\n\t};\n}\n\nfunction emptyResult(warning: string): AddonStackResult {\n\treturn {\n\t\t...emptyResultBase(),\n\t\twarnings: [warning],\n\t};\n}\n\nfunction emptyUpdateResult(warning: string): AddonStackUpdateResult {\n\treturn {\n\t\tcomposeOverride: \"services: {}\\n\",\n\t\tenvFile: \"\",\n\t\tnewSkillFiles: {},\n\t\tremovedSkillSlugs: [],\n\t\topenclawConfigPatch: { skills: { add: {}, remove: [] } },\n\t\taddProxyRoutes: [],\n\t\tremoveProxyRoutes: [],\n\t\timagesToPull: [],\n\t\trestartRequired: [],\n\t\tmetadata: {\n\t\t\tadded: [],\n\t\t\tremoved: [],\n\t\t\tunchanged: [],\n\t\t\testimatedMemoryDelta: 0,\n\t\t},\n\t\twarnings: [warning],\n\t};\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"addon-stack.cjs","names":["AddonStackInputSchema","getFrameworkById","getServiceById","resolve","buildCompanionService","getDbRequirements","quotedStr","generateSkillFiles","YAML_OPTIONS","AddonStackUpdateInputSchema"],"sources":["../src/addon-stack.ts"],"sourcesContent":["import { randomBytes } from \"node:crypto\";\nimport { parse as parseYaml, stringify } from \"yaml\";\nimport { buildCompanionService, quotedStr, YAML_OPTIONS } from \"./composer.js\";\nimport { getFrameworkById } from \"./frameworks/index.js\";\nimport type { AgentFrameworkDefinition } from \"./frameworks/types.js\";\nimport { getDbRequirements } from \"./generators/postgres-init.js\";\nimport { generateSkillFiles } from \"./generators/skills.js\";\nimport { resolve } from \"./resolver.js\";\nimport { AddonStackInputSchema, AddonStackUpdateInputSchema } from \"./schema.js\";\nimport { getServiceById } from \"./services/registry.js\";\nimport type {\n\tAddonStackInput,\n\tAddonStackResult,\n\tAddonStackUpdateInput,\n\tAddonStackUpdateResult,\n\tComposeOptions,\n\tProxyRoute,\n\tResolvedService,\n\tResolverOutput,\n\tServiceDefinition,\n\tSkippedService,\n} from \"./types.js\";\n\n// ── Constants ────────────────────────────────────────────────────────────────\n\n/** Base infrastructure service IDs that Clawexa's cloud-init provisions. */\nconst BASE_INFRA_SERVICE_IDS = [\n\t\"redis\",\n\t\"postgresql\",\n\t\"open-webui\",\n\t\"caddy\",\n\t\"traefik\",\n\t\"postgres-setup\",\n];\n\n/** Build the full set of infra IDs for a given framework. */\nfunction getInfraServiceIds(framework: AgentFrameworkDefinition): Set<string> {\n\treturn new Set([\n\t\t`${framework.id}-gateway`,\n\t\t`${framework.id}-cli`,\n\t\t...BASE_INFRA_SERVICE_IDS,\n\t\t...framework.getMandatoryServices(),\n\t]);\n}\n\n/** Env keys managed by Clawexa's cloud-init — never include in addon env output. */\nconst CLAWEXA_MANAGED_ENV_KEYS = new Set([\n\t\"COMPOSE_FILE\",\n\t\"COMPOSE_PROFILES\",\n\t\"REDIS_PASSWORD\",\n\t\"REDIS_HOST\",\n\t\"REDIS_PORT\",\n\t\"POSTGRES_USER\",\n\t\"POSTGRES_PASSWORD\",\n\t\"POSTGRES_DB\",\n\t\"POSTGRES_HOST\",\n\t\"POSTGRES_PORT\",\n]);\n\n/** Build the full set of managed env keys for a given framework. */\nfunction getManagedEnvKeys(framework: AgentFrameworkDefinition): Set<string> {\n\tconst keys = new Set(CLAWEXA_MANAGED_ENV_KEYS);\n\tfor (const envLine of framework.getBaseEnvVars({\n\t\tgenerateSecrets: false,\n\t\tframeworkVersion: \"latest\",\n\t\tframeworkImageVariant: \"official\",\n\t})) {\n\t\tkeys.add(envLine.key);\n\t}\n\treturn keys;\n}\n\n// ── Helpers ──────────────────────────────────────────────────────────────────\n\n/** Sanitize instanceId into a valid Docker Compose project name. */\nfunction sanitizeProjectName(instanceId: string): string {\n\treturn (\n\t\tinstanceId\n\t\t\t.toLowerCase()\n\t\t\t.replace(/[^a-z0-9-]/g, \"-\")\n\t\t\t.replace(/^-+|-+$/g, \"\")\n\t\t\t.replace(/-{2,}/g, \"-\")\n\t\t\t.slice(0, 64) || \"addon\"\n\t);\n}\n\n/** Generate a cryptographically secure hex secret of the given byte length. */\nfunction generateHexSecret(bytes: number): string {\n\treturn randomBytes(bytes).toString(\"hex\");\n}\n\n/** Generate a cryptographically secure base64url secret of the given byte length. */\nfunction generateBase64UrlSecret(bytes: number): string {\n\treturn randomBytes(bytes).toString(\"base64url\");\n}\n\n/**\n * Check if a service requires user-provided credentials that are missing.\n * Returns the list of missing credential keys, or empty if all are satisfied.\n *\n * When `generateSecrets` is true, empty-default secrets are auto-generated\n * (passwords, tokens, etc.) and are NOT considered missing. Only secrets\n * with `validation` regex patterns (indicating specific format like API keys)\n * are flagged as missing when not provided by the user.\n */\nfunction getMissingCredentials(\n\tdef: ServiceDefinition,\n\tuserCredentials: Record<string, string> | undefined,\n\tgenerateSecrets: boolean,\n): string[] {\n\tconst missing: string[] = [];\n\tfor (const env of def.environment) {\n\t\t// Skip if not required or not a secret\n\t\tif (!env.required || !env.secret) continue;\n\t\t// Skip if it has a non-empty default value or is a reference\n\t\tif (env.defaultValue && env.defaultValue.length > 0) continue;\n\t\t// Skip if user provided the credential\n\t\tif (userCredentials?.[env.key]) continue;\n\t\t// When generateSecrets is true, empty secrets are auto-generated\n\t\t// Only flag as missing if the env var has a validation pattern\n\t\t// (indicating it needs a specific format like an API key)\n\t\tif (generateSecrets && !env.validation) continue;\n\n\t\tmissing.push(env.key);\n\t}\n\treturn missing;\n}\n\n/**\n * Apply env quirks (from service definition) to the generated env values.\n * Handles: empty_string_crashes → set fixed value, min_length → generate longer secret,\n * must_sync → ensure two keys have the same value.\n */\nfunction applyEnvQuirks(\n\tdef: ServiceDefinition,\n\tenvValues: Map<string, string>,\n\tgenerateSecrets: boolean,\n): void {\n\tif (!def.envQuirks) return;\n\n\tfor (const quirk of def.envQuirks) {\n\t\tswitch (quirk.issue) {\n\t\t\tcase \"empty_string_crashes\": {\n\t\t\t\tif (quirk.fix.type === \"set_value\" && quirk.fix.value !== undefined) {\n\t\t\t\t\tenvValues.set(quirk.key, quirk.fix.value);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"min_length\": {\n\t\t\t\tif (!generateSecrets) break;\n\t\t\t\tconst current = envValues.get(quirk.key) || \"\";\n\t\t\t\tconst minBytes = quirk.fix.minBytes || 24;\n\t\t\t\tconst minHexLen = minBytes * 2;\n\t\t\t\tif (current.length < minHexLen) {\n\t\t\t\t\tif (quirk.fix.type === \"generate_hex\") {\n\t\t\t\t\t\tenvValues.set(quirk.key, generateHexSecret(minBytes));\n\t\t\t\t\t} else if (quirk.fix.type === \"generate_base64url\") {\n\t\t\t\t\t\tenvValues.set(quirk.key, generateBase64UrlSecret(minBytes));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"must_sync\": {\n\t\t\t\tif (quirk.fix.type === \"sync_with\" && quirk.fix.syncKey) {\n\t\t\t\t\tconst sourceValue = envValues.get(quirk.key) || envValues.get(quirk.fix.syncKey);\n\t\t\t\t\tif (sourceValue) {\n\t\t\t\t\t\tenvValues.set(quirk.key, sourceValue);\n\t\t\t\t\t\tenvValues.set(quirk.fix.syncKey, sourceValue);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Build proxy routes from resolved addon services.\n */\nfunction buildProxyRoutes(services: ResolvedService[]): ProxyRoute[] {\n\tconst routes: ProxyRoute[] = [];\n\tfor (const { definition: def } of services) {\n\t\tconst exposedPort = def.ports.find((p) => p.exposed);\n\t\tif (!exposedPort) continue;\n\n\t\troutes.push({\n\t\t\tserviceId: def.id,\n\t\t\tpath: def.proxyPath || `/${def.id}`,\n\t\t\tport: exposedPort.container,\n\t\t\tprotocol: \"http\",\n\t\t\tstripPrefix: true,\n\t\t});\n\t}\n\treturn routes;\n}\n\n/**\n * Build a minimal ComposeOptions suitable for addon stack generation.\n * No proxy, no gateway, no hardening by default.\n */\nfunction buildAddonComposeOptions(projectName: string, input: AddonStackInput): ComposeOptions {\n\treturn {\n\t\tprojectName,\n\t\tproxy: \"none\",\n\t\tgpu: false,\n\t\tplatform: input.platform ?? \"linux/amd64\",\n\t\tdeployment: \"clawexa\",\n\t\topenclawVersion: input.openclawVersion ?? \"latest\",\n\t\topenclawImage: \"official\",\n\t\thardened: false, // Clawexa default: no cap_drop/security_opt\n\t\topenclawInstallMethod: \"docker\",\n\t};\n}\n\n/**\n * Resolve port conflicts between addon services and reserved ports.\n * Returns a map of serviceId → { originalPort → assignedPort }.\n */\nfunction resolvePortConflicts(\n\taddonServices: ResolvedService[],\n\treservedPorts: number[],\n\tportOverrides?: Record<string, Record<string, number>>,\n): { assignments: Record<string, number>; overrides: Record<string, Record<string, number>> } {\n\tconst usedPorts = new Set(reservedPorts);\n\tconst assignments: Record<string, number> = {};\n\tconst overrides: Record<string, Record<string, number>> = {};\n\n\tfor (const { definition: def } of addonServices) {\n\t\tfor (const port of def.ports) {\n\t\t\tif (!port.exposed) continue;\n\n\t\t\t// Check for user-specified override\n\t\t\tconst userOverride = portOverrides?.[def.id]?.[String(port.host)];\n\t\t\tif (userOverride) {\n\t\t\t\tusedPorts.add(userOverride);\n\t\t\t\tassignments[`${def.id}:${port.container}`] = userOverride;\n\t\t\t\toverrides[def.id] ??= {};\n\t\t\t\toverrides[def.id]![String(port.host)] = userOverride;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tlet assignedPort = port.host;\n\t\t\tif (usedPorts.has(assignedPort)) {\n\t\t\t\t// Auto-reassign to port+1000 range\n\t\t\t\tassignedPort = port.host + 1000;\n\t\t\t\twhile (usedPorts.has(assignedPort)) {\n\t\t\t\t\tassignedPort++;\n\t\t\t\t}\n\t\t\t\toverrides[def.id] ??= {};\n\t\t\t\toverrides[def.id]![String(port.host)] = assignedPort;\n\t\t\t}\n\t\t\tusedPorts.add(assignedPort);\n\t\t\tassignments[`${def.id}:${port.container}`] = assignedPort;\n\t\t}\n\t}\n\n\treturn { assignments, overrides };\n}\n\n// ── Main: generateAddonStack ─────────────────────────────────────────────────\n\n/**\n * Generates a Docker Compose override stack containing only addon services\n * for Clawexa managed instances. Infrastructure services (gateway, redis,\n * postgres, open-webui, caddy) are excluded since Clawexa's cloud-init\n * already provisions them.\n *\n * This function never throws. Errors are reported via `warnings` and\n * `metadata.skippedServices`.\n */\nexport function generateAddonStack(rawInput: AddonStackInput): AddonStackResult {\n\tconst warnings: string[] = [];\n\tconst skippedServices: SkippedService[] = [];\n\tconst generatedSecretKeys: string[] = [];\n\n\t// 1. Parse & validate input\n\tlet input: AddonStackInput;\n\ttry {\n\t\tinput = AddonStackInputSchema.parse(rawInput);\n\t} catch (err) {\n\t\treturn emptyResult(`Invalid input: ${err instanceof Error ? err.message : String(err)}`);\n\t}\n\n\tconst projectName = sanitizeProjectName(input.instanceId);\n\n\t// Resolve framework for this addon stack (defaults to openclaw)\n\tconst framework = getFrameworkById(\"openclaw\")!;\n\tconst infraIds = getInfraServiceIds(framework);\n\tconst managedKeys = getManagedEnvKeys(framework);\n\n\t// 2. Filter out infrastructure service IDs from request\n\tconst addonServiceIds = input.services.filter((id) => {\n\t\tif (infraIds.has(id)) {\n\t\t\twarnings.push(`Service \"${id}\" is managed by Clawexa infrastructure and was excluded.`);\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t});\n\n\tif (addonServiceIds.length === 0) {\n\t\treturn emptyResult(\"No addon services requested (all were infrastructure services).\");\n\t}\n\n\t// 3. Validate all service IDs exist in registry\n\tconst validServiceIds: string[] = [];\n\tfor (const id of addonServiceIds) {\n\t\tconst svc = getServiceById(id);\n\t\tif (!svc) {\n\t\t\tskippedServices.push({\n\t\t\t\tserviceId: id,\n\t\t\t\treason: \"unknown_service\",\n\t\t\t\tdetails: `Service \"${id}\" does not exist in the registry.`,\n\t\t\t});\n\t\t} else {\n\t\t\tvalidServiceIds.push(id);\n\t\t}\n\t}\n\n\tif (validServiceIds.length === 0) {\n\t\treturn {\n\t\t\t...emptyResultBase(),\n\t\t\tmetadata: {\n\t\t\t\t...emptyResultBase().metadata,\n\t\t\t\tskippedServices,\n\t\t\t},\n\t\t\twarnings: [...warnings, \"No valid addon services to deploy.\"],\n\t\t};\n\t}\n\n\t// 4. Resolve dependencies\n\tlet resolved: ResolverOutput;\n\ttry {\n\t\tresolved = resolve({\n\t\t\tservices: validServiceIds,\n\t\t\tskillPacks: input.skillPacks,\n\t\t\taiProviders: input.aiProviders,\n\t\t\tplatform: input.platform ?? \"linux/amd64\",\n\t\t});\n\t} catch (err) {\n\t\treturn {\n\t\t\t...emptyResultBase(),\n\t\t\tmetadata: {\n\t\t\t\t...emptyResultBase().metadata,\n\t\t\t\tskippedServices,\n\t\t\t},\n\t\t\twarnings: [\n\t\t\t\t...warnings,\n\t\t\t\t`Dependency resolution failed: ${err instanceof Error ? err.message : String(err)}`,\n\t\t\t],\n\t\t};\n\t}\n\n\t// Forward resolver warnings\n\tfor (const w of resolved.warnings) {\n\t\twarnings.push(w.message);\n\t}\n\n\t// 5. Filter resolved services: keep only addon services (not infra)\n\tconst addonResolved: ResolvedService[] = [];\n\tfor (const svc of resolved.services) {\n\t\tif (infraIds.has(svc.definition.id)) continue;\n\t\taddonResolved.push(svc);\n\t}\n\n\t// 6. Check credentials, images, platform, GPU for each addon service\n\tconst deployableServices: ResolvedService[] = [];\n\tfor (const svc of addonResolved) {\n\t\tconst def = svc.definition;\n\n\t\t// Check for git-based services without prebuilt image\n\t\tif (def.gitSource && def.buildContext && !def.image) {\n\t\t\tconst prebuilt = def.prebuiltImage || input.prebuiltImages[def.id];\n\t\t\tif (!prebuilt) {\n\t\t\t\tskippedServices.push({\n\t\t\t\t\tserviceId: def.id,\n\t\t\t\t\treason: \"no_image\",\n\t\t\t\t\tdetails: `Service \"${def.name}\" requires building from source but no pre-built image is available.`,\n\t\t\t\t});\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\n\t\t// Check GPU requirement — skip if host has no GPU support\n\t\tif (def.gpuRequired && !input.gpu) {\n\t\t\tskippedServices.push({\n\t\t\t\tserviceId: def.id,\n\t\t\t\treason: \"gpu_required\",\n\t\t\t\tdetails: `Service \"${def.name}\" requires a GPU but the host does not have GPU support.`,\n\t\t\t});\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Check user-provided credentials\n\t\tconst userCreds = input.credentials[def.id];\n\t\tconst missing = getMissingCredentials(def, userCreds, input.generateSecrets);\n\t\tif (missing.length > 0) {\n\t\t\tskippedServices.push({\n\t\t\t\tserviceId: def.id,\n\t\t\t\treason: \"missing_credentials\",\n\t\t\t\tdetails: `Service \"${def.name}\" requires credentials: ${missing.join(\", \")}`,\n\t\t\t\trequiredCredentials: missing,\n\t\t\t});\n\t\t\tcontinue;\n\t\t}\n\n\t\tdeployableServices.push(svc);\n\t}\n\n\tif (deployableServices.length === 0) {\n\t\treturn {\n\t\t\t...emptyResultBase(),\n\t\t\tmetadata: {\n\t\t\t\t...emptyResultBase().metadata,\n\t\t\t\tskippedServices,\n\t\t\t},\n\t\t\twarnings: [...warnings, \"No deployable addon services after filtering.\"],\n\t\t};\n\t}\n\n\t// 7. Resolve port conflicts (include ports from existingServices)\n\tconst allReservedPorts = [...input.reservedPorts];\n\tfor (const existingId of input.existingServices) {\n\t\tconst existingDef = getServiceById(existingId);\n\t\tif (existingDef) {\n\t\t\tfor (const port of existingDef.ports) {\n\t\t\t\tif (port.exposed) allReservedPorts.push(port.host);\n\t\t\t}\n\t\t}\n\t}\n\tconst portConflicts = resolvePortConflicts(\n\t\tdeployableServices,\n\t\tallReservedPorts,\n\t\tinput.portOverrides,\n\t);\n\n\t// Build a fake \"full\" resolved output for buildCompanionService\n\t// It needs to see all services to resolve depends_on references\n\tconst addonResolvedOutput: ResolverOutput = {\n\t\tservices: deployableServices,\n\t\taddedDependencies: resolved.addedDependencies,\n\t\tremovedConflicts: resolved.removedConflicts,\n\t\twarnings: resolved.warnings,\n\t\terrors: [],\n\t\tisValid: true,\n\t\testimatedMemoryMB: deployableServices.reduce(\n\t\t\t(sum, s) => sum + (s.definition.minMemoryMB ?? 128),\n\t\t\t0,\n\t\t),\n\t\taiProviders: input.aiProviders ?? [],\n\t\tgsdRuntimes: [],\n\t};\n\n\t// 8. Build compose options (no hardening for Clawexa)\n\tconst composeOptions = buildAddonComposeOptions(projectName, input);\n\tif (Object.keys(portConflicts.overrides).length > 0) {\n\t\tcomposeOptions.portOverrides = portConflicts.overrides;\n\t}\n\n\t// 9. Build per-service entries\n\tconst services: Record<string, Record<string, unknown>> = {};\n\tconst allVolumes = new Set<string>();\n\tconst envValues = new Map<string, string>();\n\n\tfor (const svc of deployableServices) {\n\t\tconst def = svc.definition;\n\t\ttry {\n\t\t\t// Handle prebuilt image substitution for git-based services\n\t\t\tlet effectiveDef = def;\n\t\t\tif (def.gitSource && def.buildContext && !def.image) {\n\t\t\t\tconst prebuiltImage = def.prebuiltImage || input.prebuiltImages[def.id];\n\t\t\t\tif (prebuiltImage) {\n\t\t\t\t\tconst [img, tag] = prebuiltImage.includes(\":\")\n\t\t\t\t\t\t? prebuiltImage.split(\":\")\n\t\t\t\t\t\t: [prebuiltImage, \"latest\"];\n\t\t\t\t\teffectiveDef = {\n\t\t\t\t\t\t...def,\n\t\t\t\t\t\timage: img,\n\t\t\t\t\t\timageTag: tag,\n\t\t\t\t\t\tgitSource: undefined,\n\t\t\t\t\t\tbuildContext: undefined,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst { entry, volumeNames } = buildCompanionService(\n\t\t\t\teffectiveDef,\n\t\t\t\taddonResolvedOutput,\n\t\t\t\tcomposeOptions,\n\t\t\t\tallVolumes,\n\t\t\t);\n\n\t\t\t// Remove profiles from the service entry\n\t\t\tdelete (entry as Record<string, unknown>).profiles;\n\n\t\t\t// Remove depends_on references to infrastructure services\n\t\t\tif (entry.depends_on) {\n\t\t\t\tconst deps = entry.depends_on as Record<string, { condition: string }>;\n\t\t\t\tfor (const depId of Object.keys(deps)) {\n\t\t\t\t\tif (infraIds.has(depId)) {\n\t\t\t\t\t\tdelete deps[depId];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (Object.keys(deps).length === 0) {\n\t\t\t\t\tdelete entry.depends_on;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tservices[def.id] = entry;\n\t\t\tfor (const v of volumeNames) allVolumes.add(v);\n\n\t\t\t// Inject user-provided credentials into env\n\t\t\tconst userCreds = input.credentials[def.id];\n\t\t\tif (userCreds) {\n\t\t\t\tfor (const [key, value] of Object.entries(userCreds)) {\n\t\t\t\t\tenvValues.set(key, value);\n\t\t\t\t}\n\t\t\t\t// Sync referenced keys: if a user provides e.g. DB_POSTGRESDB_PASSWORD\n\t\t\t\t// and the env var's defaultValue is \"${N8N_DB_PASSWORD}\", sync the ref key\n\t\t\t\t// so postgres-setup uses the same password.\n\t\t\t\tfor (const envVar of def.environment) {\n\t\t\t\t\tif (\n\t\t\t\t\t\tuserCreds[envVar.key] &&\n\t\t\t\t\t\tenvVar.defaultValue?.startsWith(\"${\") &&\n\t\t\t\t\t\tenvVar.defaultValue?.endsWith(\"}\")\n\t\t\t\t\t) {\n\t\t\t\t\t\tconst refKey = envVar.defaultValue.slice(2, -1);\n\t\t\t\t\t\tenvValues.set(refKey, userCreds[envVar.key]!);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (err) {\n\t\t\tskippedServices.push({\n\t\t\t\tserviceId: def.id,\n\t\t\t\treason: \"resolution_error\",\n\t\t\t\tdetails: `Failed to build compose entry: ${err instanceof Error ? err.message : String(err)}`,\n\t\t\t});\n\t\t\twarnings.push(\n\t\t\t\t`Failed to process service \"${def.name}\": ${err instanceof Error ? err.message : String(err)}`,\n\t\t\t);\n\t\t}\n\t}\n\n\t// 10. Build postgres-setup if any addon needs a DB\n\t// We need to check if any of our deployable services require DB setup\n\t// and if postgresql is in the infrastructure (it is for Clawexa)\n\tconst dbReqs = getDbRequirements(addonResolvedOutput);\n\tif (dbReqs.length > 0) {\n\t\t// Build a custom postgres-setup that references the existing PostgreSQL\n\t\t// We can't use buildPostgresSetup directly because it checks for postgresql\n\t\t// in the resolved services. Instead, build it manually.\n\t\tconst scriptLines = [\"echo '=== PostgreSQL database setup (addon) ==='\", \"FAILED=0\"];\n\n\t\tfor (const req of dbReqs) {\n\t\t\tscriptLines.push(\n\t\t\t\t`echo \"Setting up database '${req.dbName}' with user '${req.dbUser}'...\"`,\n\t\t\t\t`psql -c \"SELECT 1 FROM pg_roles WHERE rolname='${req.dbUser}'\" | grep -q 1 || psql -c \"CREATE ROLE ${req.dbUser} WITH LOGIN PASSWORD '$$${req.passwordEnvVar}'\"`,\n\t\t\t\t`psql -c \"ALTER ROLE ${req.dbUser} WITH LOGIN PASSWORD '$$${req.passwordEnvVar}'\"`,\n\t\t\t\t`psql -tc \"SELECT 1 FROM pg_database WHERE datname='${req.dbName}'\" | grep -q 1 || psql -c \"CREATE DATABASE ${req.dbName} OWNER ${req.dbUser}\"`,\n\t\t\t\t`psql -c \"GRANT ALL PRIVILEGES ON DATABASE ${req.dbName} TO ${req.dbUser}\" || FAILED=1`,\n\t\t\t\t`echo \" Done: ${req.dbName}\"`,\n\t\t\t);\n\t\t}\n\t\tscriptLines.push(\"echo '=== All databases ready ==='\", \"exit $$FAILED\");\n\n\t\tconst dbEnv: Record<string, string> = {\n\t\t\tPGHOST: \"postgresql\",\n\t\t\tPGUSER: \"${POSTGRES_USER:-openclaw}\",\n\t\t\tPGDATABASE: \"${POSTGRES_DB:-openclaw}\",\n\t\t\tPGPASSWORD: \"${POSTGRES_PASSWORD}\",\n\t\t};\n\t\tfor (const req of dbReqs) {\n\t\t\tdbEnv[req.passwordEnvVar] = `\\${${req.passwordEnvVar}}`;\n\t\t}\n\n\t\tservices[\"postgres-setup\"] = {\n\t\t\timage: \"postgres:17-alpine\",\n\t\t\tdepends_on: {\n\t\t\t\tpostgresql: { condition: \"service_healthy\" },\n\t\t\t},\n\t\t\tenvironment: dbEnv,\n\t\t\tentrypoint: [\"/bin/sh\", \"-c\"],\n\t\t\tcommand: [scriptLines.join(\"\\n\")],\n\t\t\trestart: quotedStr(\"no\"),\n\t\t\tnetworks: [framework.networkName],\n\t\t};\n\n\t\t// Update addon services that need DB to depend on postgres-setup\n\t\tfor (const req of dbReqs) {\n\t\t\tconst svcEntry = services[req.serviceId];\n\t\t\tif (svcEntry) {\n\t\t\t\tconst deps = (svcEntry.depends_on as Record<string, { condition: string }>) || {};\n\t\t\t\tdeps[\"postgres-setup\"] = { condition: \"service_completed_successfully\" };\n\t\t\t\tsvcEntry.depends_on = deps;\n\t\t\t}\n\t\t}\n\t}\n\n\t// 11. Generate secrets and env file\n\tconst envLines: string[] = [\n\t\t\"# ═══════════════════════════════════════════════════════════════════════════════\",\n\t\t\"# OpenClaw Addon Stack Environment\",\n\t\t`# Instance: ${input.instanceId}`,\n\t\t`# Generated at ${new Date().toISOString()}`,\n\t\t\"# ═══════════════════════════════════════════════════════════════════════════════\",\n\t\t\"\",\n\t];\n\n\t// DB passwords first\n\tif (dbReqs.length > 0) {\n\t\tenvLines.push(\"# ── Per-Service Database Passwords ──────────────────────────────────────\");\n\t\tfor (const req of dbReqs) {\n\t\t\tconst secretValue = input.generateSecrets ? generateHexSecret(24) : \"\";\n\t\t\tenvValues.set(req.passwordEnvVar, secretValue);\n\t\t\tif (secretValue) generatedSecretKeys.push(req.passwordEnvVar);\n\t\t\tenvLines.push(\n\t\t\t\t`# PostgreSQL password for ${req.serviceName} (db: ${req.dbName}, user: ${req.dbUser})`,\n\t\t\t);\n\t\t\tenvLines.push(`${req.passwordEnvVar}=${secretValue}`);\n\t\t\tenvLines.push(\"\");\n\t\t}\n\t}\n\n\t// Per-service env vars\n\tconst seenKeys = new Set<string>([...managedKeys, ...dbReqs.map((r) => r.passwordEnvVar)]);\n\tconst envVarGroups: AddonStackResult[\"envVars\"] = [];\n\n\tfor (const svc of deployableServices) {\n\t\tconst def = svc.definition;\n\t\tconst allEnvVars = [...def.environment, ...def.openclawEnvVars];\n\t\tif (allEnvVars.length === 0) continue;\n\n\t\tconst groupVars: AddonStackResult[\"envVars\"][number][\"vars\"] = [];\n\n\t\tenvLines.push(`# ── ${def.icon} ${def.name} ──────────────────────────────────────`);\n\n\t\tfor (const envVar of allEnvVars) {\n\t\t\tif (seenKeys.has(envVar.key)) continue;\n\t\t\tseenKeys.add(envVar.key);\n\n\t\t\t// Check if user provided this credential\n\t\t\tconst userValue = input.credentials[def.id]?.[envVar.key];\n\t\t\tlet actualValue: string;\n\n\t\t\tif (userValue !== undefined) {\n\t\t\t\tactualValue = userValue;\n\t\t\t} else if (envVar.secret) {\n\t\t\t\t// Resolve references like ${N8N_DB_PASSWORD}\n\t\t\t\tif (envVar.defaultValue.startsWith(\"${\") && envVar.defaultValue.endsWith(\"}\")) {\n\t\t\t\t\tconst refKey = envVar.defaultValue.slice(2, -1);\n\t\t\t\t\tactualValue = envValues.get(refKey) || envVar.defaultValue;\n\t\t\t\t} else if (input.generateSecrets) {\n\t\t\t\t\tactualValue = generateHexSecret(24);\n\t\t\t\t\tgeneratedSecretKeys.push(envVar.key);\n\t\t\t\t} else {\n\t\t\t\t\tactualValue = envVar.defaultValue;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tactualValue = envVar.defaultValue;\n\t\t\t}\n\n\t\t\tenvValues.set(envVar.key, actualValue);\n\n\t\t\tenvLines.push(`# ${envVar.description}`);\n\t\t\tenvLines.push(`${envVar.key}=${actualValue}`);\n\t\t\tenvLines.push(\"\");\n\n\t\t\tgroupVars.push({\n\t\t\t\tkey: envVar.key,\n\t\t\t\tdescription: envVar.description,\n\t\t\t\tvalue: actualValue,\n\t\t\t\tsecret: envVar.secret,\n\t\t\t});\n\t\t}\n\n\t\tif (groupVars.length > 0) {\n\t\t\tenvVarGroups.push({\n\t\t\t\tserviceName: def.name,\n\t\t\t\tvars: groupVars,\n\t\t\t});\n\t\t}\n\t}\n\n\t// Apply env quirks after all values are generated\n\tfor (const svc of deployableServices) {\n\t\tapplyEnvQuirks(svc.definition, envValues, input.generateSecrets);\n\t}\n\n\t// Rebuild env lines from envValues (quirks may have modified values or introduced new keys)\n\tconst quirkedKeys = new Set<string>();\n\tconst finalEnvLines: string[] = [];\n\tfor (const line of envLines) {\n\t\tconst trimmed = line.trim();\n\t\tif (!trimmed || trimmed.startsWith(\"#\")) {\n\t\t\tfinalEnvLines.push(line);\n\t\t\tcontinue;\n\t\t}\n\t\tconst eqIdx = trimmed.indexOf(\"=\");\n\t\tif (eqIdx > 0) {\n\t\t\tconst key = trimmed.slice(0, eqIdx);\n\t\t\tquirkedKeys.add(key);\n\t\t\tconst fixedValue = envValues.get(key);\n\t\t\tif (fixedValue !== undefined) {\n\t\t\t\tfinalEnvLines.push(`${key}=${fixedValue}`);\n\t\t\t} else {\n\t\t\t\tfinalEnvLines.push(line);\n\t\t\t}\n\t\t} else {\n\t\t\tfinalEnvLines.push(line);\n\t\t}\n\t}\n\t// Append any new keys introduced by quirks (e.g., must_sync creating a new key)\n\tfor (const [key, value] of envValues) {\n\t\tif (!quirkedKeys.has(key) && !seenKeys.has(key) && !managedKeys.has(key)) {\n\t\t\tfinalEnvLines.push(`# Synced by env quirk`);\n\t\t\tfinalEnvLines.push(`${key}=${value}`);\n\t\t\tfinalEnvLines.push(\"\");\n\t\t}\n\t}\n\tconst envFile = finalEnvLines.join(\"\\n\");\n\n\t// 12. Generate skill files\n\tconst skillFiles = generateSkillFiles(addonResolvedOutput);\n\n\t// 13. Build openclaw config patch\n\tconst skillEntries: Record<string, { enabled: boolean }> = {};\n\tlet skillCount = 0;\n\tfor (const svc of deployableServices) {\n\t\tfor (const skill of svc.definition.skills) {\n\t\t\tif (skill.autoInstall) {\n\t\t\t\tskillEntries[skill.skillId] = { enabled: true };\n\t\t\t\tskillCount++;\n\t\t\t}\n\t\t}\n\t}\n\n\t// 14. Build proxy routes\n\tconst proxyRoutes = buildProxyRoutes(deployableServices);\n\n\t// 14b. Build additional files (e.g. sandbox.toml for opensandbox)\n\tconst additionalFiles: Record<string, string> = {};\n\tif (deployableServices.some((s) => s.definition.id === \"opensandbox\")) {\n\t\tadditionalFiles[\"sandbox.toml\"] = [\n\t\t\t\"[server]\",\n\t\t\t'host = \"0.0.0.0\"',\n\t\t\t\"port = 8080\",\n\t\t\t'log_level = \"INFO\"',\n\t\t\t'api_key = \"${OPEN_SANDBOX_API_KEY}\"',\n\t\t\t\"\",\n\t\t\t\"[runtime]\",\n\t\t\t'type = \"docker\"',\n\t\t\t'execd_image = \"opensandbox/execd:v1.0.6\"',\n\t\t\t\"\",\n\t\t\t\"[docker]\",\n\t\t\t'network_mode = \"bridge\"',\n\t\t\t'drop_capabilities = [\"NET_ADMIN\", \"SYS_ADMIN\", \"SYS_PTRACE\", \"MKNOD\", \"NET_RAW\", \"SYS_RAWIO\"]',\n\t\t\t\"no_new_privileges = true\",\n\t\t\t\"pids_limit = 512\",\n\t\t\t\"\",\n\t\t\t\"[secure_runtime]\",\n\t\t\t'type = \"gvisor\"',\n\t\t\t\"\",\n\t\t].join(\"\\n\");\n\t}\n\n\t// 14c. Build pre-pull images list\n\tconst prePullImages: Array<{ image: string; priority: 1 | 2 | 3 }> = [];\n\tif (deployableServices.some((s) => s.definition.id === \"opensandbox\")) {\n\t\tprePullImages.push(\n\t\t\t// Priority 1: always pulled (core + Homespace)\n\t\t\t{ image: \"opensandbox/server:v1.0.6\", priority: 1 },\n\t\t\t{ image: \"opensandbox/execd:v1.0.6\", priority: 1 },\n\t\t\t{ image: \"opensandbox/desktop:latest\", priority: 1 },\n\t\t\t{ image: \"opensandbox/chrome:latest\", priority: 1 },\n\t\t\t// Priority 2: recommended (common languages)\n\t\t\t{ image: \"opensandbox/code-interpreter:python\", priority: 2 },\n\t\t\t{ image: \"opensandbox/code-interpreter:node\", priority: 2 },\n\t\t\t// Priority 3: optional (full multi-lang and IDE)\n\t\t\t{ image: \"opensandbox/code-interpreter:latest\", priority: 3 },\n\t\t\t{ image: \"opensandbox/vscode:latest\", priority: 3 },\n\t\t);\n\t}\n\n\t// 15. Compose single YAML\n\tconst volumeMap: Record<string, null> = {};\n\tfor (const v of allVolumes) {\n\t\tvolumeMap[v] = null;\n\t}\n\n\tconst composeDoc: Record<string, unknown> = {\n\t\tservices,\n\t};\n\n\tif (Object.keys(volumeMap).length > 0) {\n\t\tcomposeDoc.volumes = volumeMap;\n\t}\n\n\tcomposeDoc.networks = {\n\t\t[framework.networkName]: {\n\t\t\texternal: true,\n\t\t},\n\t};\n\n\tconst composeOverride = stringify(composeDoc, YAML_OPTIONS);\n\n\t// 16. Return result\n\treturn {\n\t\tcomposeOverride,\n\t\tenvFile,\n\t\tenvVars: envVarGroups,\n\t\tskillFiles,\n\t\topenclawConfigPatch: {\n\t\t\tskills: { entries: skillEntries },\n\t\t},\n\t\tproxyRoutes,\n\t\tadditionalFiles,\n\t\tmetadata: {\n\t\t\tserviceCount: Object.keys(services).length,\n\t\t\tskillCount,\n\t\t\testimatedMemoryMB: addonResolvedOutput.estimatedMemoryMB,\n\t\t\tresolvedServices: deployableServices.map((s) => s.definition.id),\n\t\t\tskippedServices,\n\t\t\tgeneratedSecretKeys,\n\t\t\tportAssignments: portConflicts.assignments,\n\t\t\tprePullImages,\n\t\t},\n\t\twarnings,\n\t};\n}\n\n// ── Main: updateAddonStack ───────────────────────────────────────────────────\n\n/**\n * Incrementally updates an existing addon stack by adding or removing services.\n * Preserves existing env values (never overwrites user-customized values).\n *\n * This function never throws.\n */\nexport function updateAddonStack(rawInput: AddonStackUpdateInput): AddonStackUpdateResult {\n\tconst warnings: string[] = [];\n\n\t// 1. Parse & validate\n\tlet input: AddonStackUpdateInput;\n\ttry {\n\t\tinput = AddonStackUpdateInputSchema.parse(rawInput);\n\t} catch (err) {\n\t\treturn emptyUpdateResult(`Invalid input: ${err instanceof Error ? err.message : String(err)}`);\n\t}\n\n\t// 2. Parse existing compose YAML to extract current service list\n\tlet currentServiceIds: string[] = [];\n\ttry {\n\t\tconst existingCompose = parseYaml(input.currentCompose);\n\t\tif (existingCompose?.services && typeof existingCompose.services === \"object\") {\n\t\t\tcurrentServiceIds = Object.keys(existingCompose.services).filter(\n\t\t\t\t(id) => id !== \"postgres-setup\",\n\t\t\t);\n\t\t}\n\t} catch (err) {\n\t\twarnings.push(\n\t\t\t`Failed to parse existing compose YAML: ${err instanceof Error ? err.message : String(err)}`,\n\t\t);\n\t}\n\n\t// 3. Parse existing env into a map\n\tconst existingEnvMap = new Map<string, string>();\n\tfor (const line of input.currentEnv.split(\"\\n\")) {\n\t\tconst trimmed = line.trim();\n\t\tif (!trimmed || trimmed.startsWith(\"#\")) continue;\n\t\tconst eqIdx = trimmed.indexOf(\"=\");\n\t\tif (eqIdx > 0) {\n\t\t\texistingEnvMap.set(trimmed.slice(0, eqIdx), trimmed.slice(eqIdx + 1));\n\t\t}\n\t}\n\n\t// 4. Compute desired service list\n\tconst removeSet = new Set(input.removeServices);\n\tconst desiredServiceIds = [\n\t\t...currentServiceIds.filter((id) => !removeSet.has(id)),\n\t\t...input.addServices.filter((id) => !currentServiceIds.includes(id)),\n\t];\n\n\t// 5. Generate the full target state\n\tconst targetResult = generateAddonStack({\n\t\tinstanceId: input.instanceId,\n\t\tservices: desiredServiceIds,\n\t\tskillPacks: [],\n\t\tplatform: input.platform,\n\t\topenclawVersion: input.openclawVersion,\n\t\texistingServices: input.existingServices,\n\t\treservedPorts: input.reservedPorts,\n\t\tgenerateSecrets: input.generateSecrets,\n\t\tcredentials: input.credentials,\n\t\tportOverrides: input.portOverrides,\n\t\tgpu: input.gpu,\n\t\taiProviders: input.aiProviders,\n\t\tprebuiltImages: input.prebuiltImages,\n\t});\n\n\t// 6. Merge env: preserve existing values, only add new ones\n\tconst mergedEnvLines: string[] = [];\n\tfor (const line of targetResult.envFile.split(\"\\n\")) {\n\t\tconst trimmed = line.trim();\n\t\tif (!trimmed || trimmed.startsWith(\"#\")) {\n\t\t\tmergedEnvLines.push(line);\n\t\t\tcontinue;\n\t\t}\n\t\tconst eqIdx = trimmed.indexOf(\"=\");\n\t\tif (eqIdx > 0) {\n\t\t\tconst key = trimmed.slice(0, eqIdx);\n\t\t\tif (existingEnvMap.has(key)) {\n\t\t\t\t// Preserve existing value\n\t\t\t\tmergedEnvLines.push(`${key}=${existingEnvMap.get(key)}`);\n\t\t\t} else {\n\t\t\t\tmergedEnvLines.push(line);\n\t\t\t}\n\t\t} else {\n\t\t\tmergedEnvLines.push(line);\n\t\t}\n\t}\n\n\t// 7. Compute diffs\n\tconst currentSet = new Set(currentServiceIds);\n\tconst targetSet = new Set(targetResult.metadata.resolvedServices);\n\tconst added = [...targetSet].filter((id) => !currentSet.has(id));\n\tconst removed = [...currentSet].filter((id) => !targetSet.has(id));\n\tconst unchanged = [...currentSet].filter((id) => targetSet.has(id));\n\n\t// 8. Compute skill diffs\n\tconst newSkillFiles: Record<string, string> = {};\n\tconst removedSkillSlugs: string[] = [];\n\n\t// New skills from added services\n\tfor (const id of added) {\n\t\tconst def = getServiceById(id);\n\t\tif (!def) continue;\n\t\tfor (const skill of def.skills) {\n\t\t\tconst skillPath = Object.keys(targetResult.skillFiles).find((path) =>\n\t\t\t\tpath.includes(skill.skillId),\n\t\t\t);\n\t\t\tif (skillPath && targetResult.skillFiles[skillPath]) {\n\t\t\t\tnewSkillFiles[skillPath] = targetResult.skillFiles[skillPath];\n\t\t\t}\n\t\t}\n\t}\n\n\t// Removed skills from removed services\n\tfor (const id of removed) {\n\t\tconst def = getServiceById(id);\n\t\tif (!def) continue;\n\t\tfor (const skill of def.skills) {\n\t\t\tremovedSkillSlugs.push(skill.skillId);\n\t\t}\n\t}\n\n\t// 9. Proxy route diffs\n\tconst addProxyRoutes = targetResult.proxyRoutes.filter((r) => added.includes(r.serviceId));\n\tconst removeProxyRoutes = removed;\n\n\t// 10. Images to pull for new services\n\tconst imagesToPull: string[] = [];\n\tfor (const id of added) {\n\t\tconst def = getServiceById(id);\n\t\tif (def?.image && def?.imageTag) {\n\t\t\timagesToPull.push(`${def.image}:${def.imageTag}`);\n\t\t} else if (def?.prebuiltImage) {\n\t\t\timagesToPull.push(def.prebuiltImage);\n\t\t}\n\t}\n\n\t// 11. Estimate memory delta\n\tlet memoryDelta = 0;\n\tfor (const id of added) {\n\t\tconst def = getServiceById(id);\n\t\tmemoryDelta += def?.minMemoryMB ?? 128;\n\t}\n\tfor (const id of removed) {\n\t\tconst def = getServiceById(id);\n\t\tmemoryDelta -= def?.minMemoryMB ?? 128;\n\t}\n\n\t// Add existing skills to the config patch\n\tconst addSkillEntries: Record<string, { enabled: boolean }> = {};\n\tfor (const id of added) {\n\t\tconst def = getServiceById(id);\n\t\tif (!def) continue;\n\t\tfor (const skill of def.skills) {\n\t\t\tif (skill.autoInstall) {\n\t\t\t\taddSkillEntries[skill.skillId] = { enabled: true };\n\t\t\t}\n\t\t}\n\t}\n\n\treturn {\n\t\tcomposeOverride: targetResult.composeOverride,\n\t\tenvFile: mergedEnvLines.join(\"\\n\"),\n\t\tnewSkillFiles,\n\t\tremovedSkillSlugs,\n\t\topenclawConfigPatch: {\n\t\t\tskills: {\n\t\t\t\tadd: addSkillEntries,\n\t\t\t\tremove: removedSkillSlugs,\n\t\t\t},\n\t\t},\n\t\taddProxyRoutes,\n\t\tremoveProxyRoutes,\n\t\timagesToPull,\n\t\trestartRequired: added, // New services need starting, not restarting\n\t\tmetadata: {\n\t\t\tadded,\n\t\t\tremoved,\n\t\t\tunchanged,\n\t\t\testimatedMemoryDelta: memoryDelta,\n\t\t},\n\t\twarnings: [...warnings, ...targetResult.warnings],\n\t};\n}\n\n// ── Empty Result Helpers ─────────────────────────────────────────────────────\n\nfunction emptyResultBase(): AddonStackResult {\n\treturn {\n\t\tcomposeOverride: \"services: {}\\n\",\n\t\tenvFile: \"\",\n\t\tenvVars: [],\n\t\tskillFiles: {},\n\t\topenclawConfigPatch: { skills: { entries: {} } },\n\t\tproxyRoutes: [],\n\t\tadditionalFiles: {},\n\t\tmetadata: {\n\t\t\tserviceCount: 0,\n\t\t\tskillCount: 0,\n\t\t\testimatedMemoryMB: 0,\n\t\t\tresolvedServices: [],\n\t\t\tskippedServices: [],\n\t\t\tgeneratedSecretKeys: [],\n\t\t\tportAssignments: {},\n\t\t\tprePullImages: [],\n\t\t},\n\t\twarnings: [],\n\t};\n}\n\nfunction emptyResult(warning: string): AddonStackResult {\n\treturn {\n\t\t...emptyResultBase(),\n\t\twarnings: [warning],\n\t};\n}\n\nfunction emptyUpdateResult(warning: string): AddonStackUpdateResult {\n\treturn {\n\t\tcomposeOverride: \"services: {}\\n\",\n\t\tenvFile: \"\",\n\t\tnewSkillFiles: {},\n\t\tremovedSkillSlugs: [],\n\t\topenclawConfigPatch: { skills: { add: {}, remove: [] } },\n\t\taddProxyRoutes: [],\n\t\tremoveProxyRoutes: [],\n\t\timagesToPull: [],\n\t\trestartRequired: [],\n\t\tmetadata: {\n\t\t\tadded: [],\n\t\t\tremoved: [],\n\t\t\tunchanged: [],\n\t\t\testimatedMemoryDelta: 0,\n\t\t},\n\t\twarnings: [warning],\n\t};\n}\n"],"mappings":"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"}
|
package/dist/addon-stack.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { a as AddonStackUpdateResult, i as AddonStackUpdateInput, n as AddonStackInput, r as AddonStackResult } from "./types-Bsn0XzSP.cjs";
|
|
2
2
|
|
|
3
3
|
//#region src/addon-stack.d.ts
|
|
4
4
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"addon-stack.d.cts","names":[],"sources":["../src/addon-stack.ts"],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"addon-stack.d.cts","names":[],"sources":["../src/addon-stack.ts"],"mappings":";;;;;AA8QA;;;;;;;iBAAgB,kBAAA,CAAmB,QAAA,EAAU,eAAA,GAAkB,gBAAA;;AAujB/D;;;;;iBAAgB,gBAAA,CAAiB,QAAA,EAAU,qBAAA,GAAwB,sBAAA"}
|
package/dist/addon-stack.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { a as AddonStackUpdateResult, i as AddonStackUpdateInput, n as AddonStackInput, r as AddonStackResult } from "./types-DwTKyCZ9.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/addon-stack.d.ts
|
|
4
4
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"addon-stack.d.mts","names":[],"sources":["../src/addon-stack.ts"],"mappings":";;;;;;
|
|
1
|
+
{"version":3,"file":"addon-stack.d.mts","names":[],"sources":["../src/addon-stack.ts"],"mappings":";;;;;;AA8QA;;;;;;iBAAgB,kBAAA,CAAmB,QAAA,EAAU,eAAA,GAAkB,gBAAA;;;AAujB/D;;;;iBAAgB,gBAAA,CAAiB,QAAA,EAAU,qBAAA,GAAwB,sBAAA"}
|