@better-openclaw/core 1.0.5 → 1.0.7
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/.github/workflows/publish-core.yml +32 -34
- package/dist/bare-metal-partition.d.mts +26 -0
- package/dist/bare-metal-partition.d.mts.map +1 -0
- package/dist/bare-metal-partition.mjs +48 -0
- package/dist/bare-metal-partition.mjs.map +1 -0
- package/dist/bare-metal-partition.test.d.mts +1 -0
- package/dist/bare-metal-partition.test.mjs +58 -0
- package/dist/bare-metal-partition.test.mjs.map +1 -0
- package/dist/composer.d.mts +21 -0
- package/dist/composer.d.mts.map +1 -0
- package/dist/composer.mjs +287 -0
- package/dist/composer.mjs.map +1 -0
- package/dist/composer.snapshot.test.d.mts +1 -0
- package/dist/composer.snapshot.test.mjs +92 -0
- package/dist/composer.snapshot.test.mjs.map +1 -0
- package/dist/composer.test.d.mts +1 -0
- package/dist/composer.test.mjs +166 -0
- package/dist/composer.test.mjs.map +1 -0
- package/dist/generate.d.mts +11 -0
- package/dist/generate.d.mts.map +1 -0
- package/dist/generate.mjs +169 -0
- package/dist/generate.mjs.map +1 -0
- package/dist/generate.test.d.mts +1 -0
- package/dist/generate.test.mjs +283 -0
- package/dist/generate.test.mjs.map +1 -0
- package/dist/generators/bare-metal-install.d.mts +17 -0
- package/dist/generators/bare-metal-install.d.mts.map +1 -0
- package/dist/generators/bare-metal-install.mjs +224 -0
- package/dist/generators/bare-metal-install.mjs.map +1 -0
- package/dist/generators/bare-metal-install.test.d.mts +1 -0
- package/dist/generators/bare-metal-install.test.mjs +48 -0
- package/dist/generators/bare-metal-install.test.mjs.map +1 -0
- package/dist/generators/caddy.d.mts +17 -0
- package/dist/generators/caddy.d.mts.map +1 -0
- package/dist/generators/caddy.mjs +77 -0
- package/dist/generators/caddy.mjs.map +1 -0
- package/dist/generators/env.d.mts +46 -0
- package/dist/generators/env.d.mts.map +1 -0
- package/dist/generators/env.mjs +250 -0
- package/dist/generators/env.mjs.map +1 -0
- package/dist/generators/grafana.d.mts +22 -0
- package/dist/generators/grafana.d.mts.map +1 -0
- package/dist/generators/grafana.mjs +293 -0
- package/dist/generators/grafana.mjs.map +1 -0
- package/dist/generators/n8n-workflows.d.mts +11 -0
- package/dist/generators/n8n-workflows.d.mts.map +1 -0
- package/dist/generators/n8n-workflows.mjs +75 -0
- package/dist/generators/n8n-workflows.mjs.map +1 -0
- package/dist/generators/native-services.d.mts +17 -0
- package/dist/generators/native-services.d.mts.map +1 -0
- package/dist/generators/native-services.mjs +78 -0
- package/dist/generators/native-services.mjs.map +1 -0
- package/dist/generators/postgres-init.d.mts +30 -0
- package/dist/generators/postgres-init.d.mts.map +1 -0
- package/dist/generators/postgres-init.mjs +151 -0
- package/dist/generators/postgres-init.mjs.map +1 -0
- package/dist/generators/prometheus.d.mts +14 -0
- package/dist/generators/prometheus.d.mts.map +1 -0
- package/dist/generators/prometheus.mjs +107 -0
- package/dist/generators/prometheus.mjs.map +1 -0
- package/dist/generators/readme.d.mts +25 -0
- package/dist/generators/readme.d.mts.map +1 -0
- package/dist/generators/readme.mjs +199 -0
- package/dist/generators/readme.mjs.map +1 -0
- package/dist/generators/scripts.d.mts +10 -0
- package/dist/generators/scripts.d.mts.map +1 -0
- package/dist/generators/scripts.mjs +351 -0
- package/dist/generators/scripts.mjs.map +1 -0
- package/dist/generators/skills.d.mts +14 -0
- package/dist/generators/skills.d.mts.map +1 -0
- package/dist/generators/skills.mjs +587 -0
- package/dist/generators/skills.mjs.map +1 -0
- package/dist/index.d.mts +21 -0
- package/dist/index.mjs +22 -0
- package/dist/magic-string.es-1uTtupLe.mjs +1014 -0
- package/dist/magic-string.es-1uTtupLe.mjs.map +1 -0
- package/dist/presets/registry.d.mts +9 -0
- package/dist/presets/registry.d.mts.map +1 -0
- package/dist/presets/registry.mjs +159 -0
- package/dist/presets/registry.mjs.map +1 -0
- package/dist/presets/registry.test.d.mts +1 -0
- package/dist/presets/registry.test.mjs +34 -0
- package/dist/presets/registry.test.mjs.map +1 -0
- package/dist/resolver.d.mts +21 -0
- package/dist/resolver.d.mts.map +1 -0
- package/dist/resolver.mjs +194 -0
- package/dist/resolver.mjs.map +1 -0
- package/dist/resolver.test.d.mts +1 -0
- package/dist/resolver.test.mjs +237 -0
- package/dist/resolver.test.mjs.map +1 -0
- package/dist/schema.d.mts +706 -0
- package/dist/schema.d.mts.map +1 -0
- package/dist/schema.mjs +260 -0
- package/dist/schema.mjs.map +1 -0
- package/dist/schema.test.d.mts +1 -0
- package/dist/schema.test.mjs +264 -0
- package/dist/schema.test.mjs.map +1 -0
- package/dist/services/definitions/anything-llm.d.mts +7 -0
- package/dist/services/definitions/anything-llm.d.mts.map +1 -0
- package/dist/services/definitions/anything-llm.mjs +44 -0
- package/dist/services/definitions/anything-llm.mjs.map +1 -0
- package/dist/services/definitions/appflowy.d.mts +7 -0
- package/dist/services/definitions/appflowy.d.mts.map +1 -0
- package/dist/services/definitions/appflowy.mjs +45 -0
- package/dist/services/definitions/appflowy.mjs.map +1 -0
- package/dist/services/definitions/beszel.d.mts +7 -0
- package/dist/services/definitions/beszel.d.mts.map +1 -0
- package/dist/services/definitions/beszel.mjs +45 -0
- package/dist/services/definitions/beszel.mjs.map +1 -0
- package/dist/services/definitions/browserless.d.mts +7 -0
- package/dist/services/definitions/browserless.d.mts.map +1 -0
- package/dist/services/definitions/browserless.mjs +85 -0
- package/dist/services/definitions/browserless.mjs.map +1 -0
- package/dist/services/definitions/caddy.d.mts +7 -0
- package/dist/services/definitions/caddy.d.mts.map +1 -0
- package/dist/services/definitions/caddy.mjs +52 -0
- package/dist/services/definitions/caddy.mjs.map +1 -0
- package/dist/services/definitions/chromadb.d.mts +7 -0
- package/dist/services/definitions/chromadb.d.mts.map +1 -0
- package/dist/services/definitions/chromadb.mjs +63 -0
- package/dist/services/definitions/chromadb.mjs.map +1 -0
- package/dist/services/definitions/claude-code.d.mts +7 -0
- package/dist/services/definitions/claude-code.d.mts.map +1 -0
- package/dist/services/definitions/claude-code.mjs +52 -0
- package/dist/services/definitions/claude-code.mjs.map +1 -0
- package/dist/services/definitions/code-server.d.mts +7 -0
- package/dist/services/definitions/code-server.d.mts.map +1 -0
- package/dist/services/definitions/code-server.mjs +66 -0
- package/dist/services/definitions/code-server.mjs.map +1 -0
- package/dist/services/definitions/codex.d.mts +7 -0
- package/dist/services/definitions/codex.d.mts.map +1 -0
- package/dist/services/definitions/codex.mjs +45 -0
- package/dist/services/definitions/codex.mjs.map +1 -0
- package/dist/services/definitions/convex-dashboard.d.mts +7 -0
- package/dist/services/definitions/convex-dashboard.d.mts.map +1 -0
- package/dist/services/definitions/convex-dashboard.mjs +46 -0
- package/dist/services/definitions/convex-dashboard.mjs.map +1 -0
- package/dist/services/definitions/convex.d.mts +7 -0
- package/dist/services/definitions/convex.d.mts.map +1 -0
- package/dist/services/definitions/convex.mjs +118 -0
- package/dist/services/definitions/convex.mjs.map +1 -0
- package/dist/services/definitions/coolify.d.mts +7 -0
- package/dist/services/definitions/coolify.d.mts.map +1 -0
- package/dist/services/definitions/coolify.mjs +49 -0
- package/dist/services/definitions/coolify.mjs.map +1 -0
- package/dist/services/definitions/dify.d.mts +7 -0
- package/dist/services/definitions/dify.d.mts.map +1 -0
- package/dist/services/definitions/dify.mjs +81 -0
- package/dist/services/definitions/dify.mjs.map +1 -0
- package/dist/services/definitions/docsgpt.d.mts +7 -0
- package/dist/services/definitions/docsgpt.d.mts.map +1 -0
- package/dist/services/definitions/docsgpt.mjs +45 -0
- package/dist/services/definitions/docsgpt.mjs.map +1 -0
- package/dist/services/definitions/dokploy.d.mts +7 -0
- package/dist/services/definitions/dokploy.d.mts.map +1 -0
- package/dist/services/definitions/dokploy.mjs +49 -0
- package/dist/services/definitions/dokploy.mjs.map +1 -0
- package/dist/services/definitions/dozzle.d.mts +7 -0
- package/dist/services/definitions/dozzle.d.mts.map +1 -0
- package/dist/services/definitions/dozzle.mjs +41 -0
- package/dist/services/definitions/dozzle.mjs.map +1 -0
- package/dist/services/definitions/ffmpeg.d.mts +7 -0
- package/dist/services/definitions/ffmpeg.d.mts.map +1 -0
- package/dist/services/definitions/ffmpeg.mjs +66 -0
- package/dist/services/definitions/ffmpeg.mjs.map +1 -0
- package/dist/services/definitions/flowise.d.mts +7 -0
- package/dist/services/definitions/flowise.d.mts.map +1 -0
- package/dist/services/definitions/flowise.mjs +45 -0
- package/dist/services/definitions/flowise.mjs.map +1 -0
- package/dist/services/definitions/gemini-cli.d.mts +7 -0
- package/dist/services/definitions/gemini-cli.d.mts.map +1 -0
- package/dist/services/definitions/gemini-cli.mjs +46 -0
- package/dist/services/definitions/gemini-cli.mjs.map +1 -0
- package/dist/services/definitions/gitea.d.mts +7 -0
- package/dist/services/definitions/gitea.d.mts.map +1 -0
- package/dist/services/definitions/gitea.mjs +49 -0
- package/dist/services/definitions/gitea.mjs.map +1 -0
- package/dist/services/definitions/gotify.d.mts +7 -0
- package/dist/services/definitions/gotify.d.mts.map +1 -0
- package/dist/services/definitions/gotify.mjs +62 -0
- package/dist/services/definitions/gotify.mjs.map +1 -0
- package/dist/services/definitions/grafana.d.mts +7 -0
- package/dist/services/definitions/grafana.d.mts.map +1 -0
- package/dist/services/definitions/grafana.mjs +63 -0
- package/dist/services/definitions/grafana.mjs.map +1 -0
- package/dist/services/definitions/index.d.mts +76 -0
- package/dist/services/definitions/index.d.mts.map +1 -0
- package/dist/services/definitions/index.mjs +146 -0
- package/dist/services/definitions/index.mjs.map +1 -0
- package/dist/services/definitions/kimi.d.mts +7 -0
- package/dist/services/definitions/kimi.d.mts.map +1 -0
- package/dist/services/definitions/kimi.mjs +46 -0
- package/dist/services/definitions/kimi.mjs.map +1 -0
- package/dist/services/definitions/lasuite-meet-agents.d.mts +7 -0
- package/dist/services/definitions/lasuite-meet-agents.d.mts.map +1 -0
- package/dist/services/definitions/lasuite-meet-agents.mjs +36 -0
- package/dist/services/definitions/lasuite-meet-agents.mjs.map +1 -0
- package/dist/services/definitions/lasuite-meet-backend.d.mts +7 -0
- package/dist/services/definitions/lasuite-meet-backend.d.mts.map +1 -0
- package/dist/services/definitions/lasuite-meet-backend.mjs +134 -0
- package/dist/services/definitions/lasuite-meet-backend.mjs.map +1 -0
- package/dist/services/definitions/lasuite-meet-frontend.d.mts +7 -0
- package/dist/services/definitions/lasuite-meet-frontend.d.mts.map +1 -0
- package/dist/services/definitions/lasuite-meet-frontend.mjs +48 -0
- package/dist/services/definitions/lasuite-meet-frontend.mjs.map +1 -0
- package/dist/services/definitions/librechat.d.mts +7 -0
- package/dist/services/definitions/librechat.d.mts.map +1 -0
- package/dist/services/definitions/librechat.mjs +50 -0
- package/dist/services/definitions/librechat.mjs.map +1 -0
- package/dist/services/definitions/lightpanda.d.mts +7 -0
- package/dist/services/definitions/lightpanda.d.mts.map +1 -0
- package/dist/services/definitions/lightpanda.mjs +59 -0
- package/dist/services/definitions/lightpanda.mjs.map +1 -0
- package/dist/services/definitions/litellm.d.mts +7 -0
- package/dist/services/definitions/litellm.d.mts.map +1 -0
- package/dist/services/definitions/litellm.mjs +47 -0
- package/dist/services/definitions/litellm.mjs.map +1 -0
- package/dist/services/definitions/livekit.d.mts +7 -0
- package/dist/services/definitions/livekit.d.mts.map +1 -0
- package/dist/services/definitions/livekit.mjs +56 -0
- package/dist/services/definitions/livekit.mjs.map +1 -0
- package/dist/services/definitions/matomo.d.mts +7 -0
- package/dist/services/definitions/matomo.d.mts.map +1 -0
- package/dist/services/definitions/matomo.mjs +80 -0
- package/dist/services/definitions/matomo.mjs.map +1 -0
- package/dist/services/definitions/matrix-synapse.d.mts +7 -0
- package/dist/services/definitions/matrix-synapse.d.mts.map +1 -0
- package/dist/services/definitions/matrix-synapse.mjs +88 -0
- package/dist/services/definitions/matrix-synapse.mjs.map +1 -0
- package/dist/services/definitions/mattermost.d.mts +7 -0
- package/dist/services/definitions/mattermost.d.mts.map +1 -0
- package/dist/services/definitions/mattermost.mjs +61 -0
- package/dist/services/definitions/mattermost.mjs.map +1 -0
- package/dist/services/definitions/meilisearch.d.mts +7 -0
- package/dist/services/definitions/meilisearch.d.mts.map +1 -0
- package/dist/services/definitions/meilisearch.mjs +78 -0
- package/dist/services/definitions/meilisearch.mjs.map +1 -0
- package/dist/services/definitions/minio.d.mts +7 -0
- package/dist/services/definitions/minio.d.mts.map +1 -0
- package/dist/services/definitions/minio.mjs +102 -0
- package/dist/services/definitions/minio.mjs.map +1 -0
- package/dist/services/definitions/mission-control.d.mts +7 -0
- package/dist/services/definitions/mission-control.d.mts.map +1 -0
- package/dist/services/definitions/mission-control.mjs +67 -0
- package/dist/services/definitions/mission-control.mjs.map +1 -0
- package/dist/services/definitions/mixpost.d.mts +7 -0
- package/dist/services/definitions/mixpost.d.mts.map +1 -0
- package/dist/services/definitions/mixpost.mjs +87 -0
- package/dist/services/definitions/mixpost.mjs.map +1 -0
- package/dist/services/definitions/motion-canvas.d.mts +7 -0
- package/dist/services/definitions/motion-canvas.d.mts.map +1 -0
- package/dist/services/definitions/motion-canvas.mjs +52 -0
- package/dist/services/definitions/motion-canvas.mjs.map +1 -0
- package/dist/services/definitions/n8n.d.mts +7 -0
- package/dist/services/definitions/n8n.d.mts.map +1 -0
- package/dist/services/definitions/n8n.mjs +154 -0
- package/dist/services/definitions/n8n.mjs.map +1 -0
- package/dist/services/definitions/nocodb.d.mts +7 -0
- package/dist/services/definitions/nocodb.d.mts.map +1 -0
- package/dist/services/definitions/nocodb.mjs +45 -0
- package/dist/services/definitions/nocodb.mjs.map +1 -0
- package/dist/services/definitions/ntfy.d.mts +7 -0
- package/dist/services/definitions/ntfy.d.mts.map +1 -0
- package/dist/services/definitions/ntfy.mjs +63 -0
- package/dist/services/definitions/ntfy.mjs.map +1 -0
- package/dist/services/definitions/ollama.d.mts +7 -0
- package/dist/services/definitions/ollama.d.mts.map +1 -0
- package/dist/services/definitions/ollama.mjs +66 -0
- package/dist/services/definitions/ollama.mjs.map +1 -0
- package/dist/services/definitions/open-webui.d.mts +7 -0
- package/dist/services/definitions/open-webui.d.mts.map +1 -0
- package/dist/services/definitions/open-webui.mjs +50 -0
- package/dist/services/definitions/open-webui.mjs.map +1 -0
- package/dist/services/definitions/opencode.d.mts +7 -0
- package/dist/services/definitions/opencode.d.mts.map +1 -0
- package/dist/services/definitions/opencode.mjs +50 -0
- package/dist/services/definitions/opencode.mjs.map +1 -0
- package/dist/services/definitions/openpanel.d.mts +7 -0
- package/dist/services/definitions/openpanel.d.mts.map +1 -0
- package/dist/services/definitions/openpanel.mjs +46 -0
- package/dist/services/definitions/openpanel.mjs.map +1 -0
- package/dist/services/definitions/outline.d.mts +7 -0
- package/dist/services/definitions/outline.d.mts.map +1 -0
- package/dist/services/definitions/outline.mjs +74 -0
- package/dist/services/definitions/outline.mjs.map +1 -0
- package/dist/services/definitions/paperless-ngx.d.mts +7 -0
- package/dist/services/definitions/paperless-ngx.d.mts.map +1 -0
- package/dist/services/definitions/paperless-ngx.mjs +93 -0
- package/dist/services/definitions/paperless-ngx.mjs.map +1 -0
- package/dist/services/definitions/playwright-server.d.mts +7 -0
- package/dist/services/definitions/playwright-server.d.mts.map +1 -0
- package/dist/services/definitions/playwright-server.mjs +42 -0
- package/dist/services/definitions/playwright-server.mjs.map +1 -0
- package/dist/services/definitions/portainer.d.mts +7 -0
- package/dist/services/definitions/portainer.d.mts.map +1 -0
- package/dist/services/definitions/portainer.mjs +49 -0
- package/dist/services/definitions/portainer.mjs.map +1 -0
- package/dist/services/definitions/postgresql.d.mts +7 -0
- package/dist/services/definitions/postgresql.d.mts.map +1 -0
- package/dist/services/definitions/postgresql.mjs +84 -0
- package/dist/services/definitions/postgresql.mjs.map +1 -0
- package/dist/services/definitions/postiz.d.mts +7 -0
- package/dist/services/definitions/postiz.d.mts.map +1 -0
- package/dist/services/definitions/postiz.mjs +83 -0
- package/dist/services/definitions/postiz.mjs.map +1 -0
- package/dist/services/definitions/prometheus.d.mts +7 -0
- package/dist/services/definitions/prometheus.d.mts.map +1 -0
- package/dist/services/definitions/prometheus.mjs +52 -0
- package/dist/services/definitions/prometheus.mjs.map +1 -0
- package/dist/services/definitions/qdrant.d.mts +7 -0
- package/dist/services/definitions/qdrant.d.mts.map +1 -0
- package/dist/services/definitions/qdrant.mjs +77 -0
- package/dist/services/definitions/qdrant.mjs.map +1 -0
- package/dist/services/definitions/redis.d.mts +7 -0
- package/dist/services/definitions/redis.d.mts.map +1 -0
- package/dist/services/definitions/redis.mjs +91 -0
- package/dist/services/definitions/redis.mjs.map +1 -0
- package/dist/services/definitions/remotion.d.mts +7 -0
- package/dist/services/definitions/remotion.d.mts.map +1 -0
- package/dist/services/definitions/remotion.mjs +55 -0
- package/dist/services/definitions/remotion.mjs.map +1 -0
- package/dist/services/definitions/rocketchat.d.mts +7 -0
- package/dist/services/definitions/rocketchat.d.mts.map +1 -0
- package/dist/services/definitions/rocketchat.mjs +57 -0
- package/dist/services/definitions/rocketchat.mjs.map +1 -0
- package/dist/services/definitions/searxng.d.mts +7 -0
- package/dist/services/definitions/searxng.d.mts.map +1 -0
- package/dist/services/definitions/searxng.mjs +65 -0
- package/dist/services/definitions/searxng.mjs.map +1 -0
- package/dist/services/definitions/stable-diffusion.d.mts +7 -0
- package/dist/services/definitions/stable-diffusion.d.mts.map +1 -0
- package/dist/services/definitions/stable-diffusion.mjs +48 -0
- package/dist/services/definitions/stable-diffusion.mjs.map +1 -0
- package/dist/services/definitions/steel-browser.d.mts +7 -0
- package/dist/services/definitions/steel-browser.d.mts.map +1 -0
- package/dist/services/definitions/steel-browser.mjs +77 -0
- package/dist/services/definitions/steel-browser.mjs.map +1 -0
- package/dist/services/definitions/tailscale.d.mts +7 -0
- package/dist/services/definitions/tailscale.d.mts.map +1 -0
- package/dist/services/definitions/tailscale.mjs +70 -0
- package/dist/services/definitions/tailscale.mjs.map +1 -0
- package/dist/services/definitions/temporal.d.mts +7 -0
- package/dist/services/definitions/temporal.d.mts.map +1 -0
- package/dist/services/definitions/temporal.mjs +100 -0
- package/dist/services/definitions/temporal.mjs.map +1 -0
- package/dist/services/definitions/traefik.d.mts +7 -0
- package/dist/services/definitions/traefik.d.mts.map +1 -0
- package/dist/services/definitions/traefik.mjs +58 -0
- package/dist/services/definitions/traefik.mjs.map +1 -0
- package/dist/services/definitions/umami.d.mts +7 -0
- package/dist/services/definitions/umami.d.mts.map +1 -0
- package/dist/services/definitions/umami.mjs +46 -0
- package/dist/services/definitions/umami.mjs.map +1 -0
- package/dist/services/definitions/uptime-kuma.d.mts +7 -0
- package/dist/services/definitions/uptime-kuma.d.mts.map +1 -0
- package/dist/services/definitions/uptime-kuma.mjs +51 -0
- package/dist/services/definitions/uptime-kuma.mjs.map +1 -0
- package/dist/services/definitions/usesend.d.mts +7 -0
- package/dist/services/definitions/usesend.d.mts.map +1 -0
- package/dist/services/definitions/usesend.mjs +99 -0
- package/dist/services/definitions/usesend.mjs.map +1 -0
- package/dist/services/definitions/valkey.d.mts +7 -0
- package/dist/services/definitions/valkey.d.mts.map +1 -0
- package/dist/services/definitions/valkey.mjs +61 -0
- package/dist/services/definitions/valkey.mjs.map +1 -0
- package/dist/services/definitions/watchtower.d.mts +7 -0
- package/dist/services/definitions/watchtower.d.mts.map +1 -0
- package/dist/services/definitions/watchtower.mjs +47 -0
- package/dist/services/definitions/watchtower.mjs.map +1 -0
- package/dist/services/definitions/weaviate.d.mts +7 -0
- package/dist/services/definitions/weaviate.d.mts.map +1 -0
- package/dist/services/definitions/weaviate.mjs +90 -0
- package/dist/services/definitions/weaviate.mjs.map +1 -0
- package/dist/services/definitions/whisper.d.mts +7 -0
- package/dist/services/definitions/whisper.d.mts.map +1 -0
- package/dist/services/definitions/whisper.mjs +62 -0
- package/dist/services/definitions/whisper.mjs.map +1 -0
- package/dist/services/registry.d.mts +16 -0
- package/dist/services/registry.d.mts.map +1 -0
- package/dist/services/registry.mjs +30 -0
- package/dist/services/registry.mjs.map +1 -0
- package/dist/services/registry.test.d.mts +1 -0
- package/dist/services/registry.test.mjs +64 -0
- package/dist/services/registry.test.mjs.map +1 -0
- package/dist/skills/registry.d.mts +11 -0
- package/dist/skills/registry.d.mts.map +1 -0
- package/dist/skills/registry.mjs +215 -0
- package/dist/skills/registry.mjs.map +1 -0
- package/dist/types.d.mts +64 -0
- package/dist/types.d.mts.map +1 -0
- package/dist/types.mjs +92 -0
- package/dist/types.mjs.map +1 -0
- package/dist/validator.d.mts +20 -0
- package/dist/validator.d.mts.map +1 -0
- package/dist/validator.mjs +111 -0
- package/dist/validator.mjs.map +1 -0
- package/dist/validator.test.d.mts +1 -0
- package/dist/validator.test.mjs +65 -0
- package/dist/validator.test.mjs.map +1 -0
- package/dist/version-manager.d.mts +14 -0
- package/dist/version-manager.d.mts.map +1 -0
- package/dist/version-manager.mjs +55 -0
- package/dist/version-manager.mjs.map +1 -0
- package/dist/vi.2VT5v0um-Qk6MgAnK.mjs +12916 -0
- package/dist/vi.2VT5v0um-Qk6MgAnK.mjs.map +1 -0
- package/package.json +17 -17
- package/src/schema.ts +2 -1
- package/src/services/definitions/convex-dashboard.ts +48 -0
- package/src/services/definitions/convex.ts +123 -0
- package/src/services/definitions/index.ts +12 -0
- package/src/services/definitions/mission-control.ts +71 -0
- package/src/services/definitions/tailscale.ts +2 -0
- package/src/services/definitions/usesend.ts +98 -0
- package/tsdown.config.ts +1 -0
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { n as describe, r as it, t as globalExpect } from "./vi.2VT5v0um-Qk6MgAnK.mjs";
|
|
2
|
+
import { resolve } from "./resolver.mjs";
|
|
3
|
+
import { composeMultiFile } from "./composer.mjs";
|
|
4
|
+
|
|
5
|
+
//#region src/composer.snapshot.test.ts
|
|
6
|
+
function generateForPreset(services, skillPacks = []) {
|
|
7
|
+
return composeMultiFile(resolve({
|
|
8
|
+
services,
|
|
9
|
+
skillPacks
|
|
10
|
+
}), {
|
|
11
|
+
projectName: "test-stack",
|
|
12
|
+
proxy: "none",
|
|
13
|
+
gpu: false,
|
|
14
|
+
platform: "linux/amd64",
|
|
15
|
+
deployment: "local",
|
|
16
|
+
openclawVersion: "latest"
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
describe("compose snapshot tests", () => {
|
|
20
|
+
it("minimal preset (redis only)", () => {
|
|
21
|
+
globalExpect(generateForPreset(["redis"]).files["docker-compose.yml"]).toMatchSnapshot();
|
|
22
|
+
});
|
|
23
|
+
it("creator preset (ffmpeg + remotion + minio + redis)", () => {
|
|
24
|
+
const result = generateForPreset([
|
|
25
|
+
"ffmpeg",
|
|
26
|
+
"remotion",
|
|
27
|
+
"minio",
|
|
28
|
+
"redis"
|
|
29
|
+
], ["video-creator"]);
|
|
30
|
+
globalExpect(result.files["docker-compose.yml"]).toMatchSnapshot();
|
|
31
|
+
if (result.files["docker-compose.media.yml"]) globalExpect(result.files["docker-compose.media.yml"]).toMatchSnapshot();
|
|
32
|
+
});
|
|
33
|
+
it("researcher preset (qdrant + searxng + browserless + redis)", () => {
|
|
34
|
+
globalExpect(generateForPreset([
|
|
35
|
+
"qdrant",
|
|
36
|
+
"searxng",
|
|
37
|
+
"browserless",
|
|
38
|
+
"redis"
|
|
39
|
+
], ["research-agent"]).files["docker-compose.yml"]).toMatchSnapshot();
|
|
40
|
+
});
|
|
41
|
+
it("devops preset (n8n + postgresql + redis + monitoring)", () => {
|
|
42
|
+
const result = generateForPreset([
|
|
43
|
+
"n8n",
|
|
44
|
+
"postgresql",
|
|
45
|
+
"redis",
|
|
46
|
+
"uptime-kuma",
|
|
47
|
+
"grafana",
|
|
48
|
+
"prometheus"
|
|
49
|
+
], ["dev-ops"]);
|
|
50
|
+
globalExpect(result.files["docker-compose.yml"]).toMatchSnapshot();
|
|
51
|
+
if (result.files["docker-compose.monitoring.yml"]) globalExpect(result.files["docker-compose.monitoring.yml"]).toMatchSnapshot();
|
|
52
|
+
});
|
|
53
|
+
it("full preset (many services)", () => {
|
|
54
|
+
const result = generateForPreset([
|
|
55
|
+
"redis",
|
|
56
|
+
"postgresql",
|
|
57
|
+
"qdrant",
|
|
58
|
+
"n8n",
|
|
59
|
+
"ffmpeg",
|
|
60
|
+
"remotion",
|
|
61
|
+
"minio",
|
|
62
|
+
"caddy",
|
|
63
|
+
"browserless",
|
|
64
|
+
"searxng",
|
|
65
|
+
"meilisearch",
|
|
66
|
+
"uptime-kuma",
|
|
67
|
+
"grafana",
|
|
68
|
+
"prometheus",
|
|
69
|
+
"ollama",
|
|
70
|
+
"whisper",
|
|
71
|
+
"gotify"
|
|
72
|
+
]);
|
|
73
|
+
globalExpect(result.files["docker-compose.yml"]).toMatchSnapshot();
|
|
74
|
+
globalExpect(result.profiles.length).toBeGreaterThan(0);
|
|
75
|
+
globalExpect(Object.keys(result.files).length).toBeGreaterThan(1);
|
|
76
|
+
});
|
|
77
|
+
it("multi-file output has correct profile assignments", () => {
|
|
78
|
+
const result = generateForPreset([
|
|
79
|
+
"redis",
|
|
80
|
+
"ollama",
|
|
81
|
+
"open-webui",
|
|
82
|
+
"grafana",
|
|
83
|
+
"prometheus"
|
|
84
|
+
]);
|
|
85
|
+
if (result.files["docker-compose.ai.yml"]) globalExpect(result.files["docker-compose.ai.yml"]).toContain("profiles:");
|
|
86
|
+
if (result.files["docker-compose.monitoring.yml"]) globalExpect(result.files["docker-compose.monitoring.yml"]).toContain("profiles:");
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
//#endregion
|
|
91
|
+
export { };
|
|
92
|
+
//# sourceMappingURL=composer.snapshot.test.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"composer.snapshot.test.mjs","names":[],"sources":["../src/composer.snapshot.test.ts"],"sourcesContent":["import { describe, expect, it } from \"vitest\";\nimport { composeMultiFile } from \"./composer.js\";\nimport { resolve } from \"./resolver.js\";\n\nfunction generateForPreset(services: string[], skillPacks: string[] = []) {\n\tconst resolved = resolve({ services, skillPacks });\n\treturn composeMultiFile(resolved, {\n\t\tprojectName: \"test-stack\",\n\t\tproxy: \"none\",\n\t\tgpu: false,\n\t\tplatform: \"linux/amd64\",\n\t\tdeployment: \"local\",\n\t\topenclawVersion: \"latest\",\n\t});\n}\n\ndescribe(\"compose snapshot tests\", () => {\n\tit(\"minimal preset (redis only)\", () => {\n\t\tconst result = generateForPreset([\"redis\"]);\n\t\texpect(result.files[\"docker-compose.yml\"]).toMatchSnapshot();\n\t});\n\n\tit(\"creator preset (ffmpeg + remotion + minio + redis)\", () => {\n\t\tconst result = generateForPreset([\"ffmpeg\", \"remotion\", \"minio\", \"redis\"], [\"video-creator\"]);\n\t\texpect(result.files[\"docker-compose.yml\"]).toMatchSnapshot();\n\t\tif (result.files[\"docker-compose.media.yml\"]) {\n\t\t\texpect(result.files[\"docker-compose.media.yml\"]).toMatchSnapshot();\n\t\t}\n\t});\n\n\tit(\"researcher preset (qdrant + searxng + browserless + redis)\", () => {\n\t\tconst result = generateForPreset(\n\t\t\t[\"qdrant\", \"searxng\", \"browserless\", \"redis\"],\n\t\t\t[\"research-agent\"],\n\t\t);\n\t\texpect(result.files[\"docker-compose.yml\"]).toMatchSnapshot();\n\t});\n\n\tit(\"devops preset (n8n + postgresql + redis + monitoring)\", () => {\n\t\tconst result = generateForPreset(\n\t\t\t[\"n8n\", \"postgresql\", \"redis\", \"uptime-kuma\", \"grafana\", \"prometheus\"],\n\t\t\t[\"dev-ops\"],\n\t\t);\n\t\texpect(result.files[\"docker-compose.yml\"]).toMatchSnapshot();\n\t\tif (result.files[\"docker-compose.monitoring.yml\"]) {\n\t\t\texpect(result.files[\"docker-compose.monitoring.yml\"]).toMatchSnapshot();\n\t\t}\n\t});\n\n\tit(\"full preset (many services)\", () => {\n\t\tconst result = generateForPreset([\n\t\t\t\"redis\",\n\t\t\t\"postgresql\",\n\t\t\t\"qdrant\",\n\t\t\t\"n8n\",\n\t\t\t\"ffmpeg\",\n\t\t\t\"remotion\",\n\t\t\t\"minio\",\n\t\t\t\"caddy\",\n\t\t\t\"browserless\",\n\t\t\t\"searxng\",\n\t\t\t\"meilisearch\",\n\t\t\t\"uptime-kuma\",\n\t\t\t\"grafana\",\n\t\t\t\"prometheus\",\n\t\t\t\"ollama\",\n\t\t\t\"whisper\",\n\t\t\t\"gotify\",\n\t\t]);\n\t\texpect(result.files[\"docker-compose.yml\"]).toMatchSnapshot();\n\t\texpect(result.profiles.length).toBeGreaterThan(0);\n\t\t// Verify multiple compose files were created\n\t\texpect(Object.keys(result.files).length).toBeGreaterThan(1);\n\t});\n\n\tit(\"multi-file output has correct profile assignments\", () => {\n\t\tconst result = generateForPreset([\"redis\", \"ollama\", \"open-webui\", \"grafana\", \"prometheus\"]);\n\t\t// AI services should be in the ai profile file\n\t\tif (result.files[\"docker-compose.ai.yml\"]) {\n\t\t\texpect(result.files[\"docker-compose.ai.yml\"]).toContain(\"profiles:\");\n\t\t}\n\t\t// Monitoring should be in the monitoring profile file\n\t\tif (result.files[\"docker-compose.monitoring.yml\"]) {\n\t\t\texpect(result.files[\"docker-compose.monitoring.yml\"]).toContain(\"profiles:\");\n\t\t}\n\t});\n});\n"],"mappings":";;;;;AAIA,SAAS,kBAAkB,UAAoB,aAAuB,EAAE,EAAE;AAEzE,QAAO,iBADU,QAAQ;EAAE;EAAU;EAAY,CAAC,EAChB;EACjC,aAAa;EACb,OAAO;EACP,KAAK;EACL,UAAU;EACV,YAAY;EACZ,iBAAiB;EACjB,CAAC;;AAGH,SAAS,gCAAgC;AACxC,IAAG,qCAAqC;AAEvC,eADe,kBAAkB,CAAC,QAAQ,CAAC,CAC7B,MAAM,sBAAsB,CAAC,iBAAiB;GAC3D;AAEF,IAAG,4DAA4D;EAC9D,MAAM,SAAS,kBAAkB;GAAC;GAAU;GAAY;GAAS;GAAQ,EAAE,CAAC,gBAAgB,CAAC;AAC7F,eAAO,OAAO,MAAM,sBAAsB,CAAC,iBAAiB;AAC5D,MAAI,OAAO,MAAM,4BAChB,cAAO,OAAO,MAAM,4BAA4B,CAAC,iBAAiB;GAElE;AAEF,IAAG,oEAAoE;AAKtE,eAJe,kBACd;GAAC;GAAU;GAAW;GAAe;GAAQ,EAC7C,CAAC,iBAAiB,CAClB,CACa,MAAM,sBAAsB,CAAC,iBAAiB;GAC3D;AAEF,IAAG,+DAA+D;EACjE,MAAM,SAAS,kBACd;GAAC;GAAO;GAAc;GAAS;GAAe;GAAW;GAAa,EACtE,CAAC,UAAU,CACX;AACD,eAAO,OAAO,MAAM,sBAAsB,CAAC,iBAAiB;AAC5D,MAAI,OAAO,MAAM,iCAChB,cAAO,OAAO,MAAM,iCAAiC,CAAC,iBAAiB;GAEvE;AAEF,IAAG,qCAAqC;EACvC,MAAM,SAAS,kBAAkB;GAChC;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA,CAAC;AACF,eAAO,OAAO,MAAM,sBAAsB,CAAC,iBAAiB;AAC5D,eAAO,OAAO,SAAS,OAAO,CAAC,gBAAgB,EAAE;AAEjD,eAAO,OAAO,KAAK,OAAO,MAAM,CAAC,OAAO,CAAC,gBAAgB,EAAE;GAC1D;AAEF,IAAG,2DAA2D;EAC7D,MAAM,SAAS,kBAAkB;GAAC;GAAS;GAAU;GAAc;GAAW;GAAa,CAAC;AAE5F,MAAI,OAAO,MAAM,yBAChB,cAAO,OAAO,MAAM,yBAAyB,CAAC,UAAU,YAAY;AAGrE,MAAI,OAAO,MAAM,iCAChB,cAAO,OAAO,MAAM,iCAAiC,CAAC,UAAU,YAAY;GAE5E;EACD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { n as describe, r as it, t as globalExpect } from "./vi.2VT5v0um-Qk6MgAnK.mjs";
|
|
2
|
+
import { resolve } from "./resolver.mjs";
|
|
3
|
+
import { compose } from "./composer.mjs";
|
|
4
|
+
import { parse } from "yaml";
|
|
5
|
+
|
|
6
|
+
//#region src/composer.test.ts
|
|
7
|
+
const defaultOptions = {
|
|
8
|
+
projectName: "test-project",
|
|
9
|
+
proxy: "none",
|
|
10
|
+
gpu: false,
|
|
11
|
+
platform: "linux/amd64",
|
|
12
|
+
deployment: "local",
|
|
13
|
+
openclawVersion: "latest"
|
|
14
|
+
};
|
|
15
|
+
describe("compose", () => {
|
|
16
|
+
it("generates minimal stack with just OpenClaw gateway when no companions", () => {
|
|
17
|
+
const parsed = parse(compose(resolve({
|
|
18
|
+
services: [],
|
|
19
|
+
skillPacks: []
|
|
20
|
+
}), defaultOptions));
|
|
21
|
+
globalExpect(parsed.services).toHaveProperty("openclaw-gateway");
|
|
22
|
+
globalExpect(parsed.services["openclaw-gateway"].image).toContain("ghcr.io/openclaw/openclaw");
|
|
23
|
+
globalExpect(parsed.services["openclaw-gateway"].environment.HOME).toBe("/home/node");
|
|
24
|
+
globalExpect(parsed.services["openclaw-gateway"].environment.TERM).toBe("xterm-256color");
|
|
25
|
+
const gwVolumes = parsed.services["openclaw-gateway"].volumes;
|
|
26
|
+
globalExpect(gwVolumes.some((v) => v.includes(".openclaw"))).toBe(true);
|
|
27
|
+
globalExpect(parsed.networks).toHaveProperty("openclaw-network");
|
|
28
|
+
globalExpect(parsed.networks["openclaw-network"].driver).toBe("bridge");
|
|
29
|
+
globalExpect(parsed.services).toHaveProperty("openclaw-cli");
|
|
30
|
+
globalExpect(parsed.services["openclaw-gateway"]).not.toHaveProperty("depends_on");
|
|
31
|
+
globalExpect(parsed.services["openclaw-gateway"].restart).toBe("unless-stopped");
|
|
32
|
+
});
|
|
33
|
+
it("generates Redis companion with proper gateway depends_on", () => {
|
|
34
|
+
const parsed = parse(compose(resolve({
|
|
35
|
+
services: ["redis"],
|
|
36
|
+
skillPacks: []
|
|
37
|
+
}), defaultOptions));
|
|
38
|
+
globalExpect(parsed.services).toHaveProperty("openclaw-gateway");
|
|
39
|
+
globalExpect(parsed.services).toHaveProperty("redis");
|
|
40
|
+
globalExpect(parsed.services.redis.image).toBe("redis:7-alpine");
|
|
41
|
+
globalExpect(parsed.services["openclaw-gateway"].depends_on).toHaveProperty("redis");
|
|
42
|
+
globalExpect(parsed.services["openclaw-gateway"].depends_on.redis.condition).toBe("service_healthy");
|
|
43
|
+
globalExpect(parsed.services.redis.healthcheck).toBeDefined();
|
|
44
|
+
globalExpect(parsed.services.redis.healthcheck.test).toContain("redis-cli ping");
|
|
45
|
+
globalExpect(parsed.services.redis.restart).toBe("unless-stopped");
|
|
46
|
+
globalExpect(parsed.services.redis.networks).toContain("openclaw-network");
|
|
47
|
+
globalExpect(parsed.services["openclaw-gateway"].environment).toHaveProperty("REDIS_HOST");
|
|
48
|
+
globalExpect(parsed.services["openclaw-gateway"].environment.REDIS_HOST).toBe("redis");
|
|
49
|
+
});
|
|
50
|
+
it("generates parseable YAML for a multi-service stack", () => {
|
|
51
|
+
const yaml = compose(resolve({
|
|
52
|
+
services: ["redis", "n8n"],
|
|
53
|
+
skillPacks: []
|
|
54
|
+
}), defaultOptions);
|
|
55
|
+
globalExpect(() => parse(yaml)).not.toThrow();
|
|
56
|
+
const parsed = parse(yaml);
|
|
57
|
+
globalExpect(parsed).toHaveProperty("services");
|
|
58
|
+
globalExpect(parsed).toHaveProperty("volumes");
|
|
59
|
+
globalExpect(parsed).toHaveProperty("networks");
|
|
60
|
+
globalExpect(parsed.services).toHaveProperty("openclaw-gateway");
|
|
61
|
+
globalExpect(parsed.services).toHaveProperty("redis");
|
|
62
|
+
globalExpect(parsed.services).toHaveProperty("n8n");
|
|
63
|
+
globalExpect(parsed.services).toHaveProperty("postgresql");
|
|
64
|
+
});
|
|
65
|
+
it("includes all service volumes in top-level volumes section", () => {
|
|
66
|
+
const resolved = resolve({
|
|
67
|
+
services: ["redis", "n8n"],
|
|
68
|
+
skillPacks: []
|
|
69
|
+
});
|
|
70
|
+
const parsed = parse(compose(resolved, defaultOptions));
|
|
71
|
+
const serviceVolumeNames = /* @__PURE__ */ new Set();
|
|
72
|
+
for (const rs of resolved.services) for (const vol of rs.definition.volumes) serviceVolumeNames.add(vol.name);
|
|
73
|
+
for (const volName of serviceVolumeNames) globalExpect(parsed.volumes).toHaveProperty(volName);
|
|
74
|
+
const gwVols = parsed.services["openclaw-gateway"].volumes;
|
|
75
|
+
globalExpect(gwVols.some((v) => v.includes(".openclaw"))).toBe(true);
|
|
76
|
+
});
|
|
77
|
+
it("includes GPU passthrough when gpu=true and service requires it", () => {
|
|
78
|
+
const resolved = resolve({
|
|
79
|
+
services: ["ollama"],
|
|
80
|
+
skillPacks: []
|
|
81
|
+
});
|
|
82
|
+
const ollamaService = parse(compose({
|
|
83
|
+
...resolved,
|
|
84
|
+
services: resolved.services.map((s) => ({
|
|
85
|
+
...s,
|
|
86
|
+
definition: {
|
|
87
|
+
...s.definition,
|
|
88
|
+
gpuRequired: true
|
|
89
|
+
}
|
|
90
|
+
}))
|
|
91
|
+
}, {
|
|
92
|
+
...defaultOptions,
|
|
93
|
+
gpu: true
|
|
94
|
+
})).services.ollama;
|
|
95
|
+
globalExpect(ollamaService.deploy).toBeDefined();
|
|
96
|
+
globalExpect(ollamaService.deploy.resources.reservations.devices).toEqual([{
|
|
97
|
+
driver: "nvidia",
|
|
98
|
+
count: "all",
|
|
99
|
+
capabilities: ["gpu"]
|
|
100
|
+
}]);
|
|
101
|
+
});
|
|
102
|
+
it("does not include GPU passthrough when gpu=false", () => {
|
|
103
|
+
const resolved = resolve({
|
|
104
|
+
services: ["ollama"],
|
|
105
|
+
skillPacks: []
|
|
106
|
+
});
|
|
107
|
+
const ollamaService = parse(compose({
|
|
108
|
+
...resolved,
|
|
109
|
+
services: resolved.services.map((s) => ({
|
|
110
|
+
...s,
|
|
111
|
+
definition: {
|
|
112
|
+
...s.definition,
|
|
113
|
+
gpuRequired: true
|
|
114
|
+
}
|
|
115
|
+
}))
|
|
116
|
+
}, {
|
|
117
|
+
...defaultOptions,
|
|
118
|
+
gpu: false
|
|
119
|
+
})).services.ollama;
|
|
120
|
+
globalExpect(ollamaService.deploy?.resources?.reservations?.devices).toBeUndefined();
|
|
121
|
+
});
|
|
122
|
+
it("does not map internal-only ports to host", () => {
|
|
123
|
+
const resolved = resolve({
|
|
124
|
+
services: ["redis"],
|
|
125
|
+
skillPacks: []
|
|
126
|
+
});
|
|
127
|
+
const redisPorts = parse(compose({
|
|
128
|
+
...resolved,
|
|
129
|
+
services: resolved.services.map((s) => ({
|
|
130
|
+
...s,
|
|
131
|
+
definition: {
|
|
132
|
+
...s.definition,
|
|
133
|
+
ports: [...s.definition.ports, {
|
|
134
|
+
host: 16379,
|
|
135
|
+
container: 16379,
|
|
136
|
+
description: "Redis cluster bus",
|
|
137
|
+
exposed: false
|
|
138
|
+
}]
|
|
139
|
+
}
|
|
140
|
+
}))
|
|
141
|
+
}, defaultOptions)).services.redis.ports;
|
|
142
|
+
globalExpect(redisPorts).toHaveLength(1);
|
|
143
|
+
globalExpect(redisPorts[0]).toContain("6379");
|
|
144
|
+
globalExpect(redisPorts[0]).not.toContain("16379");
|
|
145
|
+
});
|
|
146
|
+
it("uses service_started condition for services without healthcheck", () => {
|
|
147
|
+
const resolved = resolve({
|
|
148
|
+
services: ["minio"],
|
|
149
|
+
skillPacks: []
|
|
150
|
+
});
|
|
151
|
+
const gatewayDeps = parse(compose(resolved, defaultOptions)).services["openclaw-gateway"].depends_on;
|
|
152
|
+
for (const [id, dep] of Object.entries(gatewayDeps)) if (resolved.services.find((s) => s.definition.id === id)?.definition.healthcheck) globalExpect(dep.condition).toBe("service_healthy");
|
|
153
|
+
else globalExpect(dep.condition).toBe("service_started");
|
|
154
|
+
});
|
|
155
|
+
it("gateway is always the first service in the output", () => {
|
|
156
|
+
const parsed = parse(compose(resolve({
|
|
157
|
+
services: ["redis", "ollama"],
|
|
158
|
+
skillPacks: []
|
|
159
|
+
}), defaultOptions));
|
|
160
|
+
globalExpect(Object.keys(parsed.services)[0]).toBe("openclaw-gateway");
|
|
161
|
+
});
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
//#endregion
|
|
165
|
+
export { };
|
|
166
|
+
//# sourceMappingURL=composer.test.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"composer.test.mjs","names":[],"sources":["../src/composer.test.ts"],"sourcesContent":["import { describe, expect, it } from \"vitest\";\nimport { parse } from \"yaml\";\nimport { compose } from \"./composer.js\";\nimport { resolve } from \"./resolver.js\";\nimport type { ComposeOptions, ResolverOutput } from \"./types.js\";\n\nconst defaultOptions: ComposeOptions = {\n\tprojectName: \"test-project\",\n\tproxy: \"none\",\n\tgpu: false,\n\tplatform: \"linux/amd64\",\n\tdeployment: \"local\",\n\topenclawVersion: \"latest\",\n};\n\ndescribe(\"compose\", () => {\n\tit(\"generates minimal stack with just OpenClaw gateway when no companions\", () => {\n\t\tconst resolved = resolve({ services: [], skillPacks: [] });\n\t\tconst yaml = compose(resolved, defaultOptions);\n\t\tconst parsed = parse(yaml);\n\n\t\t// Should have the gateway service\n\t\texpect(parsed.services).toHaveProperty(\"openclaw-gateway\");\n\t\texpect(parsed.services[\"openclaw-gateway\"].image).toContain(\"ghcr.io/openclaw/openclaw\");\n\n\t\t// Gateway should have core environment\n\t\texpect(parsed.services[\"openclaw-gateway\"].environment.HOME).toBe(\"/home/node\");\n\t\texpect(parsed.services[\"openclaw-gateway\"].environment.TERM).toBe(\"xterm-256color\");\n\n\t\t// Gateway uses bind-mount volumes (not named volumes in top-level volumes section)\n\t\tconst gwVolumes = parsed.services[\"openclaw-gateway\"].volumes as string[];\n\t\texpect(gwVolumes.some((v: string) => v.includes(\".openclaw\"))).toBe(true);\n\n\t\t// Should have network\n\t\texpect(parsed.networks).toHaveProperty(\"openclaw-network\");\n\t\texpect(parsed.networks[\"openclaw-network\"].driver).toBe(\"bridge\");\n\n\t\t// Should have CLI companion service\n\t\texpect(parsed.services).toHaveProperty(\"openclaw-cli\");\n\n\t\t// Gateway should have no depends_on (no companions)\n\t\texpect(parsed.services[\"openclaw-gateway\"]).not.toHaveProperty(\"depends_on\");\n\n\t\t// Gateway should have restart policy\n\t\texpect(parsed.services[\"openclaw-gateway\"].restart).toBe(\"unless-stopped\");\n\t});\n\n\tit(\"generates Redis companion with proper gateway depends_on\", () => {\n\t\tconst resolved = resolve({ services: [\"redis\"], skillPacks: [] });\n\t\tconst yaml = compose(resolved, defaultOptions);\n\t\tconst parsed = parse(yaml);\n\n\t\t// Should have gateway and redis services\n\t\texpect(parsed.services).toHaveProperty(\"openclaw-gateway\");\n\t\texpect(parsed.services).toHaveProperty(\"redis\");\n\n\t\t// Redis service should have correct image\n\t\texpect(parsed.services.redis.image).toBe(\"redis:7-alpine\");\n\n\t\t// Gateway depends_on should include redis with service_healthy (redis has healthcheck)\n\t\texpect(parsed.services[\"openclaw-gateway\"].depends_on).toHaveProperty(\"redis\");\n\t\texpect(parsed.services[\"openclaw-gateway\"].depends_on.redis.condition).toBe(\"service_healthy\");\n\n\t\t// Redis should have a healthcheck\n\t\texpect(parsed.services.redis.healthcheck).toBeDefined();\n\t\texpect(parsed.services.redis.healthcheck.test).toContain(\"redis-cli ping\");\n\n\t\t// Redis should have restart policy\n\t\texpect(parsed.services.redis.restart).toBe(\"unless-stopped\");\n\n\t\t// Redis should be on openclaw-network\n\t\texpect(parsed.services.redis.networks).toContain(\"openclaw-network\");\n\n\t\t// Gateway environment should include redis-related openclawEnvVars\n\t\texpect(parsed.services[\"openclaw-gateway\"].environment).toHaveProperty(\"REDIS_HOST\");\n\t\texpect(parsed.services[\"openclaw-gateway\"].environment.REDIS_HOST).toBe(\"redis\");\n\t});\n\n\tit(\"generates parseable YAML for a multi-service stack\", () => {\n\t\tconst resolved = resolve({ services: [\"redis\", \"n8n\"], skillPacks: [] });\n\t\tconst yaml = compose(resolved, defaultOptions);\n\n\t\t// Should not throw when parsing\n\t\texpect(() => parse(yaml)).not.toThrow();\n\n\t\tconst parsed = parse(yaml);\n\t\texpect(parsed).toHaveProperty(\"services\");\n\t\texpect(parsed).toHaveProperty(\"volumes\");\n\t\texpect(parsed).toHaveProperty(\"networks\");\n\n\t\t// Should have gateway + redis + n8n + postgresql (n8n requires postgresql)\n\t\texpect(parsed.services).toHaveProperty(\"openclaw-gateway\");\n\t\texpect(parsed.services).toHaveProperty(\"redis\");\n\t\texpect(parsed.services).toHaveProperty(\"n8n\");\n\t\texpect(parsed.services).toHaveProperty(\"postgresql\");\n\t});\n\n\tit(\"includes all service volumes in top-level volumes section\", () => {\n\t\tconst resolved = resolve({ services: [\"redis\", \"n8n\"], skillPacks: [] });\n\t\tconst yaml = compose(resolved, defaultOptions);\n\t\tconst parsed = parse(yaml);\n\n\t\t// Collect all volume names from all resolved services\n\t\tconst serviceVolumeNames = new Set<string>();\n\t\tfor (const rs of resolved.services) {\n\t\t\tfor (const vol of rs.definition.volumes) {\n\t\t\t\tserviceVolumeNames.add(vol.name);\n\t\t\t}\n\t\t}\n\n\t\t// All service volumes must appear in top-level volumes\n\t\tfor (const volName of serviceVolumeNames) {\n\t\t\texpect(parsed.volumes).toHaveProperty(volName);\n\t\t}\n\n\t\t// Gateway uses bind-mount volumes (not in top-level volumes section)\n\t\tconst gwVols = parsed.services[\"openclaw-gateway\"].volumes as string[];\n\t\texpect(gwVols.some((v: string) => v.includes(\".openclaw\"))).toBe(true);\n\t});\n\n\tit(\"includes GPU passthrough when gpu=true and service requires it\", () => {\n\t\tconst resolved = resolve({ services: [\"ollama\"], skillPacks: [] });\n\n\t\t// Modify resolved output to simulate a GPU-required service\n\t\tconst gpuResolved: ResolverOutput = {\n\t\t\t...resolved,\n\t\t\tservices: resolved.services.map((s) => ({\n\t\t\t\t...s,\n\t\t\t\tdefinition: { ...s.definition, gpuRequired: true },\n\t\t\t})),\n\t\t};\n\n\t\tconst yaml = compose(gpuResolved, { ...defaultOptions, gpu: true });\n\t\tconst parsed = parse(yaml);\n\n\t\t// Ollama service should have GPU device reservation\n\t\tconst ollamaService = parsed.services.ollama;\n\t\texpect(ollamaService.deploy).toBeDefined();\n\t\texpect(ollamaService.deploy.resources.reservations.devices).toEqual([\n\t\t\t{\n\t\t\t\tdriver: \"nvidia\",\n\t\t\t\tcount: \"all\",\n\t\t\t\tcapabilities: [\"gpu\"],\n\t\t\t},\n\t\t]);\n\t});\n\n\tit(\"does not include GPU passthrough when gpu=false\", () => {\n\t\tconst resolved = resolve({ services: [\"ollama\"], skillPacks: [] });\n\n\t\t// Even if service requires GPU, gpu option is false\n\t\tconst gpuResolved: ResolverOutput = {\n\t\t\t...resolved,\n\t\t\tservices: resolved.services.map((s) => ({\n\t\t\t\t...s,\n\t\t\t\tdefinition: { ...s.definition, gpuRequired: true },\n\t\t\t})),\n\t\t};\n\n\t\tconst yaml = compose(gpuResolved, { ...defaultOptions, gpu: false });\n\t\tconst parsed = parse(yaml);\n\n\t\t// Should NOT have deploy with GPU devices\n\t\tconst ollamaService = parsed.services.ollama;\n\t\texpect(ollamaService.deploy?.resources?.reservations?.devices).toBeUndefined();\n\t});\n\n\tit(\"does not map internal-only ports to host\", () => {\n\t\tconst resolved = resolve({ services: [\"redis\"], skillPacks: [] });\n\n\t\t// Modify redis to have an internal-only port\n\t\tconst modifiedResolved: ResolverOutput = {\n\t\t\t...resolved,\n\t\t\tservices: resolved.services.map((s) => ({\n\t\t\t\t...s,\n\t\t\t\tdefinition: {\n\t\t\t\t\t...s.definition,\n\t\t\t\t\tports: [\n\t\t\t\t\t\t...s.definition.ports,\n\t\t\t\t\t\t{ host: 16379, container: 16379, description: \"Redis cluster bus\", exposed: false },\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t})),\n\t\t};\n\n\t\tconst yaml = compose(modifiedResolved, defaultOptions);\n\t\tconst parsed = parse(yaml);\n\n\t\t// Should only have the exposed port, not the internal one\n\t\tconst redisPorts = parsed.services.redis.ports;\n\t\texpect(redisPorts).toHaveLength(1);\n\t\texpect(redisPorts[0]).toContain(\"6379\");\n\t\texpect(redisPorts[0]).not.toContain(\"16379\");\n\t});\n\n\tit(\"uses service_started condition for services without healthcheck\", () => {\n\t\tconst resolved = resolve({ services: [\"minio\"], skillPacks: [] });\n\n\t\tconst yaml = compose(resolved, defaultOptions);\n\t\tconst parsed = parse(yaml);\n\n\t\t// Minio may or may not have a healthcheck – the gateway depends_on\n\t\t// condition should reflect the definition accurately\n\t\tconst gatewayDeps = parsed.services[\"openclaw-gateway\"].depends_on;\n\t\tfor (const [id, dep] of Object.entries(gatewayDeps)) {\n\t\t\tconst svc = resolved.services.find((s) => s.definition.id === id);\n\t\t\tif (svc?.definition.healthcheck) {\n\t\t\t\texpect((dep as { condition: string }).condition).toBe(\"service_healthy\");\n\t\t\t} else {\n\t\t\t\texpect((dep as { condition: string }).condition).toBe(\"service_started\");\n\t\t\t}\n\t\t}\n\t});\n\n\tit(\"gateway is always the first service in the output\", () => {\n\t\tconst resolved = resolve({ services: [\"redis\", \"ollama\"], skillPacks: [] });\n\t\tconst yaml = compose(resolved, defaultOptions);\n\t\tconst parsed = parse(yaml);\n\n\t\t// First key in services should be openclaw-gateway\n\t\tconst serviceKeys = Object.keys(parsed.services);\n\t\texpect(serviceKeys[0]).toBe(\"openclaw-gateway\");\n\t});\n});\n"],"mappings":";;;;;;AAMA,MAAM,iBAAiC;CACtC,aAAa;CACb,OAAO;CACP,KAAK;CACL,UAAU;CACV,YAAY;CACZ,iBAAiB;CACjB;AAED,SAAS,iBAAiB;AACzB,IAAG,+EAA+E;EAGjF,MAAM,SAAS,MADF,QADI,QAAQ;GAAE,UAAU,EAAE;GAAE,YAAY,EAAE;GAAE,CAAC,EAC3B,eAAe,CACpB;AAG1B,eAAO,OAAO,SAAS,CAAC,eAAe,mBAAmB;AAC1D,eAAO,OAAO,SAAS,oBAAoB,MAAM,CAAC,UAAU,4BAA4B;AAGxF,eAAO,OAAO,SAAS,oBAAoB,YAAY,KAAK,CAAC,KAAK,aAAa;AAC/E,eAAO,OAAO,SAAS,oBAAoB,YAAY,KAAK,CAAC,KAAK,iBAAiB;EAGnF,MAAM,YAAY,OAAO,SAAS,oBAAoB;AACtD,eAAO,UAAU,MAAM,MAAc,EAAE,SAAS,YAAY,CAAC,CAAC,CAAC,KAAK,KAAK;AAGzE,eAAO,OAAO,SAAS,CAAC,eAAe,mBAAmB;AAC1D,eAAO,OAAO,SAAS,oBAAoB,OAAO,CAAC,KAAK,SAAS;AAGjE,eAAO,OAAO,SAAS,CAAC,eAAe,eAAe;AAGtD,eAAO,OAAO,SAAS,oBAAoB,CAAC,IAAI,eAAe,aAAa;AAG5E,eAAO,OAAO,SAAS,oBAAoB,QAAQ,CAAC,KAAK,iBAAiB;GACzE;AAEF,IAAG,kEAAkE;EAGpE,MAAM,SAAS,MADF,QADI,QAAQ;GAAE,UAAU,CAAC,QAAQ;GAAE,YAAY,EAAE;GAAE,CAAC,EAClC,eAAe,CACpB;AAG1B,eAAO,OAAO,SAAS,CAAC,eAAe,mBAAmB;AAC1D,eAAO,OAAO,SAAS,CAAC,eAAe,QAAQ;AAG/C,eAAO,OAAO,SAAS,MAAM,MAAM,CAAC,KAAK,iBAAiB;AAG1D,eAAO,OAAO,SAAS,oBAAoB,WAAW,CAAC,eAAe,QAAQ;AAC9E,eAAO,OAAO,SAAS,oBAAoB,WAAW,MAAM,UAAU,CAAC,KAAK,kBAAkB;AAG9F,eAAO,OAAO,SAAS,MAAM,YAAY,CAAC,aAAa;AACvD,eAAO,OAAO,SAAS,MAAM,YAAY,KAAK,CAAC,UAAU,iBAAiB;AAG1E,eAAO,OAAO,SAAS,MAAM,QAAQ,CAAC,KAAK,iBAAiB;AAG5D,eAAO,OAAO,SAAS,MAAM,SAAS,CAAC,UAAU,mBAAmB;AAGpE,eAAO,OAAO,SAAS,oBAAoB,YAAY,CAAC,eAAe,aAAa;AACpF,eAAO,OAAO,SAAS,oBAAoB,YAAY,WAAW,CAAC,KAAK,QAAQ;GAC/E;AAEF,IAAG,4DAA4D;EAE9D,MAAM,OAAO,QADI,QAAQ;GAAE,UAAU,CAAC,SAAS,MAAM;GAAE,YAAY,EAAE;GAAE,CAAC,EACzC,eAAe;AAG9C,qBAAa,MAAM,KAAK,CAAC,CAAC,IAAI,SAAS;EAEvC,MAAM,SAAS,MAAM,KAAK;AAC1B,eAAO,OAAO,CAAC,eAAe,WAAW;AACzC,eAAO,OAAO,CAAC,eAAe,UAAU;AACxC,eAAO,OAAO,CAAC,eAAe,WAAW;AAGzC,eAAO,OAAO,SAAS,CAAC,eAAe,mBAAmB;AAC1D,eAAO,OAAO,SAAS,CAAC,eAAe,QAAQ;AAC/C,eAAO,OAAO,SAAS,CAAC,eAAe,MAAM;AAC7C,eAAO,OAAO,SAAS,CAAC,eAAe,aAAa;GACnD;AAEF,IAAG,mEAAmE;EACrE,MAAM,WAAW,QAAQ;GAAE,UAAU,CAAC,SAAS,MAAM;GAAE,YAAY,EAAE;GAAE,CAAC;EAExE,MAAM,SAAS,MADF,QAAQ,UAAU,eAAe,CACpB;EAG1B,MAAM,qCAAqB,IAAI,KAAa;AAC5C,OAAK,MAAM,MAAM,SAAS,SACzB,MAAK,MAAM,OAAO,GAAG,WAAW,QAC/B,oBAAmB,IAAI,IAAI,KAAK;AAKlC,OAAK,MAAM,WAAW,mBACrB,cAAO,OAAO,QAAQ,CAAC,eAAe,QAAQ;EAI/C,MAAM,SAAS,OAAO,SAAS,oBAAoB;AACnD,eAAO,OAAO,MAAM,MAAc,EAAE,SAAS,YAAY,CAAC,CAAC,CAAC,KAAK,KAAK;GACrE;AAEF,IAAG,wEAAwE;EAC1E,MAAM,WAAW,QAAQ;GAAE,UAAU,CAAC,SAAS;GAAE,YAAY,EAAE;GAAE,CAAC;EAelE,MAAM,gBAHS,MADF,QARuB;GACnC,GAAG;GACH,UAAU,SAAS,SAAS,KAAK,OAAO;IACvC,GAAG;IACH,YAAY;KAAE,GAAG,EAAE;KAAY,aAAa;KAAM;IAClD,EAAE;GACH,EAEiC;GAAE,GAAG;GAAgB,KAAK;GAAM,CAAC,CACzC,CAGG,SAAS;AACtC,eAAO,cAAc,OAAO,CAAC,aAAa;AAC1C,eAAO,cAAc,OAAO,UAAU,aAAa,QAAQ,CAAC,QAAQ,CACnE;GACC,QAAQ;GACR,OAAO;GACP,cAAc,CAAC,MAAM;GACrB,CACD,CAAC;GACD;AAEF,IAAG,yDAAyD;EAC3D,MAAM,WAAW,QAAQ;GAAE,UAAU,CAAC,SAAS;GAAE,YAAY,EAAE;GAAE,CAAC;EAelE,MAAM,gBAHS,MADF,QARuB;GACnC,GAAG;GACH,UAAU,SAAS,SAAS,KAAK,OAAO;IACvC,GAAG;IACH,YAAY;KAAE,GAAG,EAAE;KAAY,aAAa;KAAM;IAClD,EAAE;GACH,EAEiC;GAAE,GAAG;GAAgB,KAAK;GAAO,CAAC,CAC1C,CAGG,SAAS;AACtC,eAAO,cAAc,QAAQ,WAAW,cAAc,QAAQ,CAAC,eAAe;GAC7E;AAEF,IAAG,kDAAkD;EACpD,MAAM,WAAW,QAAQ;GAAE,UAAU,CAAC,QAAQ;GAAE,YAAY,EAAE;GAAE,CAAC;EAqBjE,MAAM,aAHS,MADF,QAd4B;GACxC,GAAG;GACH,UAAU,SAAS,SAAS,KAAK,OAAO;IACvC,GAAG;IACH,YAAY;KACX,GAAG,EAAE;KACL,OAAO,CACN,GAAG,EAAE,WAAW,OAChB;MAAE,MAAM;MAAO,WAAW;MAAO,aAAa;MAAqB,SAAS;MAAO,CACnF;KACD;IACD,EAAE;GACH,EAEsC,eAAe,CAC5B,CAGA,SAAS,MAAM;AACzC,eAAO,WAAW,CAAC,aAAa,EAAE;AAClC,eAAO,WAAW,GAAG,CAAC,UAAU,OAAO;AACvC,eAAO,WAAW,GAAG,CAAC,IAAI,UAAU,QAAQ;GAC3C;AAEF,IAAG,yEAAyE;EAC3E,MAAM,WAAW,QAAQ;GAAE,UAAU,CAAC,QAAQ;GAAE,YAAY,EAAE;GAAE,CAAC;EAOjE,MAAM,cAJS,MADF,QAAQ,UAAU,eAAe,CACpB,CAIC,SAAS,oBAAoB;AACxD,OAAK,MAAM,CAAC,IAAI,QAAQ,OAAO,QAAQ,YAAY,CAElD,KADY,SAAS,SAAS,MAAM,MAAM,EAAE,WAAW,OAAO,GAAG,EACxD,WAAW,YACnB,cAAQ,IAA8B,UAAU,CAAC,KAAK,kBAAkB;MAExE,cAAQ,IAA8B,UAAU,CAAC,KAAK,kBAAkB;GAGzE;AAEF,IAAG,2DAA2D;EAG7D,MAAM,SAAS,MADF,QADI,QAAQ;GAAE,UAAU,CAAC,SAAS,SAAS;GAAE,YAAY,EAAE;GAAE,CAAC,EAC5C,eAAe,CACpB;AAI1B,eADoB,OAAO,KAAK,OAAO,SAAS,CAC7B,GAAG,CAAC,KAAK,mBAAmB;GAC9C;EACD"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { GenerationInput, GenerationResult } from "./types.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/generate.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Main orchestration function: takes generation input, resolves dependencies,
|
|
6
|
+
* generates all files, validates, and returns the complete file tree.
|
|
7
|
+
*/
|
|
8
|
+
declare function generate(input: GenerationInput): GenerationResult;
|
|
9
|
+
//#endregion
|
|
10
|
+
export { generate };
|
|
11
|
+
//# sourceMappingURL=generate.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate.d.mts","names":[],"sources":["../src/generate.ts"],"mappings":";;;;;AAqCA;;iBAAgB,QAAA,CAAS,KAAA,EAAO,eAAA,GAAkB,gBAAA"}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { partitionBareMetal, platformToNativePlatform, resolvedWithOnlyServices } from "./bare-metal-partition.mjs";
|
|
2
|
+
import { resolve } from "./resolver.mjs";
|
|
3
|
+
import { composeMultiFile } from "./composer.mjs";
|
|
4
|
+
import { generateBareMetalInstall } from "./generators/bare-metal-install.mjs";
|
|
5
|
+
import { generateCaddyfile } from "./generators/caddy.mjs";
|
|
6
|
+
import { generatePostgresInit } from "./generators/postgres-init.mjs";
|
|
7
|
+
import { generateEnvFiles } from "./generators/env.mjs";
|
|
8
|
+
import { generateGrafanaConfig, generateGrafanaDashboard } from "./generators/grafana.mjs";
|
|
9
|
+
import { generateN8nWorkflows } from "./generators/n8n-workflows.mjs";
|
|
10
|
+
import { generateNativeInstallScripts } from "./generators/native-services.mjs";
|
|
11
|
+
import { generatePrometheusConfig } from "./generators/prometheus.mjs";
|
|
12
|
+
import { generateReadme } from "./generators/readme.mjs";
|
|
13
|
+
import { generateScripts } from "./generators/scripts.mjs";
|
|
14
|
+
import { generateSkillFiles } from "./generators/skills.mjs";
|
|
15
|
+
import { validate } from "./validator.mjs";
|
|
16
|
+
|
|
17
|
+
//#region src/generate.ts
|
|
18
|
+
/** Resolver/compose only support linux image platforms; normalize for bare-metal (windows/macos). */
|
|
19
|
+
function getComposePlatform(platform) {
|
|
20
|
+
if (platform === "linux/amd64" || platform === "linux/arm64") return platform;
|
|
21
|
+
return "linux/amd64";
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Main orchestration function: takes generation input, resolves dependencies,
|
|
25
|
+
* generates all files, validates, and returns the complete file tree.
|
|
26
|
+
*/
|
|
27
|
+
function generate(input) {
|
|
28
|
+
const composePlatform = getComposePlatform(input.platform);
|
|
29
|
+
const resolved = resolve({
|
|
30
|
+
services: input.services,
|
|
31
|
+
skillPacks: input.skillPacks,
|
|
32
|
+
proxy: input.proxy,
|
|
33
|
+
gpu: input.gpu,
|
|
34
|
+
platform: composePlatform,
|
|
35
|
+
monitoring: input.monitoring
|
|
36
|
+
});
|
|
37
|
+
if (!resolved.isValid) throw new Error(`Invalid stack configuration: ${resolved.errors.map((e) => e.message).join("; ")}`);
|
|
38
|
+
const isBareMetal = input.deploymentType === "bare-metal";
|
|
39
|
+
let resolvedForCompose = resolved;
|
|
40
|
+
let nativeIds = /* @__PURE__ */ new Set();
|
|
41
|
+
let nativeServices = [];
|
|
42
|
+
let dockerOnlyServices = [];
|
|
43
|
+
if (isBareMetal) {
|
|
44
|
+
const partition = partitionBareMetal(resolved, input.platform);
|
|
45
|
+
nativeServices = partition.nativeServices;
|
|
46
|
+
dockerOnlyServices = partition.dockerOnlyServices;
|
|
47
|
+
nativeIds = partition.nativeIds;
|
|
48
|
+
if (nativeServices.length > 0) resolvedForCompose = resolvedWithOnlyServices(resolved, dockerOnlyServices);
|
|
49
|
+
}
|
|
50
|
+
const composeOptions = {
|
|
51
|
+
projectName: input.projectName,
|
|
52
|
+
proxy: input.proxy,
|
|
53
|
+
domain: input.domain,
|
|
54
|
+
gpu: input.gpu,
|
|
55
|
+
platform: composePlatform,
|
|
56
|
+
deployment: input.deployment,
|
|
57
|
+
openclawVersion: input.openclawVersion,
|
|
58
|
+
bareMetalNativeHost: isBareMetal && nativeIds.size > 0
|
|
59
|
+
};
|
|
60
|
+
const composeResult = composeMultiFile(resolvedForCompose, composeOptions);
|
|
61
|
+
const validation = validate(resolvedForCompose, composeResult.files["docker-compose.yml"] ?? "", {
|
|
62
|
+
domain: input.domain,
|
|
63
|
+
generateSecrets: input.generateSecrets
|
|
64
|
+
});
|
|
65
|
+
if (!validation.valid) throw new Error(`Validation failed: ${validation.errors.map((e) => e.message).join("; ")}`);
|
|
66
|
+
const files = {};
|
|
67
|
+
for (const [filename, content] of Object.entries(composeResult.files)) files[filename] = content;
|
|
68
|
+
const envFiles = generateEnvFiles(resolved, {
|
|
69
|
+
generateSecrets: input.generateSecrets,
|
|
70
|
+
domain: input.domain,
|
|
71
|
+
openclawVersion: input.openclawVersion,
|
|
72
|
+
nativeServiceIds: isBareMetal ? nativeIds : void 0
|
|
73
|
+
});
|
|
74
|
+
files[".env.example"] = envFiles.envExample;
|
|
75
|
+
files[".env"] = envFiles.env;
|
|
76
|
+
files[".gitignore"] = [
|
|
77
|
+
".env",
|
|
78
|
+
".env.local",
|
|
79
|
+
".env.*.local",
|
|
80
|
+
"*.log",
|
|
81
|
+
"docker-compose.override.yml"
|
|
82
|
+
].join("\n");
|
|
83
|
+
const skillFiles = generateSkillFiles(resolved);
|
|
84
|
+
for (const [path, content] of Object.entries(skillFiles)) files[path] = content;
|
|
85
|
+
files["README.md"] = generateReadme(resolved, {
|
|
86
|
+
projectName: input.projectName,
|
|
87
|
+
domain: input.domain,
|
|
88
|
+
proxy: input.proxy,
|
|
89
|
+
deploymentType: input.deploymentType,
|
|
90
|
+
hasNativeServices: isBareMetal && nativeServices.length > 0
|
|
91
|
+
});
|
|
92
|
+
const scripts = generateScripts();
|
|
93
|
+
for (const [path, content] of Object.entries(scripts)) files[path] = content;
|
|
94
|
+
const n8nWorkflows = generateN8nWorkflows(resolved);
|
|
95
|
+
for (const [path, content] of Object.entries(n8nWorkflows)) files[path] = content;
|
|
96
|
+
const postgresInit = generatePostgresInit(resolved);
|
|
97
|
+
if (postgresInit) files["postgres/init-databases.sh"] = postgresInit;
|
|
98
|
+
if (input.proxy === "caddy" && input.domain) files["caddy/Caddyfile"] = generateCaddyfile(resolved, input.domain);
|
|
99
|
+
if (resolved.services.some((s) => s.definition.id === "prometheus")) files["prometheus/prometheus.yml"] = generatePrometheusConfig(resolved);
|
|
100
|
+
if (resolved.services.some((s) => s.definition.id === "grafana")) {
|
|
101
|
+
const grafanaFiles = generateGrafanaConfig();
|
|
102
|
+
for (const [path, content] of Object.entries(grafanaFiles)) files[path] = content;
|
|
103
|
+
files["config/grafana/dashboards/openclaw-stack-overview.json"] = generateGrafanaDashboard();
|
|
104
|
+
}
|
|
105
|
+
files["docker-compose.override.yml"] = [
|
|
106
|
+
"# Local overrides for docker-compose.yml",
|
|
107
|
+
"# This file is gitignored — use it for personal port changes, extra volumes, etc.",
|
|
108
|
+
"services: {}",
|
|
109
|
+
""
|
|
110
|
+
].join("\n");
|
|
111
|
+
files["docs/SERVICES.md"] = generateServicesDoc(resolved);
|
|
112
|
+
if (isBareMetal) {
|
|
113
|
+
if (nativeServices.length > 0) {
|
|
114
|
+
const nativePlatform = platformToNativePlatform(input.platform);
|
|
115
|
+
const nativeScripts = generateNativeInstallScripts({
|
|
116
|
+
nativeServices,
|
|
117
|
+
platform: nativePlatform,
|
|
118
|
+
projectName: input.projectName
|
|
119
|
+
});
|
|
120
|
+
for (const [path, content] of Object.entries(nativeScripts)) files[path] = content;
|
|
121
|
+
}
|
|
122
|
+
const bareMetalFiles = generateBareMetalInstall({
|
|
123
|
+
platform: input.platform,
|
|
124
|
+
projectName: input.projectName,
|
|
125
|
+
hasNativeServices: nativeServices.length > 0
|
|
126
|
+
});
|
|
127
|
+
for (const [path, content] of Object.entries(bareMetalFiles)) files[path] = content;
|
|
128
|
+
}
|
|
129
|
+
const skillCount = resolved.services.reduce((sum, s) => sum + s.definition.skills.length, 0);
|
|
130
|
+
return {
|
|
131
|
+
files,
|
|
132
|
+
metadata: {
|
|
133
|
+
serviceCount: resolved.services.length,
|
|
134
|
+
skillCount,
|
|
135
|
+
estimatedMemoryMB: resolved.estimatedMemoryMB,
|
|
136
|
+
generatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
function generateServicesDoc(resolved) {
|
|
141
|
+
const lines = [
|
|
142
|
+
"# Service Reference",
|
|
143
|
+
"",
|
|
144
|
+
"This document describes all companion services in your OpenClaw stack.",
|
|
145
|
+
""
|
|
146
|
+
];
|
|
147
|
+
for (const svc of resolved.services) {
|
|
148
|
+
const def = svc.definition;
|
|
149
|
+
lines.push(`## ${def.icon} ${def.name}`);
|
|
150
|
+
lines.push("");
|
|
151
|
+
lines.push(def.description);
|
|
152
|
+
lines.push("");
|
|
153
|
+
lines.push(`- **Image**: \`${def.image}:${def.imageTag}\``);
|
|
154
|
+
lines.push(`- **Category**: ${def.category}`);
|
|
155
|
+
lines.push(`- **Maturity**: ${def.maturity}`);
|
|
156
|
+
if (def.minMemoryMB) lines.push(`- **Min Memory**: ${def.minMemoryMB}MB`);
|
|
157
|
+
if (def.ports.length > 0) {
|
|
158
|
+
lines.push("- **Ports**:");
|
|
159
|
+
for (const p of def.ports) lines.push(` - \`${p.container}\` — ${p.description}${p.exposed ? "" : " (internal only)"}`);
|
|
160
|
+
}
|
|
161
|
+
lines.push(`- **Docs**: ${def.docsUrl}`);
|
|
162
|
+
lines.push("");
|
|
163
|
+
}
|
|
164
|
+
return lines.join("\n");
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
//#endregion
|
|
168
|
+
export { generate };
|
|
169
|
+
//# sourceMappingURL=generate.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate.mjs","names":[],"sources":["../src/generate.ts"],"sourcesContent":["import {\n\tpartitionBareMetal,\n\tplatformToNativePlatform,\n\tresolvedWithOnlyServices,\n} from \"./bare-metal-partition.js\";\nimport { composeMultiFile } from \"./composer.js\";\nimport { generateBareMetalInstall } from \"./generators/bare-metal-install.js\";\nimport { generateCaddyfile } from \"./generators/caddy.js\";\nimport { generateEnvFiles } from \"./generators/env.js\";\nimport { generateGrafanaConfig, generateGrafanaDashboard } from \"./generators/grafana.js\";\nimport { generateN8nWorkflows } from \"./generators/n8n-workflows.js\";\nimport { generateNativeInstallScripts } from \"./generators/native-services.js\";\nimport { generatePostgresInit } from \"./generators/postgres-init.js\";\nimport { generatePrometheusConfig } from \"./generators/prometheus.js\";\nimport { generateReadme } from \"./generators/readme.js\";\nimport { generateScripts } from \"./generators/scripts.js\";\nimport { generateSkillFiles } from \"./generators/skills.js\";\nimport { resolve } from \"./resolver.js\";\nimport type {\n\tGeneratedFiles,\n\tGenerationInput,\n\tGenerationResult,\n\tPlatform,\n\tResolverInput,\n} from \"./types.js\";\nimport { validate } from \"./validator.js\";\n\n/** Resolver/compose only support linux image platforms; normalize for bare-metal (windows/macos). */\nfunction getComposePlatform(platform: Platform): \"linux/amd64\" | \"linux/arm64\" {\n\tif (platform === \"linux/amd64\" || platform === \"linux/arm64\") return platform;\n\treturn \"linux/amd64\";\n}\n\n/**\n * Main orchestration function: takes generation input, resolves dependencies,\n * generates all files, validates, and returns the complete file tree.\n */\nexport function generate(input: GenerationInput): GenerationResult {\n\tconst composePlatform = getComposePlatform(input.platform);\n\n\t// 1. Resolve dependencies\n\tconst resolverInput: ResolverInput = {\n\t\tservices: input.services,\n\t\tskillPacks: input.skillPacks,\n\t\tproxy: input.proxy,\n\t\tgpu: input.gpu,\n\t\tplatform: composePlatform,\n\t\tmonitoring: input.monitoring,\n\t};\n\tconst resolved = resolve(resolverInput);\n\n\tif (!resolved.isValid) {\n\t\tthrow new Error(\n\t\t\t`Invalid stack configuration: ${resolved.errors.map((e) => e.message).join(\"; \")}`,\n\t\t);\n\t}\n\n\tconst isBareMetal = input.deploymentType === \"bare-metal\";\n\tlet resolvedForCompose = resolved;\n\tlet nativeIds = new Set<string>();\n\tlet nativeServices: typeof resolved.services = [];\n\tlet dockerOnlyServices: typeof resolved.services = [];\n\n\tif (isBareMetal) {\n\t\tconst partition = partitionBareMetal(resolved, input.platform);\n\t\tnativeServices = partition.nativeServices;\n\t\tdockerOnlyServices = partition.dockerOnlyServices;\n\t\tnativeIds = partition.nativeIds;\n\t\tif (nativeServices.length > 0) {\n\t\t\tresolvedForCompose = resolvedWithOnlyServices(resolved, dockerOnlyServices);\n\t\t}\n\t}\n\n\t// 2. Generate Docker Compose YAML (multi-file)\n\tconst composeOptions = {\n\t\tprojectName: input.projectName,\n\t\tproxy: input.proxy,\n\t\tdomain: input.domain,\n\t\tgpu: input.gpu,\n\t\tplatform: composePlatform,\n\t\tdeployment: input.deployment,\n\t\topenclawVersion: input.openclawVersion,\n\t\tbareMetalNativeHost: isBareMetal && nativeIds.size > 0,\n\t};\n\tconst composeResult = composeMultiFile(resolvedForCompose, composeOptions);\n\n\t// 3. Validate (using the base docker-compose.yml)\n\tconst validation = validate(resolvedForCompose, composeResult.files[\"docker-compose.yml\"] ?? \"\", {\n\t\tdomain: input.domain,\n\t\tgenerateSecrets: input.generateSecrets,\n\t});\n\tif (!validation.valid) {\n\t\tthrow new Error(`Validation failed: ${validation.errors.map((e) => e.message).join(\"; \")}`);\n\t}\n\n\t// 4. Generate all files\n\tconst files: GeneratedFiles = {};\n\n\t// Docker Compose (multi-file output)\n\tfor (const [filename, content] of Object.entries(composeResult.files)) {\n\t\tfiles[filename] = content;\n\t}\n\n\t// Environment files (when bare-metal with native services, host vars use host.docker.internal)\n\tconst envFiles = generateEnvFiles(resolved, {\n\t\tgenerateSecrets: input.generateSecrets,\n\t\tdomain: input.domain,\n\t\topenclawVersion: input.openclawVersion,\n\t\tnativeServiceIds: isBareMetal ? nativeIds : undefined,\n\t});\n\tfiles[\".env.example\"] = envFiles.envExample;\n\tfiles[\".env\"] = envFiles.env;\n\n\t// .gitignore\n\tfiles[\".gitignore\"] = [\n\t\t\".env\",\n\t\t\".env.local\",\n\t\t\".env.*.local\",\n\t\t\"*.log\",\n\t\t\"docker-compose.override.yml\",\n\t].join(\"\\n\");\n\n\t// Skills\n\tconst skillFiles = generateSkillFiles(resolved);\n\tfor (const [path, content] of Object.entries(skillFiles)) {\n\t\tfiles[path] = content;\n\t}\n\n\t// README\n\tfiles[\"README.md\"] = generateReadme(resolved, {\n\t\tprojectName: input.projectName,\n\t\tdomain: input.domain,\n\t\tproxy: input.proxy,\n\t\tdeploymentType: input.deploymentType,\n\t\thasNativeServices: isBareMetal && nativeServices.length > 0,\n\t});\n\n\t// Scripts\n\tconst scripts = generateScripts();\n\tfor (const [path, content] of Object.entries(scripts)) {\n\t\tfiles[path] = content;\n\t}\n\n\t// n8n workflows\n\tconst n8nWorkflows = generateN8nWorkflows(resolved);\n\tfor (const [path, content] of Object.entries(n8nWorkflows)) {\n\t\tfiles[path] = content;\n\t}\n\n\t// PostgreSQL init script (creates per-service databases and users)\n\tconst postgresInit = generatePostgresInit(resolved);\n\tif (postgresInit) {\n\t\tfiles[\"postgres/init-databases.sh\"] = postgresInit;\n\t}\n\n\t// Caddy config\n\tif (input.proxy === \"caddy\" && input.domain) {\n\t\tfiles[\"caddy/Caddyfile\"] = generateCaddyfile(resolved, input.domain);\n\t}\n\n\t// Prometheus config\n\tconst hasPrometheus = resolved.services.some((s) => s.definition.id === \"prometheus\");\n\tif (hasPrometheus) {\n\t\tfiles[\"prometheus/prometheus.yml\"] = generatePrometheusConfig(resolved);\n\t}\n\n\t// Grafana config\n\tconst hasGrafana = resolved.services.some((s) => s.definition.id === \"grafana\");\n\tif (hasGrafana) {\n\t\tconst grafanaFiles = generateGrafanaConfig();\n\t\tfor (const [path, content] of Object.entries(grafanaFiles)) {\n\t\t\tfiles[path] = content;\n\t\t}\n\t\t// Grafana dashboard\n\t\tfiles[\"config/grafana/dashboards/openclaw-stack-overview.json\"] = generateGrafanaDashboard();\n\t}\n\n\t// Docker Compose override (empty template)\n\tfiles[\"docker-compose.override.yml\"] = [\n\t\t\"# Local overrides for docker-compose.yml\",\n\t\t\"# This file is gitignored — use it for personal port changes, extra volumes, etc.\",\n\t\t\"services: {}\",\n\t\t\"\",\n\t].join(\"\\n\");\n\n\t// SERVICES.md documentation\n\tfiles[\"docs/SERVICES.md\"] = generateServicesDoc(resolved);\n\n\t// Bare-metal: native install scripts + top-level installer\n\tif (isBareMetal) {\n\t\tif (nativeServices.length > 0) {\n\t\t\tconst nativePlatform = platformToNativePlatform(input.platform);\n\t\t\tconst nativeScripts = generateNativeInstallScripts({\n\t\t\t\tnativeServices,\n\t\t\t\tplatform: nativePlatform,\n\t\t\t\tprojectName: input.projectName,\n\t\t\t});\n\t\t\tfor (const [path, content] of Object.entries(nativeScripts)) {\n\t\t\t\tfiles[path] = content;\n\t\t\t}\n\t\t}\n\t\tconst bareMetalFiles = generateBareMetalInstall({\n\t\t\tplatform: input.platform,\n\t\t\tprojectName: input.projectName,\n\t\t\thasNativeServices: nativeServices.length > 0,\n\t\t});\n\t\tfor (const [path, content] of Object.entries(bareMetalFiles)) {\n\t\t\tfiles[path] = content;\n\t\t}\n\t}\n\n\t// 5. Calculate metadata\n\tconst skillCount = resolved.services.reduce((sum, s) => sum + s.definition.skills.length, 0);\n\n\treturn {\n\t\tfiles,\n\t\tmetadata: {\n\t\t\tserviceCount: resolved.services.length,\n\t\t\tskillCount,\n\t\t\testimatedMemoryMB: resolved.estimatedMemoryMB,\n\t\t\tgeneratedAt: new Date().toISOString(),\n\t\t},\n\t};\n}\n\nfunction generateServicesDoc(resolved: import(\"./types.js\").ResolverOutput): string {\n\tconst lines: string[] = [\n\t\t\"# Service Reference\",\n\t\t\"\",\n\t\t\"This document describes all companion services in your OpenClaw stack.\",\n\t\t\"\",\n\t];\n\n\tfor (const svc of resolved.services) {\n\t\tconst def = svc.definition;\n\t\tlines.push(`## ${def.icon} ${def.name}`);\n\t\tlines.push(\"\");\n\t\tlines.push(def.description);\n\t\tlines.push(\"\");\n\t\tlines.push(`- **Image**: \\`${def.image}:${def.imageTag}\\``);\n\t\tlines.push(`- **Category**: ${def.category}`);\n\t\tlines.push(`- **Maturity**: ${def.maturity}`);\n\t\tif (def.minMemoryMB) {\n\t\t\tlines.push(`- **Min Memory**: ${def.minMemoryMB}MB`);\n\t\t}\n\t\tif (def.ports.length > 0) {\n\t\t\tlines.push(\"- **Ports**:\");\n\t\t\tfor (const p of def.ports) {\n\t\t\t\tlines.push(\n\t\t\t\t\t` - \\`${p.container}\\` — ${p.description}${p.exposed ? \"\" : \" (internal only)\"}`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\tlines.push(`- **Docs**: ${def.docsUrl}`);\n\t\tlines.push(\"\");\n\t}\n\n\treturn lines.join(\"\\n\");\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|