@better-openclaw/core 1.0.26 → 1.0.31

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1122) hide show
  1. package/README.md +67 -7
  2. package/dist/addon-stack.cjs +41 -28
  3. package/dist/addon-stack.cjs.map +1 -1
  4. package/dist/addon-stack.d.cts +1 -1
  5. package/dist/addon-stack.d.cts.map +1 -1
  6. package/dist/addon-stack.d.mts +1 -1
  7. package/dist/addon-stack.d.mts.map +1 -1
  8. package/dist/addon-stack.mjs +40 -27
  9. package/dist/addon-stack.mjs.map +1 -1
  10. package/dist/addon-stack.test.cjs +14 -14
  11. package/dist/addon-stack.test.cjs.map +1 -1
  12. package/dist/addon-stack.test.mjs +13 -13
  13. package/dist/addon-stack.test.mjs.map +1 -1
  14. package/dist/bare-metal-partition.d.cts +1 -1
  15. package/dist/bare-metal-partition.d.mts +1 -1
  16. package/dist/bare-metal-partition.test.cjs +1 -1
  17. package/dist/bare-metal-partition.test.mjs +1 -1
  18. package/dist/callback-sink-CdMKYayY.d.mts +15 -0
  19. package/dist/callback-sink-CdMKYayY.d.mts.map +1 -0
  20. package/dist/callback-sink-iNThWRnQ.d.cts +15 -0
  21. package/dist/callback-sink-iNThWRnQ.d.cts.map +1 -0
  22. package/dist/claude-code-fw-CrbAlzTM.d.mts +7 -0
  23. package/dist/claude-code-fw-CrbAlzTM.d.mts.map +1 -0
  24. package/dist/claude-code-fw-dKYH2prH.d.cts +7 -0
  25. package/dist/claude-code-fw-dKYH2prH.d.cts.map +1 -0
  26. package/dist/codex-fw-Ct8q4pzo.d.mts +7 -0
  27. package/dist/codex-fw-Ct8q4pzo.d.mts.map +1 -0
  28. package/dist/codex-fw-l7Ku8ZI8.d.cts +7 -0
  29. package/dist/codex-fw-l7Ku8ZI8.d.cts.map +1 -0
  30. package/dist/compose-validation.test.cjs +1 -1
  31. package/dist/composer.cjs +89 -129
  32. package/dist/composer.cjs.map +1 -1
  33. package/dist/composer.d.cts +3 -3
  34. package/dist/composer.d.cts.map +1 -1
  35. package/dist/composer.d.mts +3 -3
  36. package/dist/composer.d.mts.map +1 -1
  37. package/dist/composer.mjs +88 -128
  38. package/dist/composer.mjs.map +1 -1
  39. package/dist/composer.snapshot.test.cjs +1 -1
  40. package/dist/composer.snapshot.test.mjs +1 -1
  41. package/dist/composer.test.cjs +53 -2
  42. package/dist/composer.test.cjs.map +1 -1
  43. package/dist/composer.test.mjs +52 -1
  44. package/dist/composer.test.mjs.map +1 -1
  45. package/dist/console-sink-BHQpRyCt.d.cts +13 -0
  46. package/dist/console-sink-BHQpRyCt.d.cts.map +1 -0
  47. package/dist/console-sink-bouG_M1K.d.mts +13 -0
  48. package/dist/console-sink-bouG_M1K.d.mts.map +1 -0
  49. package/dist/{coolify-BVGGcMrT.d.mts → coolify-D5E0z01M.d.mts} +2 -2
  50. package/dist/{coolify-BVGGcMrT.d.mts.map → coolify-D5E0z01M.d.mts.map} +1 -1
  51. package/dist/{coolify-vlb1G9V2.d.cts → coolify-DjHecHCr.d.cts} +2 -2
  52. package/dist/{coolify-vlb1G9V2.d.cts.map → coolify-DjHecHCr.d.cts.map} +1 -1
  53. package/dist/copaw-BQyjioz7.d.cts +7 -0
  54. package/dist/copaw-BQyjioz7.d.cts.map +1 -0
  55. package/dist/copaw-C_3N7eQu.d.mts +7 -0
  56. package/dist/copaw-C_3N7eQu.d.mts.map +1 -0
  57. package/dist/deployers/coolify.cjs +25 -0
  58. package/dist/deployers/coolify.cjs.map +1 -1
  59. package/dist/deployers/coolify.d.cts +1 -1
  60. package/dist/deployers/coolify.d.mts +1 -1
  61. package/dist/deployers/coolify.mjs +25 -0
  62. package/dist/deployers/coolify.mjs.map +1 -1
  63. package/dist/deployers/coolify.test.cjs +156 -0
  64. package/dist/deployers/coolify.test.cjs.map +1 -0
  65. package/dist/deployers/coolify.test.d.cts +1 -0
  66. package/dist/deployers/coolify.test.d.mts +1 -0
  67. package/dist/deployers/coolify.test.mjs +157 -0
  68. package/dist/deployers/coolify.test.mjs.map +1 -0
  69. package/dist/deployers/dokploy.cjs +25 -0
  70. package/dist/deployers/dokploy.cjs.map +1 -1
  71. package/dist/deployers/dokploy.d.cts +1 -1
  72. package/dist/deployers/dokploy.d.mts +1 -1
  73. package/dist/deployers/dokploy.mjs +25 -0
  74. package/dist/deployers/dokploy.mjs.map +1 -1
  75. package/dist/deployers/dokploy.test.cjs +108 -0
  76. package/dist/deployers/dokploy.test.cjs.map +1 -0
  77. package/dist/deployers/dokploy.test.d.cts +1 -0
  78. package/dist/deployers/dokploy.test.d.mts +1 -0
  79. package/dist/deployers/dokploy.test.mjs +109 -0
  80. package/dist/deployers/dokploy.test.mjs.map +1 -0
  81. package/dist/deployers/index.d.cts +3 -3
  82. package/dist/deployers/index.d.mts +3 -3
  83. package/dist/deployers/strip-host-ports.cjs +1 -1
  84. package/dist/deployers/strip-host-ports.test.cjs +1 -1
  85. package/dist/deployers/strip-host-ports.test.mjs +1 -1
  86. package/dist/deployers/types.d.cts +1 -1
  87. package/dist/deployers/types.d.mts +1 -1
  88. package/dist/{dokploy-8cbrxUun.d.cts → dokploy-BnVDjWCV.d.cts} +2 -2
  89. package/dist/{dokploy-8cbrxUun.d.cts.map → dokploy-BnVDjWCV.d.cts.map} +1 -1
  90. package/dist/{dokploy-BTflLhTM.d.mts → dokploy-BqLdCfyR.d.mts} +2 -2
  91. package/dist/{dokploy-BTflLhTM.d.mts.map → dokploy-BqLdCfyR.d.mts.map} +1 -1
  92. package/dist/frameworks/claude-code-fw.cjs +79 -0
  93. package/dist/frameworks/claude-code-fw.cjs.map +1 -0
  94. package/dist/frameworks/claude-code-fw.d.cts +2 -0
  95. package/dist/frameworks/claude-code-fw.d.mts +2 -0
  96. package/dist/frameworks/claude-code-fw.mjs +78 -0
  97. package/dist/frameworks/claude-code-fw.mjs.map +1 -0
  98. package/dist/frameworks/codex-fw.cjs +67 -0
  99. package/dist/frameworks/codex-fw.cjs.map +1 -0
  100. package/dist/frameworks/codex-fw.d.cts +2 -0
  101. package/dist/frameworks/codex-fw.d.mts +2 -0
  102. package/dist/frameworks/codex-fw.mjs +66 -0
  103. package/dist/frameworks/codex-fw.mjs.map +1 -0
  104. package/dist/frameworks/copaw.cjs +118 -0
  105. package/dist/frameworks/copaw.cjs.map +1 -0
  106. package/dist/frameworks/copaw.d.cts +2 -0
  107. package/dist/frameworks/copaw.d.mts +2 -0
  108. package/dist/frameworks/copaw.mjs +117 -0
  109. package/dist/frameworks/copaw.mjs.map +1 -0
  110. package/dist/frameworks/frameworks.test.cjs +94 -0
  111. package/dist/frameworks/frameworks.test.cjs.map +1 -0
  112. package/dist/frameworks/frameworks.test.d.cts +1 -0
  113. package/dist/frameworks/frameworks.test.d.mts +1 -0
  114. package/dist/frameworks/frameworks.test.mjs +94 -0
  115. package/dist/frameworks/frameworks.test.mjs.map +1 -0
  116. package/dist/frameworks/index.cjs +35 -0
  117. package/dist/frameworks/index.cjs.map +1 -0
  118. package/dist/frameworks/index.d.cts +11 -0
  119. package/dist/frameworks/index.d.mts +11 -0
  120. package/dist/frameworks/index.mjs +22 -0
  121. package/dist/frameworks/index.mjs.map +1 -0
  122. package/dist/frameworks/memu.cjs +118 -0
  123. package/dist/frameworks/memu.cjs.map +1 -0
  124. package/dist/frameworks/memu.d.cts +2 -0
  125. package/dist/frameworks/memu.d.mts +2 -0
  126. package/dist/frameworks/memu.mjs +117 -0
  127. package/dist/frameworks/memu.mjs.map +1 -0
  128. package/dist/frameworks/nanobot.cjs +126 -0
  129. package/dist/frameworks/nanobot.cjs.map +1 -0
  130. package/dist/frameworks/nanobot.d.cts +2 -0
  131. package/dist/frameworks/nanobot.d.mts +2 -0
  132. package/dist/frameworks/nanobot.mjs +125 -0
  133. package/dist/frameworks/nanobot.mjs.map +1 -0
  134. package/dist/frameworks/nanoclaw.cjs +99 -0
  135. package/dist/frameworks/nanoclaw.cjs.map +1 -0
  136. package/dist/frameworks/nanoclaw.d.cts +2 -0
  137. package/dist/frameworks/nanoclaw.d.mts +2 -0
  138. package/dist/frameworks/nanoclaw.mjs +98 -0
  139. package/dist/frameworks/nanoclaw.mjs.map +1 -0
  140. package/dist/frameworks/openclaw.cjs +253 -0
  141. package/dist/frameworks/openclaw.cjs.map +1 -0
  142. package/dist/frameworks/openclaw.d.cts +2 -0
  143. package/dist/frameworks/openclaw.d.mts +2 -0
  144. package/dist/frameworks/openclaw.mjs +251 -0
  145. package/dist/frameworks/openclaw.mjs.map +1 -0
  146. package/dist/frameworks/registry.cjs +31 -0
  147. package/dist/frameworks/registry.cjs.map +1 -0
  148. package/dist/frameworks/registry.d.cts +2 -0
  149. package/dist/frameworks/registry.d.mts +2 -0
  150. package/dist/frameworks/registry.mjs +26 -0
  151. package/dist/frameworks/registry.mjs.map +1 -0
  152. package/dist/frameworks/registry.test.cjs +110 -0
  153. package/dist/frameworks/registry.test.cjs.map +1 -0
  154. package/dist/frameworks/registry.test.d.cts +1 -0
  155. package/dist/frameworks/registry.test.d.mts +1 -0
  156. package/dist/frameworks/registry.test.mjs +111 -0
  157. package/dist/frameworks/registry.test.mjs.map +1 -0
  158. package/dist/frameworks/types.cjs +0 -0
  159. package/dist/frameworks/types.d.cts +2 -0
  160. package/dist/frameworks/types.d.mts +2 -0
  161. package/dist/frameworks/types.mjs +1 -0
  162. package/dist/frameworks/zeroclaw.cjs +123 -0
  163. package/dist/frameworks/zeroclaw.cjs.map +1 -0
  164. package/dist/frameworks/zeroclaw.d.cts +2 -0
  165. package/dist/frameworks/zeroclaw.d.mts +2 -0
  166. package/dist/frameworks/zeroclaw.mjs +122 -0
  167. package/dist/frameworks/zeroclaw.mjs.map +1 -0
  168. package/dist/generate.cjs +64 -13
  169. package/dist/generate.cjs.map +1 -1
  170. package/dist/generate.d.cts +5 -2
  171. package/dist/generate.d.cts.map +1 -1
  172. package/dist/generate.d.mts +5 -2
  173. package/dist/generate.d.mts.map +1 -1
  174. package/dist/generate.mjs +63 -12
  175. package/dist/generate.mjs.map +1 -1
  176. package/dist/generate.test.cjs +42 -6
  177. package/dist/generate.test.cjs.map +1 -1
  178. package/dist/generate.test.mjs +41 -5
  179. package/dist/generate.test.mjs.map +1 -1
  180. package/dist/generators/bare-metal-install.d.cts +1 -1
  181. package/dist/generators/bare-metal-install.d.mts +1 -1
  182. package/dist/generators/bare-metal-install.test.cjs +1 -1
  183. package/dist/generators/bare-metal-install.test.mjs +1 -1
  184. package/dist/generators/caddy.cjs +9 -3
  185. package/dist/generators/caddy.cjs.map +1 -1
  186. package/dist/generators/caddy.d.cts +1 -1
  187. package/dist/generators/caddy.d.mts +1 -1
  188. package/dist/generators/caddy.mjs +9 -3
  189. package/dist/generators/caddy.mjs.map +1 -1
  190. package/dist/generators/caddy.test.cjs +30 -2
  191. package/dist/generators/caddy.test.cjs.map +1 -1
  192. package/dist/generators/caddy.test.mjs +30 -2
  193. package/dist/generators/caddy.test.mjs.map +1 -1
  194. package/dist/generators/clone-repos.cjs.map +1 -1
  195. package/dist/generators/clone-repos.d.cts +1 -1
  196. package/dist/generators/clone-repos.d.mts +1 -1
  197. package/dist/generators/clone-repos.mjs.map +1 -1
  198. package/dist/generators/clone-repos.test.cjs +1 -1
  199. package/dist/generators/clone-repos.test.cjs.map +1 -1
  200. package/dist/generators/clone-repos.test.mjs +1 -1
  201. package/dist/generators/clone-repos.test.mjs.map +1 -1
  202. package/dist/generators/cloud-init.test.cjs +58 -0
  203. package/dist/generators/cloud-init.test.cjs.map +1 -0
  204. package/dist/generators/cloud-init.test.d.cts +1 -0
  205. package/dist/generators/cloud-init.test.d.mts +1 -0
  206. package/dist/generators/cloud-init.test.mjs +59 -0
  207. package/dist/generators/cloud-init.test.mjs.map +1 -0
  208. package/dist/generators/env.cjs +28 -103
  209. package/dist/generators/env.cjs.map +1 -1
  210. package/dist/generators/env.d.cts +4 -1
  211. package/dist/generators/env.d.cts.map +1 -1
  212. package/dist/generators/env.d.mts +4 -1
  213. package/dist/generators/env.d.mts.map +1 -1
  214. package/dist/generators/env.mjs +27 -102
  215. package/dist/generators/env.mjs.map +1 -1
  216. package/dist/generators/env.test.cjs +3 -3
  217. package/dist/generators/env.test.cjs.map +1 -1
  218. package/dist/generators/env.test.mjs +3 -3
  219. package/dist/generators/env.test.mjs.map +1 -1
  220. package/dist/generators/get-shit-done.d.cts +1 -1
  221. package/dist/generators/get-shit-done.d.mts +1 -1
  222. package/dist/generators/get-shit-done.test.cjs +48 -0
  223. package/dist/generators/get-shit-done.test.cjs.map +1 -0
  224. package/dist/generators/get-shit-done.test.d.cts +1 -0
  225. package/dist/generators/get-shit-done.test.d.mts +1 -0
  226. package/dist/generators/get-shit-done.test.mjs +49 -0
  227. package/dist/generators/get-shit-done.test.mjs.map +1 -0
  228. package/dist/generators/grafana.test.cjs +74 -0
  229. package/dist/generators/grafana.test.cjs.map +1 -0
  230. package/dist/generators/grafana.test.d.cts +1 -0
  231. package/dist/generators/grafana.test.d.mts +1 -0
  232. package/dist/generators/grafana.test.mjs +74 -0
  233. package/dist/generators/grafana.test.mjs.map +1 -0
  234. package/dist/generators/health-check.cjs +6 -6
  235. package/dist/generators/health-check.cjs.map +1 -1
  236. package/dist/generators/health-check.d.cts +1 -1
  237. package/dist/generators/health-check.d.mts +1 -1
  238. package/dist/generators/health-check.mjs +6 -6
  239. package/dist/generators/health-check.mjs.map +1 -1
  240. package/dist/generators/health-check.test.cjs +1 -1
  241. package/dist/generators/health-check.test.mjs +1 -1
  242. package/dist/generators/n8n-workflows.d.cts +1 -1
  243. package/dist/generators/n8n-workflows.d.mts +1 -1
  244. package/dist/generators/n8n-workflows.test.cjs +75 -0
  245. package/dist/generators/n8n-workflows.test.cjs.map +1 -0
  246. package/dist/generators/n8n-workflows.test.d.cts +1 -0
  247. package/dist/generators/n8n-workflows.test.d.mts +1 -0
  248. package/dist/generators/n8n-workflows.test.mjs +76 -0
  249. package/dist/generators/n8n-workflows.test.mjs.map +1 -0
  250. package/dist/generators/native-services.d.cts +1 -1
  251. package/dist/generators/native-services.d.mts +1 -1
  252. package/dist/generators/openclaw-install-script.test.cjs +35 -0
  253. package/dist/generators/openclaw-install-script.test.cjs.map +1 -0
  254. package/dist/generators/openclaw-install-script.test.d.cts +1 -0
  255. package/dist/generators/openclaw-install-script.test.d.mts +1 -0
  256. package/dist/generators/openclaw-install-script.test.mjs +36 -0
  257. package/dist/generators/openclaw-install-script.test.mjs.map +1 -0
  258. package/dist/generators/openclaw-json.cjs +60 -4
  259. package/dist/generators/openclaw-json.cjs.map +1 -1
  260. package/dist/generators/openclaw-json.d.cts +1 -5
  261. package/dist/generators/openclaw-json.d.cts.map +1 -1
  262. package/dist/generators/openclaw-json.d.mts +1 -5
  263. package/dist/generators/openclaw-json.d.mts.map +1 -1
  264. package/dist/generators/openclaw-json.mjs +60 -4
  265. package/dist/generators/openclaw-json.mjs.map +1 -1
  266. package/dist/generators/postgres-init.cjs +20 -0
  267. package/dist/generators/postgres-init.cjs.map +1 -1
  268. package/dist/generators/postgres-init.d.cts +1 -1
  269. package/dist/generators/postgres-init.d.cts.map +1 -1
  270. package/dist/generators/postgres-init.d.mts +1 -1
  271. package/dist/generators/postgres-init.d.mts.map +1 -1
  272. package/dist/generators/postgres-init.mjs +20 -0
  273. package/dist/generators/postgres-init.mjs.map +1 -1
  274. package/dist/generators/postgres-init.test.cjs +111 -0
  275. package/dist/generators/postgres-init.test.cjs.map +1 -0
  276. package/dist/generators/postgres-init.test.d.cts +1 -0
  277. package/dist/generators/postgres-init.test.d.mts +1 -0
  278. package/dist/generators/postgres-init.test.mjs +112 -0
  279. package/dist/generators/postgres-init.test.mjs.map +1 -0
  280. package/dist/generators/prometheus.d.cts +1 -1
  281. package/dist/generators/prometheus.d.mts +1 -1
  282. package/dist/generators/prometheus.test.cjs +99 -0
  283. package/dist/generators/prometheus.test.cjs.map +1 -0
  284. package/dist/generators/prometheus.test.d.cts +1 -0
  285. package/dist/generators/prometheus.test.d.mts +1 -0
  286. package/dist/generators/prometheus.test.mjs +99 -0
  287. package/dist/generators/prometheus.test.mjs.map +1 -0
  288. package/dist/generators/readme.cjs +50 -7
  289. package/dist/generators/readme.cjs.map +1 -1
  290. package/dist/generators/readme.d.cts +3 -1
  291. package/dist/generators/readme.d.cts.map +1 -1
  292. package/dist/generators/readme.d.mts +3 -1
  293. package/dist/generators/readme.d.mts.map +1 -1
  294. package/dist/generators/readme.mjs +50 -7
  295. package/dist/generators/readme.mjs.map +1 -1
  296. package/dist/generators/scripts.test.cjs +2 -2
  297. package/dist/generators/scripts.test.cjs.map +1 -1
  298. package/dist/generators/scripts.test.mjs +2 -2
  299. package/dist/generators/scripts.test.mjs.map +1 -1
  300. package/dist/generators/skills.cjs +1 -1
  301. package/dist/generators/skills.d.cts +1 -1
  302. package/dist/generators/skills.d.cts.map +1 -1
  303. package/dist/generators/skills.d.mts +1 -1
  304. package/dist/generators/skills.d.mts.map +1 -1
  305. package/dist/generators/skills.mjs +310 -0
  306. package/dist/generators/skills.mjs.map +1 -1
  307. package/dist/generators/stack-manifest.d.cts +1 -1
  308. package/dist/generators/stack-manifest.d.mts +1 -1
  309. package/dist/generators/stack-manifest.test.cjs +97 -0
  310. package/dist/generators/stack-manifest.test.cjs.map +1 -0
  311. package/dist/generators/stack-manifest.test.d.cts +1 -0
  312. package/dist/generators/stack-manifest.test.d.mts +1 -0
  313. package/dist/generators/stack-manifest.test.mjs +98 -0
  314. package/dist/generators/stack-manifest.test.mjs.map +1 -0
  315. package/dist/generators/traefik.d.cts +1 -1
  316. package/dist/generators/traefik.d.mts +1 -1
  317. package/dist/generators/traefik.test.cjs +12 -12
  318. package/dist/generators/traefik.test.cjs.map +1 -1
  319. package/dist/generators/traefik.test.mjs +12 -12
  320. package/dist/generators/traefik.test.mjs.map +1 -1
  321. package/dist/index.cjs +18 -2
  322. package/dist/index.d.cts +13 -7
  323. package/dist/index.d.mts +13 -7
  324. package/dist/index.mjs +9 -3
  325. package/dist/logger/__tests__/logger.test.cjs +308 -0
  326. package/dist/logger/__tests__/logger.test.cjs.map +1 -0
  327. package/dist/logger/__tests__/logger.test.d.cts +1 -0
  328. package/dist/logger/__tests__/logger.test.d.mts +1 -0
  329. package/dist/logger/__tests__/logger.test.mjs +308 -0
  330. package/dist/logger/__tests__/logger.test.mjs.map +1 -0
  331. package/dist/logger/index.cjs +8 -0
  332. package/dist/logger/index.d.cts +5 -0
  333. package/dist/logger/index.d.mts +5 -0
  334. package/dist/logger/index.mjs +4 -0
  335. package/dist/logger/logger.cjs +270 -0
  336. package/dist/logger/logger.cjs.map +1 -0
  337. package/dist/logger/logger.d.cts +2 -0
  338. package/dist/logger/logger.d.mts +2 -0
  339. package/dist/logger/logger.mjs +267 -0
  340. package/dist/logger/logger.mjs.map +1 -0
  341. package/dist/logger/sinks/callback-sink.cjs +18 -0
  342. package/dist/logger/sinks/callback-sink.cjs.map +1 -0
  343. package/dist/logger/sinks/callback-sink.d.cts +2 -0
  344. package/dist/logger/sinks/callback-sink.d.mts +2 -0
  345. package/dist/logger/sinks/callback-sink.mjs +17 -0
  346. package/dist/logger/sinks/callback-sink.mjs.map +1 -0
  347. package/dist/logger/sinks/console-sink.cjs +39 -0
  348. package/dist/logger/sinks/console-sink.cjs.map +1 -0
  349. package/dist/logger/sinks/console-sink.d.cts +2 -0
  350. package/dist/logger/sinks/console-sink.d.mts +2 -0
  351. package/dist/logger/sinks/console-sink.mjs +38 -0
  352. package/dist/logger/sinks/console-sink.mjs.map +1 -0
  353. package/dist/logger/sinks/file-sink.cjs +72 -0
  354. package/dist/logger/sinks/file-sink.cjs.map +1 -0
  355. package/dist/logger/sinks/file-sink.d.cts +36 -0
  356. package/dist/logger/sinks/file-sink.d.cts.map +1 -0
  357. package/dist/logger/sinks/file-sink.d.mts +36 -0
  358. package/dist/logger/sinks/file-sink.d.mts.map +1 -0
  359. package/dist/logger/sinks/file-sink.mjs +70 -0
  360. package/dist/logger/sinks/file-sink.mjs.map +1 -0
  361. package/dist/logger/types.cjs +0 -0
  362. package/dist/logger/types.d.cts +2 -0
  363. package/dist/logger/types.d.mts +2 -0
  364. package/dist/logger/types.mjs +1 -0
  365. package/dist/logger-CZ0Qnyiu.d.mts +66 -0
  366. package/dist/logger-CZ0Qnyiu.d.mts.map +1 -0
  367. package/dist/logger-DDfwai-A.d.cts +66 -0
  368. package/dist/logger-DDfwai-A.d.cts.map +1 -0
  369. package/dist/memu-BfRXtwmL.d.cts +7 -0
  370. package/dist/memu-BfRXtwmL.d.cts.map +1 -0
  371. package/dist/memu-C-fXbWr-.d.mts +7 -0
  372. package/dist/memu-C-fXbWr-.d.mts.map +1 -0
  373. package/dist/migrations.cjs +17 -9
  374. package/dist/migrations.cjs.map +1 -1
  375. package/dist/migrations.d.cts +1 -1
  376. package/dist/migrations.d.cts.map +1 -1
  377. package/dist/migrations.d.mts +1 -1
  378. package/dist/migrations.d.mts.map +1 -1
  379. package/dist/migrations.mjs +17 -9
  380. package/dist/migrations.mjs.map +1 -1
  381. package/dist/migrations.test.cjs +4 -4
  382. package/dist/migrations.test.mjs +4 -4
  383. package/dist/nanobot-2c0bS4lu.d.cts +7 -0
  384. package/dist/nanobot-2c0bS4lu.d.cts.map +1 -0
  385. package/dist/nanobot-BUO6pVQc.d.mts +7 -0
  386. package/dist/nanobot-BUO6pVQc.d.mts.map +1 -0
  387. package/dist/nanoclaw-CgHubEig.d.mts +7 -0
  388. package/dist/nanoclaw-CgHubEig.d.mts.map +1 -0
  389. package/dist/nanoclaw-Dvz0ef6J.d.cts +7 -0
  390. package/dist/nanoclaw-Dvz0ef6J.d.cts.map +1 -0
  391. package/dist/openclaw-D8lVecjC.d.mts +7 -0
  392. package/dist/openclaw-D8lVecjC.d.mts.map +1 -0
  393. package/dist/openclaw-DThj8i3N.d.cts +7 -0
  394. package/dist/openclaw-DThj8i3N.d.cts.map +1 -0
  395. package/dist/port-scanner.d.cts +1 -1
  396. package/dist/port-scanner.d.mts +1 -1
  397. package/dist/port-scanner.test.cjs +155 -0
  398. package/dist/port-scanner.test.cjs.map +1 -0
  399. package/dist/port-scanner.test.d.cts +1 -0
  400. package/dist/port-scanner.test.d.mts +1 -0
  401. package/dist/port-scanner.test.mjs +156 -0
  402. package/dist/port-scanner.test.mjs.map +1 -0
  403. package/dist/presets/presets.test.cjs +5 -5
  404. package/dist/presets/presets.test.cjs.map +1 -1
  405. package/dist/presets/presets.test.mjs +4 -4
  406. package/dist/presets/presets.test.mjs.map +1 -1
  407. package/dist/presets/registry.d.cts +1 -1
  408. package/dist/presets/registry.d.mts +1 -1
  409. package/dist/presets/registry.test.cjs +7 -7
  410. package/dist/presets/registry.test.cjs.map +1 -1
  411. package/dist/presets/registry.test.mjs +7 -7
  412. package/dist/presets/registry.test.mjs.map +1 -1
  413. package/dist/registry-DHX7vnVo.d.cts +16 -0
  414. package/dist/registry-DHX7vnVo.d.cts.map +1 -0
  415. package/dist/registry-DTAILnga.d.mts +16 -0
  416. package/dist/registry-DTAILnga.d.mts.map +1 -0
  417. package/dist/resolver.cjs +13 -3
  418. package/dist/resolver.cjs.map +1 -1
  419. package/dist/resolver.d.cts +1 -1
  420. package/dist/resolver.d.cts.map +1 -1
  421. package/dist/resolver.d.mts +1 -1
  422. package/dist/resolver.d.mts.map +1 -1
  423. package/dist/resolver.mjs +13 -3
  424. package/dist/resolver.mjs.map +1 -1
  425. package/dist/resolver.test.cjs +35 -3
  426. package/dist/resolver.test.cjs.map +1 -1
  427. package/dist/resolver.test.mjs +35 -3
  428. package/dist/resolver.test.mjs.map +1 -1
  429. package/dist/{schema-BQnZrcw8.d.cts → schema-BSl9wiFe.d.mts} +134 -2
  430. package/dist/schema-BSl9wiFe.d.mts.map +1 -0
  431. package/dist/{schema-SBpL0bdI.d.mts → schema-Bd9l2r7p.d.cts} +134 -2
  432. package/dist/schema-Bd9l2r7p.d.cts.map +1 -0
  433. package/dist/schema.cjs +28 -4
  434. package/dist/schema.cjs.map +1 -1
  435. package/dist/schema.d.cts +2 -2
  436. package/dist/schema.d.mts +2 -2
  437. package/dist/schema.mjs +27 -4
  438. package/dist/schema.mjs.map +1 -1
  439. package/dist/schema.test.cjs +3 -3
  440. package/dist/schema.test.cjs.map +1 -1
  441. package/dist/schema.test.mjs +3 -3
  442. package/dist/schema.test.mjs.map +1 -1
  443. package/dist/services/definitions/adguard-home.d.cts +1 -1
  444. package/dist/services/definitions/adguard-home.d.mts +1 -1
  445. package/dist/services/definitions/agent-browser.cjs +161 -0
  446. package/dist/services/definitions/agent-browser.cjs.map +1 -0
  447. package/dist/services/definitions/agent-browser.d.cts +7 -0
  448. package/dist/services/definitions/agent-browser.d.cts.map +1 -0
  449. package/dist/services/definitions/agent-browser.d.mts +7 -0
  450. package/dist/services/definitions/agent-browser.d.mts.map +1 -0
  451. package/dist/services/definitions/agent-browser.mjs +160 -0
  452. package/dist/services/definitions/agent-browser.mjs.map +1 -0
  453. package/dist/services/definitions/airbyte.d.cts +1 -1
  454. package/dist/services/definitions/airbyte.d.mts +1 -1
  455. package/dist/services/definitions/airflow.d.cts +1 -1
  456. package/dist/services/definitions/airflow.d.mts +1 -1
  457. package/dist/services/definitions/anything-llm.d.cts +1 -1
  458. package/dist/services/definitions/anything-llm.d.mts +1 -1
  459. package/dist/services/definitions/appflowy.d.cts +1 -1
  460. package/dist/services/definitions/appflowy.d.mts +1 -1
  461. package/dist/services/definitions/apptension-saas.cjs.map +1 -1
  462. package/dist/services/definitions/apptension-saas.d.cts +1 -1
  463. package/dist/services/definitions/apptension-saas.d.mts +1 -1
  464. package/dist/services/definitions/apptension-saas.mjs.map +1 -1
  465. package/dist/services/definitions/appwrite.d.cts +1 -1
  466. package/dist/services/definitions/appwrite.d.mts +1 -1
  467. package/dist/services/definitions/audiobookshelf.d.cts +1 -1
  468. package/dist/services/definitions/audiobookshelf.d.mts +1 -1
  469. package/dist/services/definitions/authelia.d.cts +1 -1
  470. package/dist/services/definitions/authelia.d.mts +1 -1
  471. package/dist/services/definitions/authentik.d.cts +1 -1
  472. package/dist/services/definitions/authentik.d.mts +1 -1
  473. package/dist/services/definitions/axolotl.d.cts +1 -1
  474. package/dist/services/definitions/axolotl.d.mts +1 -1
  475. package/dist/services/definitions/baserow.d.cts +1 -1
  476. package/dist/services/definitions/baserow.d.mts +1 -1
  477. package/dist/services/definitions/beszel.d.cts +1 -1
  478. package/dist/services/definitions/beszel.d.mts +1 -1
  479. package/dist/services/definitions/boxyhq-saas.d.cts +1 -1
  480. package/dist/services/definitions/boxyhq-saas.d.mts +1 -1
  481. package/dist/services/definitions/browserless.d.cts +1 -1
  482. package/dist/services/definitions/browserless.d.mts +1 -1
  483. package/dist/services/definitions/burnlink.d.cts +1 -1
  484. package/dist/services/definitions/burnlink.d.mts +1 -1
  485. package/dist/services/definitions/caddy.d.cts +1 -1
  486. package/dist/services/definitions/caddy.d.mts +1 -1
  487. package/dist/services/definitions/cal-com.d.cts +1 -1
  488. package/dist/services/definitions/cal-com.d.mts +1 -1
  489. package/dist/services/definitions/calibre-web.d.cts +1 -1
  490. package/dist/services/definitions/calibre-web.d.mts +1 -1
  491. package/dist/services/definitions/chatwoot-worker.d.cts +1 -1
  492. package/dist/services/definitions/chatwoot-worker.d.mts +1 -1
  493. package/dist/services/definitions/chatwoot.d.cts +1 -1
  494. package/dist/services/definitions/chatwoot.d.mts +1 -1
  495. package/dist/services/definitions/chromadb.cjs +4 -1
  496. package/dist/services/definitions/chromadb.cjs.map +1 -1
  497. package/dist/services/definitions/chromadb.d.cts +1 -1
  498. package/dist/services/definitions/chromadb.d.mts +1 -1
  499. package/dist/services/definitions/chromadb.mjs +4 -1
  500. package/dist/services/definitions/chromadb.mjs.map +1 -1
  501. package/dist/services/definitions/claude-code.cjs +1 -1
  502. package/dist/services/definitions/claude-code.cjs.map +1 -1
  503. package/dist/services/definitions/claude-code.d.cts +1 -1
  504. package/dist/services/definitions/claude-code.d.mts +1 -1
  505. package/dist/services/definitions/claude-code.mjs +1 -1
  506. package/dist/services/definitions/claude-code.mjs.map +1 -1
  507. package/dist/services/definitions/clawrouter.cjs +138 -0
  508. package/dist/services/definitions/clawrouter.cjs.map +1 -0
  509. package/dist/services/definitions/clawrouter.d.cts +7 -0
  510. package/dist/services/definitions/clawrouter.d.cts.map +1 -0
  511. package/dist/services/definitions/clawrouter.d.mts +7 -0
  512. package/dist/services/definitions/clawrouter.d.mts.map +1 -0
  513. package/dist/services/definitions/clawrouter.mjs +137 -0
  514. package/dist/services/definitions/clawrouter.mjs.map +1 -0
  515. package/dist/services/definitions/clickhouse.d.cts +1 -1
  516. package/dist/services/definitions/clickhouse.d.mts +1 -1
  517. package/dist/services/definitions/cloudflared.d.cts +1 -1
  518. package/dist/services/definitions/cloudflared.d.mts +1 -1
  519. package/dist/services/definitions/cmsaas-starter.d.cts +1 -1
  520. package/dist/services/definitions/cmsaas-starter.d.mts +1 -1
  521. package/dist/services/definitions/cockroachdb.d.cts +1 -1
  522. package/dist/services/definitions/cockroachdb.d.mts +1 -1
  523. package/dist/services/definitions/code-server.d.cts +1 -1
  524. package/dist/services/definitions/code-server.d.mts +1 -1
  525. package/dist/services/definitions/coder.d.cts +1 -1
  526. package/dist/services/definitions/coder.d.mts +1 -1
  527. package/dist/services/definitions/codex.cjs +1 -1
  528. package/dist/services/definitions/codex.cjs.map +1 -1
  529. package/dist/services/definitions/codex.d.cts +1 -1
  530. package/dist/services/definitions/codex.d.mts +1 -1
  531. package/dist/services/definitions/codex.mjs +1 -1
  532. package/dist/services/definitions/codex.mjs.map +1 -1
  533. package/dist/services/definitions/comfyui.d.cts +1 -1
  534. package/dist/services/definitions/comfyui.d.mts +1 -1
  535. package/dist/services/definitions/convex-dashboard.d.cts +1 -1
  536. package/dist/services/definitions/convex-dashboard.d.mts +1 -1
  537. package/dist/services/definitions/convex.cjs.map +1 -1
  538. package/dist/services/definitions/convex.d.cts +1 -1
  539. package/dist/services/definitions/convex.d.mts +1 -1
  540. package/dist/services/definitions/convex.mjs.map +1 -1
  541. package/dist/services/definitions/coolify.d.cts +1 -1
  542. package/dist/services/definitions/coolify.d.mts +1 -1
  543. package/dist/services/definitions/copaw.cjs +97 -0
  544. package/dist/services/definitions/copaw.cjs.map +1 -0
  545. package/dist/services/definitions/copaw.d.cts +7 -0
  546. package/dist/services/definitions/copaw.d.cts.map +1 -0
  547. package/dist/services/definitions/copaw.d.mts +7 -0
  548. package/dist/services/definitions/copaw.d.mts.map +1 -0
  549. package/dist/services/definitions/copaw.mjs +96 -0
  550. package/dist/services/definitions/copaw.mjs.map +1 -0
  551. package/dist/services/definitions/crowdsec.d.cts +1 -1
  552. package/dist/services/definitions/crowdsec.d.mts +1 -1
  553. package/dist/services/definitions/dagster.d.cts +1 -1
  554. package/dist/services/definitions/dagster.d.mts +1 -1
  555. package/dist/services/definitions/desktop-environment.cjs +2 -1
  556. package/dist/services/definitions/desktop-environment.cjs.map +1 -1
  557. package/dist/services/definitions/desktop-environment.d.cts +1 -1
  558. package/dist/services/definitions/desktop-environment.d.mts +1 -1
  559. package/dist/services/definitions/desktop-environment.mjs +2 -1
  560. package/dist/services/definitions/desktop-environment.mjs.map +1 -1
  561. package/dist/services/definitions/dify.d.cts +1 -1
  562. package/dist/services/definitions/dify.d.mts +1 -1
  563. package/dist/services/definitions/directus.d.cts +1 -1
  564. package/dist/services/definitions/directus.d.mts +1 -1
  565. package/dist/services/definitions/docsgpt.d.cts +1 -1
  566. package/dist/services/definitions/docsgpt.d.mts +1 -1
  567. package/dist/services/definitions/dokploy.d.cts +1 -1
  568. package/dist/services/definitions/dokploy.d.mts +1 -1
  569. package/dist/services/definitions/dozzle.d.cts +1 -1
  570. package/dist/services/definitions/dozzle.d.mts +1 -1
  571. package/dist/services/definitions/dragonfly.d.cts +1 -1
  572. package/dist/services/definitions/dragonfly.d.mts +1 -1
  573. package/dist/services/definitions/drone-ci.d.cts +1 -1
  574. package/dist/services/definitions/drone-ci.d.mts +1 -1
  575. package/dist/services/definitions/duplicati.d.cts +1 -1
  576. package/dist/services/definitions/duplicati.d.mts +1 -1
  577. package/dist/services/definitions/element-web.d.cts +1 -1
  578. package/dist/services/definitions/element-web.d.mts +1 -1
  579. package/dist/services/definitions/excalidraw.d.cts +1 -1
  580. package/dist/services/definitions/excalidraw.d.mts +1 -1
  581. package/dist/services/definitions/ffmpeg.d.cts +1 -1
  582. package/dist/services/definitions/ffmpeg.d.mts +1 -1
  583. package/dist/services/definitions/firecrawl-playwright.d.cts +1 -1
  584. package/dist/services/definitions/firecrawl-playwright.d.mts +1 -1
  585. package/dist/services/definitions/firecrawl.d.cts +1 -1
  586. package/dist/services/definitions/firecrawl.d.mts +1 -1
  587. package/dist/services/definitions/flagsmith.d.cts +1 -1
  588. package/dist/services/definitions/flagsmith.d.mts +1 -1
  589. package/dist/services/definitions/flowise.d.cts +1 -1
  590. package/dist/services/definitions/flowise.d.mts +1 -1
  591. package/dist/services/definitions/focalboard.d.cts +1 -1
  592. package/dist/services/definitions/focalboard.d.mts +1 -1
  593. package/dist/services/definitions/fonoster.d.cts +1 -1
  594. package/dist/services/definitions/fonoster.d.mts +1 -1
  595. package/dist/services/definitions/forgejo.d.cts +1 -1
  596. package/dist/services/definitions/forgejo.d.mts +1 -1
  597. package/dist/services/definitions/formbricks.d.cts +1 -1
  598. package/dist/services/definitions/formbricks.d.mts +1 -1
  599. package/dist/services/definitions/gemini-cli.d.cts +1 -1
  600. package/dist/services/definitions/gemini-cli.d.mts +1 -1
  601. package/dist/services/definitions/ghost.d.cts +1 -1
  602. package/dist/services/definitions/ghost.d.mts +1 -1
  603. package/dist/services/definitions/gitea.d.cts +1 -1
  604. package/dist/services/definitions/gitea.d.mts +1 -1
  605. package/dist/services/definitions/gotify.d.cts +1 -1
  606. package/dist/services/definitions/gotify.d.mts +1 -1
  607. package/dist/services/definitions/grafana.d.cts +1 -1
  608. package/dist/services/definitions/grafana.d.mts +1 -1
  609. package/dist/services/definitions/graylog.d.cts +1 -1
  610. package/dist/services/definitions/graylog.d.mts +1 -1
  611. package/dist/services/definitions/headscale.d.cts +1 -1
  612. package/dist/services/definitions/headscale.d.mts +1 -1
  613. package/dist/services/definitions/hedgedoc.d.cts +1 -1
  614. package/dist/services/definitions/hedgedoc.d.mts +1 -1
  615. package/dist/services/definitions/hexstrike.d.cts +1 -1
  616. package/dist/services/definitions/hexstrike.d.mts +1 -1
  617. package/dist/services/definitions/heyform.d.cts +1 -1
  618. package/dist/services/definitions/heyform.d.mts +1 -1
  619. package/dist/services/definitions/hindsight.cjs +4 -1
  620. package/dist/services/definitions/hindsight.cjs.map +1 -1
  621. package/dist/services/definitions/hindsight.d.cts +1 -1
  622. package/dist/services/definitions/hindsight.d.mts +1 -1
  623. package/dist/services/definitions/hindsight.mjs +4 -1
  624. package/dist/services/definitions/hindsight.mjs.map +1 -1
  625. package/dist/services/definitions/homeassistant.d.cts +1 -1
  626. package/dist/services/definitions/homeassistant.d.mts +1 -1
  627. package/dist/services/definitions/hoppscotch.d.cts +1 -1
  628. package/dist/services/definitions/hoppscotch.d.mts +1 -1
  629. package/dist/services/definitions/immich.d.cts +1 -1
  630. package/dist/services/definitions/immich.d.mts +1 -1
  631. package/dist/services/definitions/index.cjs +42 -6
  632. package/dist/services/definitions/index.cjs.map +1 -1
  633. package/dist/services/definitions/index.d.cts +16 -4
  634. package/dist/services/definitions/index.d.cts.map +1 -1
  635. package/dist/services/definitions/index.d.mts +16 -4
  636. package/dist/services/definitions/index.d.mts.map +1 -1
  637. package/dist/services/definitions/index.mjs +31 -7
  638. package/dist/services/definitions/index.mjs.map +1 -1
  639. package/dist/services/definitions/infisical.d.cts +1 -1
  640. package/dist/services/definitions/infisical.d.mts +1 -1
  641. package/dist/services/definitions/influxdb.d.cts +1 -1
  642. package/dist/services/definitions/influxdb.d.mts +1 -1
  643. package/dist/services/definitions/invoke-ai.d.cts +1 -1
  644. package/dist/services/definitions/invoke-ai.d.mts +1 -1
  645. package/dist/services/definitions/ixartz-saas.d.cts +1 -1
  646. package/dist/services/definitions/ixartz-saas.d.mts +1 -1
  647. package/dist/services/definitions/jaeger.d.cts +1 -1
  648. package/dist/services/definitions/jaeger.d.mts +1 -1
  649. package/dist/services/definitions/jan.d.cts +1 -1
  650. package/dist/services/definitions/jan.d.mts +1 -1
  651. package/dist/services/definitions/jellyfin.d.cts +1 -1
  652. package/dist/services/definitions/jellyfin.d.mts +1 -1
  653. package/dist/services/definitions/jenkins.d.cts +1 -1
  654. package/dist/services/definitions/jenkins.d.mts +1 -1
  655. package/dist/services/definitions/jitsi-meet.d.cts +1 -1
  656. package/dist/services/definitions/jitsi-meet.d.mts +1 -1
  657. package/dist/services/definitions/keycloak.d.cts +1 -1
  658. package/dist/services/definitions/keycloak.d.mts +1 -1
  659. package/dist/services/definitions/kimi.d.cts +1 -1
  660. package/dist/services/definitions/kimi.d.mts +1 -1
  661. package/dist/services/definitions/kong.d.cts +1 -1
  662. package/dist/services/definitions/kong.d.mts +1 -1
  663. package/dist/services/definitions/lago.d.cts +1 -1
  664. package/dist/services/definitions/lago.d.mts +1 -1
  665. package/dist/services/definitions/langflow.d.cts +1 -1
  666. package/dist/services/definitions/langflow.d.mts +1 -1
  667. package/dist/services/definitions/langfuse.d.cts +1 -1
  668. package/dist/services/definitions/langfuse.d.mts +1 -1
  669. package/dist/services/definitions/lasuite-meet-agents.d.cts +1 -1
  670. package/dist/services/definitions/lasuite-meet-agents.d.mts +1 -1
  671. package/dist/services/definitions/lasuite-meet-backend.d.cts +1 -1
  672. package/dist/services/definitions/lasuite-meet-backend.d.mts +1 -1
  673. package/dist/services/definitions/lasuite-meet-frontend.d.cts +1 -1
  674. package/dist/services/definitions/lasuite-meet-frontend.d.mts +1 -1
  675. package/dist/services/definitions/librechat.d.cts +1 -1
  676. package/dist/services/definitions/librechat.d.mts +1 -1
  677. package/dist/services/definitions/lightpanda.d.cts +1 -1
  678. package/dist/services/definitions/lightpanda.d.mts +1 -1
  679. package/dist/services/definitions/listmonk.d.cts +1 -1
  680. package/dist/services/definitions/listmonk.d.mts +1 -1
  681. package/dist/services/definitions/litellm.d.cts +1 -1
  682. package/dist/services/definitions/litellm.d.mts +1 -1
  683. package/dist/services/definitions/livekit.d.cts +1 -1
  684. package/dist/services/definitions/livekit.d.mts +1 -1
  685. package/dist/services/definitions/local-ai.d.cts +1 -1
  686. package/dist/services/definitions/local-ai.d.mts +1 -1
  687. package/dist/services/definitions/loki.d.cts +1 -1
  688. package/dist/services/definitions/loki.d.mts +1 -1
  689. package/dist/services/definitions/mariadb.d.cts +1 -1
  690. package/dist/services/definitions/mariadb.d.mts +1 -1
  691. package/dist/services/definitions/matomo.d.cts +1 -1
  692. package/dist/services/definitions/matomo.d.mts +1 -1
  693. package/dist/services/definitions/matrix-synapse.d.cts +1 -1
  694. package/dist/services/definitions/matrix-synapse.d.mts +1 -1
  695. package/dist/services/definitions/mattermost.d.cts +1 -1
  696. package/dist/services/definitions/mattermost.d.mts +1 -1
  697. package/dist/services/definitions/mautic.d.cts +1 -1
  698. package/dist/services/definitions/mautic.d.mts +1 -1
  699. package/dist/services/definitions/medusa.d.cts +1 -1
  700. package/dist/services/definitions/medusa.d.mts +1 -1
  701. package/dist/services/definitions/meilisearch.d.cts +1 -1
  702. package/dist/services/definitions/meilisearch.d.mts +1 -1
  703. package/dist/services/definitions/mem0.cjs +133 -0
  704. package/dist/services/definitions/mem0.cjs.map +1 -0
  705. package/dist/services/definitions/mem0.d.cts +7 -0
  706. package/dist/services/definitions/mem0.d.cts.map +1 -0
  707. package/dist/services/definitions/mem0.d.mts +7 -0
  708. package/dist/services/definitions/mem0.d.mts.map +1 -0
  709. package/dist/services/definitions/mem0.mjs +132 -0
  710. package/dist/services/definitions/mem0.mjs.map +1 -0
  711. package/dist/services/definitions/memu.cjs +96 -0
  712. package/dist/services/definitions/memu.cjs.map +1 -0
  713. package/dist/services/definitions/memu.d.cts +7 -0
  714. package/dist/services/definitions/memu.d.cts.map +1 -0
  715. package/dist/services/definitions/memu.d.mts +7 -0
  716. package/dist/services/definitions/memu.d.mts.map +1 -0
  717. package/dist/services/definitions/memu.mjs +95 -0
  718. package/dist/services/definitions/memu.mjs.map +1 -0
  719. package/dist/services/definitions/metabase.d.cts +1 -1
  720. package/dist/services/definitions/metabase.d.mts +1 -1
  721. package/dist/services/definitions/milvus.cjs +4 -1
  722. package/dist/services/definitions/milvus.cjs.map +1 -1
  723. package/dist/services/definitions/milvus.d.cts +1 -1
  724. package/dist/services/definitions/milvus.d.mts +1 -1
  725. package/dist/services/definitions/milvus.mjs +4 -1
  726. package/dist/services/definitions/milvus.mjs.map +1 -1
  727. package/dist/services/definitions/minio.d.cts +1 -1
  728. package/dist/services/definitions/minio.d.mts +1 -1
  729. package/dist/services/definitions/mission-control.d.cts +1 -1
  730. package/dist/services/definitions/mission-control.d.mts +1 -1
  731. package/dist/services/definitions/mixpost.d.cts +1 -1
  732. package/dist/services/definitions/mixpost.d.mts +1 -1
  733. package/dist/services/definitions/mosquitto.d.cts +1 -1
  734. package/dist/services/definitions/mosquitto.d.mts +1 -1
  735. package/dist/services/definitions/motion-canvas.d.cts +1 -1
  736. package/dist/services/definitions/motion-canvas.d.mts +1 -1
  737. package/dist/services/definitions/mysql.d.cts +1 -1
  738. package/dist/services/definitions/mysql.d.mts +1 -1
  739. package/dist/services/definitions/n8n.d.cts +1 -1
  740. package/dist/services/definitions/n8n.d.mts +1 -1
  741. package/dist/services/definitions/nanobot.cjs +86 -0
  742. package/dist/services/definitions/nanobot.cjs.map +1 -0
  743. package/dist/services/definitions/nanobot.d.cts +7 -0
  744. package/dist/services/definitions/nanobot.d.cts.map +1 -0
  745. package/dist/services/definitions/nanobot.d.mts +7 -0
  746. package/dist/services/definitions/nanobot.d.mts.map +1 -0
  747. package/dist/services/definitions/nanobot.mjs +85 -0
  748. package/dist/services/definitions/nanobot.mjs.map +1 -0
  749. package/dist/services/definitions/nanoclaw.cjs +79 -0
  750. package/dist/services/definitions/nanoclaw.cjs.map +1 -0
  751. package/dist/services/definitions/nanoclaw.d.cts +7 -0
  752. package/dist/services/definitions/nanoclaw.d.cts.map +1 -0
  753. package/dist/services/definitions/nanoclaw.d.mts +7 -0
  754. package/dist/services/definitions/nanoclaw.d.mts.map +1 -0
  755. package/dist/services/definitions/nanoclaw.mjs +78 -0
  756. package/dist/services/definitions/nanoclaw.mjs.map +1 -0
  757. package/dist/services/definitions/navidrome.d.cts +1 -1
  758. package/dist/services/definitions/navidrome.d.mts +1 -1
  759. package/dist/services/definitions/neo4j.d.cts +1 -1
  760. package/dist/services/definitions/neo4j.d.mts +1 -1
  761. package/dist/services/definitions/nextcloud.d.cts +1 -1
  762. package/dist/services/definitions/nextcloud.d.mts +1 -1
  763. package/dist/services/definitions/nginx-proxy-manager.d.cts +1 -1
  764. package/dist/services/definitions/nginx-proxy-manager.d.mts +1 -1
  765. package/dist/services/definitions/nocodb.d.cts +1 -1
  766. package/dist/services/definitions/nocodb.d.mts +1 -1
  767. package/dist/services/definitions/node-red.d.cts +1 -1
  768. package/dist/services/definitions/node-red.d.mts +1 -1
  769. package/dist/services/definitions/ntfy.d.cts +1 -1
  770. package/dist/services/definitions/ntfy.d.mts +1 -1
  771. package/dist/services/definitions/ollama.d.cts +1 -1
  772. package/dist/services/definitions/ollama.d.mts +1 -1
  773. package/dist/services/definitions/open-saas.d.cts +1 -1
  774. package/dist/services/definitions/open-saas.d.mts +1 -1
  775. package/dist/services/definitions/open-webui.d.cts +1 -1
  776. package/dist/services/definitions/open-webui.d.mts +1 -1
  777. package/dist/services/definitions/opencode.d.cts +1 -1
  778. package/dist/services/definitions/opencode.d.mts +1 -1
  779. package/dist/services/definitions/openhands.d.cts +1 -1
  780. package/dist/services/definitions/openhands.d.mts +1 -1
  781. package/dist/services/definitions/openpanel.d.cts +1 -1
  782. package/dist/services/definitions/openpanel.d.mts +1 -1
  783. package/dist/services/definitions/opensandbox.cjs +2 -1
  784. package/dist/services/definitions/opensandbox.cjs.map +1 -1
  785. package/dist/services/definitions/opensandbox.d.cts +1 -1
  786. package/dist/services/definitions/opensandbox.d.mts +1 -1
  787. package/dist/services/definitions/opensandbox.mjs +2 -1
  788. package/dist/services/definitions/opensandbox.mjs.map +1 -1
  789. package/dist/services/definitions/opensearch.d.cts +1 -1
  790. package/dist/services/definitions/opensearch.d.mts +1 -1
  791. package/dist/services/definitions/outline.d.cts +1 -1
  792. package/dist/services/definitions/outline.d.mts +1 -1
  793. package/dist/services/definitions/paperless-ngx.d.cts +1 -1
  794. package/dist/services/definitions/paperless-ngx.d.mts +1 -1
  795. package/dist/services/definitions/pentagi.d.cts +1 -1
  796. package/dist/services/definitions/pentagi.d.mts +1 -1
  797. package/dist/services/definitions/pentestagent.d.cts +1 -1
  798. package/dist/services/definitions/pentestagent.d.mts +1 -1
  799. package/dist/services/definitions/photoprism.d.cts +1 -1
  800. package/dist/services/definitions/photoprism.d.mts +1 -1
  801. package/dist/services/definitions/pihole.d.cts +1 -1
  802. package/dist/services/definitions/pihole.d.mts +1 -1
  803. package/dist/services/definitions/piper-tts.d.cts +1 -1
  804. package/dist/services/definitions/piper-tts.d.mts +1 -1
  805. package/dist/services/definitions/plane.d.cts +1 -1
  806. package/dist/services/definitions/plane.d.mts +1 -1
  807. package/dist/services/definitions/plausible.d.cts +1 -1
  808. package/dist/services/definitions/plausible.d.mts +1 -1
  809. package/dist/services/definitions/playwright-server.d.cts +1 -1
  810. package/dist/services/definitions/playwright-server.d.mts +1 -1
  811. package/dist/services/definitions/pocket-id.d.cts +1 -1
  812. package/dist/services/definitions/pocket-id.d.mts +1 -1
  813. package/dist/services/definitions/pocketbase.d.cts +1 -1
  814. package/dist/services/definitions/pocketbase.d.mts +1 -1
  815. package/dist/services/definitions/portainer.d.cts +1 -1
  816. package/dist/services/definitions/portainer.d.mts +1 -1
  817. package/dist/services/definitions/postgresql.d.cts +1 -1
  818. package/dist/services/definitions/postgresql.d.mts +1 -1
  819. package/dist/services/definitions/posthog.d.cts +1 -1
  820. package/dist/services/definitions/posthog.d.mts +1 -1
  821. package/dist/services/definitions/postiz.d.cts +1 -1
  822. package/dist/services/definitions/postiz.d.mts +1 -1
  823. package/dist/services/definitions/prometheus.d.cts +1 -1
  824. package/dist/services/definitions/prometheus.d.mts +1 -1
  825. package/dist/services/definitions/qdrant.d.cts +1 -1
  826. package/dist/services/definitions/qdrant.d.mts +1 -1
  827. package/dist/services/definitions/rabbitmq.d.cts +1 -1
  828. package/dist/services/definitions/rabbitmq.d.mts +1 -1
  829. package/dist/services/definitions/ragflow.d.cts +1 -1
  830. package/dist/services/definitions/ragflow.d.mts +1 -1
  831. package/dist/services/definitions/redis.d.cts +1 -1
  832. package/dist/services/definitions/redis.d.mts +1 -1
  833. package/dist/services/definitions/relaticle-horizon.cjs +48 -0
  834. package/dist/services/definitions/relaticle-horizon.cjs.map +1 -0
  835. package/dist/services/definitions/relaticle-horizon.d.cts +7 -0
  836. package/dist/services/definitions/relaticle-horizon.d.cts.map +1 -0
  837. package/dist/services/definitions/relaticle-horizon.d.mts +7 -0
  838. package/dist/services/definitions/relaticle-horizon.d.mts.map +1 -0
  839. package/dist/services/definitions/relaticle-horizon.mjs +48 -0
  840. package/dist/services/definitions/relaticle-horizon.mjs.map +1 -0
  841. package/dist/services/definitions/relaticle-scheduler.cjs +44 -0
  842. package/dist/services/definitions/relaticle-scheduler.cjs.map +1 -0
  843. package/dist/services/definitions/relaticle-scheduler.d.cts +7 -0
  844. package/dist/services/definitions/relaticle-scheduler.d.cts.map +1 -0
  845. package/dist/services/definitions/relaticle-scheduler.d.mts +7 -0
  846. package/dist/services/definitions/relaticle-scheduler.d.mts.map +1 -0
  847. package/dist/services/definitions/relaticle-scheduler.mjs +44 -0
  848. package/dist/services/definitions/relaticle-scheduler.mjs.map +1 -0
  849. package/dist/services/definitions/relaticle.cjs +151 -0
  850. package/dist/services/definitions/relaticle.cjs.map +1 -0
  851. package/dist/services/definitions/relaticle.d.cts +80 -0
  852. package/dist/services/definitions/relaticle.d.cts.map +1 -0
  853. package/dist/services/definitions/relaticle.d.mts +80 -0
  854. package/dist/services/definitions/relaticle.d.mts.map +1 -0
  855. package/dist/services/definitions/relaticle.mjs +149 -0
  856. package/dist/services/definitions/relaticle.mjs.map +1 -0
  857. package/dist/services/definitions/remotion.d.cts +1 -1
  858. package/dist/services/definitions/remotion.d.mts +1 -1
  859. package/dist/services/definitions/restic.d.cts +1 -1
  860. package/dist/services/definitions/restic.d.mts +1 -1
  861. package/dist/services/definitions/revolt.d.cts +1 -1
  862. package/dist/services/definitions/revolt.d.mts +1 -1
  863. package/dist/services/definitions/rocketchat.d.cts +1 -1
  864. package/dist/services/definitions/rocketchat.d.mts +1 -1
  865. package/dist/services/definitions/saleor.d.cts +1 -1
  866. package/dist/services/definitions/saleor.d.mts +1 -1
  867. package/dist/services/definitions/scrapling.d.cts +1 -1
  868. package/dist/services/definitions/scrapling.d.mts +1 -1
  869. package/dist/services/definitions/searxng.d.cts +1 -1
  870. package/dist/services/definitions/searxng.d.mts +1 -1
  871. package/dist/services/definitions/sentry.d.cts +1 -1
  872. package/dist/services/definitions/sentry.d.mts +1 -1
  873. package/dist/services/definitions/signoz.d.cts +1 -1
  874. package/dist/services/definitions/signoz.d.mts +1 -1
  875. package/dist/services/definitions/solidityguard.d.cts +1 -1
  876. package/dist/services/definitions/solidityguard.d.mts +1 -1
  877. package/dist/services/definitions/sonarqube.d.cts +1 -1
  878. package/dist/services/definitions/sonarqube.d.mts +1 -1
  879. package/dist/services/definitions/stable-diffusion.d.cts +1 -1
  880. package/dist/services/definitions/stable-diffusion.d.mts +1 -1
  881. package/dist/services/definitions/steel-browser.d.cts +1 -1
  882. package/dist/services/definitions/steel-browser.d.mts +1 -1
  883. package/dist/services/definitions/stirling-pdf.d.cts +1 -1
  884. package/dist/services/definitions/stirling-pdf.d.mts +1 -1
  885. package/dist/services/definitions/strapi.d.cts +1 -1
  886. package/dist/services/definitions/strapi.d.mts +1 -1
  887. package/dist/services/definitions/stream-gateway.d.cts +1 -1
  888. package/dist/services/definitions/stream-gateway.d.mts +1 -1
  889. package/dist/services/definitions/supabase.d.cts +1 -1
  890. package/dist/services/definitions/supabase.d.mts +1 -1
  891. package/dist/services/definitions/superset.d.cts +1 -1
  892. package/dist/services/definitions/superset.d.mts +1 -1
  893. package/dist/services/definitions/surrealdb.d.cts +1 -1
  894. package/dist/services/definitions/surrealdb.d.mts +1 -1
  895. package/dist/services/definitions/tabby-ml.d.cts +1 -1
  896. package/dist/services/definitions/tabby-ml.d.mts +1 -1
  897. package/dist/services/definitions/tailscale.d.cts +1 -1
  898. package/dist/services/definitions/tailscale.d.mts +1 -1
  899. package/dist/services/definitions/tempo.d.cts +1 -1
  900. package/dist/services/definitions/tempo.d.mts +1 -1
  901. package/dist/services/definitions/temporal.d.cts +1 -1
  902. package/dist/services/definitions/temporal.d.mts +1 -1
  903. package/dist/services/definitions/text-gen-webui.d.cts +1 -1
  904. package/dist/services/definitions/text-gen-webui.d.mts +1 -1
  905. package/dist/services/definitions/timescaledb.d.cts +1 -1
  906. package/dist/services/definitions/timescaledb.d.mts +1 -1
  907. package/dist/services/definitions/traefik.d.cts +1 -1
  908. package/dist/services/definitions/traefik.d.mts +1 -1
  909. package/dist/services/definitions/twenty-worker.cjs +73 -0
  910. package/dist/services/definitions/twenty-worker.cjs.map +1 -0
  911. package/dist/services/definitions/twenty-worker.d.cts +7 -0
  912. package/dist/services/definitions/twenty-worker.d.cts.map +1 -0
  913. package/dist/services/definitions/twenty-worker.d.mts +7 -0
  914. package/dist/services/definitions/twenty-worker.d.mts.map +1 -0
  915. package/dist/services/definitions/twenty-worker.mjs +72 -0
  916. package/dist/services/definitions/twenty-worker.mjs.map +1 -0
  917. package/dist/services/definitions/twenty.cjs +24 -2
  918. package/dist/services/definitions/twenty.cjs.map +1 -1
  919. package/dist/services/definitions/twenty.d.cts +1 -1
  920. package/dist/services/definitions/twenty.d.mts +1 -1
  921. package/dist/services/definitions/twenty.mjs +24 -2
  922. package/dist/services/definitions/twenty.mjs.map +1 -1
  923. package/dist/services/definitions/umami.d.cts +1 -1
  924. package/dist/services/definitions/umami.d.mts +1 -1
  925. package/dist/services/definitions/uptime-kuma.d.cts +1 -1
  926. package/dist/services/definitions/uptime-kuma.d.mts +1 -1
  927. package/dist/services/definitions/usesend.d.cts +1 -1
  928. package/dist/services/definitions/usesend.d.mts +1 -1
  929. package/dist/services/definitions/valkey.d.cts +1 -1
  930. package/dist/services/definitions/valkey.d.mts +1 -1
  931. package/dist/services/definitions/vault.d.cts +1 -1
  932. package/dist/services/definitions/vault.d.mts +1 -1
  933. package/dist/services/definitions/vaultwarden.d.cts +1 -1
  934. package/dist/services/definitions/vaultwarden.d.mts +1 -1
  935. package/dist/services/definitions/vector-log.d.cts +1 -1
  936. package/dist/services/definitions/vector-log.d.mts +1 -1
  937. package/dist/services/definitions/vikunja.d.cts +1 -1
  938. package/dist/services/definitions/vikunja.d.mts +1 -1
  939. package/dist/services/definitions/watchtower.d.cts +1 -1
  940. package/dist/services/definitions/watchtower.d.mts +1 -1
  941. package/dist/services/definitions/weaviate.cjs +4 -1
  942. package/dist/services/definitions/weaviate.cjs.map +1 -1
  943. package/dist/services/definitions/weaviate.d.cts +1 -1
  944. package/dist/services/definitions/weaviate.d.mts +1 -1
  945. package/dist/services/definitions/weaviate.mjs +4 -1
  946. package/dist/services/definitions/weaviate.mjs.map +1 -1
  947. package/dist/services/definitions/whisper.d.cts +1 -1
  948. package/dist/services/definitions/whisper.d.mts +1 -1
  949. package/dist/services/definitions/wireguard.d.cts +1 -1
  950. package/dist/services/definitions/wireguard.d.mts +1 -1
  951. package/dist/services/definitions/woodpecker-ci.d.cts +1 -1
  952. package/dist/services/definitions/woodpecker-ci.d.mts +1 -1
  953. package/dist/services/definitions/xyops.d.cts +1 -1
  954. package/dist/services/definitions/xyops.d.mts +1 -1
  955. package/dist/services/definitions/zeroclaw.cjs +103 -0
  956. package/dist/services/definitions/zeroclaw.cjs.map +1 -0
  957. package/dist/services/definitions/zeroclaw.d.cts +7 -0
  958. package/dist/services/definitions/zeroclaw.d.cts.map +1 -0
  959. package/dist/services/definitions/zeroclaw.d.mts +7 -0
  960. package/dist/services/definitions/zeroclaw.d.mts.map +1 -0
  961. package/dist/services/definitions/zeroclaw.mjs +102 -0
  962. package/dist/services/definitions/zeroclaw.mjs.map +1 -0
  963. package/dist/services/definitions/zulip.d.cts +1 -1
  964. package/dist/services/definitions/zulip.d.mts +1 -1
  965. package/dist/services/registry.d.cts +1 -1
  966. package/dist/services/registry.d.mts +1 -1
  967. package/dist/services/registry.test.cjs +8 -8
  968. package/dist/services/registry.test.cjs.map +1 -1
  969. package/dist/services/registry.test.mjs +8 -8
  970. package/dist/services/registry.test.mjs.map +1 -1
  971. package/dist/skills/registry.cjs +19 -0
  972. package/dist/skills/registry.cjs.map +1 -1
  973. package/dist/skills/registry.d.cts +1 -1
  974. package/dist/skills/registry.d.cts.map +1 -1
  975. package/dist/skills/registry.d.mts +1 -1
  976. package/dist/skills/registry.d.mts.map +1 -1
  977. package/dist/skills/registry.mjs +19 -0
  978. package/dist/skills/registry.mjs.map +1 -1
  979. package/dist/{skills-BSF7iNa4.cjs → skills-uPxJVmKk.cjs} +311 -1
  980. package/dist/skills-uPxJVmKk.cjs.map +1 -0
  981. package/dist/{test.CTcmp4Su-ClCHJ3FA.mjs → test.CTcmp4Su-BRa7-bTj.mjs} +2 -2
  982. package/dist/{test.CTcmp4Su-ClCHJ3FA.mjs.map → test.CTcmp4Su-BRa7-bTj.mjs.map} +1 -1
  983. package/dist/{test.CTcmp4Su-DlzTarwH.cjs → test.CTcmp4Su-BWSPM8ZQ.cjs} +19 -1
  984. package/dist/{test.CTcmp4Su-DlzTarwH.cjs.map → test.CTcmp4Su-BWSPM8ZQ.cjs.map} +1 -1
  985. package/dist/track-analytics.d.cts +1 -1
  986. package/dist/track-analytics.d.mts +1 -1
  987. package/dist/track-analytics.test.cjs +1 -1
  988. package/dist/track-analytics.test.mjs +1 -1
  989. package/dist/types-BREUfzzq.d.mts +77 -0
  990. package/dist/types-BREUfzzq.d.mts.map +1 -0
  991. package/dist/types-Bsn0XzSP.d.cts +95 -0
  992. package/dist/types-Bsn0XzSP.d.cts.map +1 -0
  993. package/dist/types-CyZ5mn6w.d.cts +77 -0
  994. package/dist/types-CyZ5mn6w.d.cts.map +1 -0
  995. package/dist/types-DIsPc-hb.d.cts +100 -0
  996. package/dist/types-DIsPc-hb.d.cts.map +1 -0
  997. package/dist/types-DbXajvYq.d.mts +100 -0
  998. package/dist/types-DbXajvYq.d.mts.map +1 -0
  999. package/dist/types-DwTKyCZ9.d.mts +95 -0
  1000. package/dist/types-DwTKyCZ9.d.mts.map +1 -0
  1001. package/dist/{types-CR83OJiq.d.cts → types-dyBnrHm9.d.cts} +5 -1
  1002. package/dist/types-dyBnrHm9.d.cts.map +1 -0
  1003. package/dist/{types-zYjGTuyn.d.mts → types-fRSnaZTX.d.mts} +5 -1
  1004. package/dist/types-fRSnaZTX.d.mts.map +1 -0
  1005. package/dist/types.cjs +7 -0
  1006. package/dist/types.cjs.map +1 -1
  1007. package/dist/types.d.cts +2 -93
  1008. package/dist/types.d.mts +2 -93
  1009. package/dist/types.mjs +7 -0
  1010. package/dist/types.mjs.map +1 -1
  1011. package/dist/validator.cjs +1 -1
  1012. package/dist/validator.d.cts +1 -1
  1013. package/dist/validator.d.mts +1 -1
  1014. package/dist/validator.test.cjs +1 -1
  1015. package/dist/validator.test.mjs +1 -1
  1016. package/dist/version-manager.d.cts +1 -1
  1017. package/dist/version-manager.d.mts +1 -1
  1018. package/dist/version-manager.test.cjs +3 -3
  1019. package/dist/version-manager.test.cjs.map +1 -1
  1020. package/dist/version-manager.test.mjs +3 -3
  1021. package/dist/version-manager.test.mjs.map +1 -1
  1022. package/dist/zeroclaw-B-0TuOfZ.d.mts +7 -0
  1023. package/dist/zeroclaw-B-0TuOfZ.d.mts.map +1 -0
  1024. package/dist/zeroclaw-BvKpDHKe.d.cts +7 -0
  1025. package/dist/zeroclaw-BvKpDHKe.d.cts.map +1 -0
  1026. package/package.json +6 -2
  1027. package/src/addon-stack.test.ts +19 -23
  1028. package/src/addon-stack.ts +67 -44
  1029. package/src/composer.test.ts +59 -0
  1030. package/src/composer.ts +135 -194
  1031. package/src/deployers/coolify.test.ts +180 -0
  1032. package/src/deployers/coolify.ts +38 -0
  1033. package/src/deployers/dokploy.test.ts +120 -0
  1034. package/src/deployers/dokploy.ts +38 -0
  1035. package/src/deployers/types.ts +2 -0
  1036. package/src/frameworks/claude-code-fw.ts +118 -0
  1037. package/src/frameworks/codex-fw.ts +102 -0
  1038. package/src/frameworks/copaw.ts +154 -0
  1039. package/src/frameworks/frameworks.test.ts +119 -0
  1040. package/src/frameworks/index.ts +46 -0
  1041. package/src/frameworks/memu.ts +149 -0
  1042. package/src/frameworks/nanobot.ts +156 -0
  1043. package/src/frameworks/nanoclaw.ts +126 -0
  1044. package/src/frameworks/openclaw.ts +325 -0
  1045. package/src/frameworks/registry.test.ts +131 -0
  1046. package/src/frameworks/registry.ts +28 -0
  1047. package/src/frameworks/types.ts +146 -0
  1048. package/src/frameworks/zeroclaw.ts +148 -0
  1049. package/src/generate.test.ts +55 -4
  1050. package/src/generate.ts +67 -14
  1051. package/src/generators/caddy.test.ts +41 -1
  1052. package/src/generators/caddy.ts +16 -2
  1053. package/src/generators/clone-repos.test.ts +1 -1
  1054. package/src/generators/clone-repos.ts +7 -2
  1055. package/src/generators/cloud-init.test.ts +70 -0
  1056. package/src/generators/env.test.ts +2 -2
  1057. package/src/generators/env.ts +30 -180
  1058. package/src/generators/get-shit-done.test.ts +54 -0
  1059. package/src/generators/grafana.test.ts +90 -0
  1060. package/src/generators/health-check.ts +4 -4
  1061. package/src/generators/n8n-workflows.test.ts +80 -0
  1062. package/src/generators/openclaw-install-script.test.ts +42 -0
  1063. package/src/generators/openclaw-json.ts +57 -5
  1064. package/src/generators/postgres-init.test.ts +116 -0
  1065. package/src/generators/postgres-init.ts +9 -0
  1066. package/src/generators/prometheus.test.ts +108 -0
  1067. package/src/generators/readme.ts +75 -9
  1068. package/src/generators/scripts.test.ts +1 -1
  1069. package/src/generators/skills.ts +316 -0
  1070. package/src/generators/stack-manifest.test.ts +104 -0
  1071. package/src/generators/traefik.test.ts +13 -13
  1072. package/src/index.ts +47 -7
  1073. package/src/logger/__tests__/logger.test.ts +388 -0
  1074. package/src/logger/index.ts +15 -0
  1075. package/src/logger/logger.ts +326 -0
  1076. package/src/logger/sinks/callback-sink.ts +13 -0
  1077. package/src/logger/sinks/console-sink.ts +51 -0
  1078. package/src/logger/sinks/file-sink.ts +121 -0
  1079. package/src/logger/types.ts +90 -0
  1080. package/src/migrations.ts +8 -1
  1081. package/src/port-scanner.test.ts +167 -0
  1082. package/src/presets/presets.test.ts +4 -4
  1083. package/src/presets/registry.test.ts +6 -6
  1084. package/src/resolver.test.ts +31 -3
  1085. package/src/resolver.ts +19 -3
  1086. package/src/schema.test.ts +2 -2
  1087. package/src/schema.ts +58 -17
  1088. package/src/services/definitions/agent-browser.ts +177 -0
  1089. package/src/services/definitions/apptension-saas.ts +2 -1
  1090. package/src/services/definitions/chromadb.ts +1 -1
  1091. package/src/services/definitions/claude-code.ts +1 -1
  1092. package/src/services/definitions/clawrouter.ts +141 -0
  1093. package/src/services/definitions/codex.ts +1 -1
  1094. package/src/services/definitions/convex.ts +1 -2
  1095. package/src/services/definitions/copaw.ts +101 -0
  1096. package/src/services/definitions/desktop-environment.ts +1 -0
  1097. package/src/services/definitions/hindsight.ts +3 -2
  1098. package/src/services/definitions/index.ts +53 -16
  1099. package/src/services/definitions/mem0.ts +132 -0
  1100. package/src/services/definitions/memu.ts +96 -0
  1101. package/src/services/definitions/milvus.ts +1 -1
  1102. package/src/services/definitions/nanobot.ts +89 -0
  1103. package/src/services/definitions/nanoclaw.ts +78 -0
  1104. package/src/services/definitions/opensandbox.ts +6 -15
  1105. package/src/services/definitions/relaticle-horizon.ts +48 -0
  1106. package/src/services/definitions/relaticle-scheduler.ts +42 -0
  1107. package/src/services/definitions/relaticle.ts +142 -0
  1108. package/src/services/definitions/twenty-worker.ts +70 -0
  1109. package/src/services/definitions/twenty.ts +16 -2
  1110. package/src/services/definitions/weaviate.ts +1 -1
  1111. package/src/services/definitions/zeroclaw.ts +102 -0
  1112. package/src/services/registry.test.ts +7 -7
  1113. package/src/skills/registry.ts +10 -0
  1114. package/src/types.ts +11 -1
  1115. package/src/version-manager.test.ts +2 -2
  1116. package/dist/schema-BQnZrcw8.d.cts.map +0 -1
  1117. package/dist/schema-SBpL0bdI.d.mts.map +0 -1
  1118. package/dist/skills-BSF7iNa4.cjs.map +0 -1
  1119. package/dist/types-CR83OJiq.d.cts.map +0 -1
  1120. package/dist/types-zYjGTuyn.d.mts.map +0 -1
  1121. package/dist/types.d.cts.map +0 -1
  1122. package/dist/types.d.mts.map +0 -1
@@ -29,6 +29,7 @@ function generateCaddyfile(resolved, domain) {
29
29
  if (exposedPorts.length === 0) continue;
30
30
  const primaryPort = exposedPorts[0];
31
31
  const subdomain = `${definition.id}.${domain}`;
32
+ const needsWebSocket = primaryPort.websocket === true;
32
33
  const block = [
33
34
  `# ${definition.icon} ${definition.name}`,
34
35
  `# ${definition.description}`,
@@ -37,9 +38,10 @@ function generateCaddyfile(resolved, domain) {
37
38
  ` header_up Host {host}`,
38
39
  ` header_up X-Real-IP {remote_host}`,
39
40
  ` header_up X-Forwarded-For {remote_host}`,
40
- ` header_up X-Forwarded-Proto {scheme}`,
41
- ` }`
41
+ ` header_up X-Forwarded-Proto {scheme}`
42
42
  ];
43
+ if (needsWebSocket) block.push(` flush_interval -1`);
44
+ block.push(` }`);
43
45
  if (definition.healthcheck) {
44
46
  block.push("");
45
47
  block.push(` # Health check`);
@@ -54,7 +56,11 @@ function generateCaddyfile(resolved, domain) {
54
56
  const portSubdomain = `${definition.id}-${port.description.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/-+$/, "")}.${domain}`;
55
57
  block.push(`# ${definition.name} — ${port.description}`);
56
58
  block.push(`${portSubdomain} {`);
57
- block.push(` reverse_proxy ${definition.id}:${port.container}`);
59
+ if (port.websocket) {
60
+ block.push(` reverse_proxy ${definition.id}:${port.container} {`);
61
+ block.push(` flush_interval -1`);
62
+ block.push(` }`);
63
+ } else block.push(` reverse_proxy ${definition.id}:${port.container}`);
58
64
  block.push(`}`);
59
65
  block.push("");
60
66
  }
@@ -1 +1 @@
1
- {"version":3,"file":"caddy.cjs","names":[],"sources":["../../src/generators/caddy.ts"],"sourcesContent":["import type { ResolverOutput } from \"../types.js\";\n\n/**\n * Generates a Caddyfile with reverse proxy entries for each exposed service.\n *\n * Each service with exposed ports gets a subdomain route under the provided domain.\n * Services without exposed ports are skipped.\n *\n * @param resolved - The resolved service configuration\n * @param domain - The main domain for routing (e.g. \"example.com\")\n * @returns The Caddyfile content as a string\n */\nexport function generateCaddyfile(resolved: ResolverOutput, domain: string): string {\n\tconst sections: string[] = [];\n\n\t// ── Global Options ──────────────────────────────────────────────────────\n\n\tsections.push(`# ═══════════════════════════════════════════════════════════════════════════════\n# OpenClaw Caddyfile — Auto-generated reverse proxy configuration\n# Domain: ${domain}\n# ═══════════════════════════════════════════════════════════════════════════════\n\n{\n\t# Global options\n\temail admin@${domain}\n\tacme_ca https://acme-v02.api.letsencrypt.org/directory\n}\n`);\n\n\t// ── Per-Service Reverse Proxy Blocks ─────────────────────────────────────\n\n\tfor (const { definition } of resolved.services) {\n\t\t// Skip the proxy service itself\n\t\tif (definition.id === \"caddy\" || definition.id === \"traefik\") continue;\n\n\t\tconst exposedPorts = definition.ports.filter((p) => p.exposed);\n\t\tif (exposedPorts.length === 0) continue;\n\n\t\t// Use the first exposed port as the primary route target\n\t\tconst primaryPort = exposedPorts[0]!;\n\t\tconst subdomain = `${definition.id}.${domain}`;\n\n\t\tconst block = [\n\t\t\t`# ${definition.icon} ${definition.name}`,\n\t\t\t`# ${definition.description}`,\n\t\t\t`${subdomain} {`,\n\t\t\t`\treverse_proxy ${definition.id}:${primaryPort.container} {`,\n\t\t\t`\t\theader_up Host {host}`,\n\t\t\t`\t\theader_up X-Real-IP {remote_host}`,\n\t\t\t`\t\theader_up X-Forwarded-For {remote_host}`,\n\t\t\t`\t\theader_up X-Forwarded-Proto {scheme}`,\n\t\t\t`\t}`,\n\t\t];\n\n\t\t// Add health check if service has one\n\t\tif (definition.healthcheck) {\n\t\t\tblock.push(\"\");\n\t\t\tblock.push(`\t# Health check`);\n\t\t\tblock.push(`\thandle /health {`);\n\t\t\tblock.push(`\t\treverse_proxy ${definition.id}:${primaryPort.container}`);\n\t\t\tblock.push(`\t}`);\n\t\t}\n\n\t\tblock.push(`}`);\n\t\tblock.push(\"\");\n\n\t\t// If there are additional exposed ports, add them as separate entries\n\t\tfor (let i = 1; i < exposedPorts.length; i++) {\n\t\t\tconst port = exposedPorts[i]!;\n\t\t\tconst portSubdomain = `${definition.id}-${port.description\n\t\t\t\t.toLowerCase()\n\t\t\t\t.replace(/[^a-z0-9]+/g, \"-\")\n\t\t\t\t.replace(/-+$/, \"\")}.${domain}`;\n\n\t\t\tblock.push(`# ${definition.name} — ${port.description}`);\n\t\t\tblock.push(`${portSubdomain} {`);\n\t\t\tblock.push(`\treverse_proxy ${definition.id}:${port.container}`);\n\t\t\tblock.push(`}`);\n\t\t\tblock.push(\"\");\n\t\t}\n\n\t\tsections.push(block.join(\"\\n\"));\n\t}\n\n\t// ── Fallback / Root Domain ──────────────────────────────────────────────\n\n\tsections.push(`# Root domain — serves the OpenClaw gateway\n${domain} {\n\treverse_proxy openclaw:18789 {\n\t\theader_up Host {host}\n\t\theader_up X-Real-IP {remote_host}\n\t\theader_up X-Forwarded-For {remote_host}\n\t\theader_up X-Forwarded-Proto {scheme}\n\t}\n}\n`);\n\n\treturn sections.join(\"\\n\");\n}\n"],"mappings":";;;;;;;;;;;;AAYA,SAAgB,kBAAkB,UAA0B,QAAwB;CACnF,MAAM,WAAqB,EAAE;AAI7B,UAAS,KAAK;;YAEH,OAAO;;;;;eAKJ,OAAO;;;EAGpB;AAID,MAAK,MAAM,EAAE,gBAAgB,SAAS,UAAU;AAE/C,MAAI,WAAW,OAAO,WAAW,WAAW,OAAO,UAAW;EAE9D,MAAM,eAAe,WAAW,MAAM,QAAQ,MAAM,EAAE,QAAQ;AAC9D,MAAI,aAAa,WAAW,EAAG;EAG/B,MAAM,cAAc,aAAa;EACjC,MAAM,YAAY,GAAG,WAAW,GAAG,GAAG;EAEtC,MAAM,QAAQ;GACb,KAAK,WAAW,KAAK,GAAG,WAAW;GACnC,KAAK,WAAW;GAChB,GAAG,UAAU;GACb,kBAAkB,WAAW,GAAG,GAAG,YAAY,UAAU;GACzD;GACA;GACA;GACA;GACA;GACA;AAGD,MAAI,WAAW,aAAa;AAC3B,SAAM,KAAK,GAAG;AACd,SAAM,KAAK,kBAAkB;AAC7B,SAAM,KAAK,oBAAoB;AAC/B,SAAM,KAAK,mBAAmB,WAAW,GAAG,GAAG,YAAY,YAAY;AACvE,SAAM,KAAK,KAAK;;AAGjB,QAAM,KAAK,IAAI;AACf,QAAM,KAAK,GAAG;AAGd,OAAK,IAAI,IAAI,GAAG,IAAI,aAAa,QAAQ,KAAK;GAC7C,MAAM,OAAO,aAAa;GAC1B,MAAM,gBAAgB,GAAG,WAAW,GAAG,GAAG,KAAK,YAC7C,aAAa,CACb,QAAQ,eAAe,IAAI,CAC3B,QAAQ,OAAO,GAAG,CAAC,GAAG;AAExB,SAAM,KAAK,KAAK,WAAW,KAAK,KAAK,KAAK,cAAc;AACxD,SAAM,KAAK,GAAG,cAAc,IAAI;AAChC,SAAM,KAAK,kBAAkB,WAAW,GAAG,GAAG,KAAK,YAAY;AAC/D,SAAM,KAAK,IAAI;AACf,SAAM,KAAK,GAAG;;AAGf,WAAS,KAAK,MAAM,KAAK,KAAK,CAAC;;AAKhC,UAAS,KAAK;EACb,OAAO;;;;;;;;EAQP;AAED,QAAO,SAAS,KAAK,KAAK"}
1
+ {"version":3,"file":"caddy.cjs","names":[],"sources":["../../src/generators/caddy.ts"],"sourcesContent":["import type { ResolverOutput } from \"../types.js\";\n\n/**\n * Generates a Caddyfile with reverse proxy entries for each exposed service.\n *\n * Each service with exposed ports gets a subdomain route under the provided domain.\n * Services without exposed ports are skipped.\n *\n * @param resolved - The resolved service configuration\n * @param domain - The main domain for routing (e.g. \"example.com\")\n * @returns The Caddyfile content as a string\n */\nexport function generateCaddyfile(resolved: ResolverOutput, domain: string): string {\n\tconst sections: string[] = [];\n\n\t// ── Global Options ──────────────────────────────────────────────────────\n\n\tsections.push(`# ═══════════════════════════════════════════════════════════════════════════════\n# OpenClaw Caddyfile — Auto-generated reverse proxy configuration\n# Domain: ${domain}\n# ═══════════════════════════════════════════════════════════════════════════════\n\n{\n\t# Global options\n\temail admin@${domain}\n\tacme_ca https://acme-v02.api.letsencrypt.org/directory\n}\n`);\n\n\t// ── Per-Service Reverse Proxy Blocks ─────────────────────────────────────\n\n\tfor (const { definition } of resolved.services) {\n\t\t// Skip the proxy service itself\n\t\tif (definition.id === \"caddy\" || definition.id === \"traefik\") continue;\n\n\t\tconst exposedPorts = definition.ports.filter((p) => p.exposed);\n\t\tif (exposedPorts.length === 0) continue;\n\n\t\t// Use the first exposed port as the primary route target\n\t\tconst primaryPort = exposedPorts[0]!;\n\t\tconst subdomain = `${definition.id}.${domain}`;\n\n\t\tconst needsWebSocket = primaryPort.websocket === true;\n\n\t\tconst block = [\n\t\t\t`# ${definition.icon} ${definition.name}`,\n\t\t\t`# ${definition.description}`,\n\t\t\t`${subdomain} {`,\n\t\t\t`\treverse_proxy ${definition.id}:${primaryPort.container} {`,\n\t\t\t`\t\theader_up Host {host}`,\n\t\t\t`\t\theader_up X-Real-IP {remote_host}`,\n\t\t\t`\t\theader_up X-Forwarded-For {remote_host}`,\n\t\t\t`\t\theader_up X-Forwarded-Proto {scheme}`,\n\t\t];\n\n\t\t// Disable response buffering for streaming WebSocket connections (noVNC, KasmVNC)\n\t\tif (needsWebSocket) {\n\t\t\tblock.push(`\t\tflush_interval -1`);\n\t\t}\n\n\t\tblock.push(`\t}`);\n\n\t\t// Add health check if service has one\n\t\tif (definition.healthcheck) {\n\t\t\tblock.push(\"\");\n\t\t\tblock.push(`\t# Health check`);\n\t\t\tblock.push(`\thandle /health {`);\n\t\t\tblock.push(`\t\treverse_proxy ${definition.id}:${primaryPort.container}`);\n\t\t\tblock.push(`\t}`);\n\t\t}\n\n\t\tblock.push(`}`);\n\t\tblock.push(\"\");\n\n\t\t// If there are additional exposed ports, add them as separate entries\n\t\tfor (let i = 1; i < exposedPorts.length; i++) {\n\t\t\tconst port = exposedPorts[i]!;\n\t\t\tconst portSubdomain = `${definition.id}-${port.description\n\t\t\t\t.toLowerCase()\n\t\t\t\t.replace(/[^a-z0-9]+/g, \"-\")\n\t\t\t\t.replace(/-+$/, \"\")}.${domain}`;\n\n\t\t\tblock.push(`# ${definition.name} — ${port.description}`);\n\t\t\tblock.push(`${portSubdomain} {`);\n\t\t\tif (port.websocket) {\n\t\t\t\tblock.push(`\treverse_proxy ${definition.id}:${port.container} {`);\n\t\t\t\tblock.push(`\t\tflush_interval -1`);\n\t\t\t\tblock.push(`\t}`);\n\t\t\t} else {\n\t\t\t\tblock.push(`\treverse_proxy ${definition.id}:${port.container}`);\n\t\t\t}\n\t\t\tblock.push(`}`);\n\t\t\tblock.push(\"\");\n\t\t}\n\n\t\tsections.push(block.join(\"\\n\"));\n\t}\n\n\t// ── Fallback / Root Domain ──────────────────────────────────────────────\n\n\tsections.push(`# Root domain — serves the OpenClaw gateway\n${domain} {\n\treverse_proxy openclaw:18789 {\n\t\theader_up Host {host}\n\t\theader_up X-Real-IP {remote_host}\n\t\theader_up X-Forwarded-For {remote_host}\n\t\theader_up X-Forwarded-Proto {scheme}\n\t}\n}\n`);\n\n\treturn sections.join(\"\\n\");\n}\n"],"mappings":";;;;;;;;;;;;AAYA,SAAgB,kBAAkB,UAA0B,QAAwB;CACnF,MAAM,WAAqB,EAAE;AAI7B,UAAS,KAAK;;YAEH,OAAO;;;;;eAKJ,OAAO;;;EAGpB;AAID,MAAK,MAAM,EAAE,gBAAgB,SAAS,UAAU;AAE/C,MAAI,WAAW,OAAO,WAAW,WAAW,OAAO,UAAW;EAE9D,MAAM,eAAe,WAAW,MAAM,QAAQ,MAAM,EAAE,QAAQ;AAC9D,MAAI,aAAa,WAAW,EAAG;EAG/B,MAAM,cAAc,aAAa;EACjC,MAAM,YAAY,GAAG,WAAW,GAAG,GAAG;EAEtC,MAAM,iBAAiB,YAAY,cAAc;EAEjD,MAAM,QAAQ;GACb,KAAK,WAAW,KAAK,GAAG,WAAW;GACnC,KAAK,WAAW;GAChB,GAAG,UAAU;GACb,kBAAkB,WAAW,GAAG,GAAG,YAAY,UAAU;GACzD;GACA;GACA;GACA;GACA;AAGD,MAAI,eACH,OAAM,KAAK,sBAAsB;AAGlC,QAAM,KAAK,KAAK;AAGhB,MAAI,WAAW,aAAa;AAC3B,SAAM,KAAK,GAAG;AACd,SAAM,KAAK,kBAAkB;AAC7B,SAAM,KAAK,oBAAoB;AAC/B,SAAM,KAAK,mBAAmB,WAAW,GAAG,GAAG,YAAY,YAAY;AACvE,SAAM,KAAK,KAAK;;AAGjB,QAAM,KAAK,IAAI;AACf,QAAM,KAAK,GAAG;AAGd,OAAK,IAAI,IAAI,GAAG,IAAI,aAAa,QAAQ,KAAK;GAC7C,MAAM,OAAO,aAAa;GAC1B,MAAM,gBAAgB,GAAG,WAAW,GAAG,GAAG,KAAK,YAC7C,aAAa,CACb,QAAQ,eAAe,IAAI,CAC3B,QAAQ,OAAO,GAAG,CAAC,GAAG;AAExB,SAAM,KAAK,KAAK,WAAW,KAAK,KAAK,KAAK,cAAc;AACxD,SAAM,KAAK,GAAG,cAAc,IAAI;AAChC,OAAI,KAAK,WAAW;AACnB,UAAM,KAAK,kBAAkB,WAAW,GAAG,GAAG,KAAK,UAAU,IAAI;AACjE,UAAM,KAAK,sBAAsB;AACjC,UAAM,KAAK,KAAK;SAEhB,OAAM,KAAK,kBAAkB,WAAW,GAAG,GAAG,KAAK,YAAY;AAEhE,SAAM,KAAK,IAAI;AACf,SAAM,KAAK,GAAG;;AAGf,WAAS,KAAK,MAAM,KAAK,KAAK,CAAC;;AAKhC,UAAS,KAAK;EACb,OAAO;;;;;;;;EAQP;AAED,QAAO,SAAS,KAAK,KAAK"}
@@ -1,4 +1,4 @@
1
- import { ResolverOutput } from "../types.cjs";
1
+ import { B as ResolverOutput } from "../types-Bsn0XzSP.cjs";
2
2
 
3
3
  //#region src/generators/caddy.d.ts
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { ResolverOutput } from "../types.mjs";
1
+ import { B as ResolverOutput } from "../types-DwTKyCZ9.mjs";
2
2
 
3
3
  //#region src/generators/caddy.d.ts
4
4
  /**
@@ -28,6 +28,7 @@ function generateCaddyfile(resolved, domain) {
28
28
  if (exposedPorts.length === 0) continue;
29
29
  const primaryPort = exposedPorts[0];
30
30
  const subdomain = `${definition.id}.${domain}`;
31
+ const needsWebSocket = primaryPort.websocket === true;
31
32
  const block = [
32
33
  `# ${definition.icon} ${definition.name}`,
33
34
  `# ${definition.description}`,
@@ -36,9 +37,10 @@ function generateCaddyfile(resolved, domain) {
36
37
  ` header_up Host {host}`,
37
38
  ` header_up X-Real-IP {remote_host}`,
38
39
  ` header_up X-Forwarded-For {remote_host}`,
39
- ` header_up X-Forwarded-Proto {scheme}`,
40
- ` }`
40
+ ` header_up X-Forwarded-Proto {scheme}`
41
41
  ];
42
+ if (needsWebSocket) block.push(` flush_interval -1`);
43
+ block.push(` }`);
42
44
  if (definition.healthcheck) {
43
45
  block.push("");
44
46
  block.push(` # Health check`);
@@ -53,7 +55,11 @@ function generateCaddyfile(resolved, domain) {
53
55
  const portSubdomain = `${definition.id}-${port.description.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/-+$/, "")}.${domain}`;
54
56
  block.push(`# ${definition.name} — ${port.description}`);
55
57
  block.push(`${portSubdomain} {`);
56
- block.push(` reverse_proxy ${definition.id}:${port.container}`);
58
+ if (port.websocket) {
59
+ block.push(` reverse_proxy ${definition.id}:${port.container} {`);
60
+ block.push(` flush_interval -1`);
61
+ block.push(` }`);
62
+ } else block.push(` reverse_proxy ${definition.id}:${port.container}`);
57
63
  block.push(`}`);
58
64
  block.push("");
59
65
  }
@@ -1 +1 @@
1
- {"version":3,"file":"caddy.mjs","names":[],"sources":["../../src/generators/caddy.ts"],"sourcesContent":["import type { ResolverOutput } from \"../types.js\";\n\n/**\n * Generates a Caddyfile with reverse proxy entries for each exposed service.\n *\n * Each service with exposed ports gets a subdomain route under the provided domain.\n * Services without exposed ports are skipped.\n *\n * @param resolved - The resolved service configuration\n * @param domain - The main domain for routing (e.g. \"example.com\")\n * @returns The Caddyfile content as a string\n */\nexport function generateCaddyfile(resolved: ResolverOutput, domain: string): string {\n\tconst sections: string[] = [];\n\n\t// ── Global Options ──────────────────────────────────────────────────────\n\n\tsections.push(`# ═══════════════════════════════════════════════════════════════════════════════\n# OpenClaw Caddyfile — Auto-generated reverse proxy configuration\n# Domain: ${domain}\n# ═══════════════════════════════════════════════════════════════════════════════\n\n{\n\t# Global options\n\temail admin@${domain}\n\tacme_ca https://acme-v02.api.letsencrypt.org/directory\n}\n`);\n\n\t// ── Per-Service Reverse Proxy Blocks ─────────────────────────────────────\n\n\tfor (const { definition } of resolved.services) {\n\t\t// Skip the proxy service itself\n\t\tif (definition.id === \"caddy\" || definition.id === \"traefik\") continue;\n\n\t\tconst exposedPorts = definition.ports.filter((p) => p.exposed);\n\t\tif (exposedPorts.length === 0) continue;\n\n\t\t// Use the first exposed port as the primary route target\n\t\tconst primaryPort = exposedPorts[0]!;\n\t\tconst subdomain = `${definition.id}.${domain}`;\n\n\t\tconst block = [\n\t\t\t`# ${definition.icon} ${definition.name}`,\n\t\t\t`# ${definition.description}`,\n\t\t\t`${subdomain} {`,\n\t\t\t`\treverse_proxy ${definition.id}:${primaryPort.container} {`,\n\t\t\t`\t\theader_up Host {host}`,\n\t\t\t`\t\theader_up X-Real-IP {remote_host}`,\n\t\t\t`\t\theader_up X-Forwarded-For {remote_host}`,\n\t\t\t`\t\theader_up X-Forwarded-Proto {scheme}`,\n\t\t\t`\t}`,\n\t\t];\n\n\t\t// Add health check if service has one\n\t\tif (definition.healthcheck) {\n\t\t\tblock.push(\"\");\n\t\t\tblock.push(`\t# Health check`);\n\t\t\tblock.push(`\thandle /health {`);\n\t\t\tblock.push(`\t\treverse_proxy ${definition.id}:${primaryPort.container}`);\n\t\t\tblock.push(`\t}`);\n\t\t}\n\n\t\tblock.push(`}`);\n\t\tblock.push(\"\");\n\n\t\t// If there are additional exposed ports, add them as separate entries\n\t\tfor (let i = 1; i < exposedPorts.length; i++) {\n\t\t\tconst port = exposedPorts[i]!;\n\t\t\tconst portSubdomain = `${definition.id}-${port.description\n\t\t\t\t.toLowerCase()\n\t\t\t\t.replace(/[^a-z0-9]+/g, \"-\")\n\t\t\t\t.replace(/-+$/, \"\")}.${domain}`;\n\n\t\t\tblock.push(`# ${definition.name} — ${port.description}`);\n\t\t\tblock.push(`${portSubdomain} {`);\n\t\t\tblock.push(`\treverse_proxy ${definition.id}:${port.container}`);\n\t\t\tblock.push(`}`);\n\t\t\tblock.push(\"\");\n\t\t}\n\n\t\tsections.push(block.join(\"\\n\"));\n\t}\n\n\t// ── Fallback / Root Domain ──────────────────────────────────────────────\n\n\tsections.push(`# Root domain — serves the OpenClaw gateway\n${domain} {\n\treverse_proxy openclaw:18789 {\n\t\theader_up Host {host}\n\t\theader_up X-Real-IP {remote_host}\n\t\theader_up X-Forwarded-For {remote_host}\n\t\theader_up X-Forwarded-Proto {scheme}\n\t}\n}\n`);\n\n\treturn sections.join(\"\\n\");\n}\n"],"mappings":";;;;;;;;;;;AAYA,SAAgB,kBAAkB,UAA0B,QAAwB;CACnF,MAAM,WAAqB,EAAE;AAI7B,UAAS,KAAK;;YAEH,OAAO;;;;;eAKJ,OAAO;;;EAGpB;AAID,MAAK,MAAM,EAAE,gBAAgB,SAAS,UAAU;AAE/C,MAAI,WAAW,OAAO,WAAW,WAAW,OAAO,UAAW;EAE9D,MAAM,eAAe,WAAW,MAAM,QAAQ,MAAM,EAAE,QAAQ;AAC9D,MAAI,aAAa,WAAW,EAAG;EAG/B,MAAM,cAAc,aAAa;EACjC,MAAM,YAAY,GAAG,WAAW,GAAG,GAAG;EAEtC,MAAM,QAAQ;GACb,KAAK,WAAW,KAAK,GAAG,WAAW;GACnC,KAAK,WAAW;GAChB,GAAG,UAAU;GACb,kBAAkB,WAAW,GAAG,GAAG,YAAY,UAAU;GACzD;GACA;GACA;GACA;GACA;GACA;AAGD,MAAI,WAAW,aAAa;AAC3B,SAAM,KAAK,GAAG;AACd,SAAM,KAAK,kBAAkB;AAC7B,SAAM,KAAK,oBAAoB;AAC/B,SAAM,KAAK,mBAAmB,WAAW,GAAG,GAAG,YAAY,YAAY;AACvE,SAAM,KAAK,KAAK;;AAGjB,QAAM,KAAK,IAAI;AACf,QAAM,KAAK,GAAG;AAGd,OAAK,IAAI,IAAI,GAAG,IAAI,aAAa,QAAQ,KAAK;GAC7C,MAAM,OAAO,aAAa;GAC1B,MAAM,gBAAgB,GAAG,WAAW,GAAG,GAAG,KAAK,YAC7C,aAAa,CACb,QAAQ,eAAe,IAAI,CAC3B,QAAQ,OAAO,GAAG,CAAC,GAAG;AAExB,SAAM,KAAK,KAAK,WAAW,KAAK,KAAK,KAAK,cAAc;AACxD,SAAM,KAAK,GAAG,cAAc,IAAI;AAChC,SAAM,KAAK,kBAAkB,WAAW,GAAG,GAAG,KAAK,YAAY;AAC/D,SAAM,KAAK,IAAI;AACf,SAAM,KAAK,GAAG;;AAGf,WAAS,KAAK,MAAM,KAAK,KAAK,CAAC;;AAKhC,UAAS,KAAK;EACb,OAAO;;;;;;;;EAQP;AAED,QAAO,SAAS,KAAK,KAAK"}
1
+ {"version":3,"file":"caddy.mjs","names":[],"sources":["../../src/generators/caddy.ts"],"sourcesContent":["import type { ResolverOutput } from \"../types.js\";\n\n/**\n * Generates a Caddyfile with reverse proxy entries for each exposed service.\n *\n * Each service with exposed ports gets a subdomain route under the provided domain.\n * Services without exposed ports are skipped.\n *\n * @param resolved - The resolved service configuration\n * @param domain - The main domain for routing (e.g. \"example.com\")\n * @returns The Caddyfile content as a string\n */\nexport function generateCaddyfile(resolved: ResolverOutput, domain: string): string {\n\tconst sections: string[] = [];\n\n\t// ── Global Options ──────────────────────────────────────────────────────\n\n\tsections.push(`# ═══════════════════════════════════════════════════════════════════════════════\n# OpenClaw Caddyfile — Auto-generated reverse proxy configuration\n# Domain: ${domain}\n# ═══════════════════════════════════════════════════════════════════════════════\n\n{\n\t# Global options\n\temail admin@${domain}\n\tacme_ca https://acme-v02.api.letsencrypt.org/directory\n}\n`);\n\n\t// ── Per-Service Reverse Proxy Blocks ─────────────────────────────────────\n\n\tfor (const { definition } of resolved.services) {\n\t\t// Skip the proxy service itself\n\t\tif (definition.id === \"caddy\" || definition.id === \"traefik\") continue;\n\n\t\tconst exposedPorts = definition.ports.filter((p) => p.exposed);\n\t\tif (exposedPorts.length === 0) continue;\n\n\t\t// Use the first exposed port as the primary route target\n\t\tconst primaryPort = exposedPorts[0]!;\n\t\tconst subdomain = `${definition.id}.${domain}`;\n\n\t\tconst needsWebSocket = primaryPort.websocket === true;\n\n\t\tconst block = [\n\t\t\t`# ${definition.icon} ${definition.name}`,\n\t\t\t`# ${definition.description}`,\n\t\t\t`${subdomain} {`,\n\t\t\t`\treverse_proxy ${definition.id}:${primaryPort.container} {`,\n\t\t\t`\t\theader_up Host {host}`,\n\t\t\t`\t\theader_up X-Real-IP {remote_host}`,\n\t\t\t`\t\theader_up X-Forwarded-For {remote_host}`,\n\t\t\t`\t\theader_up X-Forwarded-Proto {scheme}`,\n\t\t];\n\n\t\t// Disable response buffering for streaming WebSocket connections (noVNC, KasmVNC)\n\t\tif (needsWebSocket) {\n\t\t\tblock.push(`\t\tflush_interval -1`);\n\t\t}\n\n\t\tblock.push(`\t}`);\n\n\t\t// Add health check if service has one\n\t\tif (definition.healthcheck) {\n\t\t\tblock.push(\"\");\n\t\t\tblock.push(`\t# Health check`);\n\t\t\tblock.push(`\thandle /health {`);\n\t\t\tblock.push(`\t\treverse_proxy ${definition.id}:${primaryPort.container}`);\n\t\t\tblock.push(`\t}`);\n\t\t}\n\n\t\tblock.push(`}`);\n\t\tblock.push(\"\");\n\n\t\t// If there are additional exposed ports, add them as separate entries\n\t\tfor (let i = 1; i < exposedPorts.length; i++) {\n\t\t\tconst port = exposedPorts[i]!;\n\t\t\tconst portSubdomain = `${definition.id}-${port.description\n\t\t\t\t.toLowerCase()\n\t\t\t\t.replace(/[^a-z0-9]+/g, \"-\")\n\t\t\t\t.replace(/-+$/, \"\")}.${domain}`;\n\n\t\t\tblock.push(`# ${definition.name} — ${port.description}`);\n\t\t\tblock.push(`${portSubdomain} {`);\n\t\t\tif (port.websocket) {\n\t\t\t\tblock.push(`\treverse_proxy ${definition.id}:${port.container} {`);\n\t\t\t\tblock.push(`\t\tflush_interval -1`);\n\t\t\t\tblock.push(`\t}`);\n\t\t\t} else {\n\t\t\t\tblock.push(`\treverse_proxy ${definition.id}:${port.container}`);\n\t\t\t}\n\t\t\tblock.push(`}`);\n\t\t\tblock.push(\"\");\n\t\t}\n\n\t\tsections.push(block.join(\"\\n\"));\n\t}\n\n\t// ── Fallback / Root Domain ──────────────────────────────────────────────\n\n\tsections.push(`# Root domain — serves the OpenClaw gateway\n${domain} {\n\treverse_proxy openclaw:18789 {\n\t\theader_up Host {host}\n\t\theader_up X-Real-IP {remote_host}\n\t\theader_up X-Forwarded-For {remote_host}\n\t\theader_up X-Forwarded-Proto {scheme}\n\t}\n}\n`);\n\n\treturn sections.join(\"\\n\");\n}\n"],"mappings":";;;;;;;;;;;AAYA,SAAgB,kBAAkB,UAA0B,QAAwB;CACnF,MAAM,WAAqB,EAAE;AAI7B,UAAS,KAAK;;YAEH,OAAO;;;;;eAKJ,OAAO;;;EAGpB;AAID,MAAK,MAAM,EAAE,gBAAgB,SAAS,UAAU;AAE/C,MAAI,WAAW,OAAO,WAAW,WAAW,OAAO,UAAW;EAE9D,MAAM,eAAe,WAAW,MAAM,QAAQ,MAAM,EAAE,QAAQ;AAC9D,MAAI,aAAa,WAAW,EAAG;EAG/B,MAAM,cAAc,aAAa;EACjC,MAAM,YAAY,GAAG,WAAW,GAAG,GAAG;EAEtC,MAAM,iBAAiB,YAAY,cAAc;EAEjD,MAAM,QAAQ;GACb,KAAK,WAAW,KAAK,GAAG,WAAW;GACnC,KAAK,WAAW;GAChB,GAAG,UAAU;GACb,kBAAkB,WAAW,GAAG,GAAG,YAAY,UAAU;GACzD;GACA;GACA;GACA;GACA;AAGD,MAAI,eACH,OAAM,KAAK,sBAAsB;AAGlC,QAAM,KAAK,KAAK;AAGhB,MAAI,WAAW,aAAa;AAC3B,SAAM,KAAK,GAAG;AACd,SAAM,KAAK,kBAAkB;AAC7B,SAAM,KAAK,oBAAoB;AAC/B,SAAM,KAAK,mBAAmB,WAAW,GAAG,GAAG,YAAY,YAAY;AACvE,SAAM,KAAK,KAAK;;AAGjB,QAAM,KAAK,IAAI;AACf,QAAM,KAAK,GAAG;AAGd,OAAK,IAAI,IAAI,GAAG,IAAI,aAAa,QAAQ,KAAK;GAC7C,MAAM,OAAO,aAAa;GAC1B,MAAM,gBAAgB,GAAG,WAAW,GAAG,GAAG,KAAK,YAC7C,aAAa,CACb,QAAQ,eAAe,IAAI,CAC3B,QAAQ,OAAO,GAAG,CAAC,GAAG;AAExB,SAAM,KAAK,KAAK,WAAW,KAAK,KAAK,KAAK,cAAc;AACxD,SAAM,KAAK,GAAG,cAAc,IAAI;AAChC,OAAI,KAAK,WAAW;AACnB,UAAM,KAAK,kBAAkB,WAAW,GAAG,GAAG,KAAK,UAAU,IAAI;AACjE,UAAM,KAAK,sBAAsB;AACjC,UAAM,KAAK,KAAK;SAEhB,OAAM,KAAK,kBAAkB,WAAW,GAAG,GAAG,KAAK,YAAY;AAEhE,SAAM,KAAK,IAAI;AACf,SAAM,KAAK,GAAG;;AAGf,WAAS,KAAK,MAAM,KAAK,KAAK,CAAC;;AAKhC,UAAS,KAAK;EACb,OAAO;;;;;;;;EAQP;AAED,QAAO,SAAS,KAAK,KAAK"}
@@ -1,4 +1,4 @@
1
- const require_test_CTcmp4Su = require("../test.CTcmp4Su-DlzTarwH.cjs");
1
+ const require_test_CTcmp4Su = require("../test.CTcmp4Su-BWSPM8ZQ.cjs");
2
2
  const require_generate = require("../generate.cjs");
3
3
  //#region src/generators/caddy.test.ts
4
4
  require_test_CTcmp4Su.describe("generateCaddyfile (via generate)", () => {
@@ -17,7 +17,7 @@ require_test_CTcmp4Su.describe("generateCaddyfile (via generate)", () => {
17
17
  require_test_CTcmp4Su.it("generates Caddyfile when proxy is caddy", () => {
18
18
  const result = require_generate.generate(baseInput);
19
19
  require_test_CTcmp4Su.globalExpect(result.files).toHaveProperty("caddy/Caddyfile");
20
- require_test_CTcmp4Su.globalExpect(result.files["caddy/Caddyfile"].length).toBeGreaterThan(0);
20
+ require_test_CTcmp4Su.globalExpect(result.files["caddy/Caddyfile"]?.length).toBeGreaterThan(0);
21
21
  });
22
22
  require_test_CTcmp4Su.it("does not generate Caddyfile when proxy is none", () => {
23
23
  require_test_CTcmp4Su.globalExpect(require_generate.generate({
@@ -37,6 +37,34 @@ require_test_CTcmp4Su.describe("generateCaddyfile (via generate)", () => {
37
37
  const caddyfile = require_generate.generate(baseInput).files["caddy/Caddyfile"];
38
38
  require_test_CTcmp4Su.globalExpect(caddyfile.length).toBeGreaterThan(50);
39
39
  });
40
+ require_test_CTcmp4Su.it("adds flush_interval -1 for WebSocket-enabled services (opensandbox)", () => {
41
+ const caddyfile = require_generate.generate({
42
+ ...baseInput,
43
+ services: ["opensandbox"]
44
+ }).files["caddy/Caddyfile"];
45
+ require_test_CTcmp4Su.globalExpect(caddyfile).toContain("opensandbox");
46
+ require_test_CTcmp4Su.globalExpect(caddyfile).toContain("flush_interval -1");
47
+ });
48
+ require_test_CTcmp4Su.it("adds flush_interval -1 for desktop-environment (KasmVNC)", () => {
49
+ const caddyfile = require_generate.generate({
50
+ ...baseInput,
51
+ services: ["desktop-environment"]
52
+ }).files["caddy/Caddyfile"];
53
+ require_test_CTcmp4Su.globalExpect(caddyfile).toContain("desktop-environment");
54
+ require_test_CTcmp4Su.globalExpect(caddyfile).toContain("flush_interval -1");
55
+ });
56
+ require_test_CTcmp4Su.it("adds flush_interval -1 for agent-browser viewport streaming port", () => {
57
+ const caddyfile = require_generate.generate({
58
+ ...baseInput,
59
+ services: ["agent-browser"]
60
+ }).files["caddy/Caddyfile"];
61
+ require_test_CTcmp4Su.globalExpect(caddyfile).toContain("agent-browser");
62
+ require_test_CTcmp4Su.globalExpect(caddyfile).toContain("flush_interval -1");
63
+ });
64
+ require_test_CTcmp4Su.it("does NOT add flush_interval for non-WebSocket services", () => {
65
+ const caddyfile = require_generate.generate(baseInput).files["caddy/Caddyfile"];
66
+ require_test_CTcmp4Su.globalExpect(caddyfile).not.toContain("flush_interval");
67
+ });
40
68
  });
41
69
  //#endregion
42
70
 
@@ -1 +1 @@
1
- {"version":3,"file":"caddy.test.cjs","names":["describe","generate"],"sources":["../../src/generators/caddy.test.ts"],"sourcesContent":["import { describe, expect, it } from \"vitest\";\nimport { generate } from \"../generate.js\";\n\ndescribe(\"generateCaddyfile (via generate)\", () => {\n\tconst baseInput = {\n\t\tprojectName: \"caddy-test\",\n\t\tservices: [\"redis\", \"n8n\"],\n\t\tskillPacks: [] as string[],\n\t\tproxy: \"caddy\" as const,\n\t\tdomain: \"example.com\",\n\t\tgpu: false,\n\t\tplatform: \"linux/amd64\" as const,\n\t\tdeployment: \"local\" as const,\n\t\tgenerateSecrets: true,\n\t\topenclawVersion: \"latest\",\n\t};\n\n\tit(\"generates Caddyfile when proxy is caddy\", () => {\n\t\tconst result = generate(baseInput);\n\n\t\texpect(result.files).toHaveProperty(\"caddy/Caddyfile\");\n\t\texpect(result.files[\"caddy/Caddyfile\"]!.length).toBeGreaterThan(0);\n\t});\n\n\tit(\"does not generate Caddyfile when proxy is none\", () => {\n\t\tconst result = generate({\n\t\t\t...baseInput,\n\t\t\tproxy: \"none\",\n\t\t});\n\n\t\texpect(result.files).not.toHaveProperty(\"caddy/Caddyfile\");\n\t});\n\n\tit(\"Caddyfile contains the domain\", () => {\n\t\tconst result = generate(baseInput);\n\t\tconst caddyfile = result.files[\"caddy/Caddyfile\"]!;\n\n\t\texpect(caddyfile).toContain(\"example.com\");\n\t});\n\n\tit(\"Caddyfile includes reverse proxy directives for services with exposed ports\", () => {\n\t\tconst result = generate(baseInput);\n\t\tconst caddyfile = result.files[\"caddy/Caddyfile\"]!;\n\n\t\t// Should reference n8n since it has exposed ports\n\t\texpect(caddyfile).toContain(\"n8n\");\n\t});\n\n\tit(\"Caddyfile includes TLS configuration\", () => {\n\t\tconst result = generate(baseInput);\n\t\tconst caddyfile = result.files[\"caddy/Caddyfile\"]!;\n\n\t\t// Caddy auto-enables TLS, so should reference HTTPS or TLS\n\t\texpect(caddyfile.length).toBeGreaterThan(50);\n\t});\n});\n"],"mappings":";;;AAGAA,sBAAAA,SAAS,0CAA0C;CAClD,MAAM,YAAY;EACjB,aAAa;EACb,UAAU,CAAC,SAAS,MAAM;EAC1B,YAAY,EAAE;EACd,OAAO;EACP,QAAQ;EACR,KAAK;EACL,UAAU;EACV,YAAY;EACZ,iBAAiB;EACjB,iBAAiB;EACjB;AAED,uBAAA,GAAG,iDAAiD;EACnD,MAAM,SAASC,iBAAAA,SAAS,UAAU;AAElC,wBAAA,aAAO,OAAO,MAAM,CAAC,eAAe,kBAAkB;AACtD,wBAAA,aAAO,OAAO,MAAM,mBAAoB,OAAO,CAAC,gBAAgB,EAAE;GACjE;AAEF,uBAAA,GAAG,wDAAwD;AAM1D,wBAAA,aALeA,iBAAAA,SAAS;GACvB,GAAG;GACH,OAAO;GACP,CAAC,CAEY,MAAM,CAAC,IAAI,eAAe,kBAAkB;GACzD;AAEF,uBAAA,GAAG,uCAAuC;EAEzC,MAAM,YADSA,iBAAAA,SAAS,UAAU,CACT,MAAM;AAE/B,wBAAA,aAAO,UAAU,CAAC,UAAU,cAAc;GACzC;AAEF,uBAAA,GAAG,qFAAqF;EAEvF,MAAM,YADSA,iBAAAA,SAAS,UAAU,CACT,MAAM;AAG/B,wBAAA,aAAO,UAAU,CAAC,UAAU,MAAM;GACjC;AAEF,uBAAA,GAAG,8CAA8C;EAEhD,MAAM,YADSA,iBAAAA,SAAS,UAAU,CACT,MAAM;AAG/B,wBAAA,aAAO,UAAU,OAAO,CAAC,gBAAgB,GAAG;GAC3C;EACD"}
1
+ {"version":3,"file":"caddy.test.cjs","names":["describe","generate"],"sources":["../../src/generators/caddy.test.ts"],"sourcesContent":["import { describe, expect, it } from \"vitest\";\nimport { generate } from \"../generate.js\";\n\ndescribe(\"generateCaddyfile (via generate)\", () => {\n\tconst baseInput = {\n\t\tprojectName: \"caddy-test\",\n\t\tservices: [\"redis\", \"n8n\"],\n\t\tskillPacks: [] as string[],\n\t\tproxy: \"caddy\" as const,\n\t\tdomain: \"example.com\",\n\t\tgpu: false,\n\t\tplatform: \"linux/amd64\" as const,\n\t\tdeployment: \"local\" as const,\n\t\tgenerateSecrets: true,\n\t\topenclawVersion: \"latest\",\n\t};\n\n\tit(\"generates Caddyfile when proxy is caddy\", () => {\n\t\tconst result = generate(baseInput);\n\n\t\texpect(result.files).toHaveProperty(\"caddy/Caddyfile\");\n\t\texpect(result.files[\"caddy/Caddyfile\"]?.length).toBeGreaterThan(0);\n\t});\n\n\tit(\"does not generate Caddyfile when proxy is none\", () => {\n\t\tconst result = generate({\n\t\t\t...baseInput,\n\t\t\tproxy: \"none\",\n\t\t});\n\n\t\texpect(result.files).not.toHaveProperty(\"caddy/Caddyfile\");\n\t});\n\n\tit(\"Caddyfile contains the domain\", () => {\n\t\tconst result = generate(baseInput);\n\t\tconst caddyfile = result.files[\"caddy/Caddyfile\"]!;\n\n\t\texpect(caddyfile).toContain(\"example.com\");\n\t});\n\n\tit(\"Caddyfile includes reverse proxy directives for services with exposed ports\", () => {\n\t\tconst result = generate(baseInput);\n\t\tconst caddyfile = result.files[\"caddy/Caddyfile\"]!;\n\n\t\t// Should reference n8n since it has exposed ports\n\t\texpect(caddyfile).toContain(\"n8n\");\n\t});\n\n\tit(\"Caddyfile includes TLS configuration\", () => {\n\t\tconst result = generate(baseInput);\n\t\tconst caddyfile = result.files[\"caddy/Caddyfile\"]!;\n\n\t\t// Caddy auto-enables TLS, so should reference HTTPS or TLS\n\t\texpect(caddyfile.length).toBeGreaterThan(50);\n\t});\n\n\tit(\"adds flush_interval -1 for WebSocket-enabled services (opensandbox)\", () => {\n\t\tconst result = generate({\n\t\t\t...baseInput,\n\t\t\tservices: [\"opensandbox\"],\n\t\t});\n\t\tconst caddyfile = result.files[\"caddy/Caddyfile\"]!;\n\n\t\texpect(caddyfile).toContain(\"opensandbox\");\n\t\texpect(caddyfile).toContain(\"flush_interval -1\");\n\t});\n\n\tit(\"adds flush_interval -1 for desktop-environment (KasmVNC)\", () => {\n\t\tconst result = generate({\n\t\t\t...baseInput,\n\t\t\tservices: [\"desktop-environment\"],\n\t\t});\n\t\tconst caddyfile = result.files[\"caddy/Caddyfile\"]!;\n\n\t\texpect(caddyfile).toContain(\"desktop-environment\");\n\t\texpect(caddyfile).toContain(\"flush_interval -1\");\n\t});\n\n\tit(\"adds flush_interval -1 for agent-browser viewport streaming port\", () => {\n\t\tconst result = generate({\n\t\t\t...baseInput,\n\t\t\tservices: [\"agent-browser\"],\n\t\t});\n\t\tconst caddyfile = result.files[\"caddy/Caddyfile\"]!;\n\n\t\texpect(caddyfile).toContain(\"agent-browser\");\n\t\texpect(caddyfile).toContain(\"flush_interval -1\");\n\t});\n\n\tit(\"does NOT add flush_interval for non-WebSocket services\", () => {\n\t\tconst result = generate(baseInput);\n\t\tconst caddyfile = result.files[\"caddy/Caddyfile\"]!;\n\n\t\texpect(caddyfile).not.toContain(\"flush_interval\");\n\t});\n});\n"],"mappings":";;;AAGAA,sBAAAA,SAAS,0CAA0C;CAClD,MAAM,YAAY;EACjB,aAAa;EACb,UAAU,CAAC,SAAS,MAAM;EAC1B,YAAY,EAAE;EACd,OAAO;EACP,QAAQ;EACR,KAAK;EACL,UAAU;EACV,YAAY;EACZ,iBAAiB;EACjB,iBAAiB;EACjB;AAED,uBAAA,GAAG,iDAAiD;EACnD,MAAM,SAASC,iBAAAA,SAAS,UAAU;AAElC,wBAAA,aAAO,OAAO,MAAM,CAAC,eAAe,kBAAkB;AACtD,wBAAA,aAAO,OAAO,MAAM,oBAAoB,OAAO,CAAC,gBAAgB,EAAE;GACjE;AAEF,uBAAA,GAAG,wDAAwD;AAM1D,wBAAA,aALeA,iBAAAA,SAAS;GACvB,GAAG;GACH,OAAO;GACP,CAAC,CAEY,MAAM,CAAC,IAAI,eAAe,kBAAkB;GACzD;AAEF,uBAAA,GAAG,uCAAuC;EAEzC,MAAM,YADSA,iBAAAA,SAAS,UAAU,CACT,MAAM;AAE/B,wBAAA,aAAO,UAAU,CAAC,UAAU,cAAc;GACzC;AAEF,uBAAA,GAAG,qFAAqF;EAEvF,MAAM,YADSA,iBAAAA,SAAS,UAAU,CACT,MAAM;AAG/B,wBAAA,aAAO,UAAU,CAAC,UAAU,MAAM;GACjC;AAEF,uBAAA,GAAG,8CAA8C;EAEhD,MAAM,YADSA,iBAAAA,SAAS,UAAU,CACT,MAAM;AAG/B,wBAAA,aAAO,UAAU,OAAO,CAAC,gBAAgB,GAAG;GAC3C;AAEF,uBAAA,GAAG,6EAA6E;EAK/E,MAAM,YAJSA,iBAAAA,SAAS;GACvB,GAAG;GACH,UAAU,CAAC,cAAc;GACzB,CAAC,CACuB,MAAM;AAE/B,wBAAA,aAAO,UAAU,CAAC,UAAU,cAAc;AAC1C,wBAAA,aAAO,UAAU,CAAC,UAAU,oBAAoB;GAC/C;AAEF,uBAAA,GAAG,kEAAkE;EAKpE,MAAM,YAJSA,iBAAAA,SAAS;GACvB,GAAG;GACH,UAAU,CAAC,sBAAsB;GACjC,CAAC,CACuB,MAAM;AAE/B,wBAAA,aAAO,UAAU,CAAC,UAAU,sBAAsB;AAClD,wBAAA,aAAO,UAAU,CAAC,UAAU,oBAAoB;GAC/C;AAEF,uBAAA,GAAG,0EAA0E;EAK5E,MAAM,YAJSA,iBAAAA,SAAS;GACvB,GAAG;GACH,UAAU,CAAC,gBAAgB;GAC3B,CAAC,CACuB,MAAM;AAE/B,wBAAA,aAAO,UAAU,CAAC,UAAU,gBAAgB;AAC5C,wBAAA,aAAO,UAAU,CAAC,UAAU,oBAAoB;GAC/C;AAEF,uBAAA,GAAG,gEAAgE;EAElE,MAAM,YADSA,iBAAAA,SAAS,UAAU,CACT,MAAM;AAE/B,wBAAA,aAAO,UAAU,CAAC,IAAI,UAAU,iBAAiB;GAChD;EACD"}
@@ -1,4 +1,4 @@
1
- import { n as describe, r as it, t as globalExpect } from "../test.CTcmp4Su-ClCHJ3FA.mjs";
1
+ import { a as describe, o as it, t as globalExpect } from "../test.CTcmp4Su-BRa7-bTj.mjs";
2
2
  import { generate } from "../generate.mjs";
3
3
  //#region src/generators/caddy.test.ts
4
4
  describe("generateCaddyfile (via generate)", () => {
@@ -17,7 +17,7 @@ describe("generateCaddyfile (via generate)", () => {
17
17
  it("generates Caddyfile when proxy is caddy", () => {
18
18
  const result = generate(baseInput);
19
19
  globalExpect(result.files).toHaveProperty("caddy/Caddyfile");
20
- globalExpect(result.files["caddy/Caddyfile"].length).toBeGreaterThan(0);
20
+ globalExpect(result.files["caddy/Caddyfile"]?.length).toBeGreaterThan(0);
21
21
  });
22
22
  it("does not generate Caddyfile when proxy is none", () => {
23
23
  globalExpect(generate({
@@ -37,6 +37,34 @@ describe("generateCaddyfile (via generate)", () => {
37
37
  const caddyfile = generate(baseInput).files["caddy/Caddyfile"];
38
38
  globalExpect(caddyfile.length).toBeGreaterThan(50);
39
39
  });
40
+ it("adds flush_interval -1 for WebSocket-enabled services (opensandbox)", () => {
41
+ const caddyfile = generate({
42
+ ...baseInput,
43
+ services: ["opensandbox"]
44
+ }).files["caddy/Caddyfile"];
45
+ globalExpect(caddyfile).toContain("opensandbox");
46
+ globalExpect(caddyfile).toContain("flush_interval -1");
47
+ });
48
+ it("adds flush_interval -1 for desktop-environment (KasmVNC)", () => {
49
+ const caddyfile = generate({
50
+ ...baseInput,
51
+ services: ["desktop-environment"]
52
+ }).files["caddy/Caddyfile"];
53
+ globalExpect(caddyfile).toContain("desktop-environment");
54
+ globalExpect(caddyfile).toContain("flush_interval -1");
55
+ });
56
+ it("adds flush_interval -1 for agent-browser viewport streaming port", () => {
57
+ const caddyfile = generate({
58
+ ...baseInput,
59
+ services: ["agent-browser"]
60
+ }).files["caddy/Caddyfile"];
61
+ globalExpect(caddyfile).toContain("agent-browser");
62
+ globalExpect(caddyfile).toContain("flush_interval -1");
63
+ });
64
+ it("does NOT add flush_interval for non-WebSocket services", () => {
65
+ const caddyfile = generate(baseInput).files["caddy/Caddyfile"];
66
+ globalExpect(caddyfile).not.toContain("flush_interval");
67
+ });
40
68
  });
41
69
  //#endregion
42
70
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"caddy.test.mjs","names":[],"sources":["../../src/generators/caddy.test.ts"],"sourcesContent":["import { describe, expect, it } from \"vitest\";\nimport { generate } from \"../generate.js\";\n\ndescribe(\"generateCaddyfile (via generate)\", () => {\n\tconst baseInput = {\n\t\tprojectName: \"caddy-test\",\n\t\tservices: [\"redis\", \"n8n\"],\n\t\tskillPacks: [] as string[],\n\t\tproxy: \"caddy\" as const,\n\t\tdomain: \"example.com\",\n\t\tgpu: false,\n\t\tplatform: \"linux/amd64\" as const,\n\t\tdeployment: \"local\" as const,\n\t\tgenerateSecrets: true,\n\t\topenclawVersion: \"latest\",\n\t};\n\n\tit(\"generates Caddyfile when proxy is caddy\", () => {\n\t\tconst result = generate(baseInput);\n\n\t\texpect(result.files).toHaveProperty(\"caddy/Caddyfile\");\n\t\texpect(result.files[\"caddy/Caddyfile\"]!.length).toBeGreaterThan(0);\n\t});\n\n\tit(\"does not generate Caddyfile when proxy is none\", () => {\n\t\tconst result = generate({\n\t\t\t...baseInput,\n\t\t\tproxy: \"none\",\n\t\t});\n\n\t\texpect(result.files).not.toHaveProperty(\"caddy/Caddyfile\");\n\t});\n\n\tit(\"Caddyfile contains the domain\", () => {\n\t\tconst result = generate(baseInput);\n\t\tconst caddyfile = result.files[\"caddy/Caddyfile\"]!;\n\n\t\texpect(caddyfile).toContain(\"example.com\");\n\t});\n\n\tit(\"Caddyfile includes reverse proxy directives for services with exposed ports\", () => {\n\t\tconst result = generate(baseInput);\n\t\tconst caddyfile = result.files[\"caddy/Caddyfile\"]!;\n\n\t\t// Should reference n8n since it has exposed ports\n\t\texpect(caddyfile).toContain(\"n8n\");\n\t});\n\n\tit(\"Caddyfile includes TLS configuration\", () => {\n\t\tconst result = generate(baseInput);\n\t\tconst caddyfile = result.files[\"caddy/Caddyfile\"]!;\n\n\t\t// Caddy auto-enables TLS, so should reference HTTPS or TLS\n\t\texpect(caddyfile.length).toBeGreaterThan(50);\n\t});\n});\n"],"mappings":";;;AAGA,SAAS,0CAA0C;CAClD,MAAM,YAAY;EACjB,aAAa;EACb,UAAU,CAAC,SAAS,MAAM;EAC1B,YAAY,EAAE;EACd,OAAO;EACP,QAAQ;EACR,KAAK;EACL,UAAU;EACV,YAAY;EACZ,iBAAiB;EACjB,iBAAiB;EACjB;AAED,IAAG,iDAAiD;EACnD,MAAM,SAAS,SAAS,UAAU;AAElC,eAAO,OAAO,MAAM,CAAC,eAAe,kBAAkB;AACtD,eAAO,OAAO,MAAM,mBAAoB,OAAO,CAAC,gBAAgB,EAAE;GACjE;AAEF,IAAG,wDAAwD;AAM1D,eALe,SAAS;GACvB,GAAG;GACH,OAAO;GACP,CAAC,CAEY,MAAM,CAAC,IAAI,eAAe,kBAAkB;GACzD;AAEF,IAAG,uCAAuC;EAEzC,MAAM,YADS,SAAS,UAAU,CACT,MAAM;AAE/B,eAAO,UAAU,CAAC,UAAU,cAAc;GACzC;AAEF,IAAG,qFAAqF;EAEvF,MAAM,YADS,SAAS,UAAU,CACT,MAAM;AAG/B,eAAO,UAAU,CAAC,UAAU,MAAM;GACjC;AAEF,IAAG,8CAA8C;EAEhD,MAAM,YADS,SAAS,UAAU,CACT,MAAM;AAG/B,eAAO,UAAU,OAAO,CAAC,gBAAgB,GAAG;GAC3C;EACD"}
1
+ {"version":3,"file":"caddy.test.mjs","names":[],"sources":["../../src/generators/caddy.test.ts"],"sourcesContent":["import { describe, expect, it } from \"vitest\";\nimport { generate } from \"../generate.js\";\n\ndescribe(\"generateCaddyfile (via generate)\", () => {\n\tconst baseInput = {\n\t\tprojectName: \"caddy-test\",\n\t\tservices: [\"redis\", \"n8n\"],\n\t\tskillPacks: [] as string[],\n\t\tproxy: \"caddy\" as const,\n\t\tdomain: \"example.com\",\n\t\tgpu: false,\n\t\tplatform: \"linux/amd64\" as const,\n\t\tdeployment: \"local\" as const,\n\t\tgenerateSecrets: true,\n\t\topenclawVersion: \"latest\",\n\t};\n\n\tit(\"generates Caddyfile when proxy is caddy\", () => {\n\t\tconst result = generate(baseInput);\n\n\t\texpect(result.files).toHaveProperty(\"caddy/Caddyfile\");\n\t\texpect(result.files[\"caddy/Caddyfile\"]?.length).toBeGreaterThan(0);\n\t});\n\n\tit(\"does not generate Caddyfile when proxy is none\", () => {\n\t\tconst result = generate({\n\t\t\t...baseInput,\n\t\t\tproxy: \"none\",\n\t\t});\n\n\t\texpect(result.files).not.toHaveProperty(\"caddy/Caddyfile\");\n\t});\n\n\tit(\"Caddyfile contains the domain\", () => {\n\t\tconst result = generate(baseInput);\n\t\tconst caddyfile = result.files[\"caddy/Caddyfile\"]!;\n\n\t\texpect(caddyfile).toContain(\"example.com\");\n\t});\n\n\tit(\"Caddyfile includes reverse proxy directives for services with exposed ports\", () => {\n\t\tconst result = generate(baseInput);\n\t\tconst caddyfile = result.files[\"caddy/Caddyfile\"]!;\n\n\t\t// Should reference n8n since it has exposed ports\n\t\texpect(caddyfile).toContain(\"n8n\");\n\t});\n\n\tit(\"Caddyfile includes TLS configuration\", () => {\n\t\tconst result = generate(baseInput);\n\t\tconst caddyfile = result.files[\"caddy/Caddyfile\"]!;\n\n\t\t// Caddy auto-enables TLS, so should reference HTTPS or TLS\n\t\texpect(caddyfile.length).toBeGreaterThan(50);\n\t});\n\n\tit(\"adds flush_interval -1 for WebSocket-enabled services (opensandbox)\", () => {\n\t\tconst result = generate({\n\t\t\t...baseInput,\n\t\t\tservices: [\"opensandbox\"],\n\t\t});\n\t\tconst caddyfile = result.files[\"caddy/Caddyfile\"]!;\n\n\t\texpect(caddyfile).toContain(\"opensandbox\");\n\t\texpect(caddyfile).toContain(\"flush_interval -1\");\n\t});\n\n\tit(\"adds flush_interval -1 for desktop-environment (KasmVNC)\", () => {\n\t\tconst result = generate({\n\t\t\t...baseInput,\n\t\t\tservices: [\"desktop-environment\"],\n\t\t});\n\t\tconst caddyfile = result.files[\"caddy/Caddyfile\"]!;\n\n\t\texpect(caddyfile).toContain(\"desktop-environment\");\n\t\texpect(caddyfile).toContain(\"flush_interval -1\");\n\t});\n\n\tit(\"adds flush_interval -1 for agent-browser viewport streaming port\", () => {\n\t\tconst result = generate({\n\t\t\t...baseInput,\n\t\t\tservices: [\"agent-browser\"],\n\t\t});\n\t\tconst caddyfile = result.files[\"caddy/Caddyfile\"]!;\n\n\t\texpect(caddyfile).toContain(\"agent-browser\");\n\t\texpect(caddyfile).toContain(\"flush_interval -1\");\n\t});\n\n\tit(\"does NOT add flush_interval for non-WebSocket services\", () => {\n\t\tconst result = generate(baseInput);\n\t\tconst caddyfile = result.files[\"caddy/Caddyfile\"]!;\n\n\t\texpect(caddyfile).not.toContain(\"flush_interval\");\n\t});\n});\n"],"mappings":";;;AAGA,SAAS,0CAA0C;CAClD,MAAM,YAAY;EACjB,aAAa;EACb,UAAU,CAAC,SAAS,MAAM;EAC1B,YAAY,EAAE;EACd,OAAO;EACP,QAAQ;EACR,KAAK;EACL,UAAU;EACV,YAAY;EACZ,iBAAiB;EACjB,iBAAiB;EACjB;AAED,IAAG,iDAAiD;EACnD,MAAM,SAAS,SAAS,UAAU;AAElC,eAAO,OAAO,MAAM,CAAC,eAAe,kBAAkB;AACtD,eAAO,OAAO,MAAM,oBAAoB,OAAO,CAAC,gBAAgB,EAAE;GACjE;AAEF,IAAG,wDAAwD;AAM1D,eALe,SAAS;GACvB,GAAG;GACH,OAAO;GACP,CAAC,CAEY,MAAM,CAAC,IAAI,eAAe,kBAAkB;GACzD;AAEF,IAAG,uCAAuC;EAEzC,MAAM,YADS,SAAS,UAAU,CACT,MAAM;AAE/B,eAAO,UAAU,CAAC,UAAU,cAAc;GACzC;AAEF,IAAG,qFAAqF;EAEvF,MAAM,YADS,SAAS,UAAU,CACT,MAAM;AAG/B,eAAO,UAAU,CAAC,UAAU,MAAM;GACjC;AAEF,IAAG,8CAA8C;EAEhD,MAAM,YADS,SAAS,UAAU,CACT,MAAM;AAG/B,eAAO,UAAU,OAAO,CAAC,gBAAgB,GAAG;GAC3C;AAEF,IAAG,6EAA6E;EAK/E,MAAM,YAJS,SAAS;GACvB,GAAG;GACH,UAAU,CAAC,cAAc;GACzB,CAAC,CACuB,MAAM;AAE/B,eAAO,UAAU,CAAC,UAAU,cAAc;AAC1C,eAAO,UAAU,CAAC,UAAU,oBAAoB;GAC/C;AAEF,IAAG,kEAAkE;EAKpE,MAAM,YAJS,SAAS;GACvB,GAAG;GACH,UAAU,CAAC,sBAAsB;GACjC,CAAC,CACuB,MAAM;AAE/B,eAAO,UAAU,CAAC,UAAU,sBAAsB;AAClD,eAAO,UAAU,CAAC,UAAU,oBAAoB;GAC/C;AAEF,IAAG,0EAA0E;EAK5E,MAAM,YAJS,SAAS;GACvB,GAAG;GACH,UAAU,CAAC,gBAAgB;GAC3B,CAAC,CACuB,MAAM;AAE/B,eAAO,UAAU,CAAC,UAAU,gBAAgB;AAC5C,eAAO,UAAU,CAAC,UAAU,oBAAoB;GAC/C;AAEF,IAAG,gEAAgE;EAElE,MAAM,YADS,SAAS,UAAU,CACT,MAAM;AAE/B,eAAO,UAAU,CAAC,IAAI,UAAU,iBAAiB;GAChD;EACD"}
@@ -1 +1 @@
1
- {"version":3,"file":"clone-repos.cjs","names":[],"sources":["../../src/generators/clone-repos.ts"],"sourcesContent":["import type { ResolverOutput } from \"../types.js\";\n\n/**\n * Generates clone scripts for git-based services (SaaS boilerplates).\n * Returns empty object if no git-based services exist in the resolved stack.\n */\nexport function generateCloneScripts(resolved: ResolverOutput): Record<string, string> {\n\tconst gitServices = resolved.services.filter(\n\t\t(s) => s.definition.gitSource && s.definition.buildContext,\n\t);\n\n\tif (gitServices.length === 0) return {};\n\n\tconst files: Record<string, string> = {};\n\n\t// ── scripts/clone-repos.sh ─────────────────────────────────────────────\n\n\tconst bashEntries = gitServices\n\t\t.map((s) => {\n\t\t\tconst gs = s.definition.gitSource!;\n\t\t\tconst branchArg = gs.branch ? `\"${gs.branch}\"` : '\"\"';\n\t\t\tlet block = `clone_or_update \"${s.definition.id}\" \"${gs.repoUrl}\" ${branchArg}`;\n\t\t\tif (gs.postCloneCommands && gs.postCloneCommands.length > 0) {\n\t\t\t\tconst cmds = gs.postCloneCommands\n\t\t\t\t\t.map((cmd) => ` (cd \"$REPOS_DIR/${s.definition.id}${gs.subdirectory ? `/${gs.subdirectory}` : \"\"}\" && ${cmd})`)\n\t\t\t\t\t.join(\"\\n\");\n\t\t\t\tblock += `\\n${cmds}`;\n\t\t\t}\n\t\t\treturn block;\n\t\t})\n\t\t.join(\"\\n\\n\");\n\n\tfiles[\"scripts/clone-repos.sh\"] = `#!/usr/bin/env bash\nset -euo pipefail\n\n# ─── Clone/Update Git-Based Service Repositories ────────────────────────────\n# Idempotent: clones if missing, pulls if already present.\n\nSCRIPT_DIR=\"$(cd \"$(dirname \"\\${BASH_SOURCE[0]}\")\" && pwd)\"\nPROJECT_DIR=\"$(dirname \"$SCRIPT_DIR\")\"\nREPOS_DIR=\"$PROJECT_DIR/repos\"\n\n# ── Colour helpers ──────────────────────────────────────────────────────────\nif [ -t 1 ]; then\n GREEN='\\\\033[0;32m'; YELLOW='\\\\033[1;33m'; CYAN='\\\\033[0;36m'; RED='\\\\033[0;31m'; NC='\\\\033[0m'\nelse\n GREEN=''; YELLOW=''; CYAN=''; RED=''; NC=''\nfi\ninfo() { echo -e \"\\${CYAN}i $*\\${NC}\"; }\nok() { echo -e \"\\${GREEN}✓ $*\\${NC}\"; }\nwarn() { echo -e \"\\${YELLOW}⚠ $*\\${NC}\"; }\nerr() { echo -e \"\\${RED}✗ $*\\${NC}\" >&2; }\n\n# ── Check git ───────────────────────────────────────────────────────────────\nif ! command -v git &> /dev/null; then\n err \"git is not installed. Please install git first.\"\n exit 1\nfi\n\nmkdir -p \"$REPOS_DIR\"\n\nclone_or_update() {\n local name=\"$1\" url=\"$2\" branch=\"\\${3:-}\"\n local dir=\"$REPOS_DIR/$name\"\n\n if [ -d \"$dir/.git\" ]; then\n info \"Updating $name...\"\n git -C \"$dir\" pull --ff-only 2>/dev/null || warn \"Could not fast-forward $name (you may have local changes)\"\n else\n info \"Cloning $name...\"\n if [ -n \"$branch\" ]; then\n git clone --depth 1 --branch \"$branch\" \"$url\" \"$dir\"\n else\n git clone --depth 1 \"$url\" \"$dir\"\n fi\n fi\n}\n\necho \"\"\ninfo \"Cloning/updating SaaS boilerplate repositories...\"\necho \"\"\n\n${bashEntries}\n\necho \"\"\nok \"All repositories ready.\"\n`;\n\n\t// ── scripts/clone-repos.ps1 ────────────────────────────────────────────\n\n\tconst psEntries = gitServices\n\t\t.map((s) => {\n\t\t\tconst gs = s.definition.gitSource!;\n\t\t\tconst branchArg = gs.branch ? ` -Branch \"${gs.branch}\"` : \"\";\n\t\t\tlet block = `Clone-OrUpdate -Name \"${s.definition.id}\" -Url \"${gs.repoUrl}\"${branchArg}`;\n\t\t\tif (gs.postCloneCommands && gs.postCloneCommands.length > 0) {\n\t\t\t\tconst subdir = gs.subdirectory ? `/${gs.subdirectory}` : \"\";\n\t\t\t\tconst cmds = gs.postCloneCommands\n\t\t\t\t\t.map((cmd) => `Push-Location \"$ReposDir/${s.definition.id}${subdir}\"; ${cmd}; Pop-Location`)\n\t\t\t\t\t.join(\"\\n\");\n\t\t\t\tblock += `\\n${cmds}`;\n\t\t\t}\n\t\t\treturn block;\n\t\t})\n\t\t.join(\"\\n\\n\");\n\n\tfiles[\"scripts/clone-repos.ps1\"] = `#Requires -Version 5.1\n<#\n.SYNOPSIS\n Clone/update git-based service repositories.\n Idempotent: clones if missing, pulls if already present.\n#>\n$ErrorActionPreference = \"Stop\"\n\n$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path\n$ProjectDir = Split-Path -Parent $ScriptDir\n$ReposDir = Join-Path $ProjectDir \"repos\"\n\nif (-not (Get-Command git -ErrorAction SilentlyContinue)) {\n Write-Error \"git is not installed. Please install git first.\"\n exit 1\n}\n\nif (-not (Test-Path $ReposDir)) { New-Item -ItemType Directory -Path $ReposDir -Force | Out-Null }\n\nfunction Clone-OrUpdate {\n param(\n [string]$Name,\n [string]$Url,\n [string]$Branch = \"\"\n )\n $dir = Join-Path $ReposDir $Name\n\n if (Test-Path (Join-Path $dir \".git\")) {\n Write-Host \" Updating $Name...\" -ForegroundColor Cyan\n git -C $dir pull --ff-only 2>$null\n if ($LASTEXITCODE -ne 0) { Write-Warning \"Could not fast-forward $Name\" }\n } else {\n Write-Host \" Cloning $Name...\" -ForegroundColor Cyan\n if ($Branch) {\n git clone --depth 1 --branch $Branch $Url $dir\n } else {\n git clone --depth 1 $Url $dir\n }\n }\n}\n\nWrite-Host \"\"\nWrite-Host \"Cloning/updating SaaS boilerplate repositories...\" -ForegroundColor Cyan\nWrite-Host \"\"\n\n${psEntries}\n\nWrite-Host \"\"\nWrite-Host \"All repositories ready.\" -ForegroundColor Green\n`;\n\n\treturn files;\n}\n"],"mappings":";;;;;;AAMA,SAAgB,qBAAqB,UAAkD;CACtF,MAAM,cAAc,SAAS,SAAS,QACpC,MAAM,EAAE,WAAW,aAAa,EAAE,WAAW,aAC9C;AAED,KAAI,YAAY,WAAW,EAAG,QAAO,EAAE;CAEvC,MAAM,QAAgC,EAAE;AAmBxC,OAAM,4BAA4B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAfd,YAClB,KAAK,MAAM;EACX,MAAM,KAAK,EAAE,WAAW;EACxB,MAAM,YAAY,GAAG,SAAS,IAAI,GAAG,OAAO,KAAK;EACjD,IAAI,QAAQ,oBAAoB,EAAE,WAAW,GAAG,KAAK,GAAG,QAAQ,IAAI;AACpE,MAAI,GAAG,qBAAqB,GAAG,kBAAkB,SAAS,GAAG;GAC5D,MAAM,OAAO,GAAG,kBACd,KAAK,QAAQ,qBAAqB,EAAE,WAAW,KAAK,GAAG,eAAe,IAAI,GAAG,iBAAiB,GAAG,OAAO,IAAI,GAAG,CAC/G,KAAK,KAAK;AACZ,YAAS,KAAK;;AAEf,SAAO;GACN,CACD,KAAK,OAAO,CAoDD;;;;;AAwBb,OAAM,6BAA6B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAhBjB,YAChB,KAAK,MAAM;EACX,MAAM,KAAK,EAAE,WAAW;EACxB,MAAM,YAAY,GAAG,SAAS,aAAa,GAAG,OAAO,KAAK;EAC1D,IAAI,QAAQ,yBAAyB,EAAE,WAAW,GAAG,UAAU,GAAG,QAAQ,GAAG;AAC7E,MAAI,GAAG,qBAAqB,GAAG,kBAAkB,SAAS,GAAG;GAC5D,MAAM,SAAS,GAAG,eAAe,IAAI,GAAG,iBAAiB;GACzD,MAAM,OAAO,GAAG,kBACd,KAAK,QAAQ,4BAA4B,EAAE,WAAW,KAAK,OAAO,KAAK,IAAI,gBAAgB,CAC3F,KAAK,KAAK;AACZ,YAAS,KAAK;;AAEf,SAAO;GACN,CACD,KAAK,OAAO,CA+CH;;;;;AAMX,QAAO"}
1
+ {"version":3,"file":"clone-repos.cjs","names":[],"sources":["../../src/generators/clone-repos.ts"],"sourcesContent":["import type { ResolverOutput } from \"../types.js\";\n\n/**\n * Generates clone scripts for git-based services (SaaS boilerplates).\n * Returns empty object if no git-based services exist in the resolved stack.\n */\nexport function generateCloneScripts(resolved: ResolverOutput): Record<string, string> {\n\tconst gitServices = resolved.services.filter(\n\t\t(s) => s.definition.gitSource && s.definition.buildContext,\n\t);\n\n\tif (gitServices.length === 0) return {};\n\n\tconst files: Record<string, string> = {};\n\n\t// ── scripts/clone-repos.sh ─────────────────────────────────────────────\n\n\tconst bashEntries = gitServices\n\t\t.map((s) => {\n\t\t\tconst gs = s.definition.gitSource!;\n\t\t\tconst branchArg = gs.branch ? `\"${gs.branch}\"` : '\"\"';\n\t\t\tlet block = `clone_or_update \"${s.definition.id}\" \"${gs.repoUrl}\" ${branchArg}`;\n\t\t\tif (gs.postCloneCommands && gs.postCloneCommands.length > 0) {\n\t\t\t\tconst cmds = gs.postCloneCommands\n\t\t\t\t\t.map(\n\t\t\t\t\t\t(cmd) =>\n\t\t\t\t\t\t\t` (cd \"$REPOS_DIR/${s.definition.id}${gs.subdirectory ? `/${gs.subdirectory}` : \"\"}\" && ${cmd})`,\n\t\t\t\t\t)\n\t\t\t\t\t.join(\"\\n\");\n\t\t\t\tblock += `\\n${cmds}`;\n\t\t\t}\n\t\t\treturn block;\n\t\t})\n\t\t.join(\"\\n\\n\");\n\n\tfiles[\"scripts/clone-repos.sh\"] = `#!/usr/bin/env bash\nset -euo pipefail\n\n# ─── Clone/Update Git-Based Service Repositories ────────────────────────────\n# Idempotent: clones if missing, pulls if already present.\n\nSCRIPT_DIR=\"$(cd \"$(dirname \"\\${BASH_SOURCE[0]}\")\" && pwd)\"\nPROJECT_DIR=\"$(dirname \"$SCRIPT_DIR\")\"\nREPOS_DIR=\"$PROJECT_DIR/repos\"\n\n# ── Colour helpers ──────────────────────────────────────────────────────────\nif [ -t 1 ]; then\n GREEN='\\\\033[0;32m'; YELLOW='\\\\033[1;33m'; CYAN='\\\\033[0;36m'; RED='\\\\033[0;31m'; NC='\\\\033[0m'\nelse\n GREEN=''; YELLOW=''; CYAN=''; RED=''; NC=''\nfi\ninfo() { echo -e \"\\${CYAN}i $*\\${NC}\"; }\nok() { echo -e \"\\${GREEN}✓ $*\\${NC}\"; }\nwarn() { echo -e \"\\${YELLOW}⚠ $*\\${NC}\"; }\nerr() { echo -e \"\\${RED}✗ $*\\${NC}\" >&2; }\n\n# ── Check git ───────────────────────────────────────────────────────────────\nif ! command -v git &> /dev/null; then\n err \"git is not installed. Please install git first.\"\n exit 1\nfi\n\nmkdir -p \"$REPOS_DIR\"\n\nclone_or_update() {\n local name=\"$1\" url=\"$2\" branch=\"\\${3:-}\"\n local dir=\"$REPOS_DIR/$name\"\n\n if [ -d \"$dir/.git\" ]; then\n info \"Updating $name...\"\n git -C \"$dir\" pull --ff-only 2>/dev/null || warn \"Could not fast-forward $name (you may have local changes)\"\n else\n info \"Cloning $name...\"\n if [ -n \"$branch\" ]; then\n git clone --depth 1 --branch \"$branch\" \"$url\" \"$dir\"\n else\n git clone --depth 1 \"$url\" \"$dir\"\n fi\n fi\n}\n\necho \"\"\ninfo \"Cloning/updating SaaS boilerplate repositories...\"\necho \"\"\n\n${bashEntries}\n\necho \"\"\nok \"All repositories ready.\"\n`;\n\n\t// ── scripts/clone-repos.ps1 ────────────────────────────────────────────\n\n\tconst psEntries = gitServices\n\t\t.map((s) => {\n\t\t\tconst gs = s.definition.gitSource!;\n\t\t\tconst branchArg = gs.branch ? ` -Branch \"${gs.branch}\"` : \"\";\n\t\t\tlet block = `Clone-OrUpdate -Name \"${s.definition.id}\" -Url \"${gs.repoUrl}\"${branchArg}`;\n\t\t\tif (gs.postCloneCommands && gs.postCloneCommands.length > 0) {\n\t\t\t\tconst subdir = gs.subdirectory ? `/${gs.subdirectory}` : \"\";\n\t\t\t\tconst cmds = gs.postCloneCommands\n\t\t\t\t\t.map(\n\t\t\t\t\t\t(cmd) => `Push-Location \"$ReposDir/${s.definition.id}${subdir}\"; ${cmd}; Pop-Location`,\n\t\t\t\t\t)\n\t\t\t\t\t.join(\"\\n\");\n\t\t\t\tblock += `\\n${cmds}`;\n\t\t\t}\n\t\t\treturn block;\n\t\t})\n\t\t.join(\"\\n\\n\");\n\n\tfiles[\"scripts/clone-repos.ps1\"] = `#Requires -Version 5.1\n<#\n.SYNOPSIS\n Clone/update git-based service repositories.\n Idempotent: clones if missing, pulls if already present.\n#>\n$ErrorActionPreference = \"Stop\"\n\n$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path\n$ProjectDir = Split-Path -Parent $ScriptDir\n$ReposDir = Join-Path $ProjectDir \"repos\"\n\nif (-not (Get-Command git -ErrorAction SilentlyContinue)) {\n Write-Error \"git is not installed. Please install git first.\"\n exit 1\n}\n\nif (-not (Test-Path $ReposDir)) { New-Item -ItemType Directory -Path $ReposDir -Force | Out-Null }\n\nfunction Clone-OrUpdate {\n param(\n [string]$Name,\n [string]$Url,\n [string]$Branch = \"\"\n )\n $dir = Join-Path $ReposDir $Name\n\n if (Test-Path (Join-Path $dir \".git\")) {\n Write-Host \" Updating $Name...\" -ForegroundColor Cyan\n git -C $dir pull --ff-only 2>$null\n if ($LASTEXITCODE -ne 0) { Write-Warning \"Could not fast-forward $Name\" }\n } else {\n Write-Host \" Cloning $Name...\" -ForegroundColor Cyan\n if ($Branch) {\n git clone --depth 1 --branch $Branch $Url $dir\n } else {\n git clone --depth 1 $Url $dir\n }\n }\n}\n\nWrite-Host \"\"\nWrite-Host \"Cloning/updating SaaS boilerplate repositories...\" -ForegroundColor Cyan\nWrite-Host \"\"\n\n${psEntries}\n\nWrite-Host \"\"\nWrite-Host \"All repositories ready.\" -ForegroundColor Green\n`;\n\n\treturn files;\n}\n"],"mappings":";;;;;;AAMA,SAAgB,qBAAqB,UAAkD;CACtF,MAAM,cAAc,SAAS,SAAS,QACpC,MAAM,EAAE,WAAW,aAAa,EAAE,WAAW,aAC9C;AAED,KAAI,YAAY,WAAW,EAAG,QAAO,EAAE;CAEvC,MAAM,QAAgC,EAAE;AAsBxC,OAAM,4BAA4B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAlBd,YAClB,KAAK,MAAM;EACX,MAAM,KAAK,EAAE,WAAW;EACxB,MAAM,YAAY,GAAG,SAAS,IAAI,GAAG,OAAO,KAAK;EACjD,IAAI,QAAQ,oBAAoB,EAAE,WAAW,GAAG,KAAK,GAAG,QAAQ,IAAI;AACpE,MAAI,GAAG,qBAAqB,GAAG,kBAAkB,SAAS,GAAG;GAC5D,MAAM,OAAO,GAAG,kBACd,KACC,QACA,qBAAqB,EAAE,WAAW,KAAK,GAAG,eAAe,IAAI,GAAG,iBAAiB,GAAG,OAAO,IAAI,GAChG,CACA,KAAK,KAAK;AACZ,YAAS,KAAK;;AAEf,SAAO;GACN,CACD,KAAK,OAAO,CAoDD;;;;;AA0Bb,OAAM,6BAA6B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAlBjB,YAChB,KAAK,MAAM;EACX,MAAM,KAAK,EAAE,WAAW;EACxB,MAAM,YAAY,GAAG,SAAS,aAAa,GAAG,OAAO,KAAK;EAC1D,IAAI,QAAQ,yBAAyB,EAAE,WAAW,GAAG,UAAU,GAAG,QAAQ,GAAG;AAC7E,MAAI,GAAG,qBAAqB,GAAG,kBAAkB,SAAS,GAAG;GAC5D,MAAM,SAAS,GAAG,eAAe,IAAI,GAAG,iBAAiB;GACzD,MAAM,OAAO,GAAG,kBACd,KACC,QAAQ,4BAA4B,EAAE,WAAW,KAAK,OAAO,KAAK,IAAI,gBACvE,CACA,KAAK,KAAK;AACZ,YAAS,KAAK;;AAEf,SAAO;GACN,CACD,KAAK,OAAO,CA+CH;;;;;AAMX,QAAO"}
@@ -1,4 +1,4 @@
1
- import { ResolverOutput } from "../types.cjs";
1
+ import { B as ResolverOutput } from "../types-Bsn0XzSP.cjs";
2
2
 
3
3
  //#region src/generators/clone-repos.d.ts
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { ResolverOutput } from "../types.mjs";
1
+ import { B as ResolverOutput } from "../types-DwTKyCZ9.mjs";
2
2
 
3
3
  //#region src/generators/clone-repos.d.ts
4
4
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"clone-repos.mjs","names":[],"sources":["../../src/generators/clone-repos.ts"],"sourcesContent":["import type { ResolverOutput } from \"../types.js\";\n\n/**\n * Generates clone scripts for git-based services (SaaS boilerplates).\n * Returns empty object if no git-based services exist in the resolved stack.\n */\nexport function generateCloneScripts(resolved: ResolverOutput): Record<string, string> {\n\tconst gitServices = resolved.services.filter(\n\t\t(s) => s.definition.gitSource && s.definition.buildContext,\n\t);\n\n\tif (gitServices.length === 0) return {};\n\n\tconst files: Record<string, string> = {};\n\n\t// ── scripts/clone-repos.sh ─────────────────────────────────────────────\n\n\tconst bashEntries = gitServices\n\t\t.map((s) => {\n\t\t\tconst gs = s.definition.gitSource!;\n\t\t\tconst branchArg = gs.branch ? `\"${gs.branch}\"` : '\"\"';\n\t\t\tlet block = `clone_or_update \"${s.definition.id}\" \"${gs.repoUrl}\" ${branchArg}`;\n\t\t\tif (gs.postCloneCommands && gs.postCloneCommands.length > 0) {\n\t\t\t\tconst cmds = gs.postCloneCommands\n\t\t\t\t\t.map((cmd) => ` (cd \"$REPOS_DIR/${s.definition.id}${gs.subdirectory ? `/${gs.subdirectory}` : \"\"}\" && ${cmd})`)\n\t\t\t\t\t.join(\"\\n\");\n\t\t\t\tblock += `\\n${cmds}`;\n\t\t\t}\n\t\t\treturn block;\n\t\t})\n\t\t.join(\"\\n\\n\");\n\n\tfiles[\"scripts/clone-repos.sh\"] = `#!/usr/bin/env bash\nset -euo pipefail\n\n# ─── Clone/Update Git-Based Service Repositories ────────────────────────────\n# Idempotent: clones if missing, pulls if already present.\n\nSCRIPT_DIR=\"$(cd \"$(dirname \"\\${BASH_SOURCE[0]}\")\" && pwd)\"\nPROJECT_DIR=\"$(dirname \"$SCRIPT_DIR\")\"\nREPOS_DIR=\"$PROJECT_DIR/repos\"\n\n# ── Colour helpers ──────────────────────────────────────────────────────────\nif [ -t 1 ]; then\n GREEN='\\\\033[0;32m'; YELLOW='\\\\033[1;33m'; CYAN='\\\\033[0;36m'; RED='\\\\033[0;31m'; NC='\\\\033[0m'\nelse\n GREEN=''; YELLOW=''; CYAN=''; RED=''; NC=''\nfi\ninfo() { echo -e \"\\${CYAN}i $*\\${NC}\"; }\nok() { echo -e \"\\${GREEN}✓ $*\\${NC}\"; }\nwarn() { echo -e \"\\${YELLOW}⚠ $*\\${NC}\"; }\nerr() { echo -e \"\\${RED}✗ $*\\${NC}\" >&2; }\n\n# ── Check git ───────────────────────────────────────────────────────────────\nif ! command -v git &> /dev/null; then\n err \"git is not installed. Please install git first.\"\n exit 1\nfi\n\nmkdir -p \"$REPOS_DIR\"\n\nclone_or_update() {\n local name=\"$1\" url=\"$2\" branch=\"\\${3:-}\"\n local dir=\"$REPOS_DIR/$name\"\n\n if [ -d \"$dir/.git\" ]; then\n info \"Updating $name...\"\n git -C \"$dir\" pull --ff-only 2>/dev/null || warn \"Could not fast-forward $name (you may have local changes)\"\n else\n info \"Cloning $name...\"\n if [ -n \"$branch\" ]; then\n git clone --depth 1 --branch \"$branch\" \"$url\" \"$dir\"\n else\n git clone --depth 1 \"$url\" \"$dir\"\n fi\n fi\n}\n\necho \"\"\ninfo \"Cloning/updating SaaS boilerplate repositories...\"\necho \"\"\n\n${bashEntries}\n\necho \"\"\nok \"All repositories ready.\"\n`;\n\n\t// ── scripts/clone-repos.ps1 ────────────────────────────────────────────\n\n\tconst psEntries = gitServices\n\t\t.map((s) => {\n\t\t\tconst gs = s.definition.gitSource!;\n\t\t\tconst branchArg = gs.branch ? ` -Branch \"${gs.branch}\"` : \"\";\n\t\t\tlet block = `Clone-OrUpdate -Name \"${s.definition.id}\" -Url \"${gs.repoUrl}\"${branchArg}`;\n\t\t\tif (gs.postCloneCommands && gs.postCloneCommands.length > 0) {\n\t\t\t\tconst subdir = gs.subdirectory ? `/${gs.subdirectory}` : \"\";\n\t\t\t\tconst cmds = gs.postCloneCommands\n\t\t\t\t\t.map((cmd) => `Push-Location \"$ReposDir/${s.definition.id}${subdir}\"; ${cmd}; Pop-Location`)\n\t\t\t\t\t.join(\"\\n\");\n\t\t\t\tblock += `\\n${cmds}`;\n\t\t\t}\n\t\t\treturn block;\n\t\t})\n\t\t.join(\"\\n\\n\");\n\n\tfiles[\"scripts/clone-repos.ps1\"] = `#Requires -Version 5.1\n<#\n.SYNOPSIS\n Clone/update git-based service repositories.\n Idempotent: clones if missing, pulls if already present.\n#>\n$ErrorActionPreference = \"Stop\"\n\n$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path\n$ProjectDir = Split-Path -Parent $ScriptDir\n$ReposDir = Join-Path $ProjectDir \"repos\"\n\nif (-not (Get-Command git -ErrorAction SilentlyContinue)) {\n Write-Error \"git is not installed. Please install git first.\"\n exit 1\n}\n\nif (-not (Test-Path $ReposDir)) { New-Item -ItemType Directory -Path $ReposDir -Force | Out-Null }\n\nfunction Clone-OrUpdate {\n param(\n [string]$Name,\n [string]$Url,\n [string]$Branch = \"\"\n )\n $dir = Join-Path $ReposDir $Name\n\n if (Test-Path (Join-Path $dir \".git\")) {\n Write-Host \" Updating $Name...\" -ForegroundColor Cyan\n git -C $dir pull --ff-only 2>$null\n if ($LASTEXITCODE -ne 0) { Write-Warning \"Could not fast-forward $Name\" }\n } else {\n Write-Host \" Cloning $Name...\" -ForegroundColor Cyan\n if ($Branch) {\n git clone --depth 1 --branch $Branch $Url $dir\n } else {\n git clone --depth 1 $Url $dir\n }\n }\n}\n\nWrite-Host \"\"\nWrite-Host \"Cloning/updating SaaS boilerplate repositories...\" -ForegroundColor Cyan\nWrite-Host \"\"\n\n${psEntries}\n\nWrite-Host \"\"\nWrite-Host \"All repositories ready.\" -ForegroundColor Green\n`;\n\n\treturn files;\n}\n"],"mappings":";;;;;AAMA,SAAgB,qBAAqB,UAAkD;CACtF,MAAM,cAAc,SAAS,SAAS,QACpC,MAAM,EAAE,WAAW,aAAa,EAAE,WAAW,aAC9C;AAED,KAAI,YAAY,WAAW,EAAG,QAAO,EAAE;CAEvC,MAAM,QAAgC,EAAE;AAmBxC,OAAM,4BAA4B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAfd,YAClB,KAAK,MAAM;EACX,MAAM,KAAK,EAAE,WAAW;EACxB,MAAM,YAAY,GAAG,SAAS,IAAI,GAAG,OAAO,KAAK;EACjD,IAAI,QAAQ,oBAAoB,EAAE,WAAW,GAAG,KAAK,GAAG,QAAQ,IAAI;AACpE,MAAI,GAAG,qBAAqB,GAAG,kBAAkB,SAAS,GAAG;GAC5D,MAAM,OAAO,GAAG,kBACd,KAAK,QAAQ,qBAAqB,EAAE,WAAW,KAAK,GAAG,eAAe,IAAI,GAAG,iBAAiB,GAAG,OAAO,IAAI,GAAG,CAC/G,KAAK,KAAK;AACZ,YAAS,KAAK;;AAEf,SAAO;GACN,CACD,KAAK,OAAO,CAoDD;;;;;AAwBb,OAAM,6BAA6B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAhBjB,YAChB,KAAK,MAAM;EACX,MAAM,KAAK,EAAE,WAAW;EACxB,MAAM,YAAY,GAAG,SAAS,aAAa,GAAG,OAAO,KAAK;EAC1D,IAAI,QAAQ,yBAAyB,EAAE,WAAW,GAAG,UAAU,GAAG,QAAQ,GAAG;AAC7E,MAAI,GAAG,qBAAqB,GAAG,kBAAkB,SAAS,GAAG;GAC5D,MAAM,SAAS,GAAG,eAAe,IAAI,GAAG,iBAAiB;GACzD,MAAM,OAAO,GAAG,kBACd,KAAK,QAAQ,4BAA4B,EAAE,WAAW,KAAK,OAAO,KAAK,IAAI,gBAAgB,CAC3F,KAAK,KAAK;AACZ,YAAS,KAAK;;AAEf,SAAO;GACN,CACD,KAAK,OAAO,CA+CH;;;;;AAMX,QAAO"}
1
+ {"version":3,"file":"clone-repos.mjs","names":[],"sources":["../../src/generators/clone-repos.ts"],"sourcesContent":["import type { ResolverOutput } from \"../types.js\";\n\n/**\n * Generates clone scripts for git-based services (SaaS boilerplates).\n * Returns empty object if no git-based services exist in the resolved stack.\n */\nexport function generateCloneScripts(resolved: ResolverOutput): Record<string, string> {\n\tconst gitServices = resolved.services.filter(\n\t\t(s) => s.definition.gitSource && s.definition.buildContext,\n\t);\n\n\tif (gitServices.length === 0) return {};\n\n\tconst files: Record<string, string> = {};\n\n\t// ── scripts/clone-repos.sh ─────────────────────────────────────────────\n\n\tconst bashEntries = gitServices\n\t\t.map((s) => {\n\t\t\tconst gs = s.definition.gitSource!;\n\t\t\tconst branchArg = gs.branch ? `\"${gs.branch}\"` : '\"\"';\n\t\t\tlet block = `clone_or_update \"${s.definition.id}\" \"${gs.repoUrl}\" ${branchArg}`;\n\t\t\tif (gs.postCloneCommands && gs.postCloneCommands.length > 0) {\n\t\t\t\tconst cmds = gs.postCloneCommands\n\t\t\t\t\t.map(\n\t\t\t\t\t\t(cmd) =>\n\t\t\t\t\t\t\t` (cd \"$REPOS_DIR/${s.definition.id}${gs.subdirectory ? `/${gs.subdirectory}` : \"\"}\" && ${cmd})`,\n\t\t\t\t\t)\n\t\t\t\t\t.join(\"\\n\");\n\t\t\t\tblock += `\\n${cmds}`;\n\t\t\t}\n\t\t\treturn block;\n\t\t})\n\t\t.join(\"\\n\\n\");\n\n\tfiles[\"scripts/clone-repos.sh\"] = `#!/usr/bin/env bash\nset -euo pipefail\n\n# ─── Clone/Update Git-Based Service Repositories ────────────────────────────\n# Idempotent: clones if missing, pulls if already present.\n\nSCRIPT_DIR=\"$(cd \"$(dirname \"\\${BASH_SOURCE[0]}\")\" && pwd)\"\nPROJECT_DIR=\"$(dirname \"$SCRIPT_DIR\")\"\nREPOS_DIR=\"$PROJECT_DIR/repos\"\n\n# ── Colour helpers ──────────────────────────────────────────────────────────\nif [ -t 1 ]; then\n GREEN='\\\\033[0;32m'; YELLOW='\\\\033[1;33m'; CYAN='\\\\033[0;36m'; RED='\\\\033[0;31m'; NC='\\\\033[0m'\nelse\n GREEN=''; YELLOW=''; CYAN=''; RED=''; NC=''\nfi\ninfo() { echo -e \"\\${CYAN}i $*\\${NC}\"; }\nok() { echo -e \"\\${GREEN}✓ $*\\${NC}\"; }\nwarn() { echo -e \"\\${YELLOW}⚠ $*\\${NC}\"; }\nerr() { echo -e \"\\${RED}✗ $*\\${NC}\" >&2; }\n\n# ── Check git ───────────────────────────────────────────────────────────────\nif ! command -v git &> /dev/null; then\n err \"git is not installed. Please install git first.\"\n exit 1\nfi\n\nmkdir -p \"$REPOS_DIR\"\n\nclone_or_update() {\n local name=\"$1\" url=\"$2\" branch=\"\\${3:-}\"\n local dir=\"$REPOS_DIR/$name\"\n\n if [ -d \"$dir/.git\" ]; then\n info \"Updating $name...\"\n git -C \"$dir\" pull --ff-only 2>/dev/null || warn \"Could not fast-forward $name (you may have local changes)\"\n else\n info \"Cloning $name...\"\n if [ -n \"$branch\" ]; then\n git clone --depth 1 --branch \"$branch\" \"$url\" \"$dir\"\n else\n git clone --depth 1 \"$url\" \"$dir\"\n fi\n fi\n}\n\necho \"\"\ninfo \"Cloning/updating SaaS boilerplate repositories...\"\necho \"\"\n\n${bashEntries}\n\necho \"\"\nok \"All repositories ready.\"\n`;\n\n\t// ── scripts/clone-repos.ps1 ────────────────────────────────────────────\n\n\tconst psEntries = gitServices\n\t\t.map((s) => {\n\t\t\tconst gs = s.definition.gitSource!;\n\t\t\tconst branchArg = gs.branch ? ` -Branch \"${gs.branch}\"` : \"\";\n\t\t\tlet block = `Clone-OrUpdate -Name \"${s.definition.id}\" -Url \"${gs.repoUrl}\"${branchArg}`;\n\t\t\tif (gs.postCloneCommands && gs.postCloneCommands.length > 0) {\n\t\t\t\tconst subdir = gs.subdirectory ? `/${gs.subdirectory}` : \"\";\n\t\t\t\tconst cmds = gs.postCloneCommands\n\t\t\t\t\t.map(\n\t\t\t\t\t\t(cmd) => `Push-Location \"$ReposDir/${s.definition.id}${subdir}\"; ${cmd}; Pop-Location`,\n\t\t\t\t\t)\n\t\t\t\t\t.join(\"\\n\");\n\t\t\t\tblock += `\\n${cmds}`;\n\t\t\t}\n\t\t\treturn block;\n\t\t})\n\t\t.join(\"\\n\\n\");\n\n\tfiles[\"scripts/clone-repos.ps1\"] = `#Requires -Version 5.1\n<#\n.SYNOPSIS\n Clone/update git-based service repositories.\n Idempotent: clones if missing, pulls if already present.\n#>\n$ErrorActionPreference = \"Stop\"\n\n$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path\n$ProjectDir = Split-Path -Parent $ScriptDir\n$ReposDir = Join-Path $ProjectDir \"repos\"\n\nif (-not (Get-Command git -ErrorAction SilentlyContinue)) {\n Write-Error \"git is not installed. Please install git first.\"\n exit 1\n}\n\nif (-not (Test-Path $ReposDir)) { New-Item -ItemType Directory -Path $ReposDir -Force | Out-Null }\n\nfunction Clone-OrUpdate {\n param(\n [string]$Name,\n [string]$Url,\n [string]$Branch = \"\"\n )\n $dir = Join-Path $ReposDir $Name\n\n if (Test-Path (Join-Path $dir \".git\")) {\n Write-Host \" Updating $Name...\" -ForegroundColor Cyan\n git -C $dir pull --ff-only 2>$null\n if ($LASTEXITCODE -ne 0) { Write-Warning \"Could not fast-forward $Name\" }\n } else {\n Write-Host \" Cloning $Name...\" -ForegroundColor Cyan\n if ($Branch) {\n git clone --depth 1 --branch $Branch $Url $dir\n } else {\n git clone --depth 1 $Url $dir\n }\n }\n}\n\nWrite-Host \"\"\nWrite-Host \"Cloning/updating SaaS boilerplate repositories...\" -ForegroundColor Cyan\nWrite-Host \"\"\n\n${psEntries}\n\nWrite-Host \"\"\nWrite-Host \"All repositories ready.\" -ForegroundColor Green\n`;\n\n\treturn files;\n}\n"],"mappings":";;;;;AAMA,SAAgB,qBAAqB,UAAkD;CACtF,MAAM,cAAc,SAAS,SAAS,QACpC,MAAM,EAAE,WAAW,aAAa,EAAE,WAAW,aAC9C;AAED,KAAI,YAAY,WAAW,EAAG,QAAO,EAAE;CAEvC,MAAM,QAAgC,EAAE;AAsBxC,OAAM,4BAA4B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAlBd,YAClB,KAAK,MAAM;EACX,MAAM,KAAK,EAAE,WAAW;EACxB,MAAM,YAAY,GAAG,SAAS,IAAI,GAAG,OAAO,KAAK;EACjD,IAAI,QAAQ,oBAAoB,EAAE,WAAW,GAAG,KAAK,GAAG,QAAQ,IAAI;AACpE,MAAI,GAAG,qBAAqB,GAAG,kBAAkB,SAAS,GAAG;GAC5D,MAAM,OAAO,GAAG,kBACd,KACC,QACA,qBAAqB,EAAE,WAAW,KAAK,GAAG,eAAe,IAAI,GAAG,iBAAiB,GAAG,OAAO,IAAI,GAChG,CACA,KAAK,KAAK;AACZ,YAAS,KAAK;;AAEf,SAAO;GACN,CACD,KAAK,OAAO,CAoDD;;;;;AA0Bb,OAAM,6BAA6B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAlBjB,YAChB,KAAK,MAAM;EACX,MAAM,KAAK,EAAE,WAAW;EACxB,MAAM,YAAY,GAAG,SAAS,aAAa,GAAG,OAAO,KAAK;EAC1D,IAAI,QAAQ,yBAAyB,EAAE,WAAW,GAAG,UAAU,GAAG,QAAQ,GAAG;AAC7E,MAAI,GAAG,qBAAqB,GAAG,kBAAkB,SAAS,GAAG;GAC5D,MAAM,SAAS,GAAG,eAAe,IAAI,GAAG,iBAAiB;GACzD,MAAM,OAAO,GAAG,kBACd,KACC,QAAQ,4BAA4B,EAAE,WAAW,KAAK,OAAO,KAAK,IAAI,gBACvE,CACA,KAAK,KAAK;AACZ,YAAS,KAAK;;AAEf,SAAO;GACN,CACD,KAAK,OAAO,CA+CH;;;;;AAMX,QAAO"}
@@ -1,4 +1,4 @@
1
- const require_test_CTcmp4Su = require("../test.CTcmp4Su-DlzTarwH.cjs");
1
+ const require_test_CTcmp4Su = require("../test.CTcmp4Su-BWSPM8ZQ.cjs");
2
2
  const require_generators_clone_repos = require("./clone-repos.cjs");
3
3
  //#region src/generators/clone-repos.test.ts
4
4
  /** Minimal resolved output with no services */
@@ -1 +1 @@
1
- {"version":3,"file":"clone-repos.test.cjs","names":["describe","generateCloneScripts"],"sources":["../../src/generators/clone-repos.test.ts"],"sourcesContent":["import { describe, expect, it } from \"vitest\";\nimport { generateCloneScripts } from \"./clone-repos.js\";\nimport type { ResolverOutput } from \"../types.js\";\n\n/** Minimal resolved output with no services */\nfunction emptyResolved(): ResolverOutput {\n\treturn {\n\t\tservices: [],\n\t\taddedDependencies: [],\n\t\tremovedConflicts: [],\n\t\twarnings: [],\n\t\terrors: [],\n\t\tisValid: true,\n\t\testimatedMemoryMB: 0,\n\t\taiProviders: [],\n\t\tgsdRuntimes: [],\n\t};\n}\n\n/** Create a resolved output with image-based services only */\nfunction imageOnlyResolved(): ResolverOutput {\n\treturn {\n\t\t...emptyResolved(),\n\t\tservices: [\n\t\t\t{\n\t\t\t\tdefinition: {\n\t\t\t\t\tid: \"redis\",\n\t\t\t\t\tname: \"Redis\",\n\t\t\t\t\tdescription: \"In-memory cache\",\n\t\t\t\t\tcategory: \"database\",\n\t\t\t\t\ticon: \"🔴\",\n\t\t\t\t\timage: \"redis\",\n\t\t\t\t\timageTag: \"7-alpine\",\n\t\t\t\t\tports: [],\n\t\t\t\t\tvolumes: [],\n\t\t\t\t\tenvironment: [],\n\t\t\t\t\tdependsOn: [],\n\t\t\t\t\trestartPolicy: \"unless-stopped\",\n\t\t\t\t\tnetworks: [\"openclaw-network\"],\n\t\t\t\t\tskills: [],\n\t\t\t\t\topenclawEnvVars: [],\n\t\t\t\t\tdocsUrl: \"https://redis.io\",\n\t\t\t\t\ttags: [],\n\t\t\t\t\tmaturity: \"stable\",\n\t\t\t\t\trequires: [],\n\t\t\t\t\trecommends: [],\n\t\t\t\t\tconflictsWith: [],\n\t\t\t\t\tgpuRequired: false,\n\t\t\t\t},\n\t\t\t\taddedBy: \"user\",\n\t\t\t},\n\t\t],\n\t};\n}\n\n/** Create a resolved output with a git-based service */\nfunction gitServiceResolved(): ResolverOutput {\n\treturn {\n\t\t...emptyResolved(),\n\t\tservices: [\n\t\t\t{\n\t\t\t\tdefinition: {\n\t\t\t\t\tid: \"open-saas\",\n\t\t\t\t\tname: \"Open SaaS\",\n\t\t\t\t\tdescription: \"SaaS boilerplate\",\n\t\t\t\t\tcategory: \"saas-boilerplate\",\n\t\t\t\t\ticon: \"🚀\",\n\t\t\t\t\tgitSource: {\n\t\t\t\t\t\trepoUrl: \"https://github.com/wasp-lang/open-saas.git\",\n\t\t\t\t\t\tbranch: \"main\",\n\t\t\t\t\t\tsubdirectory: \"template\",\n\t\t\t\t\t\tpostCloneCommands: [\"cp .env.example .env\"],\n\t\t\t\t\t},\n\t\t\t\t\tbuildContext: {\n\t\t\t\t\t\tdockerfile: \"Dockerfile\",\n\t\t\t\t\t\tcontext: \".\",\n\t\t\t\t\t},\n\t\t\t\t\tports: [{ host: 3100, container: 3000, description: \"Web app\", exposed: true }],\n\t\t\t\t\tvolumes: [],\n\t\t\t\t\tenvironment: [],\n\t\t\t\t\tdependsOn: [],\n\t\t\t\t\trestartPolicy: \"unless-stopped\",\n\t\t\t\t\tnetworks: [\"openclaw-network\"],\n\t\t\t\t\tskills: [],\n\t\t\t\t\topenclawEnvVars: [],\n\t\t\t\t\tdocsUrl: \"https://opensaas.sh/docs\",\n\t\t\t\t\ttags: [],\n\t\t\t\t\tmaturity: \"beta\",\n\t\t\t\t\trequires: [],\n\t\t\t\t\trecommends: [],\n\t\t\t\t\tconflictsWith: [],\n\t\t\t\t\tgpuRequired: false,\n\t\t\t\t},\n\t\t\t\taddedBy: \"user\",\n\t\t\t},\n\t\t],\n\t};\n}\n\ndescribe(\"generateCloneScripts\", () => {\n\tit(\"returns empty object when no git-based services exist\", () => {\n\t\tconst result = generateCloneScripts(emptyResolved());\n\t\texpect(result).toEqual({});\n\t});\n\n\tit(\"returns empty object when only image-based services exist\", () => {\n\t\tconst result = generateCloneScripts(imageOnlyResolved());\n\t\texpect(result).toEqual({});\n\t});\n\n\tit(\"generates bash and PowerShell scripts for git-based services\", () => {\n\t\tconst result = generateCloneScripts(gitServiceResolved());\n\t\texpect(Object.keys(result)).toHaveLength(2);\n\t\texpect(result).toHaveProperty(\"scripts/clone-repos.sh\");\n\t\texpect(result).toHaveProperty(\"scripts/clone-repos.ps1\");\n\t});\n\n\tit(\"bash script contains clone command with repo URL\", () => {\n\t\tconst result = generateCloneScripts(gitServiceResolved());\n\t\tconst bash = result[\"scripts/clone-repos.sh\"];\n\t\texpect(bash).toContain(\"https://github.com/wasp-lang/open-saas.git\");\n\t\texpect(bash).toContain('\"open-saas\"');\n\t\texpect(bash).toContain('\"main\"');\n\t});\n\n\tit(\"bash script includes postCloneCommands\", () => {\n\t\tconst result = generateCloneScripts(gitServiceResolved());\n\t\tconst bash = result[\"scripts/clone-repos.sh\"];\n\t\texpect(bash).toContain(\"cp .env.example .env\");\n\t});\n\n\tit(\"bash script includes git check and idempotency logic\", () => {\n\t\tconst result = generateCloneScripts(gitServiceResolved());\n\t\tconst bash = result[\"scripts/clone-repos.sh\"];\n\t\texpect(bash).toContain(\"command -v git\");\n\t\texpect(bash).toContain(\"clone_or_update\");\n\t\texpect(bash).toContain(\"pull --ff-only\");\n\t\texpect(bash).toContain(\"git clone --depth 1\");\n\t});\n\n\tit(\"PowerShell script contains clone command with repo URL\", () => {\n\t\tconst result = generateCloneScripts(gitServiceResolved());\n\t\tconst ps = result[\"scripts/clone-repos.ps1\"];\n\t\texpect(ps).toContain(\"https://github.com/wasp-lang/open-saas.git\");\n\t\texpect(ps).toContain('\"open-saas\"');\n\t\texpect(ps).toContain(\"Clone-OrUpdate\");\n\t});\n\n\tit(\"bash script is executable (starts with shebang)\", () => {\n\t\tconst result = generateCloneScripts(gitServiceResolved());\n\t\tconst bash = result[\"scripts/clone-repos.sh\"];\n\t\texpect(bash).toMatch(/^#!/);\n\t});\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"clone-repos.test.cjs","names":["describe","generateCloneScripts"],"sources":["../../src/generators/clone-repos.test.ts"],"sourcesContent":["import { describe, expect, it } from \"vitest\";\nimport type { ResolverOutput } from \"../types.js\";\nimport { generateCloneScripts } from \"./clone-repos.js\";\n\n/** Minimal resolved output with no services */\nfunction emptyResolved(): ResolverOutput {\n\treturn {\n\t\tservices: [],\n\t\taddedDependencies: [],\n\t\tremovedConflicts: [],\n\t\twarnings: [],\n\t\terrors: [],\n\t\tisValid: true,\n\t\testimatedMemoryMB: 0,\n\t\taiProviders: [],\n\t\tgsdRuntimes: [],\n\t};\n}\n\n/** Create a resolved output with image-based services only */\nfunction imageOnlyResolved(): ResolverOutput {\n\treturn {\n\t\t...emptyResolved(),\n\t\tservices: [\n\t\t\t{\n\t\t\t\tdefinition: {\n\t\t\t\t\tid: \"redis\",\n\t\t\t\t\tname: \"Redis\",\n\t\t\t\t\tdescription: \"In-memory cache\",\n\t\t\t\t\tcategory: \"database\",\n\t\t\t\t\ticon: \"🔴\",\n\t\t\t\t\timage: \"redis\",\n\t\t\t\t\timageTag: \"7-alpine\",\n\t\t\t\t\tports: [],\n\t\t\t\t\tvolumes: [],\n\t\t\t\t\tenvironment: [],\n\t\t\t\t\tdependsOn: [],\n\t\t\t\t\trestartPolicy: \"unless-stopped\",\n\t\t\t\t\tnetworks: [\"openclaw-network\"],\n\t\t\t\t\tskills: [],\n\t\t\t\t\topenclawEnvVars: [],\n\t\t\t\t\tdocsUrl: \"https://redis.io\",\n\t\t\t\t\ttags: [],\n\t\t\t\t\tmaturity: \"stable\",\n\t\t\t\t\trequires: [],\n\t\t\t\t\trecommends: [],\n\t\t\t\t\tconflictsWith: [],\n\t\t\t\t\tgpuRequired: false,\n\t\t\t\t},\n\t\t\t\taddedBy: \"user\",\n\t\t\t},\n\t\t],\n\t};\n}\n\n/** Create a resolved output with a git-based service */\nfunction gitServiceResolved(): ResolverOutput {\n\treturn {\n\t\t...emptyResolved(),\n\t\tservices: [\n\t\t\t{\n\t\t\t\tdefinition: {\n\t\t\t\t\tid: \"open-saas\",\n\t\t\t\t\tname: \"Open SaaS\",\n\t\t\t\t\tdescription: \"SaaS boilerplate\",\n\t\t\t\t\tcategory: \"saas-boilerplate\",\n\t\t\t\t\ticon: \"🚀\",\n\t\t\t\t\tgitSource: {\n\t\t\t\t\t\trepoUrl: \"https://github.com/wasp-lang/open-saas.git\",\n\t\t\t\t\t\tbranch: \"main\",\n\t\t\t\t\t\tsubdirectory: \"template\",\n\t\t\t\t\t\tpostCloneCommands: [\"cp .env.example .env\"],\n\t\t\t\t\t},\n\t\t\t\t\tbuildContext: {\n\t\t\t\t\t\tdockerfile: \"Dockerfile\",\n\t\t\t\t\t\tcontext: \".\",\n\t\t\t\t\t},\n\t\t\t\t\tports: [{ host: 3100, container: 3000, description: \"Web app\", exposed: true }],\n\t\t\t\t\tvolumes: [],\n\t\t\t\t\tenvironment: [],\n\t\t\t\t\tdependsOn: [],\n\t\t\t\t\trestartPolicy: \"unless-stopped\",\n\t\t\t\t\tnetworks: [\"openclaw-network\"],\n\t\t\t\t\tskills: [],\n\t\t\t\t\topenclawEnvVars: [],\n\t\t\t\t\tdocsUrl: \"https://opensaas.sh/docs\",\n\t\t\t\t\ttags: [],\n\t\t\t\t\tmaturity: \"beta\",\n\t\t\t\t\trequires: [],\n\t\t\t\t\trecommends: [],\n\t\t\t\t\tconflictsWith: [],\n\t\t\t\t\tgpuRequired: false,\n\t\t\t\t},\n\t\t\t\taddedBy: \"user\",\n\t\t\t},\n\t\t],\n\t};\n}\n\ndescribe(\"generateCloneScripts\", () => {\n\tit(\"returns empty object when no git-based services exist\", () => {\n\t\tconst result = generateCloneScripts(emptyResolved());\n\t\texpect(result).toEqual({});\n\t});\n\n\tit(\"returns empty object when only image-based services exist\", () => {\n\t\tconst result = generateCloneScripts(imageOnlyResolved());\n\t\texpect(result).toEqual({});\n\t});\n\n\tit(\"generates bash and PowerShell scripts for git-based services\", () => {\n\t\tconst result = generateCloneScripts(gitServiceResolved());\n\t\texpect(Object.keys(result)).toHaveLength(2);\n\t\texpect(result).toHaveProperty(\"scripts/clone-repos.sh\");\n\t\texpect(result).toHaveProperty(\"scripts/clone-repos.ps1\");\n\t});\n\n\tit(\"bash script contains clone command with repo URL\", () => {\n\t\tconst result = generateCloneScripts(gitServiceResolved());\n\t\tconst bash = result[\"scripts/clone-repos.sh\"];\n\t\texpect(bash).toContain(\"https://github.com/wasp-lang/open-saas.git\");\n\t\texpect(bash).toContain('\"open-saas\"');\n\t\texpect(bash).toContain('\"main\"');\n\t});\n\n\tit(\"bash script includes postCloneCommands\", () => {\n\t\tconst result = generateCloneScripts(gitServiceResolved());\n\t\tconst bash = result[\"scripts/clone-repos.sh\"];\n\t\texpect(bash).toContain(\"cp .env.example .env\");\n\t});\n\n\tit(\"bash script includes git check and idempotency logic\", () => {\n\t\tconst result = generateCloneScripts(gitServiceResolved());\n\t\tconst bash = result[\"scripts/clone-repos.sh\"];\n\t\texpect(bash).toContain(\"command -v git\");\n\t\texpect(bash).toContain(\"clone_or_update\");\n\t\texpect(bash).toContain(\"pull --ff-only\");\n\t\texpect(bash).toContain(\"git clone --depth 1\");\n\t});\n\n\tit(\"PowerShell script contains clone command with repo URL\", () => {\n\t\tconst result = generateCloneScripts(gitServiceResolved());\n\t\tconst ps = result[\"scripts/clone-repos.ps1\"];\n\t\texpect(ps).toContain(\"https://github.com/wasp-lang/open-saas.git\");\n\t\texpect(ps).toContain('\"open-saas\"');\n\t\texpect(ps).toContain(\"Clone-OrUpdate\");\n\t});\n\n\tit(\"bash script is executable (starts with shebang)\", () => {\n\t\tconst result = generateCloneScripts(gitServiceResolved());\n\t\tconst bash = result[\"scripts/clone-repos.sh\"];\n\t\texpect(bash).toMatch(/^#!/);\n\t});\n});\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { n as describe, r as it, t as globalExpect } from "../test.CTcmp4Su-ClCHJ3FA.mjs";
1
+ import { a as describe, o as it, t as globalExpect } from "../test.CTcmp4Su-BRa7-bTj.mjs";
2
2
  import { generateCloneScripts } from "./clone-repos.mjs";
3
3
  //#region src/generators/clone-repos.test.ts
4
4
  /** Minimal resolved output with no services */
@@ -1 +1 @@
1
- {"version":3,"file":"clone-repos.test.mjs","names":[],"sources":["../../src/generators/clone-repos.test.ts"],"sourcesContent":["import { describe, expect, it } from \"vitest\";\nimport { generateCloneScripts } from \"./clone-repos.js\";\nimport type { ResolverOutput } from \"../types.js\";\n\n/** Minimal resolved output with no services */\nfunction emptyResolved(): ResolverOutput {\n\treturn {\n\t\tservices: [],\n\t\taddedDependencies: [],\n\t\tremovedConflicts: [],\n\t\twarnings: [],\n\t\terrors: [],\n\t\tisValid: true,\n\t\testimatedMemoryMB: 0,\n\t\taiProviders: [],\n\t\tgsdRuntimes: [],\n\t};\n}\n\n/** Create a resolved output with image-based services only */\nfunction imageOnlyResolved(): ResolverOutput {\n\treturn {\n\t\t...emptyResolved(),\n\t\tservices: [\n\t\t\t{\n\t\t\t\tdefinition: {\n\t\t\t\t\tid: \"redis\",\n\t\t\t\t\tname: \"Redis\",\n\t\t\t\t\tdescription: \"In-memory cache\",\n\t\t\t\t\tcategory: \"database\",\n\t\t\t\t\ticon: \"🔴\",\n\t\t\t\t\timage: \"redis\",\n\t\t\t\t\timageTag: \"7-alpine\",\n\t\t\t\t\tports: [],\n\t\t\t\t\tvolumes: [],\n\t\t\t\t\tenvironment: [],\n\t\t\t\t\tdependsOn: [],\n\t\t\t\t\trestartPolicy: \"unless-stopped\",\n\t\t\t\t\tnetworks: [\"openclaw-network\"],\n\t\t\t\t\tskills: [],\n\t\t\t\t\topenclawEnvVars: [],\n\t\t\t\t\tdocsUrl: \"https://redis.io\",\n\t\t\t\t\ttags: [],\n\t\t\t\t\tmaturity: \"stable\",\n\t\t\t\t\trequires: [],\n\t\t\t\t\trecommends: [],\n\t\t\t\t\tconflictsWith: [],\n\t\t\t\t\tgpuRequired: false,\n\t\t\t\t},\n\t\t\t\taddedBy: \"user\",\n\t\t\t},\n\t\t],\n\t};\n}\n\n/** Create a resolved output with a git-based service */\nfunction gitServiceResolved(): ResolverOutput {\n\treturn {\n\t\t...emptyResolved(),\n\t\tservices: [\n\t\t\t{\n\t\t\t\tdefinition: {\n\t\t\t\t\tid: \"open-saas\",\n\t\t\t\t\tname: \"Open SaaS\",\n\t\t\t\t\tdescription: \"SaaS boilerplate\",\n\t\t\t\t\tcategory: \"saas-boilerplate\",\n\t\t\t\t\ticon: \"🚀\",\n\t\t\t\t\tgitSource: {\n\t\t\t\t\t\trepoUrl: \"https://github.com/wasp-lang/open-saas.git\",\n\t\t\t\t\t\tbranch: \"main\",\n\t\t\t\t\t\tsubdirectory: \"template\",\n\t\t\t\t\t\tpostCloneCommands: [\"cp .env.example .env\"],\n\t\t\t\t\t},\n\t\t\t\t\tbuildContext: {\n\t\t\t\t\t\tdockerfile: \"Dockerfile\",\n\t\t\t\t\t\tcontext: \".\",\n\t\t\t\t\t},\n\t\t\t\t\tports: [{ host: 3100, container: 3000, description: \"Web app\", exposed: true }],\n\t\t\t\t\tvolumes: [],\n\t\t\t\t\tenvironment: [],\n\t\t\t\t\tdependsOn: [],\n\t\t\t\t\trestartPolicy: \"unless-stopped\",\n\t\t\t\t\tnetworks: [\"openclaw-network\"],\n\t\t\t\t\tskills: [],\n\t\t\t\t\topenclawEnvVars: [],\n\t\t\t\t\tdocsUrl: \"https://opensaas.sh/docs\",\n\t\t\t\t\ttags: [],\n\t\t\t\t\tmaturity: \"beta\",\n\t\t\t\t\trequires: [],\n\t\t\t\t\trecommends: [],\n\t\t\t\t\tconflictsWith: [],\n\t\t\t\t\tgpuRequired: false,\n\t\t\t\t},\n\t\t\t\taddedBy: \"user\",\n\t\t\t},\n\t\t],\n\t};\n}\n\ndescribe(\"generateCloneScripts\", () => {\n\tit(\"returns empty object when no git-based services exist\", () => {\n\t\tconst result = generateCloneScripts(emptyResolved());\n\t\texpect(result).toEqual({});\n\t});\n\n\tit(\"returns empty object when only image-based services exist\", () => {\n\t\tconst result = generateCloneScripts(imageOnlyResolved());\n\t\texpect(result).toEqual({});\n\t});\n\n\tit(\"generates bash and PowerShell scripts for git-based services\", () => {\n\t\tconst result = generateCloneScripts(gitServiceResolved());\n\t\texpect(Object.keys(result)).toHaveLength(2);\n\t\texpect(result).toHaveProperty(\"scripts/clone-repos.sh\");\n\t\texpect(result).toHaveProperty(\"scripts/clone-repos.ps1\");\n\t});\n\n\tit(\"bash script contains clone command with repo URL\", () => {\n\t\tconst result = generateCloneScripts(gitServiceResolved());\n\t\tconst bash = result[\"scripts/clone-repos.sh\"];\n\t\texpect(bash).toContain(\"https://github.com/wasp-lang/open-saas.git\");\n\t\texpect(bash).toContain('\"open-saas\"');\n\t\texpect(bash).toContain('\"main\"');\n\t});\n\n\tit(\"bash script includes postCloneCommands\", () => {\n\t\tconst result = generateCloneScripts(gitServiceResolved());\n\t\tconst bash = result[\"scripts/clone-repos.sh\"];\n\t\texpect(bash).toContain(\"cp .env.example .env\");\n\t});\n\n\tit(\"bash script includes git check and idempotency logic\", () => {\n\t\tconst result = generateCloneScripts(gitServiceResolved());\n\t\tconst bash = result[\"scripts/clone-repos.sh\"];\n\t\texpect(bash).toContain(\"command -v git\");\n\t\texpect(bash).toContain(\"clone_or_update\");\n\t\texpect(bash).toContain(\"pull --ff-only\");\n\t\texpect(bash).toContain(\"git clone --depth 1\");\n\t});\n\n\tit(\"PowerShell script contains clone command with repo URL\", () => {\n\t\tconst result = generateCloneScripts(gitServiceResolved());\n\t\tconst ps = result[\"scripts/clone-repos.ps1\"];\n\t\texpect(ps).toContain(\"https://github.com/wasp-lang/open-saas.git\");\n\t\texpect(ps).toContain('\"open-saas\"');\n\t\texpect(ps).toContain(\"Clone-OrUpdate\");\n\t});\n\n\tit(\"bash script is executable (starts with shebang)\", () => {\n\t\tconst result = generateCloneScripts(gitServiceResolved());\n\t\tconst bash = result[\"scripts/clone-repos.sh\"];\n\t\texpect(bash).toMatch(/^#!/);\n\t});\n});\n"],"mappings":";;;;AAKA,SAAS,gBAAgC;AACxC,QAAO;EACN,UAAU,EAAE;EACZ,mBAAmB,EAAE;EACrB,kBAAkB,EAAE;EACpB,UAAU,EAAE;EACZ,QAAQ,EAAE;EACV,SAAS;EACT,mBAAmB;EACnB,aAAa,EAAE;EACf,aAAa,EAAE;EACf;;;AAIF,SAAS,oBAAoC;AAC5C,QAAO;EACN,GAAG,eAAe;EAClB,UAAU,CACT;GACC,YAAY;IACX,IAAI;IACJ,MAAM;IACN,aAAa;IACb,UAAU;IACV,MAAM;IACN,OAAO;IACP,UAAU;IACV,OAAO,EAAE;IACT,SAAS,EAAE;IACX,aAAa,EAAE;IACf,WAAW,EAAE;IACb,eAAe;IACf,UAAU,CAAC,mBAAmB;IAC9B,QAAQ,EAAE;IACV,iBAAiB,EAAE;IACnB,SAAS;IACT,MAAM,EAAE;IACR,UAAU;IACV,UAAU,EAAE;IACZ,YAAY,EAAE;IACd,eAAe,EAAE;IACjB,aAAa;IACb;GACD,SAAS;GACT,CACD;EACD;;;AAIF,SAAS,qBAAqC;AAC7C,QAAO;EACN,GAAG,eAAe;EAClB,UAAU,CACT;GACC,YAAY;IACX,IAAI;IACJ,MAAM;IACN,aAAa;IACb,UAAU;IACV,MAAM;IACN,WAAW;KACV,SAAS;KACT,QAAQ;KACR,cAAc;KACd,mBAAmB,CAAC,uBAAuB;KAC3C;IACD,cAAc;KACb,YAAY;KACZ,SAAS;KACT;IACD,OAAO,CAAC;KAAE,MAAM;KAAM,WAAW;KAAM,aAAa;KAAW,SAAS;KAAM,CAAC;IAC/E,SAAS,EAAE;IACX,aAAa,EAAE;IACf,WAAW,EAAE;IACb,eAAe;IACf,UAAU,CAAC,mBAAmB;IAC9B,QAAQ,EAAE;IACV,iBAAiB,EAAE;IACnB,SAAS;IACT,MAAM,EAAE;IACR,UAAU;IACV,UAAU,EAAE;IACZ,YAAY,EAAE;IACd,eAAe,EAAE;IACjB,aAAa;IACb;GACD,SAAS;GACT,CACD;EACD;;AAGF,SAAS,8BAA8B;AACtC,IAAG,+DAA+D;AAEjE,eADe,qBAAqB,eAAe,CAAC,CACtC,CAAC,QAAQ,EAAE,CAAC;GACzB;AAEF,IAAG,mEAAmE;AAErE,eADe,qBAAqB,mBAAmB,CAAC,CAC1C,CAAC,QAAQ,EAAE,CAAC;GACzB;AAEF,IAAG,sEAAsE;EACxE,MAAM,SAAS,qBAAqB,oBAAoB,CAAC;AACzD,eAAO,OAAO,KAAK,OAAO,CAAC,CAAC,aAAa,EAAE;AAC3C,eAAO,OAAO,CAAC,eAAe,yBAAyB;AACvD,eAAO,OAAO,CAAC,eAAe,0BAA0B;GACvD;AAEF,IAAG,0DAA0D;EAE5D,MAAM,OADS,qBAAqB,oBAAoB,CAAC,CACrC;AACpB,eAAO,KAAK,CAAC,UAAU,6CAA6C;AACpE,eAAO,KAAK,CAAC,UAAU,gBAAc;AACrC,eAAO,KAAK,CAAC,UAAU,WAAS;GAC/B;AAEF,IAAG,gDAAgD;EAElD,MAAM,OADS,qBAAqB,oBAAoB,CAAC,CACrC;AACpB,eAAO,KAAK,CAAC,UAAU,uBAAuB;GAC7C;AAEF,IAAG,8DAA8D;EAEhE,MAAM,OADS,qBAAqB,oBAAoB,CAAC,CACrC;AACpB,eAAO,KAAK,CAAC,UAAU,iBAAiB;AACxC,eAAO,KAAK,CAAC,UAAU,kBAAkB;AACzC,eAAO,KAAK,CAAC,UAAU,iBAAiB;AACxC,eAAO,KAAK,CAAC,UAAU,sBAAsB;GAC5C;AAEF,IAAG,gEAAgE;EAElE,MAAM,KADS,qBAAqB,oBAAoB,CAAC,CACvC;AAClB,eAAO,GAAG,CAAC,UAAU,6CAA6C;AAClE,eAAO,GAAG,CAAC,UAAU,gBAAc;AACnC,eAAO,GAAG,CAAC,UAAU,iBAAiB;GACrC;AAEF,IAAG,yDAAyD;EAE3D,MAAM,OADS,qBAAqB,oBAAoB,CAAC,CACrC;AACpB,eAAO,KAAK,CAAC,QAAQ,MAAM;GAC1B;EACD"}
1
+ {"version":3,"file":"clone-repos.test.mjs","names":[],"sources":["../../src/generators/clone-repos.test.ts"],"sourcesContent":["import { describe, expect, it } from \"vitest\";\nimport type { ResolverOutput } from \"../types.js\";\nimport { generateCloneScripts } from \"./clone-repos.js\";\n\n/** Minimal resolved output with no services */\nfunction emptyResolved(): ResolverOutput {\n\treturn {\n\t\tservices: [],\n\t\taddedDependencies: [],\n\t\tremovedConflicts: [],\n\t\twarnings: [],\n\t\terrors: [],\n\t\tisValid: true,\n\t\testimatedMemoryMB: 0,\n\t\taiProviders: [],\n\t\tgsdRuntimes: [],\n\t};\n}\n\n/** Create a resolved output with image-based services only */\nfunction imageOnlyResolved(): ResolverOutput {\n\treturn {\n\t\t...emptyResolved(),\n\t\tservices: [\n\t\t\t{\n\t\t\t\tdefinition: {\n\t\t\t\t\tid: \"redis\",\n\t\t\t\t\tname: \"Redis\",\n\t\t\t\t\tdescription: \"In-memory cache\",\n\t\t\t\t\tcategory: \"database\",\n\t\t\t\t\ticon: \"🔴\",\n\t\t\t\t\timage: \"redis\",\n\t\t\t\t\timageTag: \"7-alpine\",\n\t\t\t\t\tports: [],\n\t\t\t\t\tvolumes: [],\n\t\t\t\t\tenvironment: [],\n\t\t\t\t\tdependsOn: [],\n\t\t\t\t\trestartPolicy: \"unless-stopped\",\n\t\t\t\t\tnetworks: [\"openclaw-network\"],\n\t\t\t\t\tskills: [],\n\t\t\t\t\topenclawEnvVars: [],\n\t\t\t\t\tdocsUrl: \"https://redis.io\",\n\t\t\t\t\ttags: [],\n\t\t\t\t\tmaturity: \"stable\",\n\t\t\t\t\trequires: [],\n\t\t\t\t\trecommends: [],\n\t\t\t\t\tconflictsWith: [],\n\t\t\t\t\tgpuRequired: false,\n\t\t\t\t},\n\t\t\t\taddedBy: \"user\",\n\t\t\t},\n\t\t],\n\t};\n}\n\n/** Create a resolved output with a git-based service */\nfunction gitServiceResolved(): ResolverOutput {\n\treturn {\n\t\t...emptyResolved(),\n\t\tservices: [\n\t\t\t{\n\t\t\t\tdefinition: {\n\t\t\t\t\tid: \"open-saas\",\n\t\t\t\t\tname: \"Open SaaS\",\n\t\t\t\t\tdescription: \"SaaS boilerplate\",\n\t\t\t\t\tcategory: \"saas-boilerplate\",\n\t\t\t\t\ticon: \"🚀\",\n\t\t\t\t\tgitSource: {\n\t\t\t\t\t\trepoUrl: \"https://github.com/wasp-lang/open-saas.git\",\n\t\t\t\t\t\tbranch: \"main\",\n\t\t\t\t\t\tsubdirectory: \"template\",\n\t\t\t\t\t\tpostCloneCommands: [\"cp .env.example .env\"],\n\t\t\t\t\t},\n\t\t\t\t\tbuildContext: {\n\t\t\t\t\t\tdockerfile: \"Dockerfile\",\n\t\t\t\t\t\tcontext: \".\",\n\t\t\t\t\t},\n\t\t\t\t\tports: [{ host: 3100, container: 3000, description: \"Web app\", exposed: true }],\n\t\t\t\t\tvolumes: [],\n\t\t\t\t\tenvironment: [],\n\t\t\t\t\tdependsOn: [],\n\t\t\t\t\trestartPolicy: \"unless-stopped\",\n\t\t\t\t\tnetworks: [\"openclaw-network\"],\n\t\t\t\t\tskills: [],\n\t\t\t\t\topenclawEnvVars: [],\n\t\t\t\t\tdocsUrl: \"https://opensaas.sh/docs\",\n\t\t\t\t\ttags: [],\n\t\t\t\t\tmaturity: \"beta\",\n\t\t\t\t\trequires: [],\n\t\t\t\t\trecommends: [],\n\t\t\t\t\tconflictsWith: [],\n\t\t\t\t\tgpuRequired: false,\n\t\t\t\t},\n\t\t\t\taddedBy: \"user\",\n\t\t\t},\n\t\t],\n\t};\n}\n\ndescribe(\"generateCloneScripts\", () => {\n\tit(\"returns empty object when no git-based services exist\", () => {\n\t\tconst result = generateCloneScripts(emptyResolved());\n\t\texpect(result).toEqual({});\n\t});\n\n\tit(\"returns empty object when only image-based services exist\", () => {\n\t\tconst result = generateCloneScripts(imageOnlyResolved());\n\t\texpect(result).toEqual({});\n\t});\n\n\tit(\"generates bash and PowerShell scripts for git-based services\", () => {\n\t\tconst result = generateCloneScripts(gitServiceResolved());\n\t\texpect(Object.keys(result)).toHaveLength(2);\n\t\texpect(result).toHaveProperty(\"scripts/clone-repos.sh\");\n\t\texpect(result).toHaveProperty(\"scripts/clone-repos.ps1\");\n\t});\n\n\tit(\"bash script contains clone command with repo URL\", () => {\n\t\tconst result = generateCloneScripts(gitServiceResolved());\n\t\tconst bash = result[\"scripts/clone-repos.sh\"];\n\t\texpect(bash).toContain(\"https://github.com/wasp-lang/open-saas.git\");\n\t\texpect(bash).toContain('\"open-saas\"');\n\t\texpect(bash).toContain('\"main\"');\n\t});\n\n\tit(\"bash script includes postCloneCommands\", () => {\n\t\tconst result = generateCloneScripts(gitServiceResolved());\n\t\tconst bash = result[\"scripts/clone-repos.sh\"];\n\t\texpect(bash).toContain(\"cp .env.example .env\");\n\t});\n\n\tit(\"bash script includes git check and idempotency logic\", () => {\n\t\tconst result = generateCloneScripts(gitServiceResolved());\n\t\tconst bash = result[\"scripts/clone-repos.sh\"];\n\t\texpect(bash).toContain(\"command -v git\");\n\t\texpect(bash).toContain(\"clone_or_update\");\n\t\texpect(bash).toContain(\"pull --ff-only\");\n\t\texpect(bash).toContain(\"git clone --depth 1\");\n\t});\n\n\tit(\"PowerShell script contains clone command with repo URL\", () => {\n\t\tconst result = generateCloneScripts(gitServiceResolved());\n\t\tconst ps = result[\"scripts/clone-repos.ps1\"];\n\t\texpect(ps).toContain(\"https://github.com/wasp-lang/open-saas.git\");\n\t\texpect(ps).toContain('\"open-saas\"');\n\t\texpect(ps).toContain(\"Clone-OrUpdate\");\n\t});\n\n\tit(\"bash script is executable (starts with shebang)\", () => {\n\t\tconst result = generateCloneScripts(gitServiceResolved());\n\t\tconst bash = result[\"scripts/clone-repos.sh\"];\n\t\texpect(bash).toMatch(/^#!/);\n\t});\n});\n"],"mappings":";;;;AAKA,SAAS,gBAAgC;AACxC,QAAO;EACN,UAAU,EAAE;EACZ,mBAAmB,EAAE;EACrB,kBAAkB,EAAE;EACpB,UAAU,EAAE;EACZ,QAAQ,EAAE;EACV,SAAS;EACT,mBAAmB;EACnB,aAAa,EAAE;EACf,aAAa,EAAE;EACf;;;AAIF,SAAS,oBAAoC;AAC5C,QAAO;EACN,GAAG,eAAe;EAClB,UAAU,CACT;GACC,YAAY;IACX,IAAI;IACJ,MAAM;IACN,aAAa;IACb,UAAU;IACV,MAAM;IACN,OAAO;IACP,UAAU;IACV,OAAO,EAAE;IACT,SAAS,EAAE;IACX,aAAa,EAAE;IACf,WAAW,EAAE;IACb,eAAe;IACf,UAAU,CAAC,mBAAmB;IAC9B,QAAQ,EAAE;IACV,iBAAiB,EAAE;IACnB,SAAS;IACT,MAAM,EAAE;IACR,UAAU;IACV,UAAU,EAAE;IACZ,YAAY,EAAE;IACd,eAAe,EAAE;IACjB,aAAa;IACb;GACD,SAAS;GACT,CACD;EACD;;;AAIF,SAAS,qBAAqC;AAC7C,QAAO;EACN,GAAG,eAAe;EAClB,UAAU,CACT;GACC,YAAY;IACX,IAAI;IACJ,MAAM;IACN,aAAa;IACb,UAAU;IACV,MAAM;IACN,WAAW;KACV,SAAS;KACT,QAAQ;KACR,cAAc;KACd,mBAAmB,CAAC,uBAAuB;KAC3C;IACD,cAAc;KACb,YAAY;KACZ,SAAS;KACT;IACD,OAAO,CAAC;KAAE,MAAM;KAAM,WAAW;KAAM,aAAa;KAAW,SAAS;KAAM,CAAC;IAC/E,SAAS,EAAE;IACX,aAAa,EAAE;IACf,WAAW,EAAE;IACb,eAAe;IACf,UAAU,CAAC,mBAAmB;IAC9B,QAAQ,EAAE;IACV,iBAAiB,EAAE;IACnB,SAAS;IACT,MAAM,EAAE;IACR,UAAU;IACV,UAAU,EAAE;IACZ,YAAY,EAAE;IACd,eAAe,EAAE;IACjB,aAAa;IACb;GACD,SAAS;GACT,CACD;EACD;;AAGF,SAAS,8BAA8B;AACtC,IAAG,+DAA+D;AAEjE,eADe,qBAAqB,eAAe,CAAC,CACtC,CAAC,QAAQ,EAAE,CAAC;GACzB;AAEF,IAAG,mEAAmE;AAErE,eADe,qBAAqB,mBAAmB,CAAC,CAC1C,CAAC,QAAQ,EAAE,CAAC;GACzB;AAEF,IAAG,sEAAsE;EACxE,MAAM,SAAS,qBAAqB,oBAAoB,CAAC;AACzD,eAAO,OAAO,KAAK,OAAO,CAAC,CAAC,aAAa,EAAE;AAC3C,eAAO,OAAO,CAAC,eAAe,yBAAyB;AACvD,eAAO,OAAO,CAAC,eAAe,0BAA0B;GACvD;AAEF,IAAG,0DAA0D;EAE5D,MAAM,OADS,qBAAqB,oBAAoB,CAAC,CACrC;AACpB,eAAO,KAAK,CAAC,UAAU,6CAA6C;AACpE,eAAO,KAAK,CAAC,UAAU,gBAAc;AACrC,eAAO,KAAK,CAAC,UAAU,WAAS;GAC/B;AAEF,IAAG,gDAAgD;EAElD,MAAM,OADS,qBAAqB,oBAAoB,CAAC,CACrC;AACpB,eAAO,KAAK,CAAC,UAAU,uBAAuB;GAC7C;AAEF,IAAG,8DAA8D;EAEhE,MAAM,OADS,qBAAqB,oBAAoB,CAAC,CACrC;AACpB,eAAO,KAAK,CAAC,UAAU,iBAAiB;AACxC,eAAO,KAAK,CAAC,UAAU,kBAAkB;AACzC,eAAO,KAAK,CAAC,UAAU,iBAAiB;AACxC,eAAO,KAAK,CAAC,UAAU,sBAAsB;GAC5C;AAEF,IAAG,gEAAgE;EAElE,MAAM,KADS,qBAAqB,oBAAoB,CAAC,CACvC;AAClB,eAAO,GAAG,CAAC,UAAU,6CAA6C;AAClE,eAAO,GAAG,CAAC,UAAU,gBAAc;AACnC,eAAO,GAAG,CAAC,UAAU,iBAAiB;GACrC;AAEF,IAAG,yDAAyD;EAE3D,MAAM,OADS,qBAAqB,oBAAoB,CAAC,CACrC;AACpB,eAAO,KAAK,CAAC,QAAQ,MAAM;GAC1B;EACD"}
@@ -0,0 +1,58 @@
1
+ const require_test_CTcmp4Su = require("../test.CTcmp4Su-BWSPM8ZQ.cjs");
2
+ const require_generators_cloud_init = require("./cloud-init.cjs");
3
+ //#region src/generators/cloud-init.test.ts
4
+ require_test_CTcmp4Su.describe("generateCloudInit", () => {
5
+ const baseOptions = {
6
+ composeYaml: "version: '3'\nservices:\n redis:\n image: redis:7",
7
+ envContent: "REDIS_PASSWORD=secret123",
8
+ projectName: "my-stack"
9
+ };
10
+ require_test_CTcmp4Su.it("generates valid cloud-init YAML starting with #cloud-config", () => {
11
+ require_test_CTcmp4Su.globalExpect(require_generators_cloud_init.generateCloudInit(baseOptions)).toMatch(/^#cloud-config/);
12
+ });
13
+ require_test_CTcmp4Su.it("embeds the compose YAML content", () => {
14
+ require_test_CTcmp4Su.globalExpect(require_generators_cloud_init.generateCloudInit(baseOptions)).toContain("redis:7");
15
+ });
16
+ require_test_CTcmp4Su.it("embeds the env content with restrictive permissions", () => {
17
+ const result = require_generators_cloud_init.generateCloudInit(baseOptions);
18
+ require_test_CTcmp4Su.globalExpect(result).toContain("REDIS_PASSWORD=secret123");
19
+ require_test_CTcmp4Su.globalExpect(result).toContain("\"0600\"");
20
+ });
21
+ require_test_CTcmp4Su.it("includes project name in the output", () => {
22
+ require_test_CTcmp4Su.globalExpect(require_generators_cloud_init.generateCloudInit(baseOptions)).toContain("my-stack");
23
+ });
24
+ require_test_CTcmp4Su.it("uses default gateway port 18789 when not specified", () => {
25
+ require_test_CTcmp4Su.globalExpect(require_generators_cloud_init.generateCloudInit(baseOptions)).toContain("18789");
26
+ });
27
+ require_test_CTcmp4Su.it("uses custom gateway port when specified", () => {
28
+ const result = require_generators_cloud_init.generateCloudInit({
29
+ ...baseOptions,
30
+ gatewayPort: 9999
31
+ });
32
+ require_test_CTcmp4Su.globalExpect(result).toContain("9999");
33
+ require_test_CTcmp4Su.globalExpect(result).not.toContain("18789");
34
+ });
35
+ require_test_CTcmp4Su.it("includes Docker installation via convenience script", () => {
36
+ require_test_CTcmp4Su.globalExpect(require_generators_cloud_init.generateCloudInit(baseOptions)).toContain("get.docker.com");
37
+ });
38
+ require_test_CTcmp4Su.it("includes health check polling logic", () => {
39
+ const result = require_generators_cloud_init.generateCloudInit(baseOptions);
40
+ require_test_CTcmp4Su.globalExpect(result).toContain("RETRIES=");
41
+ require_test_CTcmp4Su.globalExpect(result).toContain("curl");
42
+ });
43
+ require_test_CTcmp4Su.it("includes runcmd section", () => {
44
+ require_test_CTcmp4Su.globalExpect(require_generators_cloud_init.generateCloudInit(baseOptions)).toContain("runcmd:");
45
+ });
46
+ require_test_CTcmp4Su.it("includes final_message", () => {
47
+ require_test_CTcmp4Su.globalExpect(require_generators_cloud_init.generateCloudInit(baseOptions)).toContain("final_message:");
48
+ });
49
+ require_test_CTcmp4Su.it("includes required packages", () => {
50
+ const result = require_generators_cloud_init.generateCloudInit(baseOptions);
51
+ require_test_CTcmp4Su.globalExpect(result).toContain("packages:");
52
+ require_test_CTcmp4Su.globalExpect(result).toContain("curl");
53
+ require_test_CTcmp4Su.globalExpect(result).toContain("git");
54
+ });
55
+ });
56
+ //#endregion
57
+
58
+ //# sourceMappingURL=cloud-init.test.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cloud-init.test.cjs","names":["describe","generateCloudInit"],"sources":["../../src/generators/cloud-init.test.ts"],"sourcesContent":["import { describe, expect, it } from \"vitest\";\nimport { generateCloudInit } from \"./cloud-init.js\";\n\ndescribe(\"generateCloudInit\", () => {\n\tconst baseOptions = {\n\t\tcomposeYaml: \"version: '3'\\nservices:\\n redis:\\n image: redis:7\",\n\t\tenvContent: \"REDIS_PASSWORD=secret123\",\n\t\tprojectName: \"my-stack\",\n\t};\n\n\tit(\"generates valid cloud-init YAML starting with #cloud-config\", () => {\n\t\tconst result = generateCloudInit(baseOptions);\n\t\texpect(result).toMatch(/^#cloud-config/);\n\t});\n\n\tit(\"embeds the compose YAML content\", () => {\n\t\tconst result = generateCloudInit(baseOptions);\n\t\texpect(result).toContain(\"redis:7\");\n\t});\n\n\tit(\"embeds the env content with restrictive permissions\", () => {\n\t\tconst result = generateCloudInit(baseOptions);\n\t\texpect(result).toContain(\"REDIS_PASSWORD=secret123\");\n\t\texpect(result).toContain('\"0600\"');\n\t});\n\n\tit(\"includes project name in the output\", () => {\n\t\tconst result = generateCloudInit(baseOptions);\n\t\texpect(result).toContain(\"my-stack\");\n\t});\n\n\tit(\"uses default gateway port 18789 when not specified\", () => {\n\t\tconst result = generateCloudInit(baseOptions);\n\t\texpect(result).toContain(\"18789\");\n\t});\n\n\tit(\"uses custom gateway port when specified\", () => {\n\t\tconst result = generateCloudInit({ ...baseOptions, gatewayPort: 9999 });\n\t\texpect(result).toContain(\"9999\");\n\t\texpect(result).not.toContain(\"18789\");\n\t});\n\n\tit(\"includes Docker installation via convenience script\", () => {\n\t\tconst result = generateCloudInit(baseOptions);\n\t\texpect(result).toContain(\"get.docker.com\");\n\t});\n\n\tit(\"includes health check polling logic\", () => {\n\t\tconst result = generateCloudInit(baseOptions);\n\t\texpect(result).toContain(\"RETRIES=\");\n\t\texpect(result).toContain(\"curl\");\n\t});\n\n\tit(\"includes runcmd section\", () => {\n\t\tconst result = generateCloudInit(baseOptions);\n\t\texpect(result).toContain(\"runcmd:\");\n\t});\n\n\tit(\"includes final_message\", () => {\n\t\tconst result = generateCloudInit(baseOptions);\n\t\texpect(result).toContain(\"final_message:\");\n\t});\n\n\tit(\"includes required packages\", () => {\n\t\tconst result = generateCloudInit(baseOptions);\n\t\texpect(result).toContain(\"packages:\");\n\t\texpect(result).toContain(\"curl\");\n\t\texpect(result).toContain(\"git\");\n\t});\n});\n"],"mappings":";;;AAGAA,sBAAAA,SAAS,2BAA2B;CACnC,MAAM,cAAc;EACnB,aAAa;EACb,YAAY;EACZ,aAAa;EACb;AAED,uBAAA,GAAG,qEAAqE;AAEvE,wBAAA,aADeC,8BAAAA,kBAAkB,YAAY,CAC/B,CAAC,QAAQ,iBAAiB;GACvC;AAEF,uBAAA,GAAG,yCAAyC;AAE3C,wBAAA,aADeA,8BAAAA,kBAAkB,YAAY,CAC/B,CAAC,UAAU,UAAU;GAClC;AAEF,uBAAA,GAAG,6DAA6D;EAC/D,MAAM,SAASA,8BAAAA,kBAAkB,YAAY;AAC7C,wBAAA,aAAO,OAAO,CAAC,UAAU,2BAA2B;AACpD,wBAAA,aAAO,OAAO,CAAC,UAAU,WAAS;GACjC;AAEF,uBAAA,GAAG,6CAA6C;AAE/C,wBAAA,aADeA,8BAAAA,kBAAkB,YAAY,CAC/B,CAAC,UAAU,WAAW;GACnC;AAEF,uBAAA,GAAG,4DAA4D;AAE9D,wBAAA,aADeA,8BAAAA,kBAAkB,YAAY,CAC/B,CAAC,UAAU,QAAQ;GAChC;AAEF,uBAAA,GAAG,iDAAiD;EACnD,MAAM,SAASA,8BAAAA,kBAAkB;GAAE,GAAG;GAAa,aAAa;GAAM,CAAC;AACvE,wBAAA,aAAO,OAAO,CAAC,UAAU,OAAO;AAChC,wBAAA,aAAO,OAAO,CAAC,IAAI,UAAU,QAAQ;GACpC;AAEF,uBAAA,GAAG,6DAA6D;AAE/D,wBAAA,aADeA,8BAAAA,kBAAkB,YAAY,CAC/B,CAAC,UAAU,iBAAiB;GACzC;AAEF,uBAAA,GAAG,6CAA6C;EAC/C,MAAM,SAASA,8BAAAA,kBAAkB,YAAY;AAC7C,wBAAA,aAAO,OAAO,CAAC,UAAU,WAAW;AACpC,wBAAA,aAAO,OAAO,CAAC,UAAU,OAAO;GAC/B;AAEF,uBAAA,GAAG,iCAAiC;AAEnC,wBAAA,aADeA,8BAAAA,kBAAkB,YAAY,CAC/B,CAAC,UAAU,UAAU;GAClC;AAEF,uBAAA,GAAG,gCAAgC;AAElC,wBAAA,aADeA,8BAAAA,kBAAkB,YAAY,CAC/B,CAAC,UAAU,iBAAiB;GACzC;AAEF,uBAAA,GAAG,oCAAoC;EACtC,MAAM,SAASA,8BAAAA,kBAAkB,YAAY;AAC7C,wBAAA,aAAO,OAAO,CAAC,UAAU,YAAY;AACrC,wBAAA,aAAO,OAAO,CAAC,UAAU,OAAO;AAChC,wBAAA,aAAO,OAAO,CAAC,UAAU,MAAM;GAC9B;EACD"}
@@ -0,0 +1 @@
1
+ export { };
@@ -0,0 +1 @@
1
+ export { };