@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.
Files changed (414) hide show
  1. package/.github/workflows/publish-core.yml +32 -34
  2. package/dist/bare-metal-partition.d.mts +26 -0
  3. package/dist/bare-metal-partition.d.mts.map +1 -0
  4. package/dist/bare-metal-partition.mjs +48 -0
  5. package/dist/bare-metal-partition.mjs.map +1 -0
  6. package/dist/bare-metal-partition.test.d.mts +1 -0
  7. package/dist/bare-metal-partition.test.mjs +58 -0
  8. package/dist/bare-metal-partition.test.mjs.map +1 -0
  9. package/dist/composer.d.mts +21 -0
  10. package/dist/composer.d.mts.map +1 -0
  11. package/dist/composer.mjs +287 -0
  12. package/dist/composer.mjs.map +1 -0
  13. package/dist/composer.snapshot.test.d.mts +1 -0
  14. package/dist/composer.snapshot.test.mjs +92 -0
  15. package/dist/composer.snapshot.test.mjs.map +1 -0
  16. package/dist/composer.test.d.mts +1 -0
  17. package/dist/composer.test.mjs +166 -0
  18. package/dist/composer.test.mjs.map +1 -0
  19. package/dist/generate.d.mts +11 -0
  20. package/dist/generate.d.mts.map +1 -0
  21. package/dist/generate.mjs +169 -0
  22. package/dist/generate.mjs.map +1 -0
  23. package/dist/generate.test.d.mts +1 -0
  24. package/dist/generate.test.mjs +283 -0
  25. package/dist/generate.test.mjs.map +1 -0
  26. package/dist/generators/bare-metal-install.d.mts +17 -0
  27. package/dist/generators/bare-metal-install.d.mts.map +1 -0
  28. package/dist/generators/bare-metal-install.mjs +224 -0
  29. package/dist/generators/bare-metal-install.mjs.map +1 -0
  30. package/dist/generators/bare-metal-install.test.d.mts +1 -0
  31. package/dist/generators/bare-metal-install.test.mjs +48 -0
  32. package/dist/generators/bare-metal-install.test.mjs.map +1 -0
  33. package/dist/generators/caddy.d.mts +17 -0
  34. package/dist/generators/caddy.d.mts.map +1 -0
  35. package/dist/generators/caddy.mjs +77 -0
  36. package/dist/generators/caddy.mjs.map +1 -0
  37. package/dist/generators/env.d.mts +46 -0
  38. package/dist/generators/env.d.mts.map +1 -0
  39. package/dist/generators/env.mjs +250 -0
  40. package/dist/generators/env.mjs.map +1 -0
  41. package/dist/generators/grafana.d.mts +22 -0
  42. package/dist/generators/grafana.d.mts.map +1 -0
  43. package/dist/generators/grafana.mjs +293 -0
  44. package/dist/generators/grafana.mjs.map +1 -0
  45. package/dist/generators/n8n-workflows.d.mts +11 -0
  46. package/dist/generators/n8n-workflows.d.mts.map +1 -0
  47. package/dist/generators/n8n-workflows.mjs +75 -0
  48. package/dist/generators/n8n-workflows.mjs.map +1 -0
  49. package/dist/generators/native-services.d.mts +17 -0
  50. package/dist/generators/native-services.d.mts.map +1 -0
  51. package/dist/generators/native-services.mjs +78 -0
  52. package/dist/generators/native-services.mjs.map +1 -0
  53. package/dist/generators/postgres-init.d.mts +30 -0
  54. package/dist/generators/postgres-init.d.mts.map +1 -0
  55. package/dist/generators/postgres-init.mjs +151 -0
  56. package/dist/generators/postgres-init.mjs.map +1 -0
  57. package/dist/generators/prometheus.d.mts +14 -0
  58. package/dist/generators/prometheus.d.mts.map +1 -0
  59. package/dist/generators/prometheus.mjs +107 -0
  60. package/dist/generators/prometheus.mjs.map +1 -0
  61. package/dist/generators/readme.d.mts +25 -0
  62. package/dist/generators/readme.d.mts.map +1 -0
  63. package/dist/generators/readme.mjs +199 -0
  64. package/dist/generators/readme.mjs.map +1 -0
  65. package/dist/generators/scripts.d.mts +10 -0
  66. package/dist/generators/scripts.d.mts.map +1 -0
  67. package/dist/generators/scripts.mjs +351 -0
  68. package/dist/generators/scripts.mjs.map +1 -0
  69. package/dist/generators/skills.d.mts +14 -0
  70. package/dist/generators/skills.d.mts.map +1 -0
  71. package/dist/generators/skills.mjs +587 -0
  72. package/dist/generators/skills.mjs.map +1 -0
  73. package/dist/index.d.mts +21 -0
  74. package/dist/index.mjs +22 -0
  75. package/dist/magic-string.es-1uTtupLe.mjs +1014 -0
  76. package/dist/magic-string.es-1uTtupLe.mjs.map +1 -0
  77. package/dist/presets/registry.d.mts +9 -0
  78. package/dist/presets/registry.d.mts.map +1 -0
  79. package/dist/presets/registry.mjs +159 -0
  80. package/dist/presets/registry.mjs.map +1 -0
  81. package/dist/presets/registry.test.d.mts +1 -0
  82. package/dist/presets/registry.test.mjs +34 -0
  83. package/dist/presets/registry.test.mjs.map +1 -0
  84. package/dist/resolver.d.mts +21 -0
  85. package/dist/resolver.d.mts.map +1 -0
  86. package/dist/resolver.mjs +194 -0
  87. package/dist/resolver.mjs.map +1 -0
  88. package/dist/resolver.test.d.mts +1 -0
  89. package/dist/resolver.test.mjs +237 -0
  90. package/dist/resolver.test.mjs.map +1 -0
  91. package/dist/schema.d.mts +706 -0
  92. package/dist/schema.d.mts.map +1 -0
  93. package/dist/schema.mjs +260 -0
  94. package/dist/schema.mjs.map +1 -0
  95. package/dist/schema.test.d.mts +1 -0
  96. package/dist/schema.test.mjs +264 -0
  97. package/dist/schema.test.mjs.map +1 -0
  98. package/dist/services/definitions/anything-llm.d.mts +7 -0
  99. package/dist/services/definitions/anything-llm.d.mts.map +1 -0
  100. package/dist/services/definitions/anything-llm.mjs +44 -0
  101. package/dist/services/definitions/anything-llm.mjs.map +1 -0
  102. package/dist/services/definitions/appflowy.d.mts +7 -0
  103. package/dist/services/definitions/appflowy.d.mts.map +1 -0
  104. package/dist/services/definitions/appflowy.mjs +45 -0
  105. package/dist/services/definitions/appflowy.mjs.map +1 -0
  106. package/dist/services/definitions/beszel.d.mts +7 -0
  107. package/dist/services/definitions/beszel.d.mts.map +1 -0
  108. package/dist/services/definitions/beszel.mjs +45 -0
  109. package/dist/services/definitions/beszel.mjs.map +1 -0
  110. package/dist/services/definitions/browserless.d.mts +7 -0
  111. package/dist/services/definitions/browserless.d.mts.map +1 -0
  112. package/dist/services/definitions/browserless.mjs +85 -0
  113. package/dist/services/definitions/browserless.mjs.map +1 -0
  114. package/dist/services/definitions/caddy.d.mts +7 -0
  115. package/dist/services/definitions/caddy.d.mts.map +1 -0
  116. package/dist/services/definitions/caddy.mjs +52 -0
  117. package/dist/services/definitions/caddy.mjs.map +1 -0
  118. package/dist/services/definitions/chromadb.d.mts +7 -0
  119. package/dist/services/definitions/chromadb.d.mts.map +1 -0
  120. package/dist/services/definitions/chromadb.mjs +63 -0
  121. package/dist/services/definitions/chromadb.mjs.map +1 -0
  122. package/dist/services/definitions/claude-code.d.mts +7 -0
  123. package/dist/services/definitions/claude-code.d.mts.map +1 -0
  124. package/dist/services/definitions/claude-code.mjs +52 -0
  125. package/dist/services/definitions/claude-code.mjs.map +1 -0
  126. package/dist/services/definitions/code-server.d.mts +7 -0
  127. package/dist/services/definitions/code-server.d.mts.map +1 -0
  128. package/dist/services/definitions/code-server.mjs +66 -0
  129. package/dist/services/definitions/code-server.mjs.map +1 -0
  130. package/dist/services/definitions/codex.d.mts +7 -0
  131. package/dist/services/definitions/codex.d.mts.map +1 -0
  132. package/dist/services/definitions/codex.mjs +45 -0
  133. package/dist/services/definitions/codex.mjs.map +1 -0
  134. package/dist/services/definitions/convex-dashboard.d.mts +7 -0
  135. package/dist/services/definitions/convex-dashboard.d.mts.map +1 -0
  136. package/dist/services/definitions/convex-dashboard.mjs +46 -0
  137. package/dist/services/definitions/convex-dashboard.mjs.map +1 -0
  138. package/dist/services/definitions/convex.d.mts +7 -0
  139. package/dist/services/definitions/convex.d.mts.map +1 -0
  140. package/dist/services/definitions/convex.mjs +118 -0
  141. package/dist/services/definitions/convex.mjs.map +1 -0
  142. package/dist/services/definitions/coolify.d.mts +7 -0
  143. package/dist/services/definitions/coolify.d.mts.map +1 -0
  144. package/dist/services/definitions/coolify.mjs +49 -0
  145. package/dist/services/definitions/coolify.mjs.map +1 -0
  146. package/dist/services/definitions/dify.d.mts +7 -0
  147. package/dist/services/definitions/dify.d.mts.map +1 -0
  148. package/dist/services/definitions/dify.mjs +81 -0
  149. package/dist/services/definitions/dify.mjs.map +1 -0
  150. package/dist/services/definitions/docsgpt.d.mts +7 -0
  151. package/dist/services/definitions/docsgpt.d.mts.map +1 -0
  152. package/dist/services/definitions/docsgpt.mjs +45 -0
  153. package/dist/services/definitions/docsgpt.mjs.map +1 -0
  154. package/dist/services/definitions/dokploy.d.mts +7 -0
  155. package/dist/services/definitions/dokploy.d.mts.map +1 -0
  156. package/dist/services/definitions/dokploy.mjs +49 -0
  157. package/dist/services/definitions/dokploy.mjs.map +1 -0
  158. package/dist/services/definitions/dozzle.d.mts +7 -0
  159. package/dist/services/definitions/dozzle.d.mts.map +1 -0
  160. package/dist/services/definitions/dozzle.mjs +41 -0
  161. package/dist/services/definitions/dozzle.mjs.map +1 -0
  162. package/dist/services/definitions/ffmpeg.d.mts +7 -0
  163. package/dist/services/definitions/ffmpeg.d.mts.map +1 -0
  164. package/dist/services/definitions/ffmpeg.mjs +66 -0
  165. package/dist/services/definitions/ffmpeg.mjs.map +1 -0
  166. package/dist/services/definitions/flowise.d.mts +7 -0
  167. package/dist/services/definitions/flowise.d.mts.map +1 -0
  168. package/dist/services/definitions/flowise.mjs +45 -0
  169. package/dist/services/definitions/flowise.mjs.map +1 -0
  170. package/dist/services/definitions/gemini-cli.d.mts +7 -0
  171. package/dist/services/definitions/gemini-cli.d.mts.map +1 -0
  172. package/dist/services/definitions/gemini-cli.mjs +46 -0
  173. package/dist/services/definitions/gemini-cli.mjs.map +1 -0
  174. package/dist/services/definitions/gitea.d.mts +7 -0
  175. package/dist/services/definitions/gitea.d.mts.map +1 -0
  176. package/dist/services/definitions/gitea.mjs +49 -0
  177. package/dist/services/definitions/gitea.mjs.map +1 -0
  178. package/dist/services/definitions/gotify.d.mts +7 -0
  179. package/dist/services/definitions/gotify.d.mts.map +1 -0
  180. package/dist/services/definitions/gotify.mjs +62 -0
  181. package/dist/services/definitions/gotify.mjs.map +1 -0
  182. package/dist/services/definitions/grafana.d.mts +7 -0
  183. package/dist/services/definitions/grafana.d.mts.map +1 -0
  184. package/dist/services/definitions/grafana.mjs +63 -0
  185. package/dist/services/definitions/grafana.mjs.map +1 -0
  186. package/dist/services/definitions/index.d.mts +76 -0
  187. package/dist/services/definitions/index.d.mts.map +1 -0
  188. package/dist/services/definitions/index.mjs +146 -0
  189. package/dist/services/definitions/index.mjs.map +1 -0
  190. package/dist/services/definitions/kimi.d.mts +7 -0
  191. package/dist/services/definitions/kimi.d.mts.map +1 -0
  192. package/dist/services/definitions/kimi.mjs +46 -0
  193. package/dist/services/definitions/kimi.mjs.map +1 -0
  194. package/dist/services/definitions/lasuite-meet-agents.d.mts +7 -0
  195. package/dist/services/definitions/lasuite-meet-agents.d.mts.map +1 -0
  196. package/dist/services/definitions/lasuite-meet-agents.mjs +36 -0
  197. package/dist/services/definitions/lasuite-meet-agents.mjs.map +1 -0
  198. package/dist/services/definitions/lasuite-meet-backend.d.mts +7 -0
  199. package/dist/services/definitions/lasuite-meet-backend.d.mts.map +1 -0
  200. package/dist/services/definitions/lasuite-meet-backend.mjs +134 -0
  201. package/dist/services/definitions/lasuite-meet-backend.mjs.map +1 -0
  202. package/dist/services/definitions/lasuite-meet-frontend.d.mts +7 -0
  203. package/dist/services/definitions/lasuite-meet-frontend.d.mts.map +1 -0
  204. package/dist/services/definitions/lasuite-meet-frontend.mjs +48 -0
  205. package/dist/services/definitions/lasuite-meet-frontend.mjs.map +1 -0
  206. package/dist/services/definitions/librechat.d.mts +7 -0
  207. package/dist/services/definitions/librechat.d.mts.map +1 -0
  208. package/dist/services/definitions/librechat.mjs +50 -0
  209. package/dist/services/definitions/librechat.mjs.map +1 -0
  210. package/dist/services/definitions/lightpanda.d.mts +7 -0
  211. package/dist/services/definitions/lightpanda.d.mts.map +1 -0
  212. package/dist/services/definitions/lightpanda.mjs +59 -0
  213. package/dist/services/definitions/lightpanda.mjs.map +1 -0
  214. package/dist/services/definitions/litellm.d.mts +7 -0
  215. package/dist/services/definitions/litellm.d.mts.map +1 -0
  216. package/dist/services/definitions/litellm.mjs +47 -0
  217. package/dist/services/definitions/litellm.mjs.map +1 -0
  218. package/dist/services/definitions/livekit.d.mts +7 -0
  219. package/dist/services/definitions/livekit.d.mts.map +1 -0
  220. package/dist/services/definitions/livekit.mjs +56 -0
  221. package/dist/services/definitions/livekit.mjs.map +1 -0
  222. package/dist/services/definitions/matomo.d.mts +7 -0
  223. package/dist/services/definitions/matomo.d.mts.map +1 -0
  224. package/dist/services/definitions/matomo.mjs +80 -0
  225. package/dist/services/definitions/matomo.mjs.map +1 -0
  226. package/dist/services/definitions/matrix-synapse.d.mts +7 -0
  227. package/dist/services/definitions/matrix-synapse.d.mts.map +1 -0
  228. package/dist/services/definitions/matrix-synapse.mjs +88 -0
  229. package/dist/services/definitions/matrix-synapse.mjs.map +1 -0
  230. package/dist/services/definitions/mattermost.d.mts +7 -0
  231. package/dist/services/definitions/mattermost.d.mts.map +1 -0
  232. package/dist/services/definitions/mattermost.mjs +61 -0
  233. package/dist/services/definitions/mattermost.mjs.map +1 -0
  234. package/dist/services/definitions/meilisearch.d.mts +7 -0
  235. package/dist/services/definitions/meilisearch.d.mts.map +1 -0
  236. package/dist/services/definitions/meilisearch.mjs +78 -0
  237. package/dist/services/definitions/meilisearch.mjs.map +1 -0
  238. package/dist/services/definitions/minio.d.mts +7 -0
  239. package/dist/services/definitions/minio.d.mts.map +1 -0
  240. package/dist/services/definitions/minio.mjs +102 -0
  241. package/dist/services/definitions/minio.mjs.map +1 -0
  242. package/dist/services/definitions/mission-control.d.mts +7 -0
  243. package/dist/services/definitions/mission-control.d.mts.map +1 -0
  244. package/dist/services/definitions/mission-control.mjs +67 -0
  245. package/dist/services/definitions/mission-control.mjs.map +1 -0
  246. package/dist/services/definitions/mixpost.d.mts +7 -0
  247. package/dist/services/definitions/mixpost.d.mts.map +1 -0
  248. package/dist/services/definitions/mixpost.mjs +87 -0
  249. package/dist/services/definitions/mixpost.mjs.map +1 -0
  250. package/dist/services/definitions/motion-canvas.d.mts +7 -0
  251. package/dist/services/definitions/motion-canvas.d.mts.map +1 -0
  252. package/dist/services/definitions/motion-canvas.mjs +52 -0
  253. package/dist/services/definitions/motion-canvas.mjs.map +1 -0
  254. package/dist/services/definitions/n8n.d.mts +7 -0
  255. package/dist/services/definitions/n8n.d.mts.map +1 -0
  256. package/dist/services/definitions/n8n.mjs +154 -0
  257. package/dist/services/definitions/n8n.mjs.map +1 -0
  258. package/dist/services/definitions/nocodb.d.mts +7 -0
  259. package/dist/services/definitions/nocodb.d.mts.map +1 -0
  260. package/dist/services/definitions/nocodb.mjs +45 -0
  261. package/dist/services/definitions/nocodb.mjs.map +1 -0
  262. package/dist/services/definitions/ntfy.d.mts +7 -0
  263. package/dist/services/definitions/ntfy.d.mts.map +1 -0
  264. package/dist/services/definitions/ntfy.mjs +63 -0
  265. package/dist/services/definitions/ntfy.mjs.map +1 -0
  266. package/dist/services/definitions/ollama.d.mts +7 -0
  267. package/dist/services/definitions/ollama.d.mts.map +1 -0
  268. package/dist/services/definitions/ollama.mjs +66 -0
  269. package/dist/services/definitions/ollama.mjs.map +1 -0
  270. package/dist/services/definitions/open-webui.d.mts +7 -0
  271. package/dist/services/definitions/open-webui.d.mts.map +1 -0
  272. package/dist/services/definitions/open-webui.mjs +50 -0
  273. package/dist/services/definitions/open-webui.mjs.map +1 -0
  274. package/dist/services/definitions/opencode.d.mts +7 -0
  275. package/dist/services/definitions/opencode.d.mts.map +1 -0
  276. package/dist/services/definitions/opencode.mjs +50 -0
  277. package/dist/services/definitions/opencode.mjs.map +1 -0
  278. package/dist/services/definitions/openpanel.d.mts +7 -0
  279. package/dist/services/definitions/openpanel.d.mts.map +1 -0
  280. package/dist/services/definitions/openpanel.mjs +46 -0
  281. package/dist/services/definitions/openpanel.mjs.map +1 -0
  282. package/dist/services/definitions/outline.d.mts +7 -0
  283. package/dist/services/definitions/outline.d.mts.map +1 -0
  284. package/dist/services/definitions/outline.mjs +74 -0
  285. package/dist/services/definitions/outline.mjs.map +1 -0
  286. package/dist/services/definitions/paperless-ngx.d.mts +7 -0
  287. package/dist/services/definitions/paperless-ngx.d.mts.map +1 -0
  288. package/dist/services/definitions/paperless-ngx.mjs +93 -0
  289. package/dist/services/definitions/paperless-ngx.mjs.map +1 -0
  290. package/dist/services/definitions/playwright-server.d.mts +7 -0
  291. package/dist/services/definitions/playwright-server.d.mts.map +1 -0
  292. package/dist/services/definitions/playwright-server.mjs +42 -0
  293. package/dist/services/definitions/playwright-server.mjs.map +1 -0
  294. package/dist/services/definitions/portainer.d.mts +7 -0
  295. package/dist/services/definitions/portainer.d.mts.map +1 -0
  296. package/dist/services/definitions/portainer.mjs +49 -0
  297. package/dist/services/definitions/portainer.mjs.map +1 -0
  298. package/dist/services/definitions/postgresql.d.mts +7 -0
  299. package/dist/services/definitions/postgresql.d.mts.map +1 -0
  300. package/dist/services/definitions/postgresql.mjs +84 -0
  301. package/dist/services/definitions/postgresql.mjs.map +1 -0
  302. package/dist/services/definitions/postiz.d.mts +7 -0
  303. package/dist/services/definitions/postiz.d.mts.map +1 -0
  304. package/dist/services/definitions/postiz.mjs +83 -0
  305. package/dist/services/definitions/postiz.mjs.map +1 -0
  306. package/dist/services/definitions/prometheus.d.mts +7 -0
  307. package/dist/services/definitions/prometheus.d.mts.map +1 -0
  308. package/dist/services/definitions/prometheus.mjs +52 -0
  309. package/dist/services/definitions/prometheus.mjs.map +1 -0
  310. package/dist/services/definitions/qdrant.d.mts +7 -0
  311. package/dist/services/definitions/qdrant.d.mts.map +1 -0
  312. package/dist/services/definitions/qdrant.mjs +77 -0
  313. package/dist/services/definitions/qdrant.mjs.map +1 -0
  314. package/dist/services/definitions/redis.d.mts +7 -0
  315. package/dist/services/definitions/redis.d.mts.map +1 -0
  316. package/dist/services/definitions/redis.mjs +91 -0
  317. package/dist/services/definitions/redis.mjs.map +1 -0
  318. package/dist/services/definitions/remotion.d.mts +7 -0
  319. package/dist/services/definitions/remotion.d.mts.map +1 -0
  320. package/dist/services/definitions/remotion.mjs +55 -0
  321. package/dist/services/definitions/remotion.mjs.map +1 -0
  322. package/dist/services/definitions/rocketchat.d.mts +7 -0
  323. package/dist/services/definitions/rocketchat.d.mts.map +1 -0
  324. package/dist/services/definitions/rocketchat.mjs +57 -0
  325. package/dist/services/definitions/rocketchat.mjs.map +1 -0
  326. package/dist/services/definitions/searxng.d.mts +7 -0
  327. package/dist/services/definitions/searxng.d.mts.map +1 -0
  328. package/dist/services/definitions/searxng.mjs +65 -0
  329. package/dist/services/definitions/searxng.mjs.map +1 -0
  330. package/dist/services/definitions/stable-diffusion.d.mts +7 -0
  331. package/dist/services/definitions/stable-diffusion.d.mts.map +1 -0
  332. package/dist/services/definitions/stable-diffusion.mjs +48 -0
  333. package/dist/services/definitions/stable-diffusion.mjs.map +1 -0
  334. package/dist/services/definitions/steel-browser.d.mts +7 -0
  335. package/dist/services/definitions/steel-browser.d.mts.map +1 -0
  336. package/dist/services/definitions/steel-browser.mjs +77 -0
  337. package/dist/services/definitions/steel-browser.mjs.map +1 -0
  338. package/dist/services/definitions/tailscale.d.mts +7 -0
  339. package/dist/services/definitions/tailscale.d.mts.map +1 -0
  340. package/dist/services/definitions/tailscale.mjs +70 -0
  341. package/dist/services/definitions/tailscale.mjs.map +1 -0
  342. package/dist/services/definitions/temporal.d.mts +7 -0
  343. package/dist/services/definitions/temporal.d.mts.map +1 -0
  344. package/dist/services/definitions/temporal.mjs +100 -0
  345. package/dist/services/definitions/temporal.mjs.map +1 -0
  346. package/dist/services/definitions/traefik.d.mts +7 -0
  347. package/dist/services/definitions/traefik.d.mts.map +1 -0
  348. package/dist/services/definitions/traefik.mjs +58 -0
  349. package/dist/services/definitions/traefik.mjs.map +1 -0
  350. package/dist/services/definitions/umami.d.mts +7 -0
  351. package/dist/services/definitions/umami.d.mts.map +1 -0
  352. package/dist/services/definitions/umami.mjs +46 -0
  353. package/dist/services/definitions/umami.mjs.map +1 -0
  354. package/dist/services/definitions/uptime-kuma.d.mts +7 -0
  355. package/dist/services/definitions/uptime-kuma.d.mts.map +1 -0
  356. package/dist/services/definitions/uptime-kuma.mjs +51 -0
  357. package/dist/services/definitions/uptime-kuma.mjs.map +1 -0
  358. package/dist/services/definitions/usesend.d.mts +7 -0
  359. package/dist/services/definitions/usesend.d.mts.map +1 -0
  360. package/dist/services/definitions/usesend.mjs +99 -0
  361. package/dist/services/definitions/usesend.mjs.map +1 -0
  362. package/dist/services/definitions/valkey.d.mts +7 -0
  363. package/dist/services/definitions/valkey.d.mts.map +1 -0
  364. package/dist/services/definitions/valkey.mjs +61 -0
  365. package/dist/services/definitions/valkey.mjs.map +1 -0
  366. package/dist/services/definitions/watchtower.d.mts +7 -0
  367. package/dist/services/definitions/watchtower.d.mts.map +1 -0
  368. package/dist/services/definitions/watchtower.mjs +47 -0
  369. package/dist/services/definitions/watchtower.mjs.map +1 -0
  370. package/dist/services/definitions/weaviate.d.mts +7 -0
  371. package/dist/services/definitions/weaviate.d.mts.map +1 -0
  372. package/dist/services/definitions/weaviate.mjs +90 -0
  373. package/dist/services/definitions/weaviate.mjs.map +1 -0
  374. package/dist/services/definitions/whisper.d.mts +7 -0
  375. package/dist/services/definitions/whisper.d.mts.map +1 -0
  376. package/dist/services/definitions/whisper.mjs +62 -0
  377. package/dist/services/definitions/whisper.mjs.map +1 -0
  378. package/dist/services/registry.d.mts +16 -0
  379. package/dist/services/registry.d.mts.map +1 -0
  380. package/dist/services/registry.mjs +30 -0
  381. package/dist/services/registry.mjs.map +1 -0
  382. package/dist/services/registry.test.d.mts +1 -0
  383. package/dist/services/registry.test.mjs +64 -0
  384. package/dist/services/registry.test.mjs.map +1 -0
  385. package/dist/skills/registry.d.mts +11 -0
  386. package/dist/skills/registry.d.mts.map +1 -0
  387. package/dist/skills/registry.mjs +215 -0
  388. package/dist/skills/registry.mjs.map +1 -0
  389. package/dist/types.d.mts +64 -0
  390. package/dist/types.d.mts.map +1 -0
  391. package/dist/types.mjs +92 -0
  392. package/dist/types.mjs.map +1 -0
  393. package/dist/validator.d.mts +20 -0
  394. package/dist/validator.d.mts.map +1 -0
  395. package/dist/validator.mjs +111 -0
  396. package/dist/validator.mjs.map +1 -0
  397. package/dist/validator.test.d.mts +1 -0
  398. package/dist/validator.test.mjs +65 -0
  399. package/dist/validator.test.mjs.map +1 -0
  400. package/dist/version-manager.d.mts +14 -0
  401. package/dist/version-manager.d.mts.map +1 -0
  402. package/dist/version-manager.mjs +55 -0
  403. package/dist/version-manager.mjs.map +1 -0
  404. package/dist/vi.2VT5v0um-Qk6MgAnK.mjs +12916 -0
  405. package/dist/vi.2VT5v0um-Qk6MgAnK.mjs.map +1 -0
  406. package/package.json +17 -17
  407. package/src/schema.ts +2 -1
  408. package/src/services/definitions/convex-dashboard.ts +48 -0
  409. package/src/services/definitions/convex.ts +123 -0
  410. package/src/services/definitions/index.ts +12 -0
  411. package/src/services/definitions/mission-control.ts +71 -0
  412. package/src/services/definitions/tailscale.ts +2 -0
  413. package/src/services/definitions/usesend.ts +98 -0
  414. 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":"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"}
@@ -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 { };