@better-openclaw/core 1.0.26 → 1.0.30

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 (1038) hide show
  1. package/README.md +66 -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/dokploy.cjs +25 -0
  64. package/dist/deployers/dokploy.cjs.map +1 -1
  65. package/dist/deployers/dokploy.d.cts +1 -1
  66. package/dist/deployers/dokploy.d.mts +1 -1
  67. package/dist/deployers/dokploy.mjs +25 -0
  68. package/dist/deployers/dokploy.mjs.map +1 -1
  69. package/dist/deployers/index.d.cts +3 -3
  70. package/dist/deployers/index.d.mts +3 -3
  71. package/dist/deployers/strip-host-ports.cjs +1 -1
  72. package/dist/deployers/strip-host-ports.test.cjs +1 -1
  73. package/dist/deployers/strip-host-ports.test.mjs +1 -1
  74. package/dist/deployers/types.d.cts +1 -1
  75. package/dist/deployers/types.d.mts +1 -1
  76. package/dist/{dokploy-8cbrxUun.d.cts → dokploy-BnVDjWCV.d.cts} +2 -2
  77. package/dist/{dokploy-8cbrxUun.d.cts.map → dokploy-BnVDjWCV.d.cts.map} +1 -1
  78. package/dist/{dokploy-BTflLhTM.d.mts → dokploy-BqLdCfyR.d.mts} +2 -2
  79. package/dist/{dokploy-BTflLhTM.d.mts.map → dokploy-BqLdCfyR.d.mts.map} +1 -1
  80. package/dist/frameworks/claude-code-fw.cjs +79 -0
  81. package/dist/frameworks/claude-code-fw.cjs.map +1 -0
  82. package/dist/frameworks/claude-code-fw.d.cts +2 -0
  83. package/dist/frameworks/claude-code-fw.d.mts +2 -0
  84. package/dist/frameworks/claude-code-fw.mjs +78 -0
  85. package/dist/frameworks/claude-code-fw.mjs.map +1 -0
  86. package/dist/frameworks/codex-fw.cjs +67 -0
  87. package/dist/frameworks/codex-fw.cjs.map +1 -0
  88. package/dist/frameworks/codex-fw.d.cts +2 -0
  89. package/dist/frameworks/codex-fw.d.mts +2 -0
  90. package/dist/frameworks/codex-fw.mjs +66 -0
  91. package/dist/frameworks/codex-fw.mjs.map +1 -0
  92. package/dist/frameworks/copaw.cjs +118 -0
  93. package/dist/frameworks/copaw.cjs.map +1 -0
  94. package/dist/frameworks/copaw.d.cts +2 -0
  95. package/dist/frameworks/copaw.d.mts +2 -0
  96. package/dist/frameworks/copaw.mjs +117 -0
  97. package/dist/frameworks/copaw.mjs.map +1 -0
  98. package/dist/frameworks/index.cjs +35 -0
  99. package/dist/frameworks/index.cjs.map +1 -0
  100. package/dist/frameworks/index.d.cts +11 -0
  101. package/dist/frameworks/index.d.mts +11 -0
  102. package/dist/frameworks/index.mjs +22 -0
  103. package/dist/frameworks/index.mjs.map +1 -0
  104. package/dist/frameworks/memu.cjs +118 -0
  105. package/dist/frameworks/memu.cjs.map +1 -0
  106. package/dist/frameworks/memu.d.cts +2 -0
  107. package/dist/frameworks/memu.d.mts +2 -0
  108. package/dist/frameworks/memu.mjs +117 -0
  109. package/dist/frameworks/memu.mjs.map +1 -0
  110. package/dist/frameworks/nanobot.cjs +126 -0
  111. package/dist/frameworks/nanobot.cjs.map +1 -0
  112. package/dist/frameworks/nanobot.d.cts +2 -0
  113. package/dist/frameworks/nanobot.d.mts +2 -0
  114. package/dist/frameworks/nanobot.mjs +125 -0
  115. package/dist/frameworks/nanobot.mjs.map +1 -0
  116. package/dist/frameworks/nanoclaw.cjs +99 -0
  117. package/dist/frameworks/nanoclaw.cjs.map +1 -0
  118. package/dist/frameworks/nanoclaw.d.cts +2 -0
  119. package/dist/frameworks/nanoclaw.d.mts +2 -0
  120. package/dist/frameworks/nanoclaw.mjs +98 -0
  121. package/dist/frameworks/nanoclaw.mjs.map +1 -0
  122. package/dist/frameworks/openclaw.cjs +253 -0
  123. package/dist/frameworks/openclaw.cjs.map +1 -0
  124. package/dist/frameworks/openclaw.d.cts +2 -0
  125. package/dist/frameworks/openclaw.d.mts +2 -0
  126. package/dist/frameworks/openclaw.mjs +251 -0
  127. package/dist/frameworks/openclaw.mjs.map +1 -0
  128. package/dist/frameworks/registry.cjs +31 -0
  129. package/dist/frameworks/registry.cjs.map +1 -0
  130. package/dist/frameworks/registry.d.cts +2 -0
  131. package/dist/frameworks/registry.d.mts +2 -0
  132. package/dist/frameworks/registry.mjs +26 -0
  133. package/dist/frameworks/registry.mjs.map +1 -0
  134. package/dist/frameworks/registry.test.cjs +110 -0
  135. package/dist/frameworks/registry.test.cjs.map +1 -0
  136. package/dist/frameworks/registry.test.d.cts +1 -0
  137. package/dist/frameworks/registry.test.d.mts +1 -0
  138. package/dist/frameworks/registry.test.mjs +111 -0
  139. package/dist/frameworks/registry.test.mjs.map +1 -0
  140. package/dist/frameworks/types.cjs +0 -0
  141. package/dist/frameworks/types.d.cts +2 -0
  142. package/dist/frameworks/types.d.mts +2 -0
  143. package/dist/frameworks/types.mjs +1 -0
  144. package/dist/frameworks/zeroclaw.cjs +123 -0
  145. package/dist/frameworks/zeroclaw.cjs.map +1 -0
  146. package/dist/frameworks/zeroclaw.d.cts +2 -0
  147. package/dist/frameworks/zeroclaw.d.mts +2 -0
  148. package/dist/frameworks/zeroclaw.mjs +122 -0
  149. package/dist/frameworks/zeroclaw.mjs.map +1 -0
  150. package/dist/generate.cjs +64 -13
  151. package/dist/generate.cjs.map +1 -1
  152. package/dist/generate.d.cts +5 -2
  153. package/dist/generate.d.cts.map +1 -1
  154. package/dist/generate.d.mts +5 -2
  155. package/dist/generate.d.mts.map +1 -1
  156. package/dist/generate.mjs +63 -12
  157. package/dist/generate.mjs.map +1 -1
  158. package/dist/generate.test.cjs +42 -6
  159. package/dist/generate.test.cjs.map +1 -1
  160. package/dist/generate.test.mjs +41 -5
  161. package/dist/generate.test.mjs.map +1 -1
  162. package/dist/generators/bare-metal-install.d.cts +1 -1
  163. package/dist/generators/bare-metal-install.d.mts +1 -1
  164. package/dist/generators/bare-metal-install.test.cjs +1 -1
  165. package/dist/generators/bare-metal-install.test.mjs +1 -1
  166. package/dist/generators/caddy.cjs +9 -3
  167. package/dist/generators/caddy.cjs.map +1 -1
  168. package/dist/generators/caddy.d.cts +1 -1
  169. package/dist/generators/caddy.d.mts +1 -1
  170. package/dist/generators/caddy.mjs +9 -3
  171. package/dist/generators/caddy.mjs.map +1 -1
  172. package/dist/generators/caddy.test.cjs +30 -2
  173. package/dist/generators/caddy.test.cjs.map +1 -1
  174. package/dist/generators/caddy.test.mjs +30 -2
  175. package/dist/generators/caddy.test.mjs.map +1 -1
  176. package/dist/generators/clone-repos.cjs.map +1 -1
  177. package/dist/generators/clone-repos.d.cts +1 -1
  178. package/dist/generators/clone-repos.d.mts +1 -1
  179. package/dist/generators/clone-repos.mjs.map +1 -1
  180. package/dist/generators/clone-repos.test.cjs +1 -1
  181. package/dist/generators/clone-repos.test.cjs.map +1 -1
  182. package/dist/generators/clone-repos.test.mjs +1 -1
  183. package/dist/generators/clone-repos.test.mjs.map +1 -1
  184. package/dist/generators/env.cjs +28 -103
  185. package/dist/generators/env.cjs.map +1 -1
  186. package/dist/generators/env.d.cts +4 -1
  187. package/dist/generators/env.d.cts.map +1 -1
  188. package/dist/generators/env.d.mts +4 -1
  189. package/dist/generators/env.d.mts.map +1 -1
  190. package/dist/generators/env.mjs +27 -102
  191. package/dist/generators/env.mjs.map +1 -1
  192. package/dist/generators/env.test.cjs +3 -3
  193. package/dist/generators/env.test.cjs.map +1 -1
  194. package/dist/generators/env.test.mjs +3 -3
  195. package/dist/generators/env.test.mjs.map +1 -1
  196. package/dist/generators/get-shit-done.d.cts +1 -1
  197. package/dist/generators/get-shit-done.d.mts +1 -1
  198. package/dist/generators/health-check.cjs +6 -6
  199. package/dist/generators/health-check.cjs.map +1 -1
  200. package/dist/generators/health-check.d.cts +1 -1
  201. package/dist/generators/health-check.d.mts +1 -1
  202. package/dist/generators/health-check.mjs +6 -6
  203. package/dist/generators/health-check.mjs.map +1 -1
  204. package/dist/generators/health-check.test.cjs +1 -1
  205. package/dist/generators/health-check.test.mjs +1 -1
  206. package/dist/generators/n8n-workflows.d.cts +1 -1
  207. package/dist/generators/n8n-workflows.d.mts +1 -1
  208. package/dist/generators/native-services.d.cts +1 -1
  209. package/dist/generators/native-services.d.mts +1 -1
  210. package/dist/generators/openclaw-json.cjs +60 -4
  211. package/dist/generators/openclaw-json.cjs.map +1 -1
  212. package/dist/generators/openclaw-json.d.cts +1 -5
  213. package/dist/generators/openclaw-json.d.cts.map +1 -1
  214. package/dist/generators/openclaw-json.d.mts +1 -5
  215. package/dist/generators/openclaw-json.d.mts.map +1 -1
  216. package/dist/generators/openclaw-json.mjs +60 -4
  217. package/dist/generators/openclaw-json.mjs.map +1 -1
  218. package/dist/generators/postgres-init.cjs +20 -0
  219. package/dist/generators/postgres-init.cjs.map +1 -1
  220. package/dist/generators/postgres-init.d.cts +1 -1
  221. package/dist/generators/postgres-init.d.cts.map +1 -1
  222. package/dist/generators/postgres-init.d.mts +1 -1
  223. package/dist/generators/postgres-init.d.mts.map +1 -1
  224. package/dist/generators/postgres-init.mjs +20 -0
  225. package/dist/generators/postgres-init.mjs.map +1 -1
  226. package/dist/generators/prometheus.d.cts +1 -1
  227. package/dist/generators/prometheus.d.mts +1 -1
  228. package/dist/generators/readme.cjs +50 -7
  229. package/dist/generators/readme.cjs.map +1 -1
  230. package/dist/generators/readme.d.cts +3 -1
  231. package/dist/generators/readme.d.cts.map +1 -1
  232. package/dist/generators/readme.d.mts +3 -1
  233. package/dist/generators/readme.d.mts.map +1 -1
  234. package/dist/generators/readme.mjs +50 -7
  235. package/dist/generators/readme.mjs.map +1 -1
  236. package/dist/generators/scripts.test.cjs +2 -2
  237. package/dist/generators/scripts.test.cjs.map +1 -1
  238. package/dist/generators/scripts.test.mjs +2 -2
  239. package/dist/generators/scripts.test.mjs.map +1 -1
  240. package/dist/generators/skills.cjs +1 -1
  241. package/dist/generators/skills.d.cts +1 -1
  242. package/dist/generators/skills.d.cts.map +1 -1
  243. package/dist/generators/skills.d.mts +1 -1
  244. package/dist/generators/skills.d.mts.map +1 -1
  245. package/dist/generators/skills.mjs +310 -0
  246. package/dist/generators/skills.mjs.map +1 -1
  247. package/dist/generators/stack-manifest.d.cts +1 -1
  248. package/dist/generators/stack-manifest.d.mts +1 -1
  249. package/dist/generators/traefik.d.cts +1 -1
  250. package/dist/generators/traefik.d.mts +1 -1
  251. package/dist/generators/traefik.test.cjs +12 -12
  252. package/dist/generators/traefik.test.cjs.map +1 -1
  253. package/dist/generators/traefik.test.mjs +12 -12
  254. package/dist/generators/traefik.test.mjs.map +1 -1
  255. package/dist/index.cjs +20 -2
  256. package/dist/index.d.cts +14 -7
  257. package/dist/index.d.mts +14 -7
  258. package/dist/index.mjs +10 -3
  259. package/dist/logger/__tests__/logger.test.cjs +308 -0
  260. package/dist/logger/__tests__/logger.test.cjs.map +1 -0
  261. package/dist/logger/__tests__/logger.test.d.cts +1 -0
  262. package/dist/logger/__tests__/logger.test.d.mts +1 -0
  263. package/dist/logger/__tests__/logger.test.mjs +308 -0
  264. package/dist/logger/__tests__/logger.test.mjs.map +1 -0
  265. package/dist/logger/index.cjs +10 -0
  266. package/dist/logger/index.d.cts +6 -0
  267. package/dist/logger/index.d.mts +6 -0
  268. package/dist/logger/index.mjs +5 -0
  269. package/dist/logger/logger.cjs +270 -0
  270. package/dist/logger/logger.cjs.map +1 -0
  271. package/dist/logger/logger.d.cts +2 -0
  272. package/dist/logger/logger.d.mts +2 -0
  273. package/dist/logger/logger.mjs +267 -0
  274. package/dist/logger/logger.mjs.map +1 -0
  275. package/dist/logger/sinks/callback-sink.cjs +18 -0
  276. package/dist/logger/sinks/callback-sink.cjs.map +1 -0
  277. package/dist/logger/sinks/callback-sink.d.cts +2 -0
  278. package/dist/logger/sinks/callback-sink.d.mts +2 -0
  279. package/dist/logger/sinks/callback-sink.mjs +17 -0
  280. package/dist/logger/sinks/callback-sink.mjs.map +1 -0
  281. package/dist/logger/sinks/console-sink.cjs +39 -0
  282. package/dist/logger/sinks/console-sink.cjs.map +1 -0
  283. package/dist/logger/sinks/console-sink.d.cts +2 -0
  284. package/dist/logger/sinks/console-sink.d.mts +2 -0
  285. package/dist/logger/sinks/console-sink.mjs +38 -0
  286. package/dist/logger/sinks/console-sink.mjs.map +1 -0
  287. package/dist/logger/sinks/file-sink.cjs +72 -0
  288. package/dist/logger/sinks/file-sink.cjs.map +1 -0
  289. package/dist/logger/sinks/file-sink.d.cts +36 -0
  290. package/dist/logger/sinks/file-sink.d.cts.map +1 -0
  291. package/dist/logger/sinks/file-sink.d.mts +36 -0
  292. package/dist/logger/sinks/file-sink.d.mts.map +1 -0
  293. package/dist/logger/sinks/file-sink.mjs +70 -0
  294. package/dist/logger/sinks/file-sink.mjs.map +1 -0
  295. package/dist/logger/types.cjs +0 -0
  296. package/dist/logger/types.d.cts +2 -0
  297. package/dist/logger/types.d.mts +2 -0
  298. package/dist/logger/types.mjs +1 -0
  299. package/dist/logger-CZ0Qnyiu.d.mts +66 -0
  300. package/dist/logger-CZ0Qnyiu.d.mts.map +1 -0
  301. package/dist/logger-DDfwai-A.d.cts +66 -0
  302. package/dist/logger-DDfwai-A.d.cts.map +1 -0
  303. package/dist/memu-BfRXtwmL.d.cts +7 -0
  304. package/dist/memu-BfRXtwmL.d.cts.map +1 -0
  305. package/dist/memu-C-fXbWr-.d.mts +7 -0
  306. package/dist/memu-C-fXbWr-.d.mts.map +1 -0
  307. package/dist/migrations.cjs +17 -9
  308. package/dist/migrations.cjs.map +1 -1
  309. package/dist/migrations.d.cts +1 -1
  310. package/dist/migrations.d.cts.map +1 -1
  311. package/dist/migrations.d.mts +1 -1
  312. package/dist/migrations.d.mts.map +1 -1
  313. package/dist/migrations.mjs +17 -9
  314. package/dist/migrations.mjs.map +1 -1
  315. package/dist/migrations.test.cjs +4 -4
  316. package/dist/migrations.test.mjs +4 -4
  317. package/dist/nanobot-2c0bS4lu.d.cts +7 -0
  318. package/dist/nanobot-2c0bS4lu.d.cts.map +1 -0
  319. package/dist/nanobot-BUO6pVQc.d.mts +7 -0
  320. package/dist/nanobot-BUO6pVQc.d.mts.map +1 -0
  321. package/dist/nanoclaw-CgHubEig.d.mts +7 -0
  322. package/dist/nanoclaw-CgHubEig.d.mts.map +1 -0
  323. package/dist/nanoclaw-Dvz0ef6J.d.cts +7 -0
  324. package/dist/nanoclaw-Dvz0ef6J.d.cts.map +1 -0
  325. package/dist/openclaw-D8lVecjC.d.mts +7 -0
  326. package/dist/openclaw-D8lVecjC.d.mts.map +1 -0
  327. package/dist/openclaw-DThj8i3N.d.cts +7 -0
  328. package/dist/openclaw-DThj8i3N.d.cts.map +1 -0
  329. package/dist/port-scanner.d.cts +1 -1
  330. package/dist/port-scanner.d.mts +1 -1
  331. package/dist/presets/presets.test.cjs +5 -5
  332. package/dist/presets/presets.test.cjs.map +1 -1
  333. package/dist/presets/presets.test.mjs +4 -4
  334. package/dist/presets/presets.test.mjs.map +1 -1
  335. package/dist/presets/registry.d.cts +1 -1
  336. package/dist/presets/registry.d.mts +1 -1
  337. package/dist/presets/registry.test.cjs +7 -7
  338. package/dist/presets/registry.test.cjs.map +1 -1
  339. package/dist/presets/registry.test.mjs +7 -7
  340. package/dist/presets/registry.test.mjs.map +1 -1
  341. package/dist/registry-DHX7vnVo.d.cts +16 -0
  342. package/dist/registry-DHX7vnVo.d.cts.map +1 -0
  343. package/dist/registry-DTAILnga.d.mts +16 -0
  344. package/dist/registry-DTAILnga.d.mts.map +1 -0
  345. package/dist/resolver.cjs +13 -3
  346. package/dist/resolver.cjs.map +1 -1
  347. package/dist/resolver.d.cts +1 -1
  348. package/dist/resolver.d.cts.map +1 -1
  349. package/dist/resolver.d.mts +1 -1
  350. package/dist/resolver.d.mts.map +1 -1
  351. package/dist/resolver.mjs +13 -3
  352. package/dist/resolver.mjs.map +1 -1
  353. package/dist/resolver.test.cjs +35 -3
  354. package/dist/resolver.test.cjs.map +1 -1
  355. package/dist/resolver.test.mjs +35 -3
  356. package/dist/resolver.test.mjs.map +1 -1
  357. package/dist/{schema-BQnZrcw8.d.cts → schema-BSl9wiFe.d.mts} +134 -2
  358. package/dist/schema-BSl9wiFe.d.mts.map +1 -0
  359. package/dist/{schema-SBpL0bdI.d.mts → schema-Bd9l2r7p.d.cts} +134 -2
  360. package/dist/schema-Bd9l2r7p.d.cts.map +1 -0
  361. package/dist/schema.cjs +28 -4
  362. package/dist/schema.cjs.map +1 -1
  363. package/dist/schema.d.cts +2 -2
  364. package/dist/schema.d.mts +2 -2
  365. package/dist/schema.mjs +27 -4
  366. package/dist/schema.mjs.map +1 -1
  367. package/dist/schema.test.cjs +3 -3
  368. package/dist/schema.test.cjs.map +1 -1
  369. package/dist/schema.test.mjs +3 -3
  370. package/dist/schema.test.mjs.map +1 -1
  371. package/dist/services/definitions/adguard-home.d.cts +1 -1
  372. package/dist/services/definitions/adguard-home.d.mts +1 -1
  373. package/dist/services/definitions/agent-browser.cjs +161 -0
  374. package/dist/services/definitions/agent-browser.cjs.map +1 -0
  375. package/dist/services/definitions/agent-browser.d.cts +7 -0
  376. package/dist/services/definitions/agent-browser.d.cts.map +1 -0
  377. package/dist/services/definitions/agent-browser.d.mts +7 -0
  378. package/dist/services/definitions/agent-browser.d.mts.map +1 -0
  379. package/dist/services/definitions/agent-browser.mjs +160 -0
  380. package/dist/services/definitions/agent-browser.mjs.map +1 -0
  381. package/dist/services/definitions/airbyte.d.cts +1 -1
  382. package/dist/services/definitions/airbyte.d.mts +1 -1
  383. package/dist/services/definitions/airflow.d.cts +1 -1
  384. package/dist/services/definitions/airflow.d.mts +1 -1
  385. package/dist/services/definitions/anything-llm.d.cts +1 -1
  386. package/dist/services/definitions/anything-llm.d.mts +1 -1
  387. package/dist/services/definitions/appflowy.d.cts +1 -1
  388. package/dist/services/definitions/appflowy.d.mts +1 -1
  389. package/dist/services/definitions/apptension-saas.cjs.map +1 -1
  390. package/dist/services/definitions/apptension-saas.d.cts +1 -1
  391. package/dist/services/definitions/apptension-saas.d.mts +1 -1
  392. package/dist/services/definitions/apptension-saas.mjs.map +1 -1
  393. package/dist/services/definitions/appwrite.d.cts +1 -1
  394. package/dist/services/definitions/appwrite.d.mts +1 -1
  395. package/dist/services/definitions/audiobookshelf.d.cts +1 -1
  396. package/dist/services/definitions/audiobookshelf.d.mts +1 -1
  397. package/dist/services/definitions/authelia.d.cts +1 -1
  398. package/dist/services/definitions/authelia.d.mts +1 -1
  399. package/dist/services/definitions/authentik.d.cts +1 -1
  400. package/dist/services/definitions/authentik.d.mts +1 -1
  401. package/dist/services/definitions/axolotl.d.cts +1 -1
  402. package/dist/services/definitions/axolotl.d.mts +1 -1
  403. package/dist/services/definitions/baserow.d.cts +1 -1
  404. package/dist/services/definitions/baserow.d.mts +1 -1
  405. package/dist/services/definitions/beszel.d.cts +1 -1
  406. package/dist/services/definitions/beszel.d.mts +1 -1
  407. package/dist/services/definitions/boxyhq-saas.d.cts +1 -1
  408. package/dist/services/definitions/boxyhq-saas.d.mts +1 -1
  409. package/dist/services/definitions/browserless.d.cts +1 -1
  410. package/dist/services/definitions/browserless.d.mts +1 -1
  411. package/dist/services/definitions/burnlink.d.cts +1 -1
  412. package/dist/services/definitions/burnlink.d.mts +1 -1
  413. package/dist/services/definitions/caddy.d.cts +1 -1
  414. package/dist/services/definitions/caddy.d.mts +1 -1
  415. package/dist/services/definitions/cal-com.d.cts +1 -1
  416. package/dist/services/definitions/cal-com.d.mts +1 -1
  417. package/dist/services/definitions/calibre-web.d.cts +1 -1
  418. package/dist/services/definitions/calibre-web.d.mts +1 -1
  419. package/dist/services/definitions/chatwoot-worker.d.cts +1 -1
  420. package/dist/services/definitions/chatwoot-worker.d.mts +1 -1
  421. package/dist/services/definitions/chatwoot.d.cts +1 -1
  422. package/dist/services/definitions/chatwoot.d.mts +1 -1
  423. package/dist/services/definitions/chromadb.cjs +4 -1
  424. package/dist/services/definitions/chromadb.cjs.map +1 -1
  425. package/dist/services/definitions/chromadb.d.cts +1 -1
  426. package/dist/services/definitions/chromadb.d.mts +1 -1
  427. package/dist/services/definitions/chromadb.mjs +4 -1
  428. package/dist/services/definitions/chromadb.mjs.map +1 -1
  429. package/dist/services/definitions/claude-code.cjs +1 -1
  430. package/dist/services/definitions/claude-code.cjs.map +1 -1
  431. package/dist/services/definitions/claude-code.d.cts +1 -1
  432. package/dist/services/definitions/claude-code.d.mts +1 -1
  433. package/dist/services/definitions/claude-code.mjs +1 -1
  434. package/dist/services/definitions/claude-code.mjs.map +1 -1
  435. package/dist/services/definitions/clawrouter.cjs +138 -0
  436. package/dist/services/definitions/clawrouter.cjs.map +1 -0
  437. package/dist/services/definitions/clawrouter.d.cts +7 -0
  438. package/dist/services/definitions/clawrouter.d.cts.map +1 -0
  439. package/dist/services/definitions/clawrouter.d.mts +7 -0
  440. package/dist/services/definitions/clawrouter.d.mts.map +1 -0
  441. package/dist/services/definitions/clawrouter.mjs +137 -0
  442. package/dist/services/definitions/clawrouter.mjs.map +1 -0
  443. package/dist/services/definitions/clickhouse.d.cts +1 -1
  444. package/dist/services/definitions/clickhouse.d.mts +1 -1
  445. package/dist/services/definitions/cloudflared.d.cts +1 -1
  446. package/dist/services/definitions/cloudflared.d.mts +1 -1
  447. package/dist/services/definitions/cmsaas-starter.d.cts +1 -1
  448. package/dist/services/definitions/cmsaas-starter.d.mts +1 -1
  449. package/dist/services/definitions/cockroachdb.d.cts +1 -1
  450. package/dist/services/definitions/cockroachdb.d.mts +1 -1
  451. package/dist/services/definitions/code-server.d.cts +1 -1
  452. package/dist/services/definitions/code-server.d.mts +1 -1
  453. package/dist/services/definitions/coder.d.cts +1 -1
  454. package/dist/services/definitions/coder.d.mts +1 -1
  455. package/dist/services/definitions/codex.cjs +1 -1
  456. package/dist/services/definitions/codex.cjs.map +1 -1
  457. package/dist/services/definitions/codex.d.cts +1 -1
  458. package/dist/services/definitions/codex.d.mts +1 -1
  459. package/dist/services/definitions/codex.mjs +1 -1
  460. package/dist/services/definitions/codex.mjs.map +1 -1
  461. package/dist/services/definitions/comfyui.d.cts +1 -1
  462. package/dist/services/definitions/comfyui.d.mts +1 -1
  463. package/dist/services/definitions/convex-dashboard.d.cts +1 -1
  464. package/dist/services/definitions/convex-dashboard.d.mts +1 -1
  465. package/dist/services/definitions/convex.cjs.map +1 -1
  466. package/dist/services/definitions/convex.d.cts +1 -1
  467. package/dist/services/definitions/convex.d.mts +1 -1
  468. package/dist/services/definitions/convex.mjs.map +1 -1
  469. package/dist/services/definitions/coolify.d.cts +1 -1
  470. package/dist/services/definitions/coolify.d.mts +1 -1
  471. package/dist/services/definitions/copaw.cjs +97 -0
  472. package/dist/services/definitions/copaw.cjs.map +1 -0
  473. package/dist/services/definitions/copaw.d.cts +7 -0
  474. package/dist/services/definitions/copaw.d.cts.map +1 -0
  475. package/dist/services/definitions/copaw.d.mts +7 -0
  476. package/dist/services/definitions/copaw.d.mts.map +1 -0
  477. package/dist/services/definitions/copaw.mjs +96 -0
  478. package/dist/services/definitions/copaw.mjs.map +1 -0
  479. package/dist/services/definitions/crowdsec.d.cts +1 -1
  480. package/dist/services/definitions/crowdsec.d.mts +1 -1
  481. package/dist/services/definitions/dagster.d.cts +1 -1
  482. package/dist/services/definitions/dagster.d.mts +1 -1
  483. package/dist/services/definitions/desktop-environment.cjs +2 -1
  484. package/dist/services/definitions/desktop-environment.cjs.map +1 -1
  485. package/dist/services/definitions/desktop-environment.d.cts +1 -1
  486. package/dist/services/definitions/desktop-environment.d.mts +1 -1
  487. package/dist/services/definitions/desktop-environment.mjs +2 -1
  488. package/dist/services/definitions/desktop-environment.mjs.map +1 -1
  489. package/dist/services/definitions/dify.d.cts +1 -1
  490. package/dist/services/definitions/dify.d.mts +1 -1
  491. package/dist/services/definitions/directus.d.cts +1 -1
  492. package/dist/services/definitions/directus.d.mts +1 -1
  493. package/dist/services/definitions/docsgpt.d.cts +1 -1
  494. package/dist/services/definitions/docsgpt.d.mts +1 -1
  495. package/dist/services/definitions/dokploy.d.cts +1 -1
  496. package/dist/services/definitions/dokploy.d.mts +1 -1
  497. package/dist/services/definitions/dozzle.d.cts +1 -1
  498. package/dist/services/definitions/dozzle.d.mts +1 -1
  499. package/dist/services/definitions/dragonfly.d.cts +1 -1
  500. package/dist/services/definitions/dragonfly.d.mts +1 -1
  501. package/dist/services/definitions/drone-ci.d.cts +1 -1
  502. package/dist/services/definitions/drone-ci.d.mts +1 -1
  503. package/dist/services/definitions/duplicati.d.cts +1 -1
  504. package/dist/services/definitions/duplicati.d.mts +1 -1
  505. package/dist/services/definitions/element-web.d.cts +1 -1
  506. package/dist/services/definitions/element-web.d.mts +1 -1
  507. package/dist/services/definitions/excalidraw.d.cts +1 -1
  508. package/dist/services/definitions/excalidraw.d.mts +1 -1
  509. package/dist/services/definitions/ffmpeg.d.cts +1 -1
  510. package/dist/services/definitions/ffmpeg.d.mts +1 -1
  511. package/dist/services/definitions/firecrawl-playwright.d.cts +1 -1
  512. package/dist/services/definitions/firecrawl-playwright.d.mts +1 -1
  513. package/dist/services/definitions/firecrawl.d.cts +1 -1
  514. package/dist/services/definitions/firecrawl.d.mts +1 -1
  515. package/dist/services/definitions/flagsmith.d.cts +1 -1
  516. package/dist/services/definitions/flagsmith.d.mts +1 -1
  517. package/dist/services/definitions/flowise.d.cts +1 -1
  518. package/dist/services/definitions/flowise.d.mts +1 -1
  519. package/dist/services/definitions/focalboard.d.cts +1 -1
  520. package/dist/services/definitions/focalboard.d.mts +1 -1
  521. package/dist/services/definitions/fonoster.d.cts +1 -1
  522. package/dist/services/definitions/fonoster.d.mts +1 -1
  523. package/dist/services/definitions/forgejo.d.cts +1 -1
  524. package/dist/services/definitions/forgejo.d.mts +1 -1
  525. package/dist/services/definitions/formbricks.d.cts +1 -1
  526. package/dist/services/definitions/formbricks.d.mts +1 -1
  527. package/dist/services/definitions/gemini-cli.d.cts +1 -1
  528. package/dist/services/definitions/gemini-cli.d.mts +1 -1
  529. package/dist/services/definitions/ghost.d.cts +1 -1
  530. package/dist/services/definitions/ghost.d.mts +1 -1
  531. package/dist/services/definitions/gitea.d.cts +1 -1
  532. package/dist/services/definitions/gitea.d.mts +1 -1
  533. package/dist/services/definitions/gotify.d.cts +1 -1
  534. package/dist/services/definitions/gotify.d.mts +1 -1
  535. package/dist/services/definitions/grafana.d.cts +1 -1
  536. package/dist/services/definitions/grafana.d.mts +1 -1
  537. package/dist/services/definitions/graylog.d.cts +1 -1
  538. package/dist/services/definitions/graylog.d.mts +1 -1
  539. package/dist/services/definitions/headscale.d.cts +1 -1
  540. package/dist/services/definitions/headscale.d.mts +1 -1
  541. package/dist/services/definitions/hedgedoc.d.cts +1 -1
  542. package/dist/services/definitions/hedgedoc.d.mts +1 -1
  543. package/dist/services/definitions/hexstrike.d.cts +1 -1
  544. package/dist/services/definitions/hexstrike.d.mts +1 -1
  545. package/dist/services/definitions/heyform.d.cts +1 -1
  546. package/dist/services/definitions/heyform.d.mts +1 -1
  547. package/dist/services/definitions/hindsight.cjs +4 -1
  548. package/dist/services/definitions/hindsight.cjs.map +1 -1
  549. package/dist/services/definitions/hindsight.d.cts +1 -1
  550. package/dist/services/definitions/hindsight.d.mts +1 -1
  551. package/dist/services/definitions/hindsight.mjs +4 -1
  552. package/dist/services/definitions/hindsight.mjs.map +1 -1
  553. package/dist/services/definitions/homeassistant.d.cts +1 -1
  554. package/dist/services/definitions/homeassistant.d.mts +1 -1
  555. package/dist/services/definitions/hoppscotch.d.cts +1 -1
  556. package/dist/services/definitions/hoppscotch.d.mts +1 -1
  557. package/dist/services/definitions/immich.d.cts +1 -1
  558. package/dist/services/definitions/immich.d.mts +1 -1
  559. package/dist/services/definitions/index.cjs +42 -6
  560. package/dist/services/definitions/index.cjs.map +1 -1
  561. package/dist/services/definitions/index.d.cts +16 -4
  562. package/dist/services/definitions/index.d.cts.map +1 -1
  563. package/dist/services/definitions/index.d.mts +16 -4
  564. package/dist/services/definitions/index.d.mts.map +1 -1
  565. package/dist/services/definitions/index.mjs +31 -7
  566. package/dist/services/definitions/index.mjs.map +1 -1
  567. package/dist/services/definitions/infisical.d.cts +1 -1
  568. package/dist/services/definitions/infisical.d.mts +1 -1
  569. package/dist/services/definitions/influxdb.d.cts +1 -1
  570. package/dist/services/definitions/influxdb.d.mts +1 -1
  571. package/dist/services/definitions/invoke-ai.d.cts +1 -1
  572. package/dist/services/definitions/invoke-ai.d.mts +1 -1
  573. package/dist/services/definitions/ixartz-saas.d.cts +1 -1
  574. package/dist/services/definitions/ixartz-saas.d.mts +1 -1
  575. package/dist/services/definitions/jaeger.d.cts +1 -1
  576. package/dist/services/definitions/jaeger.d.mts +1 -1
  577. package/dist/services/definitions/jan.d.cts +1 -1
  578. package/dist/services/definitions/jan.d.mts +1 -1
  579. package/dist/services/definitions/jellyfin.d.cts +1 -1
  580. package/dist/services/definitions/jellyfin.d.mts +1 -1
  581. package/dist/services/definitions/jenkins.d.cts +1 -1
  582. package/dist/services/definitions/jenkins.d.mts +1 -1
  583. package/dist/services/definitions/jitsi-meet.d.cts +1 -1
  584. package/dist/services/definitions/jitsi-meet.d.mts +1 -1
  585. package/dist/services/definitions/keycloak.d.cts +1 -1
  586. package/dist/services/definitions/keycloak.d.mts +1 -1
  587. package/dist/services/definitions/kimi.d.cts +1 -1
  588. package/dist/services/definitions/kimi.d.mts +1 -1
  589. package/dist/services/definitions/kong.d.cts +1 -1
  590. package/dist/services/definitions/kong.d.mts +1 -1
  591. package/dist/services/definitions/lago.d.cts +1 -1
  592. package/dist/services/definitions/lago.d.mts +1 -1
  593. package/dist/services/definitions/langflow.d.cts +1 -1
  594. package/dist/services/definitions/langflow.d.mts +1 -1
  595. package/dist/services/definitions/langfuse.d.cts +1 -1
  596. package/dist/services/definitions/langfuse.d.mts +1 -1
  597. package/dist/services/definitions/lasuite-meet-agents.d.cts +1 -1
  598. package/dist/services/definitions/lasuite-meet-agents.d.mts +1 -1
  599. package/dist/services/definitions/lasuite-meet-backend.d.cts +1 -1
  600. package/dist/services/definitions/lasuite-meet-backend.d.mts +1 -1
  601. package/dist/services/definitions/lasuite-meet-frontend.d.cts +1 -1
  602. package/dist/services/definitions/lasuite-meet-frontend.d.mts +1 -1
  603. package/dist/services/definitions/librechat.d.cts +1 -1
  604. package/dist/services/definitions/librechat.d.mts +1 -1
  605. package/dist/services/definitions/lightpanda.d.cts +1 -1
  606. package/dist/services/definitions/lightpanda.d.mts +1 -1
  607. package/dist/services/definitions/listmonk.d.cts +1 -1
  608. package/dist/services/definitions/listmonk.d.mts +1 -1
  609. package/dist/services/definitions/litellm.d.cts +1 -1
  610. package/dist/services/definitions/litellm.d.mts +1 -1
  611. package/dist/services/definitions/livekit.d.cts +1 -1
  612. package/dist/services/definitions/livekit.d.mts +1 -1
  613. package/dist/services/definitions/local-ai.d.cts +1 -1
  614. package/dist/services/definitions/local-ai.d.mts +1 -1
  615. package/dist/services/definitions/loki.d.cts +1 -1
  616. package/dist/services/definitions/loki.d.mts +1 -1
  617. package/dist/services/definitions/mariadb.d.cts +1 -1
  618. package/dist/services/definitions/mariadb.d.mts +1 -1
  619. package/dist/services/definitions/matomo.d.cts +1 -1
  620. package/dist/services/definitions/matomo.d.mts +1 -1
  621. package/dist/services/definitions/matrix-synapse.d.cts +1 -1
  622. package/dist/services/definitions/matrix-synapse.d.mts +1 -1
  623. package/dist/services/definitions/mattermost.d.cts +1 -1
  624. package/dist/services/definitions/mattermost.d.mts +1 -1
  625. package/dist/services/definitions/mautic.d.cts +1 -1
  626. package/dist/services/definitions/mautic.d.mts +1 -1
  627. package/dist/services/definitions/medusa.d.cts +1 -1
  628. package/dist/services/definitions/medusa.d.mts +1 -1
  629. package/dist/services/definitions/meilisearch.d.cts +1 -1
  630. package/dist/services/definitions/meilisearch.d.mts +1 -1
  631. package/dist/services/definitions/mem0.cjs +133 -0
  632. package/dist/services/definitions/mem0.cjs.map +1 -0
  633. package/dist/services/definitions/mem0.d.cts +7 -0
  634. package/dist/services/definitions/mem0.d.cts.map +1 -0
  635. package/dist/services/definitions/mem0.d.mts +7 -0
  636. package/dist/services/definitions/mem0.d.mts.map +1 -0
  637. package/dist/services/definitions/mem0.mjs +132 -0
  638. package/dist/services/definitions/mem0.mjs.map +1 -0
  639. package/dist/services/definitions/memu.cjs +96 -0
  640. package/dist/services/definitions/memu.cjs.map +1 -0
  641. package/dist/services/definitions/memu.d.cts +7 -0
  642. package/dist/services/definitions/memu.d.cts.map +1 -0
  643. package/dist/services/definitions/memu.d.mts +7 -0
  644. package/dist/services/definitions/memu.d.mts.map +1 -0
  645. package/dist/services/definitions/memu.mjs +95 -0
  646. package/dist/services/definitions/memu.mjs.map +1 -0
  647. package/dist/services/definitions/metabase.d.cts +1 -1
  648. package/dist/services/definitions/metabase.d.mts +1 -1
  649. package/dist/services/definitions/milvus.cjs +4 -1
  650. package/dist/services/definitions/milvus.cjs.map +1 -1
  651. package/dist/services/definitions/milvus.d.cts +1 -1
  652. package/dist/services/definitions/milvus.d.mts +1 -1
  653. package/dist/services/definitions/milvus.mjs +4 -1
  654. package/dist/services/definitions/milvus.mjs.map +1 -1
  655. package/dist/services/definitions/minio.d.cts +1 -1
  656. package/dist/services/definitions/minio.d.mts +1 -1
  657. package/dist/services/definitions/mission-control.d.cts +1 -1
  658. package/dist/services/definitions/mission-control.d.mts +1 -1
  659. package/dist/services/definitions/mixpost.d.cts +1 -1
  660. package/dist/services/definitions/mixpost.d.mts +1 -1
  661. package/dist/services/definitions/mosquitto.d.cts +1 -1
  662. package/dist/services/definitions/mosquitto.d.mts +1 -1
  663. package/dist/services/definitions/motion-canvas.d.cts +1 -1
  664. package/dist/services/definitions/motion-canvas.d.mts +1 -1
  665. package/dist/services/definitions/mysql.d.cts +1 -1
  666. package/dist/services/definitions/mysql.d.mts +1 -1
  667. package/dist/services/definitions/n8n.d.cts +1 -1
  668. package/dist/services/definitions/n8n.d.mts +1 -1
  669. package/dist/services/definitions/nanobot.cjs +86 -0
  670. package/dist/services/definitions/nanobot.cjs.map +1 -0
  671. package/dist/services/definitions/nanobot.d.cts +7 -0
  672. package/dist/services/definitions/nanobot.d.cts.map +1 -0
  673. package/dist/services/definitions/nanobot.d.mts +7 -0
  674. package/dist/services/definitions/nanobot.d.mts.map +1 -0
  675. package/dist/services/definitions/nanobot.mjs +85 -0
  676. package/dist/services/definitions/nanobot.mjs.map +1 -0
  677. package/dist/services/definitions/nanoclaw.cjs +79 -0
  678. package/dist/services/definitions/nanoclaw.cjs.map +1 -0
  679. package/dist/services/definitions/nanoclaw.d.cts +7 -0
  680. package/dist/services/definitions/nanoclaw.d.cts.map +1 -0
  681. package/dist/services/definitions/nanoclaw.d.mts +7 -0
  682. package/dist/services/definitions/nanoclaw.d.mts.map +1 -0
  683. package/dist/services/definitions/nanoclaw.mjs +78 -0
  684. package/dist/services/definitions/nanoclaw.mjs.map +1 -0
  685. package/dist/services/definitions/navidrome.d.cts +1 -1
  686. package/dist/services/definitions/navidrome.d.mts +1 -1
  687. package/dist/services/definitions/neo4j.d.cts +1 -1
  688. package/dist/services/definitions/neo4j.d.mts +1 -1
  689. package/dist/services/definitions/nextcloud.d.cts +1 -1
  690. package/dist/services/definitions/nextcloud.d.mts +1 -1
  691. package/dist/services/definitions/nginx-proxy-manager.d.cts +1 -1
  692. package/dist/services/definitions/nginx-proxy-manager.d.mts +1 -1
  693. package/dist/services/definitions/nocodb.d.cts +1 -1
  694. package/dist/services/definitions/nocodb.d.mts +1 -1
  695. package/dist/services/definitions/node-red.d.cts +1 -1
  696. package/dist/services/definitions/node-red.d.mts +1 -1
  697. package/dist/services/definitions/ntfy.d.cts +1 -1
  698. package/dist/services/definitions/ntfy.d.mts +1 -1
  699. package/dist/services/definitions/ollama.d.cts +1 -1
  700. package/dist/services/definitions/ollama.d.mts +1 -1
  701. package/dist/services/definitions/open-saas.d.cts +1 -1
  702. package/dist/services/definitions/open-saas.d.mts +1 -1
  703. package/dist/services/definitions/open-webui.d.cts +1 -1
  704. package/dist/services/definitions/open-webui.d.mts +1 -1
  705. package/dist/services/definitions/opencode.d.cts +1 -1
  706. package/dist/services/definitions/opencode.d.mts +1 -1
  707. package/dist/services/definitions/openhands.d.cts +1 -1
  708. package/dist/services/definitions/openhands.d.mts +1 -1
  709. package/dist/services/definitions/openpanel.d.cts +1 -1
  710. package/dist/services/definitions/openpanel.d.mts +1 -1
  711. package/dist/services/definitions/opensandbox.cjs +2 -1
  712. package/dist/services/definitions/opensandbox.cjs.map +1 -1
  713. package/dist/services/definitions/opensandbox.d.cts +1 -1
  714. package/dist/services/definitions/opensandbox.d.mts +1 -1
  715. package/dist/services/definitions/opensandbox.mjs +2 -1
  716. package/dist/services/definitions/opensandbox.mjs.map +1 -1
  717. package/dist/services/definitions/opensearch.d.cts +1 -1
  718. package/dist/services/definitions/opensearch.d.mts +1 -1
  719. package/dist/services/definitions/outline.d.cts +1 -1
  720. package/dist/services/definitions/outline.d.mts +1 -1
  721. package/dist/services/definitions/paperless-ngx.d.cts +1 -1
  722. package/dist/services/definitions/paperless-ngx.d.mts +1 -1
  723. package/dist/services/definitions/pentagi.d.cts +1 -1
  724. package/dist/services/definitions/pentagi.d.mts +1 -1
  725. package/dist/services/definitions/pentestagent.d.cts +1 -1
  726. package/dist/services/definitions/pentestagent.d.mts +1 -1
  727. package/dist/services/definitions/photoprism.d.cts +1 -1
  728. package/dist/services/definitions/photoprism.d.mts +1 -1
  729. package/dist/services/definitions/pihole.d.cts +1 -1
  730. package/dist/services/definitions/pihole.d.mts +1 -1
  731. package/dist/services/definitions/piper-tts.d.cts +1 -1
  732. package/dist/services/definitions/piper-tts.d.mts +1 -1
  733. package/dist/services/definitions/plane.d.cts +1 -1
  734. package/dist/services/definitions/plane.d.mts +1 -1
  735. package/dist/services/definitions/plausible.d.cts +1 -1
  736. package/dist/services/definitions/plausible.d.mts +1 -1
  737. package/dist/services/definitions/playwright-server.d.cts +1 -1
  738. package/dist/services/definitions/playwright-server.d.mts +1 -1
  739. package/dist/services/definitions/pocket-id.d.cts +1 -1
  740. package/dist/services/definitions/pocket-id.d.mts +1 -1
  741. package/dist/services/definitions/pocketbase.d.cts +1 -1
  742. package/dist/services/definitions/pocketbase.d.mts +1 -1
  743. package/dist/services/definitions/portainer.d.cts +1 -1
  744. package/dist/services/definitions/portainer.d.mts +1 -1
  745. package/dist/services/definitions/postgresql.d.cts +1 -1
  746. package/dist/services/definitions/postgresql.d.mts +1 -1
  747. package/dist/services/definitions/posthog.d.cts +1 -1
  748. package/dist/services/definitions/posthog.d.mts +1 -1
  749. package/dist/services/definitions/postiz.d.cts +1 -1
  750. package/dist/services/definitions/postiz.d.mts +1 -1
  751. package/dist/services/definitions/prometheus.d.cts +1 -1
  752. package/dist/services/definitions/prometheus.d.mts +1 -1
  753. package/dist/services/definitions/qdrant.d.cts +1 -1
  754. package/dist/services/definitions/qdrant.d.mts +1 -1
  755. package/dist/services/definitions/rabbitmq.d.cts +1 -1
  756. package/dist/services/definitions/rabbitmq.d.mts +1 -1
  757. package/dist/services/definitions/ragflow.d.cts +1 -1
  758. package/dist/services/definitions/ragflow.d.mts +1 -1
  759. package/dist/services/definitions/redis.d.cts +1 -1
  760. package/dist/services/definitions/redis.d.mts +1 -1
  761. package/dist/services/definitions/relaticle-horizon.cjs +48 -0
  762. package/dist/services/definitions/relaticle-horizon.cjs.map +1 -0
  763. package/dist/services/definitions/relaticle-horizon.d.cts +7 -0
  764. package/dist/services/definitions/relaticle-horizon.d.cts.map +1 -0
  765. package/dist/services/definitions/relaticle-horizon.d.mts +7 -0
  766. package/dist/services/definitions/relaticle-horizon.d.mts.map +1 -0
  767. package/dist/services/definitions/relaticle-horizon.mjs +48 -0
  768. package/dist/services/definitions/relaticle-horizon.mjs.map +1 -0
  769. package/dist/services/definitions/relaticle-scheduler.cjs +44 -0
  770. package/dist/services/definitions/relaticle-scheduler.cjs.map +1 -0
  771. package/dist/services/definitions/relaticle-scheduler.d.cts +7 -0
  772. package/dist/services/definitions/relaticle-scheduler.d.cts.map +1 -0
  773. package/dist/services/definitions/relaticle-scheduler.d.mts +7 -0
  774. package/dist/services/definitions/relaticle-scheduler.d.mts.map +1 -0
  775. package/dist/services/definitions/relaticle-scheduler.mjs +44 -0
  776. package/dist/services/definitions/relaticle-scheduler.mjs.map +1 -0
  777. package/dist/services/definitions/relaticle.cjs +151 -0
  778. package/dist/services/definitions/relaticle.cjs.map +1 -0
  779. package/dist/services/definitions/relaticle.d.cts +80 -0
  780. package/dist/services/definitions/relaticle.d.cts.map +1 -0
  781. package/dist/services/definitions/relaticle.d.mts +80 -0
  782. package/dist/services/definitions/relaticle.d.mts.map +1 -0
  783. package/dist/services/definitions/relaticle.mjs +149 -0
  784. package/dist/services/definitions/relaticle.mjs.map +1 -0
  785. package/dist/services/definitions/remotion.d.cts +1 -1
  786. package/dist/services/definitions/remotion.d.mts +1 -1
  787. package/dist/services/definitions/restic.d.cts +1 -1
  788. package/dist/services/definitions/restic.d.mts +1 -1
  789. package/dist/services/definitions/revolt.d.cts +1 -1
  790. package/dist/services/definitions/revolt.d.mts +1 -1
  791. package/dist/services/definitions/rocketchat.d.cts +1 -1
  792. package/dist/services/definitions/rocketchat.d.mts +1 -1
  793. package/dist/services/definitions/saleor.d.cts +1 -1
  794. package/dist/services/definitions/saleor.d.mts +1 -1
  795. package/dist/services/definitions/scrapling.d.cts +1 -1
  796. package/dist/services/definitions/scrapling.d.mts +1 -1
  797. package/dist/services/definitions/searxng.d.cts +1 -1
  798. package/dist/services/definitions/searxng.d.mts +1 -1
  799. package/dist/services/definitions/sentry.d.cts +1 -1
  800. package/dist/services/definitions/sentry.d.mts +1 -1
  801. package/dist/services/definitions/signoz.d.cts +1 -1
  802. package/dist/services/definitions/signoz.d.mts +1 -1
  803. package/dist/services/definitions/solidityguard.d.cts +1 -1
  804. package/dist/services/definitions/solidityguard.d.mts +1 -1
  805. package/dist/services/definitions/sonarqube.d.cts +1 -1
  806. package/dist/services/definitions/sonarqube.d.mts +1 -1
  807. package/dist/services/definitions/stable-diffusion.d.cts +1 -1
  808. package/dist/services/definitions/stable-diffusion.d.mts +1 -1
  809. package/dist/services/definitions/steel-browser.d.cts +1 -1
  810. package/dist/services/definitions/steel-browser.d.mts +1 -1
  811. package/dist/services/definitions/stirling-pdf.d.cts +1 -1
  812. package/dist/services/definitions/stirling-pdf.d.mts +1 -1
  813. package/dist/services/definitions/strapi.d.cts +1 -1
  814. package/dist/services/definitions/strapi.d.mts +1 -1
  815. package/dist/services/definitions/stream-gateway.d.cts +1 -1
  816. package/dist/services/definitions/stream-gateway.d.mts +1 -1
  817. package/dist/services/definitions/supabase.d.cts +1 -1
  818. package/dist/services/definitions/supabase.d.mts +1 -1
  819. package/dist/services/definitions/superset.d.cts +1 -1
  820. package/dist/services/definitions/superset.d.mts +1 -1
  821. package/dist/services/definitions/surrealdb.d.cts +1 -1
  822. package/dist/services/definitions/surrealdb.d.mts +1 -1
  823. package/dist/services/definitions/tabby-ml.d.cts +1 -1
  824. package/dist/services/definitions/tabby-ml.d.mts +1 -1
  825. package/dist/services/definitions/tailscale.d.cts +1 -1
  826. package/dist/services/definitions/tailscale.d.mts +1 -1
  827. package/dist/services/definitions/tempo.d.cts +1 -1
  828. package/dist/services/definitions/tempo.d.mts +1 -1
  829. package/dist/services/definitions/temporal.d.cts +1 -1
  830. package/dist/services/definitions/temporal.d.mts +1 -1
  831. package/dist/services/definitions/text-gen-webui.d.cts +1 -1
  832. package/dist/services/definitions/text-gen-webui.d.mts +1 -1
  833. package/dist/services/definitions/timescaledb.d.cts +1 -1
  834. package/dist/services/definitions/timescaledb.d.mts +1 -1
  835. package/dist/services/definitions/traefik.d.cts +1 -1
  836. package/dist/services/definitions/traefik.d.mts +1 -1
  837. package/dist/services/definitions/twenty-worker.cjs +73 -0
  838. package/dist/services/definitions/twenty-worker.cjs.map +1 -0
  839. package/dist/services/definitions/twenty-worker.d.cts +7 -0
  840. package/dist/services/definitions/twenty-worker.d.cts.map +1 -0
  841. package/dist/services/definitions/twenty-worker.d.mts +7 -0
  842. package/dist/services/definitions/twenty-worker.d.mts.map +1 -0
  843. package/dist/services/definitions/twenty-worker.mjs +72 -0
  844. package/dist/services/definitions/twenty-worker.mjs.map +1 -0
  845. package/dist/services/definitions/twenty.cjs +24 -2
  846. package/dist/services/definitions/twenty.cjs.map +1 -1
  847. package/dist/services/definitions/twenty.d.cts +1 -1
  848. package/dist/services/definitions/twenty.d.mts +1 -1
  849. package/dist/services/definitions/twenty.mjs +24 -2
  850. package/dist/services/definitions/twenty.mjs.map +1 -1
  851. package/dist/services/definitions/umami.d.cts +1 -1
  852. package/dist/services/definitions/umami.d.mts +1 -1
  853. package/dist/services/definitions/uptime-kuma.d.cts +1 -1
  854. package/dist/services/definitions/uptime-kuma.d.mts +1 -1
  855. package/dist/services/definitions/usesend.d.cts +1 -1
  856. package/dist/services/definitions/usesend.d.mts +1 -1
  857. package/dist/services/definitions/valkey.d.cts +1 -1
  858. package/dist/services/definitions/valkey.d.mts +1 -1
  859. package/dist/services/definitions/vault.d.cts +1 -1
  860. package/dist/services/definitions/vault.d.mts +1 -1
  861. package/dist/services/definitions/vaultwarden.d.cts +1 -1
  862. package/dist/services/definitions/vaultwarden.d.mts +1 -1
  863. package/dist/services/definitions/vector-log.d.cts +1 -1
  864. package/dist/services/definitions/vector-log.d.mts +1 -1
  865. package/dist/services/definitions/vikunja.d.cts +1 -1
  866. package/dist/services/definitions/vikunja.d.mts +1 -1
  867. package/dist/services/definitions/watchtower.d.cts +1 -1
  868. package/dist/services/definitions/watchtower.d.mts +1 -1
  869. package/dist/services/definitions/weaviate.cjs +4 -1
  870. package/dist/services/definitions/weaviate.cjs.map +1 -1
  871. package/dist/services/definitions/weaviate.d.cts +1 -1
  872. package/dist/services/definitions/weaviate.d.mts +1 -1
  873. package/dist/services/definitions/weaviate.mjs +4 -1
  874. package/dist/services/definitions/weaviate.mjs.map +1 -1
  875. package/dist/services/definitions/whisper.d.cts +1 -1
  876. package/dist/services/definitions/whisper.d.mts +1 -1
  877. package/dist/services/definitions/wireguard.d.cts +1 -1
  878. package/dist/services/definitions/wireguard.d.mts +1 -1
  879. package/dist/services/definitions/woodpecker-ci.d.cts +1 -1
  880. package/dist/services/definitions/woodpecker-ci.d.mts +1 -1
  881. package/dist/services/definitions/xyops.d.cts +1 -1
  882. package/dist/services/definitions/xyops.d.mts +1 -1
  883. package/dist/services/definitions/zeroclaw.cjs +103 -0
  884. package/dist/services/definitions/zeroclaw.cjs.map +1 -0
  885. package/dist/services/definitions/zeroclaw.d.cts +7 -0
  886. package/dist/services/definitions/zeroclaw.d.cts.map +1 -0
  887. package/dist/services/definitions/zeroclaw.d.mts +7 -0
  888. package/dist/services/definitions/zeroclaw.d.mts.map +1 -0
  889. package/dist/services/definitions/zeroclaw.mjs +102 -0
  890. package/dist/services/definitions/zeroclaw.mjs.map +1 -0
  891. package/dist/services/definitions/zulip.d.cts +1 -1
  892. package/dist/services/definitions/zulip.d.mts +1 -1
  893. package/dist/services/registry.d.cts +1 -1
  894. package/dist/services/registry.d.mts +1 -1
  895. package/dist/services/registry.test.cjs +8 -8
  896. package/dist/services/registry.test.cjs.map +1 -1
  897. package/dist/services/registry.test.mjs +8 -8
  898. package/dist/services/registry.test.mjs.map +1 -1
  899. package/dist/skills/registry.cjs +19 -0
  900. package/dist/skills/registry.cjs.map +1 -1
  901. package/dist/skills/registry.d.cts +1 -1
  902. package/dist/skills/registry.d.cts.map +1 -1
  903. package/dist/skills/registry.d.mts +1 -1
  904. package/dist/skills/registry.d.mts.map +1 -1
  905. package/dist/skills/registry.mjs +19 -0
  906. package/dist/skills/registry.mjs.map +1 -1
  907. package/dist/{skills-BSF7iNa4.cjs → skills-uPxJVmKk.cjs} +311 -1
  908. package/dist/skills-uPxJVmKk.cjs.map +1 -0
  909. package/dist/{test.CTcmp4Su-ClCHJ3FA.mjs → test.CTcmp4Su-BRa7-bTj.mjs} +2 -2
  910. package/dist/{test.CTcmp4Su-ClCHJ3FA.mjs.map → test.CTcmp4Su-BRa7-bTj.mjs.map} +1 -1
  911. package/dist/{test.CTcmp4Su-DlzTarwH.cjs → test.CTcmp4Su-BWSPM8ZQ.cjs} +19 -1
  912. package/dist/{test.CTcmp4Su-DlzTarwH.cjs.map → test.CTcmp4Su-BWSPM8ZQ.cjs.map} +1 -1
  913. package/dist/track-analytics.d.cts +1 -1
  914. package/dist/track-analytics.d.mts +1 -1
  915. package/dist/track-analytics.test.cjs +1 -1
  916. package/dist/track-analytics.test.mjs +1 -1
  917. package/dist/types-BREUfzzq.d.mts +77 -0
  918. package/dist/types-BREUfzzq.d.mts.map +1 -0
  919. package/dist/types-Bsn0XzSP.d.cts +95 -0
  920. package/dist/types-Bsn0XzSP.d.cts.map +1 -0
  921. package/dist/types-CyZ5mn6w.d.cts +77 -0
  922. package/dist/types-CyZ5mn6w.d.cts.map +1 -0
  923. package/dist/types-DIsPc-hb.d.cts +100 -0
  924. package/dist/types-DIsPc-hb.d.cts.map +1 -0
  925. package/dist/types-DbXajvYq.d.mts +100 -0
  926. package/dist/types-DbXajvYq.d.mts.map +1 -0
  927. package/dist/types-DwTKyCZ9.d.mts +95 -0
  928. package/dist/types-DwTKyCZ9.d.mts.map +1 -0
  929. package/dist/{types-CR83OJiq.d.cts → types-dyBnrHm9.d.cts} +5 -1
  930. package/dist/types-dyBnrHm9.d.cts.map +1 -0
  931. package/dist/{types-zYjGTuyn.d.mts → types-fRSnaZTX.d.mts} +5 -1
  932. package/dist/types-fRSnaZTX.d.mts.map +1 -0
  933. package/dist/types.cjs +7 -0
  934. package/dist/types.cjs.map +1 -1
  935. package/dist/types.d.cts +2 -93
  936. package/dist/types.d.mts +2 -93
  937. package/dist/types.mjs +7 -0
  938. package/dist/types.mjs.map +1 -1
  939. package/dist/validator.cjs +1 -1
  940. package/dist/validator.d.cts +1 -1
  941. package/dist/validator.d.mts +1 -1
  942. package/dist/validator.test.cjs +1 -1
  943. package/dist/validator.test.mjs +1 -1
  944. package/dist/version-manager.d.cts +1 -1
  945. package/dist/version-manager.d.mts +1 -1
  946. package/dist/version-manager.test.cjs +3 -3
  947. package/dist/version-manager.test.cjs.map +1 -1
  948. package/dist/version-manager.test.mjs +3 -3
  949. package/dist/version-manager.test.mjs.map +1 -1
  950. package/dist/zeroclaw-B-0TuOfZ.d.mts +7 -0
  951. package/dist/zeroclaw-B-0TuOfZ.d.mts.map +1 -0
  952. package/dist/zeroclaw-BvKpDHKe.d.cts +7 -0
  953. package/dist/zeroclaw-BvKpDHKe.d.cts.map +1 -0
  954. package/package.json +6 -2
  955. package/src/addon-stack.test.ts +19 -23
  956. package/src/addon-stack.ts +67 -44
  957. package/src/composer.test.ts +59 -0
  958. package/src/composer.ts +135 -194
  959. package/src/deployers/coolify.ts +38 -0
  960. package/src/deployers/dokploy.ts +38 -0
  961. package/src/deployers/types.ts +2 -0
  962. package/src/frameworks/claude-code-fw.ts +118 -0
  963. package/src/frameworks/codex-fw.ts +102 -0
  964. package/src/frameworks/copaw.ts +154 -0
  965. package/src/frameworks/index.ts +46 -0
  966. package/src/frameworks/memu.ts +149 -0
  967. package/src/frameworks/nanobot.ts +156 -0
  968. package/src/frameworks/nanoclaw.ts +126 -0
  969. package/src/frameworks/openclaw.ts +325 -0
  970. package/src/frameworks/registry.test.ts +131 -0
  971. package/src/frameworks/registry.ts +28 -0
  972. package/src/frameworks/types.ts +146 -0
  973. package/src/frameworks/zeroclaw.ts +148 -0
  974. package/src/generate.test.ts +55 -4
  975. package/src/generate.ts +67 -14
  976. package/src/generators/caddy.test.ts +41 -1
  977. package/src/generators/caddy.ts +16 -2
  978. package/src/generators/clone-repos.test.ts +1 -1
  979. package/src/generators/clone-repos.ts +7 -2
  980. package/src/generators/env.test.ts +2 -2
  981. package/src/generators/env.ts +30 -180
  982. package/src/generators/health-check.ts +4 -4
  983. package/src/generators/openclaw-json.ts +57 -5
  984. package/src/generators/postgres-init.ts +9 -0
  985. package/src/generators/readme.ts +75 -9
  986. package/src/generators/scripts.test.ts +1 -1
  987. package/src/generators/skills.ts +316 -0
  988. package/src/generators/traefik.test.ts +13 -13
  989. package/src/index.ts +46 -7
  990. package/src/logger/__tests__/logger.test.ts +388 -0
  991. package/src/logger/index.ts +14 -0
  992. package/src/logger/logger.ts +326 -0
  993. package/src/logger/sinks/callback-sink.ts +13 -0
  994. package/src/logger/sinks/console-sink.ts +51 -0
  995. package/src/logger/sinks/file-sink.ts +121 -0
  996. package/src/logger/types.ts +90 -0
  997. package/src/migrations.ts +8 -1
  998. package/src/presets/presets.test.ts +4 -4
  999. package/src/presets/registry.test.ts +6 -6
  1000. package/src/resolver.test.ts +31 -3
  1001. package/src/resolver.ts +19 -3
  1002. package/src/schema.test.ts +2 -2
  1003. package/src/schema.ts +58 -17
  1004. package/src/services/definitions/agent-browser.ts +177 -0
  1005. package/src/services/definitions/apptension-saas.ts +2 -1
  1006. package/src/services/definitions/chromadb.ts +1 -1
  1007. package/src/services/definitions/claude-code.ts +1 -1
  1008. package/src/services/definitions/clawrouter.ts +141 -0
  1009. package/src/services/definitions/codex.ts +1 -1
  1010. package/src/services/definitions/convex.ts +1 -2
  1011. package/src/services/definitions/copaw.ts +101 -0
  1012. package/src/services/definitions/desktop-environment.ts +1 -0
  1013. package/src/services/definitions/hindsight.ts +3 -2
  1014. package/src/services/definitions/index.ts +53 -16
  1015. package/src/services/definitions/mem0.ts +132 -0
  1016. package/src/services/definitions/memu.ts +96 -0
  1017. package/src/services/definitions/milvus.ts +1 -1
  1018. package/src/services/definitions/nanobot.ts +89 -0
  1019. package/src/services/definitions/nanoclaw.ts +78 -0
  1020. package/src/services/definitions/opensandbox.ts +6 -15
  1021. package/src/services/definitions/relaticle-horizon.ts +48 -0
  1022. package/src/services/definitions/relaticle-scheduler.ts +42 -0
  1023. package/src/services/definitions/relaticle.ts +142 -0
  1024. package/src/services/definitions/twenty-worker.ts +70 -0
  1025. package/src/services/definitions/twenty.ts +16 -2
  1026. package/src/services/definitions/weaviate.ts +1 -1
  1027. package/src/services/definitions/zeroclaw.ts +102 -0
  1028. package/src/services/registry.test.ts +7 -7
  1029. package/src/skills/registry.ts +10 -0
  1030. package/src/types.ts +11 -1
  1031. package/src/version-manager.test.ts +2 -2
  1032. package/dist/schema-BQnZrcw8.d.cts.map +0 -1
  1033. package/dist/schema-SBpL0bdI.d.mts.map +0 -1
  1034. package/dist/skills-BSF7iNa4.cjs.map +0 -1
  1035. package/dist/types-CR83OJiq.d.cts.map +0 -1
  1036. package/dist/types-zYjGTuyn.d.mts.map +0 -1
  1037. package/dist/types.d.cts.map +0 -1
  1038. package/dist/types.d.mts.map +0 -1
package/README.md CHANGED
@@ -1,13 +1,14 @@
1
1
  # @better-openclaw/core
2
2
 
3
- The core engine responsible for parsing configurations, resolving dependencies, formatting outputs, and generating production-ready OpenClaw Docker Compose stacks.
3
+ The core engine responsible for parsing configurations, resolving dependencies, formatting outputs, and generating production-ready AI agent Docker Compose stacks with support for 8 agent frameworks.
4
4
 
5
5
  ## Features
6
6
 
7
- - **Service Registry:** A unified, expandable catalog of pre-configured Docker services (e.g., Traefik, PostgreSQL, Qdrant, Ollama, N8N, SearXNG, Scrapling, etc.) categorized by function (databases, models, scrapers, tools).
8
- - **Dependency Resolution Engine:** Automatically detects and resolves required services. If you select a Postgres-dependent service, Postgres is automatically injected into the generation plan.
7
+ - **Multi-Agent Framework Registry:** Choose from 8 pluggable agent frameworks (OpenClaw, CoPaw, NanoClaw, NanoBot, ZeroClaw, MemU, Claude Code, Codex) as primary orchestrator, with optional companion frameworks for hybrid stacks. Framework definitions live in `src/frameworks/` and use a registry pattern.
8
+ - **Service Registry:** A unified, expandable catalog of 94+ pre-configured Docker services (e.g., Traefik, PostgreSQL, Qdrant, Ollama, N8N, SearXNG, Scrapling, etc.) categorized by function (databases, models, scrapers, tools).
9
+ - **Dependency Resolution Engine:** Automatically detects and resolves required services. Framework-specific mandatory services are injected automatically (e.g., MemU requires PostgreSQL, non-OpenClaw frameworks skip Convex/Mission-Control/Tailscale).
9
10
  - **Skill Injection (`SKILL.md`):** Deep integration with AI agent workflows. Packages specialized `SKILL.md` instructions into volume mounts for AI tools like the `browser` integration or `tinyfish`.
10
- - **Intelligent Networking & Proxies:** Fully integrated reverse proxy generation (Caddy and Traefik) and auto-SSL domain generation.
11
+ - **Intelligent Networking & Proxies:** Fully integrated reverse proxy generation (Caddy and Traefik) with auto-SSL domain generation and WebSocket streaming support (`flush_interval -1`) for noVNC/KasmVNC desktop sandbox services.
11
12
  - **Cross-Platform & Heterogeneous Topologies:** Supports generating stacks for `local` (Docker Desktop), `vps` (cloud), and `homelab` deployments. It explicitly supports a hybrid native-docker model via `deploymentType: "bare-metal"`.
12
13
  - **GPU Passthrough Support:** Automatically injects NVIDIA or AMD runtime flags to AI services if the `gpuRequired` flag is detected on the requested service and enabled by the user.
13
14
 
@@ -19,9 +20,9 @@ You can use the generation engine programmatically within any Node.js or TypeScr
19
20
  import { generate, type GenerationInput } from "@better-openclaw/core";
20
21
 
21
22
  const input: GenerationInput = {
22
- projectName: "my-openclaw-stack",
23
- services: ["postgres-database", "ollama-local-llm", "n8n-workflow"],
24
- skillPacks: ["ollama-local-llm", "n8n-workflows"],
23
+ projectName: "my-agent-stack",
24
+ services: ["postgresql", "ollama", "n8n"],
25
+ skillPacks: ["local-ai"],
25
26
  proxy: "caddy",
26
27
  domain: "my-ai.example.com",
27
28
  gpu: true,
@@ -31,6 +32,8 @@ const input: GenerationInput = {
31
32
  generateSecrets: true,
32
33
  openclawVersion: "latest",
33
34
  monitoring: true,
35
+ primaryFramework: "zeroclaw", // Choose from 8 agent frameworks
36
+ companionFrameworks: ["copaw"], // Optional companion frameworks
34
37
  };
35
38
 
36
39
  // Generates the Compose YAML, configs, skills, and .env securely.
@@ -88,6 +91,62 @@ const result = await deployer.deploy({
88
91
  });
89
92
  ```
90
93
 
94
+ ## Operations Logger
95
+
96
+ The core ships a centralized `OperationsLogger` used by all packages (CLI, API, MCP) to produce structured, NDJSON log files tracking every significant operation — generation pipelines, deployments, file writes, API requests, and MCP tool calls.
97
+
98
+ ### Programmatic Usage
99
+
100
+ ```typescript
101
+ import { OperationsLogger, FileSink, ConsoleSink, CallbackSink } from "@better-openclaw/core";
102
+
103
+ const logger = new OperationsLogger({
104
+ source: "cli", // "cli" | "api" | "mcp" | "web" | "core"
105
+ sinks: [
106
+ new ConsoleSink(), // Human-readable terminal output
107
+ new FileSink(), // NDJSON file (~/.better-openclaw/logs/operations.log)
108
+ ],
109
+ minLevel: "info", // "debug" | "info" | "warn" | "error"
110
+ });
111
+
112
+ // Basic logging
113
+ logger.info("generation", "Starting stack generation", { projectName: "my-stack" });
114
+ logger.warn("validation", "Port conflict detected", { port: 8080 });
115
+ logger.error("deployment", "Deploy failed", new Error("timeout"), { provider: "dokploy" });
116
+
117
+ // Timed operations (auto-logs duration + outcome)
118
+ const result = await logger.timed("deployment", "Deploying to Dokploy", async () => {
119
+ return await deployer.deploy(input);
120
+ });
121
+
122
+ // Child loggers (inherit correlationId)
123
+ const childLogger = logger.child({ source: "core" });
124
+
125
+ // Pass to generate()
126
+ const output = generate(input, { logger });
127
+ ```
128
+
129
+ ### Log File Location
130
+
131
+ | Default | `~/.better-openclaw/logs/operations.log` |
132
+ |---------|------------------------------------------|
133
+ | Override | `OPENCLAW_LOG_DIR` env var |
134
+ | Format | NDJSON (one JSON object per line, `jq`-friendly) |
135
+ | Rotation | 10 MB per file, 5 rotated files (~60 MB total) |
136
+
137
+ ### Environment Variables
138
+
139
+ | Variable | Default | Description |
140
+ |----------|---------|-------------|
141
+ | `OPENCLAW_LOG_DIR` | `~/.better-openclaw/logs/` | Log directory path |
142
+ | `OPENCLAW_LOG_LEVEL` | `info` | Minimum log level |
143
+ | `OPENCLAW_LOG_MAX_SIZE` | `10485760` (10 MB) | Max file size before rotation |
144
+ | `OPENCLAW_LOG_MAX_FILES` | `5` | Number of rotated files to keep |
145
+
146
+ ### Sensitive Data
147
+
148
+ The logger automatically redacts known sensitive keys (`apiKey`, `password`, `token`, `secret`, `authorization`, `credentials`, `private_key`) from context before writing to any sink.
149
+
91
150
  ## Development
92
151
 
93
152
  ```bash
@@ -1,5 +1,7 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_skills = require("./skills-BSF7iNa4.cjs");
2
+ const require_skills = require("./skills-uPxJVmKk.cjs");
3
+ const require_frameworks_registry = require("./frameworks/registry.cjs");
4
+ require("./frameworks/index.cjs");
3
5
  const require_generators_postgres_init = require("./generators/postgres-init.cjs");
4
6
  const require_composer = require("./composer.cjs");
5
7
  const require_services_registry = require("./services/registry.cjs");
@@ -8,31 +10,28 @@ const require_schema = require("./schema.cjs");
8
10
  let yaml = require("yaml");
9
11
  let node_crypto = require("node:crypto");
10
12
  //#region src/addon-stack.ts
11
- /** Services that Clawexa's cloud-init already provisions (or are mandatory platform services). */
12
- const INFRA_SERVICE_IDS = new Set([
13
- "openclaw-gateway",
14
- "openclaw-cli",
13
+ /** Base infrastructure service IDs that Clawexa's cloud-init provisions. */
14
+ const BASE_INFRA_SERVICE_IDS = [
15
15
  "redis",
16
16
  "postgresql",
17
17
  "open-webui",
18
18
  "caddy",
19
19
  "traefik",
20
- "postgres-setup",
21
- "convex",
22
- "convex-dashboard",
23
- "mission-control"
24
- ]);
20
+ "postgres-setup"
21
+ ];
22
+ /** Build the full set of infra IDs for a given framework. */
23
+ function getInfraServiceIds(framework) {
24
+ return new Set([
25
+ `${framework.id}-gateway`,
26
+ `${framework.id}-cli`,
27
+ ...BASE_INFRA_SERVICE_IDS,
28
+ ...framework.getMandatoryServices()
29
+ ]);
30
+ }
25
31
  /** Env keys managed by Clawexa's cloud-init — never include in addon env output. */
26
32
  const CLAWEXA_MANAGED_ENV_KEYS = new Set([
27
33
  "COMPOSE_FILE",
28
34
  "COMPOSE_PROFILES",
29
- "OPENCLAW_VERSION",
30
- "OPENCLAW_GATEWAY_TOKEN",
31
- "OPENCLAW_GATEWAY_PORT",
32
- "OPENCLAW_BRIDGE_PORT",
33
- "OPENCLAW_GATEWAY_BIND",
34
- "OPENCLAW_CONFIG_DIR",
35
- "OPENCLAW_WORKSPACE_DIR",
36
35
  "REDIS_PASSWORD",
37
36
  "REDIS_HOST",
38
37
  "REDIS_PORT",
@@ -42,6 +41,16 @@ const CLAWEXA_MANAGED_ENV_KEYS = new Set([
42
41
  "POSTGRES_HOST",
43
42
  "POSTGRES_PORT"
44
43
  ]);
44
+ /** Build the full set of managed env keys for a given framework. */
45
+ function getManagedEnvKeys(framework) {
46
+ const keys = new Set(CLAWEXA_MANAGED_ENV_KEYS);
47
+ for (const envLine of framework.getBaseEnvVars({
48
+ generateSecrets: false,
49
+ frameworkVersion: "latest",
50
+ frameworkImageVariant: "official"
51
+ })) keys.add(envLine.key);
52
+ return keys;
53
+ }
45
54
  /** Sanitize instanceId into a valid Docker Compose project name. */
46
55
  function sanitizeProjectName(instanceId) {
47
56
  return instanceId.toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/^-+|-+$/g, "").replace(/-{2,}/g, "-").slice(0, 64) || "addon";
@@ -156,7 +165,7 @@ function resolvePortConflicts(addonServices, reservedPorts, portOverrides) {
156
165
  if (userOverride) {
157
166
  usedPorts.add(userOverride);
158
167
  assignments[`${def.id}:${port.container}`] = userOverride;
159
- if (!overrides[def.id]) overrides[def.id] = {};
168
+ overrides[def.id] ??= {};
160
169
  overrides[def.id][String(port.host)] = userOverride;
161
170
  continue;
162
171
  }
@@ -164,7 +173,7 @@ function resolvePortConflicts(addonServices, reservedPorts, portOverrides) {
164
173
  if (usedPorts.has(assignedPort)) {
165
174
  assignedPort = port.host + 1e3;
166
175
  while (usedPorts.has(assignedPort)) assignedPort++;
167
- if (!overrides[def.id]) overrides[def.id] = {};
176
+ overrides[def.id] ??= {};
168
177
  overrides[def.id][String(port.host)] = assignedPort;
169
178
  }
170
179
  usedPorts.add(assignedPort);
@@ -195,8 +204,11 @@ function generateAddonStack(rawInput) {
195
204
  return emptyResult(`Invalid input: ${err instanceof Error ? err.message : String(err)}`);
196
205
  }
197
206
  const projectName = sanitizeProjectName(input.instanceId);
207
+ const framework = require_frameworks_registry.getFrameworkById("openclaw");
208
+ const infraIds = getInfraServiceIds(framework);
209
+ const managedKeys = getManagedEnvKeys(framework);
198
210
  const addonServiceIds = input.services.filter((id) => {
199
- if (INFRA_SERVICE_IDS.has(id)) {
211
+ if (infraIds.has(id)) {
200
212
  warnings.push(`Service "${id}" is managed by Clawexa infrastructure and was excluded.`);
201
213
  return false;
202
214
  }
@@ -239,7 +251,7 @@ function generateAddonStack(rawInput) {
239
251
  for (const w of resolved.warnings) warnings.push(w.message);
240
252
  const addonResolved = [];
241
253
  for (const svc of resolved.services) {
242
- if (INFRA_SERVICE_IDS.has(svc.definition.id)) continue;
254
+ if (infraIds.has(svc.definition.id)) continue;
243
255
  addonResolved.push(svc);
244
256
  }
245
257
  const deployableServices = [];
@@ -329,7 +341,7 @@ function generateAddonStack(rawInput) {
329
341
  delete entry.profiles;
330
342
  if (entry.depends_on) {
331
343
  const deps = entry.depends_on;
332
- for (const depId of Object.keys(deps)) if (INFRA_SERVICE_IDS.has(depId)) delete deps[depId];
344
+ for (const depId of Object.keys(deps)) if (infraIds.has(depId)) delete deps[depId];
333
345
  if (Object.keys(deps).length === 0) delete entry.depends_on;
334
346
  }
335
347
  services[def.id] = entry;
@@ -370,7 +382,7 @@ function generateAddonStack(rawInput) {
370
382
  entrypoint: ["/bin/sh", "-c"],
371
383
  command: [scriptLines.join("\n")],
372
384
  restart: require_composer.quotedStr("no"),
373
- networks: ["openclaw-network"]
385
+ networks: [framework.networkName]
374
386
  };
375
387
  for (const req of dbReqs) {
376
388
  const svcEntry = services[req.serviceId];
@@ -400,7 +412,7 @@ function generateAddonStack(rawInput) {
400
412
  envLines.push("");
401
413
  }
402
414
  }
403
- const seenKeys = new Set([...CLAWEXA_MANAGED_ENV_KEYS, ...dbReqs.map((r) => r.passwordEnvVar)]);
415
+ const seenKeys = new Set([...managedKeys, ...dbReqs.map((r) => r.passwordEnvVar)]);
404
416
  const envVarGroups = [];
405
417
  for (const svc of deployableServices) {
406
418
  const def = svc.definition;
@@ -456,7 +468,7 @@ function generateAddonStack(rawInput) {
456
468
  else finalEnvLines.push(line);
457
469
  } else finalEnvLines.push(line);
458
470
  }
459
- for (const [key, value] of envValues) if (!quirkedKeys.has(key) && !seenKeys.has(key) && !CLAWEXA_MANAGED_ENV_KEYS.has(key)) {
471
+ for (const [key, value] of envValues) if (!quirkedKeys.has(key) && !seenKeys.has(key) && !managedKeys.has(key)) {
460
472
  finalEnvLines.push(`# Synced by env quirk`);
461
473
  finalEnvLines.push(`${key}=${value}`);
462
474
  finalEnvLines.push("");
@@ -522,7 +534,7 @@ function generateAddonStack(rawInput) {
522
534
  for (const v of allVolumes) volumeMap[v] = null;
523
535
  const composeDoc = { services };
524
536
  if (Object.keys(volumeMap).length > 0) composeDoc.volumes = volumeMap;
525
- composeDoc.networks = { "openclaw-network": { external: true } };
537
+ composeDoc.networks = { [framework.networkName]: { external: true } };
526
538
  return {
527
539
  composeOverride: (0, yaml.stringify)(composeDoc, require_composer.YAML_OPTIONS),
528
540
  envFile,
@@ -572,7 +584,6 @@ function updateAddonStack(rawInput) {
572
584
  const eqIdx = trimmed.indexOf("=");
573
585
  if (eqIdx > 0) existingEnvMap.set(trimmed.slice(0, eqIdx), trimmed.slice(eqIdx + 1));
574
586
  }
575
- new Set(input.addServices);
576
587
  const removeSet = new Set(input.removeServices);
577
588
  const desiredServiceIds = [...currentServiceIds.filter((id) => !removeSet.has(id)), ...input.addServices.filter((id) => !currentServiceIds.includes(id))];
578
589
  const targetResult = generateAddonStack({
@@ -581,10 +592,12 @@ function updateAddonStack(rawInput) {
581
592
  skillPacks: [],
582
593
  platform: input.platform,
583
594
  openclawVersion: input.openclawVersion,
595
+ existingServices: input.existingServices,
584
596
  reservedPorts: input.reservedPorts,
585
597
  generateSecrets: input.generateSecrets,
586
598
  credentials: input.credentials,
587
599
  portOverrides: input.portOverrides,
600
+ gpu: input.gpu,
588
601
  aiProviders: input.aiProviders,
589
602
  prebuiltImages: input.prebuiltImages
590
603
  });
@@ -614,7 +627,7 @@ function updateAddonStack(rawInput) {
614
627
  if (!def) continue;
615
628
  for (const skill of def.skills) {
616
629
  const skillPath = Object.keys(targetResult.skillFiles).find((path) => path.includes(skill.skillId));
617
- if (skillPath) newSkillFiles[skillPath] = targetResult.skillFiles[skillPath];
630
+ if (skillPath && targetResult.skillFiles[skillPath]) newSkillFiles[skillPath] = targetResult.skillFiles[skillPath];
618
631
  }
619
632
  }
620
633
  for (const id of removed) {
@@ -1 +1 @@
1
- {"version":3,"file":"addon-stack.cjs","names":["AddonStackInputSchema","getServiceById","resolve","buildCompanionService","getDbRequirements","quotedStr","generateSkillFiles","YAML_OPTIONS","AddonStackUpdateInputSchema"],"sources":["../src/addon-stack.ts"],"sourcesContent":["import { randomBytes } from \"node:crypto\";\nimport { stringify } from \"yaml\";\nimport { parse as parseYaml } from \"yaml\";\nimport { buildCompanionService, buildPostgresSetup, quotedStr, YAML_OPTIONS } from \"./composer.js\";\nimport { getDbRequirements } from \"./generators/postgres-init.js\";\nimport { generateSkillFiles } from \"./generators/skills.js\";\nimport { resolve } from \"./resolver.js\";\nimport { AddonStackInputSchema, AddonStackUpdateInputSchema } from \"./schema.js\";\nimport { getServiceById } from \"./services/registry.js\";\nimport type {\n\tAddonStackInput,\n\tAddonStackResult,\n\tAddonStackUpdateInput,\n\tAddonStackUpdateResult,\n\tComposeOptions,\n\tProxyRoute,\n\tResolvedService,\n\tResolverOutput,\n\tServiceDefinition,\n\tSkippedService,\n} from \"./types.js\";\n\n// ── Constants ────────────────────────────────────────────────────────────────\n\n/** Services that Clawexa's cloud-init already provisions (or are mandatory platform services). */\nconst INFRA_SERVICE_IDS = new Set([\n\t\"openclaw-gateway\",\n\t\"openclaw-cli\",\n\t\"redis\",\n\t\"postgresql\",\n\t\"open-webui\",\n\t\"caddy\",\n\t\"traefik\",\n\t\"postgres-setup\",\n\t// Mandatory platform services provisioned by Clawexa cloud-init\n\t\"convex\",\n\t\"convex-dashboard\",\n\t\"mission-control\",\n]);\n\n/** Env keys managed by Clawexa's cloud-init — never include in addon env output. */\nconst CLAWEXA_MANAGED_ENV_KEYS = new Set([\n\t\"COMPOSE_FILE\",\n\t\"COMPOSE_PROFILES\",\n\t\"OPENCLAW_VERSION\",\n\t\"OPENCLAW_GATEWAY_TOKEN\",\n\t\"OPENCLAW_GATEWAY_PORT\",\n\t\"OPENCLAW_BRIDGE_PORT\",\n\t\"OPENCLAW_GATEWAY_BIND\",\n\t\"OPENCLAW_CONFIG_DIR\",\n\t\"OPENCLAW_WORKSPACE_DIR\",\n\t\"REDIS_PASSWORD\",\n\t\"REDIS_HOST\",\n\t\"REDIS_PORT\",\n\t\"POSTGRES_USER\",\n\t\"POSTGRES_PASSWORD\",\n\t\"POSTGRES_DB\",\n\t\"POSTGRES_HOST\",\n\t\"POSTGRES_PORT\",\n]);\n\n// ── Helpers ──────────────────────────────────────────────────────────────────\n\n/** Sanitize instanceId into a valid Docker Compose project name. */\nfunction sanitizeProjectName(instanceId: string): string {\n\treturn instanceId\n\t\t.toLowerCase()\n\t\t.replace(/[^a-z0-9-]/g, \"-\")\n\t\t.replace(/^-+|-+$/g, \"\")\n\t\t.replace(/-{2,}/g, \"-\")\n\t\t.slice(0, 64) || \"addon\";\n}\n\n/** Generate a cryptographically secure hex secret of the given byte length. */\nfunction generateHexSecret(bytes: number): string {\n\treturn randomBytes(bytes).toString(\"hex\");\n}\n\n/** Generate a cryptographically secure base64url secret of the given byte length. */\nfunction generateBase64UrlSecret(bytes: number): string {\n\treturn randomBytes(bytes).toString(\"base64url\");\n}\n\n/**\n * Check if a service requires user-provided credentials that are missing.\n * Returns the list of missing credential keys, or empty if all are satisfied.\n *\n * When `generateSecrets` is true, empty-default secrets are auto-generated\n * (passwords, tokens, etc.) and are NOT considered missing. Only secrets\n * with `validation` regex patterns (indicating specific format like API keys)\n * are flagged as missing when not provided by the user.\n */\nfunction getMissingCredentials(\n\tdef: ServiceDefinition,\n\tuserCredentials: Record<string, string> | undefined,\n\tgenerateSecrets: boolean,\n): string[] {\n\tconst missing: string[] = [];\n\tfor (const env of def.environment) {\n\t\t// Skip if not required or not a secret\n\t\tif (!env.required || !env.secret) continue;\n\t\t// Skip if it has a non-empty default value or is a reference\n\t\tif (env.defaultValue && env.defaultValue.length > 0) continue;\n\t\t// Skip if user provided the credential\n\t\tif (userCredentials?.[env.key]) continue;\n\t\t// When generateSecrets is true, empty secrets are auto-generated\n\t\t// Only flag as missing if the env var has a validation pattern\n\t\t// (indicating it needs a specific format like an API key)\n\t\tif (generateSecrets && !env.validation) continue;\n\n\t\tmissing.push(env.key);\n\t}\n\treturn missing;\n}\n\n/**\n * Apply env quirks (from service definition) to the generated env values.\n * Handles: empty_string_crashes → set fixed value, min_length → generate longer secret,\n * must_sync → ensure two keys have the same value.\n */\nfunction applyEnvQuirks(\n\tdef: ServiceDefinition,\n\tenvValues: Map<string, string>,\n\tgenerateSecrets: boolean,\n): void {\n\tif (!def.envQuirks) return;\n\n\tfor (const quirk of def.envQuirks) {\n\t\tswitch (quirk.issue) {\n\t\t\tcase \"empty_string_crashes\": {\n\t\t\t\tif (quirk.fix.type === \"set_value\" && quirk.fix.value !== undefined) {\n\t\t\t\t\tenvValues.set(quirk.key, quirk.fix.value);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"min_length\": {\n\t\t\t\tif (!generateSecrets) break;\n\t\t\t\tconst current = envValues.get(quirk.key) || \"\";\n\t\t\t\tconst minBytes = quirk.fix.minBytes || 24;\n\t\t\t\tconst minHexLen = minBytes * 2;\n\t\t\t\tif (current.length < minHexLen) {\n\t\t\t\t\tif (quirk.fix.type === \"generate_hex\") {\n\t\t\t\t\t\tenvValues.set(quirk.key, generateHexSecret(minBytes));\n\t\t\t\t\t} else if (quirk.fix.type === \"generate_base64url\") {\n\t\t\t\t\t\tenvValues.set(quirk.key, generateBase64UrlSecret(minBytes));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"must_sync\": {\n\t\t\t\tif (quirk.fix.type === \"sync_with\" && quirk.fix.syncKey) {\n\t\t\t\t\tconst sourceValue = envValues.get(quirk.key) || envValues.get(quirk.fix.syncKey);\n\t\t\t\t\tif (sourceValue) {\n\t\t\t\t\t\tenvValues.set(quirk.key, sourceValue);\n\t\t\t\t\t\tenvValues.set(quirk.fix.syncKey, sourceValue);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Build proxy routes from resolved addon services.\n */\nfunction buildProxyRoutes(services: ResolvedService[]): ProxyRoute[] {\n\tconst routes: ProxyRoute[] = [];\n\tfor (const { definition: def } of services) {\n\t\tconst exposedPort = def.ports.find((p) => p.exposed);\n\t\tif (!exposedPort) continue;\n\n\t\troutes.push({\n\t\t\tserviceId: def.id,\n\t\t\tpath: def.proxyPath || `/${def.id}`,\n\t\t\tport: exposedPort.container,\n\t\t\tprotocol: \"http\",\n\t\t\tstripPrefix: true,\n\t\t});\n\t}\n\treturn routes;\n}\n\n/**\n * Build a minimal ComposeOptions suitable for addon stack generation.\n * No proxy, no gateway, no hardening by default.\n */\nfunction buildAddonComposeOptions(projectName: string, input: AddonStackInput): ComposeOptions {\n\treturn {\n\t\tprojectName,\n\t\tproxy: \"none\",\n\t\tgpu: false,\n\t\tplatform: input.platform ?? \"linux/amd64\",\n\t\tdeployment: \"clawexa\",\n\t\topenclawVersion: input.openclawVersion ?? \"latest\",\n\t\topenclawImage: \"official\",\n\t\thardened: false, // Clawexa default: no cap_drop/security_opt\n\t\topenclawInstallMethod: \"docker\",\n\t};\n}\n\n/**\n * Resolve port conflicts between addon services and reserved ports.\n * Returns a map of serviceId → { originalPort → assignedPort }.\n */\nfunction resolvePortConflicts(\n\taddonServices: ResolvedService[],\n\treservedPorts: number[],\n\tportOverrides?: Record<string, Record<string, number>>,\n): { assignments: Record<string, number>; overrides: Record<string, Record<string, number>> } {\n\tconst usedPorts = new Set(reservedPorts);\n\tconst assignments: Record<string, number> = {};\n\tconst overrides: Record<string, Record<string, number>> = {};\n\n\tfor (const { definition: def } of addonServices) {\n\t\tfor (const port of def.ports) {\n\t\t\tif (!port.exposed) continue;\n\n\t\t\t// Check for user-specified override\n\t\t\tconst userOverride = portOverrides?.[def.id]?.[String(port.host)];\n\t\t\tif (userOverride) {\n\t\t\t\tusedPorts.add(userOverride);\n\t\t\t\tassignments[`${def.id}:${port.container}`] = userOverride;\n\t\t\t\tif (!overrides[def.id]) overrides[def.id] = {};\n\t\t\t\toverrides[def.id][String(port.host)] = userOverride;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tlet assignedPort = port.host;\n\t\t\tif (usedPorts.has(assignedPort)) {\n\t\t\t\t// Auto-reassign to port+1000 range\n\t\t\t\tassignedPort = port.host + 1000;\n\t\t\t\twhile (usedPorts.has(assignedPort)) {\n\t\t\t\t\tassignedPort++;\n\t\t\t\t}\n\t\t\t\tif (!overrides[def.id]) overrides[def.id] = {};\n\t\t\t\toverrides[def.id][String(port.host)] = assignedPort;\n\t\t\t}\n\t\t\tusedPorts.add(assignedPort);\n\t\t\tassignments[`${def.id}:${port.container}`] = assignedPort;\n\t\t}\n\t}\n\n\treturn { assignments, overrides };\n}\n\n// ── Main: generateAddonStack ─────────────────────────────────────────────────\n\n/**\n * Generates a Docker Compose override stack containing only addon services\n * for Clawexa managed instances. Infrastructure services (gateway, redis,\n * postgres, open-webui, caddy) are excluded since Clawexa's cloud-init\n * already provisions them.\n *\n * This function never throws. Errors are reported via `warnings` and\n * `metadata.skippedServices`.\n */\nexport function generateAddonStack(rawInput: AddonStackInput): AddonStackResult {\n\tconst warnings: string[] = [];\n\tconst skippedServices: SkippedService[] = [];\n\tconst generatedSecretKeys: string[] = [];\n\n\t// 1. Parse & validate input\n\tlet input: AddonStackInput;\n\ttry {\n\t\tinput = AddonStackInputSchema.parse(rawInput);\n\t} catch (err) {\n\t\treturn emptyResult(`Invalid input: ${err instanceof Error ? err.message : String(err)}`);\n\t}\n\n\tconst projectName = sanitizeProjectName(input.instanceId);\n\n\t// 2. Filter out infrastructure service IDs from request\n\tconst addonServiceIds = input.services.filter((id) => {\n\t\tif (INFRA_SERVICE_IDS.has(id)) {\n\t\t\twarnings.push(`Service \"${id}\" is managed by Clawexa infrastructure and was excluded.`);\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t});\n\n\tif (addonServiceIds.length === 0) {\n\t\treturn emptyResult(\"No addon services requested (all were infrastructure services).\");\n\t}\n\n\t// 3. Validate all service IDs exist in registry\n\tconst validServiceIds: string[] = [];\n\tfor (const id of addonServiceIds) {\n\t\tconst svc = getServiceById(id);\n\t\tif (!svc) {\n\t\t\tskippedServices.push({\n\t\t\t\tserviceId: id,\n\t\t\t\treason: \"unknown_service\",\n\t\t\t\tdetails: `Service \"${id}\" does not exist in the registry.`,\n\t\t\t});\n\t\t} else {\n\t\t\tvalidServiceIds.push(id);\n\t\t}\n\t}\n\n\tif (validServiceIds.length === 0) {\n\t\treturn {\n\t\t\t...emptyResultBase(),\n\t\t\tmetadata: {\n\t\t\t\t...emptyResultBase().metadata,\n\t\t\t\tskippedServices,\n\t\t\t},\n\t\t\twarnings: [...warnings, \"No valid addon services to deploy.\"],\n\t\t};\n\t}\n\n\t// 4. Resolve dependencies\n\tlet resolved: ResolverOutput;\n\ttry {\n\t\tresolved = resolve({\n\t\t\tservices: validServiceIds,\n\t\t\tskillPacks: input.skillPacks,\n\t\t\taiProviders: input.aiProviders,\n\t\t\tplatform: input.platform ?? \"linux/amd64\",\n\t\t});\n\t} catch (err) {\n\t\treturn {\n\t\t\t...emptyResultBase(),\n\t\t\tmetadata: {\n\t\t\t\t...emptyResultBase().metadata,\n\t\t\t\tskippedServices,\n\t\t\t},\n\t\t\twarnings: [\n\t\t\t\t...warnings,\n\t\t\t\t`Dependency resolution failed: ${err instanceof Error ? err.message : String(err)}`,\n\t\t\t],\n\t\t};\n\t}\n\n\t// Forward resolver warnings\n\tfor (const w of resolved.warnings) {\n\t\twarnings.push(w.message);\n\t}\n\n\t// 5. Filter resolved services: keep only addon services (not infra)\n\tconst addonResolved: ResolvedService[] = [];\n\tfor (const svc of resolved.services) {\n\t\tif (INFRA_SERVICE_IDS.has(svc.definition.id)) continue;\n\t\taddonResolved.push(svc);\n\t}\n\n\t// 6. Check credentials, images, platform, GPU for each addon service\n\tconst deployableServices: ResolvedService[] = [];\n\tfor (const svc of addonResolved) {\n\t\tconst def = svc.definition;\n\n\t\t// Check for git-based services without prebuilt image\n\t\tif (def.gitSource && def.buildContext && !def.image) {\n\t\t\tconst prebuilt = def.prebuiltImage || input.prebuiltImages[def.id];\n\t\t\tif (!prebuilt) {\n\t\t\t\tskippedServices.push({\n\t\t\t\t\tserviceId: def.id,\n\t\t\t\t\treason: \"no_image\",\n\t\t\t\t\tdetails: `Service \"${def.name}\" requires building from source but no pre-built image is available.`,\n\t\t\t\t});\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\n\t\t// Check GPU requirement — skip if host has no GPU support\n\t\tif (def.gpuRequired && !input.gpu) {\n\t\t\tskippedServices.push({\n\t\t\t\tserviceId: def.id,\n\t\t\t\treason: \"gpu_required\",\n\t\t\t\tdetails: `Service \"${def.name}\" requires a GPU but the host does not have GPU support.`,\n\t\t\t});\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Check user-provided credentials\n\t\tconst userCreds = input.credentials[def.id];\n\t\tconst missing = getMissingCredentials(def, userCreds, input.generateSecrets);\n\t\tif (missing.length > 0) {\n\t\t\tskippedServices.push({\n\t\t\t\tserviceId: def.id,\n\t\t\t\treason: \"missing_credentials\",\n\t\t\t\tdetails: `Service \"${def.name}\" requires credentials: ${missing.join(\", \")}`,\n\t\t\t\trequiredCredentials: missing,\n\t\t\t});\n\t\t\tcontinue;\n\t\t}\n\n\t\tdeployableServices.push(svc);\n\t}\n\n\tif (deployableServices.length === 0) {\n\t\treturn {\n\t\t\t...emptyResultBase(),\n\t\t\tmetadata: {\n\t\t\t\t...emptyResultBase().metadata,\n\t\t\t\tskippedServices,\n\t\t\t},\n\t\t\twarnings: [...warnings, \"No deployable addon services after filtering.\"],\n\t\t};\n\t}\n\n\t// 7. Resolve port conflicts (include ports from existingServices)\n\tconst allReservedPorts = [...input.reservedPorts];\n\tfor (const existingId of input.existingServices) {\n\t\tconst existingDef = getServiceById(existingId);\n\t\tif (existingDef) {\n\t\t\tfor (const port of existingDef.ports) {\n\t\t\t\tif (port.exposed) allReservedPorts.push(port.host);\n\t\t\t}\n\t\t}\n\t}\n\tconst portConflicts = resolvePortConflicts(\n\t\tdeployableServices,\n\t\tallReservedPorts,\n\t\tinput.portOverrides,\n\t);\n\n\t// Build a fake \"full\" resolved output for buildCompanionService\n\t// It needs to see all services to resolve depends_on references\n\tconst addonResolvedOutput: ResolverOutput = {\n\t\tservices: deployableServices,\n\t\taddedDependencies: resolved.addedDependencies,\n\t\tremovedConflicts: resolved.removedConflicts,\n\t\twarnings: resolved.warnings,\n\t\terrors: [],\n\t\tisValid: true,\n\t\testimatedMemoryMB: deployableServices.reduce(\n\t\t\t(sum, s) => sum + (s.definition.minMemoryMB ?? 128),\n\t\t\t0,\n\t\t),\n\t\taiProviders: input.aiProviders ?? [],\n\t\tgsdRuntimes: [],\n\t};\n\n\t// 8. Build compose options (no hardening for Clawexa)\n\tconst composeOptions = buildAddonComposeOptions(projectName, input);\n\tif (Object.keys(portConflicts.overrides).length > 0) {\n\t\tcomposeOptions.portOverrides = portConflicts.overrides;\n\t}\n\n\t// 9. Build per-service entries\n\tconst services: Record<string, Record<string, unknown>> = {};\n\tconst allVolumes = new Set<string>();\n\tconst envValues = new Map<string, string>();\n\n\tfor (const svc of deployableServices) {\n\t\tconst def = svc.definition;\n\t\ttry {\n\t\t\t// Handle prebuilt image substitution for git-based services\n\t\t\tlet effectiveDef = def;\n\t\t\tif (def.gitSource && def.buildContext && !def.image) {\n\t\t\t\tconst prebuiltImage = def.prebuiltImage || input.prebuiltImages[def.id];\n\t\t\t\tif (prebuiltImage) {\n\t\t\t\t\tconst [img, tag] = prebuiltImage.includes(\":\")\n\t\t\t\t\t\t? prebuiltImage.split(\":\")\n\t\t\t\t\t\t: [prebuiltImage, \"latest\"];\n\t\t\t\t\teffectiveDef = {\n\t\t\t\t\t\t...def,\n\t\t\t\t\t\timage: img,\n\t\t\t\t\t\timageTag: tag,\n\t\t\t\t\t\tgitSource: undefined,\n\t\t\t\t\t\tbuildContext: undefined,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst { entry, volumeNames } = buildCompanionService(\n\t\t\t\teffectiveDef,\n\t\t\t\taddonResolvedOutput,\n\t\t\t\tcomposeOptions,\n\t\t\t\tallVolumes,\n\t\t\t);\n\n\t\t\t// Remove profiles from the service entry\n\t\t\tdelete (entry as Record<string, unknown>).profiles;\n\n\t\t\t// Remove depends_on references to infrastructure services\n\t\t\tif (entry.depends_on) {\n\t\t\t\tconst deps = entry.depends_on as Record<string, { condition: string }>;\n\t\t\t\tfor (const depId of Object.keys(deps)) {\n\t\t\t\t\tif (INFRA_SERVICE_IDS.has(depId)) {\n\t\t\t\t\t\tdelete deps[depId];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (Object.keys(deps).length === 0) {\n\t\t\t\t\tdelete entry.depends_on;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tservices[def.id] = entry;\n\t\t\tfor (const v of volumeNames) allVolumes.add(v);\n\n\t\t\t// Inject user-provided credentials into env\n\t\t\tconst userCreds = input.credentials[def.id];\n\t\t\tif (userCreds) {\n\t\t\t\tfor (const [key, value] of Object.entries(userCreds)) {\n\t\t\t\t\tenvValues.set(key, value);\n\t\t\t\t}\n\t\t\t\t// Sync referenced keys: if a user provides e.g. DB_POSTGRESDB_PASSWORD\n\t\t\t\t// and the env var's defaultValue is \"${N8N_DB_PASSWORD}\", sync the ref key\n\t\t\t\t// so postgres-setup uses the same password.\n\t\t\t\tfor (const envVar of def.environment) {\n\t\t\t\t\tif (\n\t\t\t\t\t\tuserCreds[envVar.key] &&\n\t\t\t\t\t\tenvVar.defaultValue?.startsWith(\"${\") &&\n\t\t\t\t\t\tenvVar.defaultValue?.endsWith(\"}\")\n\t\t\t\t\t) {\n\t\t\t\t\t\tconst refKey = envVar.defaultValue.slice(2, -1);\n\t\t\t\t\t\tenvValues.set(refKey, userCreds[envVar.key]);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (err) {\n\t\t\tskippedServices.push({\n\t\t\t\tserviceId: def.id,\n\t\t\t\treason: \"resolution_error\",\n\t\t\t\tdetails: `Failed to build compose entry: ${err instanceof Error ? err.message : String(err)}`,\n\t\t\t});\n\t\t\twarnings.push(`Failed to process service \"${def.name}\": ${err instanceof Error ? err.message : String(err)}`);\n\t\t}\n\t}\n\n\t// 10. Build postgres-setup if any addon needs a DB\n\t// We need to check if any of our deployable services require DB setup\n\t// and if postgresql is in the infrastructure (it is for Clawexa)\n\tconst dbReqs = getDbRequirements(addonResolvedOutput);\n\tif (dbReqs.length > 0) {\n\t\t// Build a custom postgres-setup that references the existing PostgreSQL\n\t\t// We can't use buildPostgresSetup directly because it checks for postgresql\n\t\t// in the resolved services. Instead, build it manually.\n\t\tconst scriptLines = [\"echo '=== PostgreSQL database setup (addon) ==='\", \"FAILED=0\"];\n\n\t\tfor (const req of dbReqs) {\n\t\t\tscriptLines.push(\n\t\t\t\t`echo \"Setting up database '${req.dbName}' with user '${req.dbUser}'...\"`,\n\t\t\t\t`psql -c \"SELECT 1 FROM pg_roles WHERE rolname='${req.dbUser}'\" | grep -q 1 || psql -c \"CREATE ROLE ${req.dbUser} WITH LOGIN PASSWORD '$$${req.passwordEnvVar}'\"`,\n\t\t\t\t`psql -c \"ALTER ROLE ${req.dbUser} WITH LOGIN PASSWORD '$$${req.passwordEnvVar}'\"`,\n\t\t\t\t`psql -tc \"SELECT 1 FROM pg_database WHERE datname='${req.dbName}'\" | grep -q 1 || psql -c \"CREATE DATABASE ${req.dbName} OWNER ${req.dbUser}\"`,\n\t\t\t\t`psql -c \"GRANT ALL PRIVILEGES ON DATABASE ${req.dbName} TO ${req.dbUser}\" || FAILED=1`,\n\t\t\t\t`echo \" Done: ${req.dbName}\"`,\n\t\t\t);\n\t\t}\n\t\tscriptLines.push(\"echo '=== All databases ready ==='\", \"exit $$FAILED\");\n\n\t\tconst dbEnv: Record<string, string> = {\n\t\t\tPGHOST: \"postgresql\",\n\t\t\tPGUSER: \"${POSTGRES_USER:-openclaw}\",\n\t\t\tPGDATABASE: \"${POSTGRES_DB:-openclaw}\",\n\t\t\tPGPASSWORD: \"${POSTGRES_PASSWORD}\",\n\t\t};\n\t\tfor (const req of dbReqs) {\n\t\t\tdbEnv[req.passwordEnvVar] = `\\${${req.passwordEnvVar}}`;\n\t\t}\n\n\t\tservices[\"postgres-setup\"] = {\n\t\t\timage: \"postgres:17-alpine\",\n\t\t\tdepends_on: {\n\t\t\t\tpostgresql: { condition: \"service_healthy\" },\n\t\t\t},\n\t\t\tenvironment: dbEnv,\n\t\t\tentrypoint: [\"/bin/sh\", \"-c\"],\n\t\t\tcommand: [scriptLines.join(\"\\n\")],\n\t\t\trestart: quotedStr(\"no\"),\n\t\t\tnetworks: [\"openclaw-network\"],\n\t\t};\n\n\t\t// Update addon services that need DB to depend on postgres-setup\n\t\tfor (const req of dbReqs) {\n\t\t\tconst svcEntry = services[req.serviceId];\n\t\t\tif (svcEntry) {\n\t\t\t\tconst deps = (svcEntry.depends_on as Record<string, { condition: string }>) || {};\n\t\t\t\tdeps[\"postgres-setup\"] = { condition: \"service_completed_successfully\" };\n\t\t\t\tsvcEntry.depends_on = deps;\n\t\t\t}\n\t\t}\n\t}\n\n\t// 11. Generate secrets and env file\n\tconst envLines: string[] = [\n\t\t\"# ═══════════════════════════════════════════════════════════════════════════════\",\n\t\t\"# OpenClaw Addon Stack Environment\",\n\t\t`# Instance: ${input.instanceId}`,\n\t\t`# Generated at ${new Date().toISOString()}`,\n\t\t\"# ═══════════════════════════════════════════════════════════════════════════════\",\n\t\t\"\",\n\t];\n\n\t// DB passwords first\n\tif (dbReqs.length > 0) {\n\t\tenvLines.push(\"# ── Per-Service Database Passwords ──────────────────────────────────────\");\n\t\tfor (const req of dbReqs) {\n\t\t\tconst secretValue = input.generateSecrets ? generateHexSecret(24) : \"\";\n\t\t\tenvValues.set(req.passwordEnvVar, secretValue);\n\t\t\tif (secretValue) generatedSecretKeys.push(req.passwordEnvVar);\n\t\t\tenvLines.push(`# PostgreSQL password for ${req.serviceName} (db: ${req.dbName}, user: ${req.dbUser})`);\n\t\t\tenvLines.push(`${req.passwordEnvVar}=${secretValue}`);\n\t\t\tenvLines.push(\"\");\n\t\t}\n\t}\n\n\t// Per-service env vars\n\tconst seenKeys = new Set<string>([...CLAWEXA_MANAGED_ENV_KEYS, ...dbReqs.map((r) => r.passwordEnvVar)]);\n\tconst envVarGroups: AddonStackResult[\"envVars\"] = [];\n\n\tfor (const svc of deployableServices) {\n\t\tconst def = svc.definition;\n\t\tconst allEnvVars = [...def.environment, ...def.openclawEnvVars];\n\t\tif (allEnvVars.length === 0) continue;\n\n\t\tconst groupVars: AddonStackResult[\"envVars\"][number][\"vars\"] = [];\n\n\t\tenvLines.push(`# ── ${def.icon} ${def.name} ──────────────────────────────────────`);\n\n\t\tfor (const envVar of allEnvVars) {\n\t\t\tif (seenKeys.has(envVar.key)) continue;\n\t\t\tseenKeys.add(envVar.key);\n\n\t\t\t// Check if user provided this credential\n\t\t\tconst userValue = input.credentials[def.id]?.[envVar.key];\n\t\t\tlet actualValue: string;\n\n\t\t\tif (userValue !== undefined) {\n\t\t\t\tactualValue = userValue;\n\t\t\t} else if (envVar.secret) {\n\t\t\t\t// Resolve references like ${N8N_DB_PASSWORD}\n\t\t\t\tif (envVar.defaultValue.startsWith(\"${\") && envVar.defaultValue.endsWith(\"}\")) {\n\t\t\t\t\tconst refKey = envVar.defaultValue.slice(2, -1);\n\t\t\t\t\tactualValue = envValues.get(refKey) || envVar.defaultValue;\n\t\t\t\t} else if (input.generateSecrets) {\n\t\t\t\t\tactualValue = generateHexSecret(24);\n\t\t\t\t\tgeneratedSecretKeys.push(envVar.key);\n\t\t\t\t} else {\n\t\t\t\t\tactualValue = envVar.defaultValue;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tactualValue = envVar.defaultValue;\n\t\t\t}\n\n\t\t\tenvValues.set(envVar.key, actualValue);\n\n\t\t\tenvLines.push(`# ${envVar.description}`);\n\t\t\tenvLines.push(`${envVar.key}=${actualValue}`);\n\t\t\tenvLines.push(\"\");\n\n\t\t\tgroupVars.push({\n\t\t\t\tkey: envVar.key,\n\t\t\t\tdescription: envVar.description,\n\t\t\t\tvalue: actualValue,\n\t\t\t\tsecret: envVar.secret,\n\t\t\t});\n\t\t}\n\n\t\tif (groupVars.length > 0) {\n\t\t\tenvVarGroups.push({\n\t\t\t\tserviceName: def.name,\n\t\t\t\tvars: groupVars,\n\t\t\t});\n\t\t}\n\t}\n\n\t// Apply env quirks after all values are generated\n\tfor (const svc of deployableServices) {\n\t\tapplyEnvQuirks(svc.definition, envValues, input.generateSecrets);\n\t}\n\n\t// Rebuild env lines from envValues (quirks may have modified values or introduced new keys)\n\tconst quirkedKeys = new Set<string>();\n\tconst finalEnvLines: string[] = [];\n\tfor (const line of envLines) {\n\t\tconst trimmed = line.trim();\n\t\tif (!trimmed || trimmed.startsWith(\"#\")) {\n\t\t\tfinalEnvLines.push(line);\n\t\t\tcontinue;\n\t\t}\n\t\tconst eqIdx = trimmed.indexOf(\"=\");\n\t\tif (eqIdx > 0) {\n\t\t\tconst key = trimmed.slice(0, eqIdx);\n\t\t\tquirkedKeys.add(key);\n\t\t\tconst fixedValue = envValues.get(key);\n\t\t\tif (fixedValue !== undefined) {\n\t\t\t\tfinalEnvLines.push(`${key}=${fixedValue}`);\n\t\t\t} else {\n\t\t\t\tfinalEnvLines.push(line);\n\t\t\t}\n\t\t} else {\n\t\t\tfinalEnvLines.push(line);\n\t\t}\n\t}\n\t// Append any new keys introduced by quirks (e.g., must_sync creating a new key)\n\tfor (const [key, value] of envValues) {\n\t\tif (!quirkedKeys.has(key) && !seenKeys.has(key) && !CLAWEXA_MANAGED_ENV_KEYS.has(key)) {\n\t\t\tfinalEnvLines.push(`# Synced by env quirk`);\n\t\t\tfinalEnvLines.push(`${key}=${value}`);\n\t\t\tfinalEnvLines.push(\"\");\n\t\t}\n\t}\n\tconst envFile = finalEnvLines.join(\"\\n\");\n\n\t// 12. Generate skill files\n\tconst skillFiles = generateSkillFiles(addonResolvedOutput);\n\n\t// 13. Build openclaw config patch\n\tconst skillEntries: Record<string, { enabled: boolean }> = {};\n\tlet skillCount = 0;\n\tfor (const svc of deployableServices) {\n\t\tfor (const skill of svc.definition.skills) {\n\t\t\tif (skill.autoInstall) {\n\t\t\t\tskillEntries[skill.skillId] = { enabled: true };\n\t\t\t\tskillCount++;\n\t\t\t}\n\t\t}\n\t}\n\n\t// 14. Build proxy routes\n\tconst proxyRoutes = buildProxyRoutes(deployableServices);\n\n\t// 14b. Build additional files (e.g. sandbox.toml for opensandbox)\n\tconst additionalFiles: Record<string, string> = {};\n\tif (deployableServices.some((s) => s.definition.id === \"opensandbox\")) {\n\t\tadditionalFiles[\"sandbox.toml\"] = [\n\t\t\t\"[server]\",\n\t\t\t'host = \"0.0.0.0\"',\n\t\t\t\"port = 8080\",\n\t\t\t'log_level = \"INFO\"',\n\t\t\t'api_key = \"${OPEN_SANDBOX_API_KEY}\"',\n\t\t\t\"\",\n\t\t\t\"[runtime]\",\n\t\t\t'type = \"docker\"',\n\t\t\t'execd_image = \"opensandbox/execd:v1.0.6\"',\n\t\t\t\"\",\n\t\t\t\"[docker]\",\n\t\t\t\"network_mode = \\\"bridge\\\"\",\n\t\t\t'drop_capabilities = [\"NET_ADMIN\", \"SYS_ADMIN\", \"SYS_PTRACE\", \"MKNOD\", \"NET_RAW\", \"SYS_RAWIO\"]',\n\t\t\t\"no_new_privileges = true\",\n\t\t\t\"pids_limit = 512\",\n\t\t\t\"\",\n\t\t\t\"[secure_runtime]\",\n\t\t\t'type = \"gvisor\"',\n\t\t\t\"\",\n\t\t].join(\"\\n\");\n\t}\n\n\t// 14c. Build pre-pull images list\n\tconst prePullImages: Array<{ image: string; priority: 1 | 2 | 3 }> = [];\n\tif (deployableServices.some((s) => s.definition.id === \"opensandbox\")) {\n\t\tprePullImages.push(\n\t\t\t// Priority 1: always pulled (core + Homespace)\n\t\t\t{ image: \"opensandbox/server:v1.0.6\", priority: 1 },\n\t\t\t{ image: \"opensandbox/execd:v1.0.6\", priority: 1 },\n\t\t\t{ image: \"opensandbox/desktop:latest\", priority: 1 },\n\t\t\t{ image: \"opensandbox/chrome:latest\", priority: 1 },\n\t\t\t// Priority 2: recommended (common languages)\n\t\t\t{ image: \"opensandbox/code-interpreter:python\", priority: 2 },\n\t\t\t{ image: \"opensandbox/code-interpreter:node\", priority: 2 },\n\t\t\t// Priority 3: optional (full multi-lang and IDE)\n\t\t\t{ image: \"opensandbox/code-interpreter:latest\", priority: 3 },\n\t\t\t{ image: \"opensandbox/vscode:latest\", priority: 3 },\n\t\t);\n\t}\n\n\t// 15. Compose single YAML\n\tconst volumeMap: Record<string, null> = {};\n\tfor (const v of allVolumes) {\n\t\tvolumeMap[v] = null;\n\t}\n\n\tconst composeDoc: Record<string, unknown> = {\n\t\tservices,\n\t};\n\n\tif (Object.keys(volumeMap).length > 0) {\n\t\tcomposeDoc.volumes = volumeMap;\n\t}\n\n\tcomposeDoc.networks = {\n\t\t\"openclaw-network\": {\n\t\t\texternal: true,\n\t\t},\n\t};\n\n\tconst composeOverride = stringify(composeDoc, YAML_OPTIONS);\n\n\t// 16. Return result\n\treturn {\n\t\tcomposeOverride,\n\t\tenvFile,\n\t\tenvVars: envVarGroups,\n\t\tskillFiles,\n\t\topenclawConfigPatch: {\n\t\t\tskills: { entries: skillEntries },\n\t\t},\n\t\tproxyRoutes,\n\t\tadditionalFiles,\n\t\tmetadata: {\n\t\t\tserviceCount: Object.keys(services).length,\n\t\t\tskillCount,\n\t\t\testimatedMemoryMB: addonResolvedOutput.estimatedMemoryMB,\n\t\t\tresolvedServices: deployableServices.map((s) => s.definition.id),\n\t\t\tskippedServices,\n\t\t\tgeneratedSecretKeys,\n\t\t\tportAssignments: portConflicts.assignments,\n\t\t\tprePullImages,\n\t\t},\n\t\twarnings,\n\t};\n}\n\n// ── Main: updateAddonStack ───────────────────────────────────────────────────\n\n/**\n * Incrementally updates an existing addon stack by adding or removing services.\n * Preserves existing env values (never overwrites user-customized values).\n *\n * This function never throws.\n */\nexport function updateAddonStack(rawInput: AddonStackUpdateInput): AddonStackUpdateResult {\n\tconst warnings: string[] = [];\n\n\t// 1. Parse & validate\n\tlet input: AddonStackUpdateInput;\n\ttry {\n\t\tinput = AddonStackUpdateInputSchema.parse(rawInput);\n\t} catch (err) {\n\t\treturn emptyUpdateResult(`Invalid input: ${err instanceof Error ? err.message : String(err)}`);\n\t}\n\n\t// 2. Parse existing compose YAML to extract current service list\n\tlet currentServiceIds: string[] = [];\n\ttry {\n\t\tconst existingCompose = parseYaml(input.currentCompose);\n\t\tif (existingCompose?.services && typeof existingCompose.services === \"object\") {\n\t\t\tcurrentServiceIds = Object.keys(existingCompose.services).filter(\n\t\t\t\t(id) => id !== \"postgres-setup\",\n\t\t\t);\n\t\t}\n\t} catch (err) {\n\t\twarnings.push(\n\t\t\t`Failed to parse existing compose YAML: ${err instanceof Error ? err.message : String(err)}`,\n\t\t);\n\t}\n\n\t// 3. Parse existing env into a map\n\tconst existingEnvMap = new Map<string, string>();\n\tfor (const line of input.currentEnv.split(\"\\n\")) {\n\t\tconst trimmed = line.trim();\n\t\tif (!trimmed || trimmed.startsWith(\"#\")) continue;\n\t\tconst eqIdx = trimmed.indexOf(\"=\");\n\t\tif (eqIdx > 0) {\n\t\t\texistingEnvMap.set(trimmed.slice(0, eqIdx), trimmed.slice(eqIdx + 1));\n\t\t}\n\t}\n\n\t// 4. Compute desired service list\n\tconst addSet = new Set(input.addServices);\n\tconst removeSet = new Set(input.removeServices);\n\tconst desiredServiceIds = [\n\t\t...currentServiceIds.filter((id) => !removeSet.has(id)),\n\t\t...input.addServices.filter((id) => !currentServiceIds.includes(id)),\n\t];\n\n\t// 5. Generate the full target state\n\tconst targetResult = generateAddonStack({\n\t\tinstanceId: input.instanceId,\n\t\tservices: desiredServiceIds,\n\t\tskillPacks: [],\n\t\tplatform: input.platform,\n\t\topenclawVersion: input.openclawVersion,\n\t\treservedPorts: input.reservedPorts,\n\t\tgenerateSecrets: input.generateSecrets,\n\t\tcredentials: input.credentials,\n\t\tportOverrides: input.portOverrides,\n\t\taiProviders: input.aiProviders,\n\t\tprebuiltImages: input.prebuiltImages,\n\t});\n\n\t// 6. Merge env: preserve existing values, only add new ones\n\tconst mergedEnvLines: string[] = [];\n\tfor (const line of targetResult.envFile.split(\"\\n\")) {\n\t\tconst trimmed = line.trim();\n\t\tif (!trimmed || trimmed.startsWith(\"#\")) {\n\t\t\tmergedEnvLines.push(line);\n\t\t\tcontinue;\n\t\t}\n\t\tconst eqIdx = trimmed.indexOf(\"=\");\n\t\tif (eqIdx > 0) {\n\t\t\tconst key = trimmed.slice(0, eqIdx);\n\t\t\tif (existingEnvMap.has(key)) {\n\t\t\t\t// Preserve existing value\n\t\t\t\tmergedEnvLines.push(`${key}=${existingEnvMap.get(key)}`);\n\t\t\t} else {\n\t\t\t\tmergedEnvLines.push(line);\n\t\t\t}\n\t\t} else {\n\t\t\tmergedEnvLines.push(line);\n\t\t}\n\t}\n\n\t// 7. Compute diffs\n\tconst currentSet = new Set(currentServiceIds);\n\tconst targetSet = new Set(targetResult.metadata.resolvedServices);\n\tconst added = [...targetSet].filter((id) => !currentSet.has(id));\n\tconst removed = [...currentSet].filter((id) => !targetSet.has(id));\n\tconst unchanged = [...currentSet].filter((id) => targetSet.has(id));\n\n\t// 8. Compute skill diffs\n\tconst newSkillFiles: Record<string, string> = {};\n\tconst removedSkillSlugs: string[] = [];\n\n\t// New skills from added services\n\tfor (const id of added) {\n\t\tconst def = getServiceById(id);\n\t\tif (!def) continue;\n\t\tfor (const skill of def.skills) {\n\t\t\tconst skillPath = Object.keys(targetResult.skillFiles).find(\n\t\t\t\t(path) => path.includes(skill.skillId),\n\t\t\t);\n\t\t\tif (skillPath) {\n\t\t\t\tnewSkillFiles[skillPath] = targetResult.skillFiles[skillPath];\n\t\t\t}\n\t\t}\n\t}\n\n\t// Removed skills from removed services\n\tfor (const id of removed) {\n\t\tconst def = getServiceById(id);\n\t\tif (!def) continue;\n\t\tfor (const skill of def.skills) {\n\t\t\tremovedSkillSlugs.push(skill.skillId);\n\t\t}\n\t}\n\n\t// 9. Proxy route diffs\n\tconst addProxyRoutes = targetResult.proxyRoutes.filter((r) => added.includes(r.serviceId));\n\tconst removeProxyRoutes = removed;\n\n\t// 10. Images to pull for new services\n\tconst imagesToPull: string[] = [];\n\tfor (const id of added) {\n\t\tconst def = getServiceById(id);\n\t\tif (def?.image && def?.imageTag) {\n\t\t\timagesToPull.push(`${def.image}:${def.imageTag}`);\n\t\t} else if (def?.prebuiltImage) {\n\t\t\timagesToPull.push(def.prebuiltImage);\n\t\t}\n\t}\n\n\t// 11. Estimate memory delta\n\tlet memoryDelta = 0;\n\tfor (const id of added) {\n\t\tconst def = getServiceById(id);\n\t\tmemoryDelta += def?.minMemoryMB ?? 128;\n\t}\n\tfor (const id of removed) {\n\t\tconst def = getServiceById(id);\n\t\tmemoryDelta -= def?.minMemoryMB ?? 128;\n\t}\n\n\t// Add existing skills to the config patch\n\tconst addSkillEntries: Record<string, { enabled: boolean }> = {};\n\tfor (const id of added) {\n\t\tconst def = getServiceById(id);\n\t\tif (!def) continue;\n\t\tfor (const skill of def.skills) {\n\t\t\tif (skill.autoInstall) {\n\t\t\t\taddSkillEntries[skill.skillId] = { enabled: true };\n\t\t\t}\n\t\t}\n\t}\n\n\treturn {\n\t\tcomposeOverride: targetResult.composeOverride,\n\t\tenvFile: mergedEnvLines.join(\"\\n\"),\n\t\tnewSkillFiles,\n\t\tremovedSkillSlugs,\n\t\topenclawConfigPatch: {\n\t\t\tskills: {\n\t\t\t\tadd: addSkillEntries,\n\t\t\t\tremove: removedSkillSlugs,\n\t\t\t},\n\t\t},\n\t\taddProxyRoutes,\n\t\tremoveProxyRoutes,\n\t\timagesToPull,\n\t\trestartRequired: added, // New services need starting, not restarting\n\t\tmetadata: {\n\t\t\tadded,\n\t\t\tremoved,\n\t\t\tunchanged,\n\t\t\testimatedMemoryDelta: memoryDelta,\n\t\t},\n\t\twarnings: [...warnings, ...targetResult.warnings],\n\t};\n}\n\n// ── Empty Result Helpers ─────────────────────────────────────────────────────\n\nfunction emptyResultBase(): AddonStackResult {\n\treturn {\n\t\tcomposeOverride: \"services: {}\\n\",\n\t\tenvFile: \"\",\n\t\tenvVars: [],\n\t\tskillFiles: {},\n\t\topenclawConfigPatch: { skills: { entries: {} } },\n\t\tproxyRoutes: [],\n\t\tadditionalFiles: {},\n\t\tmetadata: {\n\t\t\tserviceCount: 0,\n\t\t\tskillCount: 0,\n\t\t\testimatedMemoryMB: 0,\n\t\t\tresolvedServices: [],\n\t\t\tskippedServices: [],\n\t\t\tgeneratedSecretKeys: [],\n\t\t\tportAssignments: {},\n\t\t\tprePullImages: [],\n\t\t},\n\t\twarnings: [],\n\t};\n}\n\nfunction emptyResult(warning: string): AddonStackResult {\n\treturn {\n\t\t...emptyResultBase(),\n\t\twarnings: [warning],\n\t};\n}\n\nfunction emptyUpdateResult(warning: string): AddonStackUpdateResult {\n\treturn {\n\t\tcomposeOverride: \"services: {}\\n\",\n\t\tenvFile: \"\",\n\t\tnewSkillFiles: {},\n\t\tremovedSkillSlugs: [],\n\t\topenclawConfigPatch: { skills: { add: {}, remove: [] } },\n\t\taddProxyRoutes: [],\n\t\tremoveProxyRoutes: [],\n\t\timagesToPull: [],\n\t\trestartRequired: [],\n\t\tmetadata: {\n\t\t\tadded: [],\n\t\t\tremoved: [],\n\t\t\tunchanged: [],\n\t\t\testimatedMemoryDelta: 0,\n\t\t},\n\t\twarnings: [warning],\n\t};\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"addon-stack.cjs","names":["AddonStackInputSchema","getFrameworkById","getServiceById","resolve","buildCompanionService","getDbRequirements","quotedStr","generateSkillFiles","YAML_OPTIONS","AddonStackUpdateInputSchema"],"sources":["../src/addon-stack.ts"],"sourcesContent":["import { randomBytes } from \"node:crypto\";\nimport { parse as parseYaml, stringify } from \"yaml\";\nimport { buildCompanionService, quotedStr, YAML_OPTIONS } from \"./composer.js\";\nimport { getFrameworkById } from \"./frameworks/index.js\";\nimport type { AgentFrameworkDefinition } from \"./frameworks/types.js\";\nimport { getDbRequirements } from \"./generators/postgres-init.js\";\nimport { generateSkillFiles } from \"./generators/skills.js\";\nimport { resolve } from \"./resolver.js\";\nimport { AddonStackInputSchema, AddonStackUpdateInputSchema } from \"./schema.js\";\nimport { getServiceById } from \"./services/registry.js\";\nimport type {\n\tAddonStackInput,\n\tAddonStackResult,\n\tAddonStackUpdateInput,\n\tAddonStackUpdateResult,\n\tComposeOptions,\n\tProxyRoute,\n\tResolvedService,\n\tResolverOutput,\n\tServiceDefinition,\n\tSkippedService,\n} from \"./types.js\";\n\n// ── Constants ────────────────────────────────────────────────────────────────\n\n/** Base infrastructure service IDs that Clawexa's cloud-init provisions. */\nconst BASE_INFRA_SERVICE_IDS = [\n\t\"redis\",\n\t\"postgresql\",\n\t\"open-webui\",\n\t\"caddy\",\n\t\"traefik\",\n\t\"postgres-setup\",\n];\n\n/** Build the full set of infra IDs for a given framework. */\nfunction getInfraServiceIds(framework: AgentFrameworkDefinition): Set<string> {\n\treturn new Set([\n\t\t`${framework.id}-gateway`,\n\t\t`${framework.id}-cli`,\n\t\t...BASE_INFRA_SERVICE_IDS,\n\t\t...framework.getMandatoryServices(),\n\t]);\n}\n\n/** Env keys managed by Clawexa's cloud-init — never include in addon env output. */\nconst CLAWEXA_MANAGED_ENV_KEYS = new Set([\n\t\"COMPOSE_FILE\",\n\t\"COMPOSE_PROFILES\",\n\t\"REDIS_PASSWORD\",\n\t\"REDIS_HOST\",\n\t\"REDIS_PORT\",\n\t\"POSTGRES_USER\",\n\t\"POSTGRES_PASSWORD\",\n\t\"POSTGRES_DB\",\n\t\"POSTGRES_HOST\",\n\t\"POSTGRES_PORT\",\n]);\n\n/** Build the full set of managed env keys for a given framework. */\nfunction getManagedEnvKeys(framework: AgentFrameworkDefinition): Set<string> {\n\tconst keys = new Set(CLAWEXA_MANAGED_ENV_KEYS);\n\tfor (const envLine of framework.getBaseEnvVars({\n\t\tgenerateSecrets: false,\n\t\tframeworkVersion: \"latest\",\n\t\tframeworkImageVariant: \"official\",\n\t})) {\n\t\tkeys.add(envLine.key);\n\t}\n\treturn keys;\n}\n\n// ── Helpers ──────────────────────────────────────────────────────────────────\n\n/** Sanitize instanceId into a valid Docker Compose project name. */\nfunction sanitizeProjectName(instanceId: string): string {\n\treturn (\n\t\tinstanceId\n\t\t\t.toLowerCase()\n\t\t\t.replace(/[^a-z0-9-]/g, \"-\")\n\t\t\t.replace(/^-+|-+$/g, \"\")\n\t\t\t.replace(/-{2,}/g, \"-\")\n\t\t\t.slice(0, 64) || \"addon\"\n\t);\n}\n\n/** Generate a cryptographically secure hex secret of the given byte length. */\nfunction generateHexSecret(bytes: number): string {\n\treturn randomBytes(bytes).toString(\"hex\");\n}\n\n/** Generate a cryptographically secure base64url secret of the given byte length. */\nfunction generateBase64UrlSecret(bytes: number): string {\n\treturn randomBytes(bytes).toString(\"base64url\");\n}\n\n/**\n * Check if a service requires user-provided credentials that are missing.\n * Returns the list of missing credential keys, or empty if all are satisfied.\n *\n * When `generateSecrets` is true, empty-default secrets are auto-generated\n * (passwords, tokens, etc.) and are NOT considered missing. Only secrets\n * with `validation` regex patterns (indicating specific format like API keys)\n * are flagged as missing when not provided by the user.\n */\nfunction getMissingCredentials(\n\tdef: ServiceDefinition,\n\tuserCredentials: Record<string, string> | undefined,\n\tgenerateSecrets: boolean,\n): string[] {\n\tconst missing: string[] = [];\n\tfor (const env of def.environment) {\n\t\t// Skip if not required or not a secret\n\t\tif (!env.required || !env.secret) continue;\n\t\t// Skip if it has a non-empty default value or is a reference\n\t\tif (env.defaultValue && env.defaultValue.length > 0) continue;\n\t\t// Skip if user provided the credential\n\t\tif (userCredentials?.[env.key]) continue;\n\t\t// When generateSecrets is true, empty secrets are auto-generated\n\t\t// Only flag as missing if the env var has a validation pattern\n\t\t// (indicating it needs a specific format like an API key)\n\t\tif (generateSecrets && !env.validation) continue;\n\n\t\tmissing.push(env.key);\n\t}\n\treturn missing;\n}\n\n/**\n * Apply env quirks (from service definition) to the generated env values.\n * Handles: empty_string_crashes → set fixed value, min_length → generate longer secret,\n * must_sync → ensure two keys have the same value.\n */\nfunction applyEnvQuirks(\n\tdef: ServiceDefinition,\n\tenvValues: Map<string, string>,\n\tgenerateSecrets: boolean,\n): void {\n\tif (!def.envQuirks) return;\n\n\tfor (const quirk of def.envQuirks) {\n\t\tswitch (quirk.issue) {\n\t\t\tcase \"empty_string_crashes\": {\n\t\t\t\tif (quirk.fix.type === \"set_value\" && quirk.fix.value !== undefined) {\n\t\t\t\t\tenvValues.set(quirk.key, quirk.fix.value);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"min_length\": {\n\t\t\t\tif (!generateSecrets) break;\n\t\t\t\tconst current = envValues.get(quirk.key) || \"\";\n\t\t\t\tconst minBytes = quirk.fix.minBytes || 24;\n\t\t\t\tconst minHexLen = minBytes * 2;\n\t\t\t\tif (current.length < minHexLen) {\n\t\t\t\t\tif (quirk.fix.type === \"generate_hex\") {\n\t\t\t\t\t\tenvValues.set(quirk.key, generateHexSecret(minBytes));\n\t\t\t\t\t} else if (quirk.fix.type === \"generate_base64url\") {\n\t\t\t\t\t\tenvValues.set(quirk.key, generateBase64UrlSecret(minBytes));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"must_sync\": {\n\t\t\t\tif (quirk.fix.type === \"sync_with\" && quirk.fix.syncKey) {\n\t\t\t\t\tconst sourceValue = envValues.get(quirk.key) || envValues.get(quirk.fix.syncKey);\n\t\t\t\t\tif (sourceValue) {\n\t\t\t\t\t\tenvValues.set(quirk.key, sourceValue);\n\t\t\t\t\t\tenvValues.set(quirk.fix.syncKey, sourceValue);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Build proxy routes from resolved addon services.\n */\nfunction buildProxyRoutes(services: ResolvedService[]): ProxyRoute[] {\n\tconst routes: ProxyRoute[] = [];\n\tfor (const { definition: def } of services) {\n\t\tconst exposedPort = def.ports.find((p) => p.exposed);\n\t\tif (!exposedPort) continue;\n\n\t\troutes.push({\n\t\t\tserviceId: def.id,\n\t\t\tpath: def.proxyPath || `/${def.id}`,\n\t\t\tport: exposedPort.container,\n\t\t\tprotocol: \"http\",\n\t\t\tstripPrefix: true,\n\t\t});\n\t}\n\treturn routes;\n}\n\n/**\n * Build a minimal ComposeOptions suitable for addon stack generation.\n * No proxy, no gateway, no hardening by default.\n */\nfunction buildAddonComposeOptions(projectName: string, input: AddonStackInput): ComposeOptions {\n\treturn {\n\t\tprojectName,\n\t\tproxy: \"none\",\n\t\tgpu: false,\n\t\tplatform: input.platform ?? \"linux/amd64\",\n\t\tdeployment: \"clawexa\",\n\t\topenclawVersion: input.openclawVersion ?? \"latest\",\n\t\topenclawImage: \"official\",\n\t\thardened: false, // Clawexa default: no cap_drop/security_opt\n\t\topenclawInstallMethod: \"docker\",\n\t};\n}\n\n/**\n * Resolve port conflicts between addon services and reserved ports.\n * Returns a map of serviceId → { originalPort → assignedPort }.\n */\nfunction resolvePortConflicts(\n\taddonServices: ResolvedService[],\n\treservedPorts: number[],\n\tportOverrides?: Record<string, Record<string, number>>,\n): { assignments: Record<string, number>; overrides: Record<string, Record<string, number>> } {\n\tconst usedPorts = new Set(reservedPorts);\n\tconst assignments: Record<string, number> = {};\n\tconst overrides: Record<string, Record<string, number>> = {};\n\n\tfor (const { definition: def } of addonServices) {\n\t\tfor (const port of def.ports) {\n\t\t\tif (!port.exposed) continue;\n\n\t\t\t// Check for user-specified override\n\t\t\tconst userOverride = portOverrides?.[def.id]?.[String(port.host)];\n\t\t\tif (userOverride) {\n\t\t\t\tusedPorts.add(userOverride);\n\t\t\t\tassignments[`${def.id}:${port.container}`] = userOverride;\n\t\t\t\toverrides[def.id] ??= {};\n\t\t\t\toverrides[def.id]![String(port.host)] = userOverride;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tlet assignedPort = port.host;\n\t\t\tif (usedPorts.has(assignedPort)) {\n\t\t\t\t// Auto-reassign to port+1000 range\n\t\t\t\tassignedPort = port.host + 1000;\n\t\t\t\twhile (usedPorts.has(assignedPort)) {\n\t\t\t\t\tassignedPort++;\n\t\t\t\t}\n\t\t\t\toverrides[def.id] ??= {};\n\t\t\t\toverrides[def.id]![String(port.host)] = assignedPort;\n\t\t\t}\n\t\t\tusedPorts.add(assignedPort);\n\t\t\tassignments[`${def.id}:${port.container}`] = assignedPort;\n\t\t}\n\t}\n\n\treturn { assignments, overrides };\n}\n\n// ── Main: generateAddonStack ─────────────────────────────────────────────────\n\n/**\n * Generates a Docker Compose override stack containing only addon services\n * for Clawexa managed instances. Infrastructure services (gateway, redis,\n * postgres, open-webui, caddy) are excluded since Clawexa's cloud-init\n * already provisions them.\n *\n * This function never throws. Errors are reported via `warnings` and\n * `metadata.skippedServices`.\n */\nexport function generateAddonStack(rawInput: AddonStackInput): AddonStackResult {\n\tconst warnings: string[] = [];\n\tconst skippedServices: SkippedService[] = [];\n\tconst generatedSecretKeys: string[] = [];\n\n\t// 1. Parse & validate input\n\tlet input: AddonStackInput;\n\ttry {\n\t\tinput = AddonStackInputSchema.parse(rawInput);\n\t} catch (err) {\n\t\treturn emptyResult(`Invalid input: ${err instanceof Error ? err.message : String(err)}`);\n\t}\n\n\tconst projectName = sanitizeProjectName(input.instanceId);\n\n\t// Resolve framework for this addon stack (defaults to openclaw)\n\tconst framework = getFrameworkById(\"openclaw\")!;\n\tconst infraIds = getInfraServiceIds(framework);\n\tconst managedKeys = getManagedEnvKeys(framework);\n\n\t// 2. Filter out infrastructure service IDs from request\n\tconst addonServiceIds = input.services.filter((id) => {\n\t\tif (infraIds.has(id)) {\n\t\t\twarnings.push(`Service \"${id}\" is managed by Clawexa infrastructure and was excluded.`);\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t});\n\n\tif (addonServiceIds.length === 0) {\n\t\treturn emptyResult(\"No addon services requested (all were infrastructure services).\");\n\t}\n\n\t// 3. Validate all service IDs exist in registry\n\tconst validServiceIds: string[] = [];\n\tfor (const id of addonServiceIds) {\n\t\tconst svc = getServiceById(id);\n\t\tif (!svc) {\n\t\t\tskippedServices.push({\n\t\t\t\tserviceId: id,\n\t\t\t\treason: \"unknown_service\",\n\t\t\t\tdetails: `Service \"${id}\" does not exist in the registry.`,\n\t\t\t});\n\t\t} else {\n\t\t\tvalidServiceIds.push(id);\n\t\t}\n\t}\n\n\tif (validServiceIds.length === 0) {\n\t\treturn {\n\t\t\t...emptyResultBase(),\n\t\t\tmetadata: {\n\t\t\t\t...emptyResultBase().metadata,\n\t\t\t\tskippedServices,\n\t\t\t},\n\t\t\twarnings: [...warnings, \"No valid addon services to deploy.\"],\n\t\t};\n\t}\n\n\t// 4. Resolve dependencies\n\tlet resolved: ResolverOutput;\n\ttry {\n\t\tresolved = resolve({\n\t\t\tservices: validServiceIds,\n\t\t\tskillPacks: input.skillPacks,\n\t\t\taiProviders: input.aiProviders,\n\t\t\tplatform: input.platform ?? \"linux/amd64\",\n\t\t});\n\t} catch (err) {\n\t\treturn {\n\t\t\t...emptyResultBase(),\n\t\t\tmetadata: {\n\t\t\t\t...emptyResultBase().metadata,\n\t\t\t\tskippedServices,\n\t\t\t},\n\t\t\twarnings: [\n\t\t\t\t...warnings,\n\t\t\t\t`Dependency resolution failed: ${err instanceof Error ? err.message : String(err)}`,\n\t\t\t],\n\t\t};\n\t}\n\n\t// Forward resolver warnings\n\tfor (const w of resolved.warnings) {\n\t\twarnings.push(w.message);\n\t}\n\n\t// 5. Filter resolved services: keep only addon services (not infra)\n\tconst addonResolved: ResolvedService[] = [];\n\tfor (const svc of resolved.services) {\n\t\tif (infraIds.has(svc.definition.id)) continue;\n\t\taddonResolved.push(svc);\n\t}\n\n\t// 6. Check credentials, images, platform, GPU for each addon service\n\tconst deployableServices: ResolvedService[] = [];\n\tfor (const svc of addonResolved) {\n\t\tconst def = svc.definition;\n\n\t\t// Check for git-based services without prebuilt image\n\t\tif (def.gitSource && def.buildContext && !def.image) {\n\t\t\tconst prebuilt = def.prebuiltImage || input.prebuiltImages[def.id];\n\t\t\tif (!prebuilt) {\n\t\t\t\tskippedServices.push({\n\t\t\t\t\tserviceId: def.id,\n\t\t\t\t\treason: \"no_image\",\n\t\t\t\t\tdetails: `Service \"${def.name}\" requires building from source but no pre-built image is available.`,\n\t\t\t\t});\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\n\t\t// Check GPU requirement — skip if host has no GPU support\n\t\tif (def.gpuRequired && !input.gpu) {\n\t\t\tskippedServices.push({\n\t\t\t\tserviceId: def.id,\n\t\t\t\treason: \"gpu_required\",\n\t\t\t\tdetails: `Service \"${def.name}\" requires a GPU but the host does not have GPU support.`,\n\t\t\t});\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Check user-provided credentials\n\t\tconst userCreds = input.credentials[def.id];\n\t\tconst missing = getMissingCredentials(def, userCreds, input.generateSecrets);\n\t\tif (missing.length > 0) {\n\t\t\tskippedServices.push({\n\t\t\t\tserviceId: def.id,\n\t\t\t\treason: \"missing_credentials\",\n\t\t\t\tdetails: `Service \"${def.name}\" requires credentials: ${missing.join(\", \")}`,\n\t\t\t\trequiredCredentials: missing,\n\t\t\t});\n\t\t\tcontinue;\n\t\t}\n\n\t\tdeployableServices.push(svc);\n\t}\n\n\tif (deployableServices.length === 0) {\n\t\treturn {\n\t\t\t...emptyResultBase(),\n\t\t\tmetadata: {\n\t\t\t\t...emptyResultBase().metadata,\n\t\t\t\tskippedServices,\n\t\t\t},\n\t\t\twarnings: [...warnings, \"No deployable addon services after filtering.\"],\n\t\t};\n\t}\n\n\t// 7. Resolve port conflicts (include ports from existingServices)\n\tconst allReservedPorts = [...input.reservedPorts];\n\tfor (const existingId of input.existingServices) {\n\t\tconst existingDef = getServiceById(existingId);\n\t\tif (existingDef) {\n\t\t\tfor (const port of existingDef.ports) {\n\t\t\t\tif (port.exposed) allReservedPorts.push(port.host);\n\t\t\t}\n\t\t}\n\t}\n\tconst portConflicts = resolvePortConflicts(\n\t\tdeployableServices,\n\t\tallReservedPorts,\n\t\tinput.portOverrides,\n\t);\n\n\t// Build a fake \"full\" resolved output for buildCompanionService\n\t// It needs to see all services to resolve depends_on references\n\tconst addonResolvedOutput: ResolverOutput = {\n\t\tservices: deployableServices,\n\t\taddedDependencies: resolved.addedDependencies,\n\t\tremovedConflicts: resolved.removedConflicts,\n\t\twarnings: resolved.warnings,\n\t\terrors: [],\n\t\tisValid: true,\n\t\testimatedMemoryMB: deployableServices.reduce(\n\t\t\t(sum, s) => sum + (s.definition.minMemoryMB ?? 128),\n\t\t\t0,\n\t\t),\n\t\taiProviders: input.aiProviders ?? [],\n\t\tgsdRuntimes: [],\n\t};\n\n\t// 8. Build compose options (no hardening for Clawexa)\n\tconst composeOptions = buildAddonComposeOptions(projectName, input);\n\tif (Object.keys(portConflicts.overrides).length > 0) {\n\t\tcomposeOptions.portOverrides = portConflicts.overrides;\n\t}\n\n\t// 9. Build per-service entries\n\tconst services: Record<string, Record<string, unknown>> = {};\n\tconst allVolumes = new Set<string>();\n\tconst envValues = new Map<string, string>();\n\n\tfor (const svc of deployableServices) {\n\t\tconst def = svc.definition;\n\t\ttry {\n\t\t\t// Handle prebuilt image substitution for git-based services\n\t\t\tlet effectiveDef = def;\n\t\t\tif (def.gitSource && def.buildContext && !def.image) {\n\t\t\t\tconst prebuiltImage = def.prebuiltImage || input.prebuiltImages[def.id];\n\t\t\t\tif (prebuiltImage) {\n\t\t\t\t\tconst [img, tag] = prebuiltImage.includes(\":\")\n\t\t\t\t\t\t? prebuiltImage.split(\":\")\n\t\t\t\t\t\t: [prebuiltImage, \"latest\"];\n\t\t\t\t\teffectiveDef = {\n\t\t\t\t\t\t...def,\n\t\t\t\t\t\timage: img,\n\t\t\t\t\t\timageTag: tag,\n\t\t\t\t\t\tgitSource: undefined,\n\t\t\t\t\t\tbuildContext: undefined,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst { entry, volumeNames } = buildCompanionService(\n\t\t\t\teffectiveDef,\n\t\t\t\taddonResolvedOutput,\n\t\t\t\tcomposeOptions,\n\t\t\t\tallVolumes,\n\t\t\t);\n\n\t\t\t// Remove profiles from the service entry\n\t\t\tdelete (entry as Record<string, unknown>).profiles;\n\n\t\t\t// Remove depends_on references to infrastructure services\n\t\t\tif (entry.depends_on) {\n\t\t\t\tconst deps = entry.depends_on as Record<string, { condition: string }>;\n\t\t\t\tfor (const depId of Object.keys(deps)) {\n\t\t\t\t\tif (infraIds.has(depId)) {\n\t\t\t\t\t\tdelete deps[depId];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (Object.keys(deps).length === 0) {\n\t\t\t\t\tdelete entry.depends_on;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tservices[def.id] = entry;\n\t\t\tfor (const v of volumeNames) allVolumes.add(v);\n\n\t\t\t// Inject user-provided credentials into env\n\t\t\tconst userCreds = input.credentials[def.id];\n\t\t\tif (userCreds) {\n\t\t\t\tfor (const [key, value] of Object.entries(userCreds)) {\n\t\t\t\t\tenvValues.set(key, value);\n\t\t\t\t}\n\t\t\t\t// Sync referenced keys: if a user provides e.g. DB_POSTGRESDB_PASSWORD\n\t\t\t\t// and the env var's defaultValue is \"${N8N_DB_PASSWORD}\", sync the ref key\n\t\t\t\t// so postgres-setup uses the same password.\n\t\t\t\tfor (const envVar of def.environment) {\n\t\t\t\t\tif (\n\t\t\t\t\t\tuserCreds[envVar.key] &&\n\t\t\t\t\t\tenvVar.defaultValue?.startsWith(\"${\") &&\n\t\t\t\t\t\tenvVar.defaultValue?.endsWith(\"}\")\n\t\t\t\t\t) {\n\t\t\t\t\t\tconst refKey = envVar.defaultValue.slice(2, -1);\n\t\t\t\t\t\tenvValues.set(refKey, userCreds[envVar.key]!);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (err) {\n\t\t\tskippedServices.push({\n\t\t\t\tserviceId: def.id,\n\t\t\t\treason: \"resolution_error\",\n\t\t\t\tdetails: `Failed to build compose entry: ${err instanceof Error ? err.message : String(err)}`,\n\t\t\t});\n\t\t\twarnings.push(\n\t\t\t\t`Failed to process service \"${def.name}\": ${err instanceof Error ? err.message : String(err)}`,\n\t\t\t);\n\t\t}\n\t}\n\n\t// 10. Build postgres-setup if any addon needs a DB\n\t// We need to check if any of our deployable services require DB setup\n\t// and if postgresql is in the infrastructure (it is for Clawexa)\n\tconst dbReqs = getDbRequirements(addonResolvedOutput);\n\tif (dbReqs.length > 0) {\n\t\t// Build a custom postgres-setup that references the existing PostgreSQL\n\t\t// We can't use buildPostgresSetup directly because it checks for postgresql\n\t\t// in the resolved services. Instead, build it manually.\n\t\tconst scriptLines = [\"echo '=== PostgreSQL database setup (addon) ==='\", \"FAILED=0\"];\n\n\t\tfor (const req of dbReqs) {\n\t\t\tscriptLines.push(\n\t\t\t\t`echo \"Setting up database '${req.dbName}' with user '${req.dbUser}'...\"`,\n\t\t\t\t`psql -c \"SELECT 1 FROM pg_roles WHERE rolname='${req.dbUser}'\" | grep -q 1 || psql -c \"CREATE ROLE ${req.dbUser} WITH LOGIN PASSWORD '$$${req.passwordEnvVar}'\"`,\n\t\t\t\t`psql -c \"ALTER ROLE ${req.dbUser} WITH LOGIN PASSWORD '$$${req.passwordEnvVar}'\"`,\n\t\t\t\t`psql -tc \"SELECT 1 FROM pg_database WHERE datname='${req.dbName}'\" | grep -q 1 || psql -c \"CREATE DATABASE ${req.dbName} OWNER ${req.dbUser}\"`,\n\t\t\t\t`psql -c \"GRANT ALL PRIVILEGES ON DATABASE ${req.dbName} TO ${req.dbUser}\" || FAILED=1`,\n\t\t\t\t`echo \" Done: ${req.dbName}\"`,\n\t\t\t);\n\t\t}\n\t\tscriptLines.push(\"echo '=== All databases ready ==='\", \"exit $$FAILED\");\n\n\t\tconst dbEnv: Record<string, string> = {\n\t\t\tPGHOST: \"postgresql\",\n\t\t\tPGUSER: \"${POSTGRES_USER:-openclaw}\",\n\t\t\tPGDATABASE: \"${POSTGRES_DB:-openclaw}\",\n\t\t\tPGPASSWORD: \"${POSTGRES_PASSWORD}\",\n\t\t};\n\t\tfor (const req of dbReqs) {\n\t\t\tdbEnv[req.passwordEnvVar] = `\\${${req.passwordEnvVar}}`;\n\t\t}\n\n\t\tservices[\"postgres-setup\"] = {\n\t\t\timage: \"postgres:17-alpine\",\n\t\t\tdepends_on: {\n\t\t\t\tpostgresql: { condition: \"service_healthy\" },\n\t\t\t},\n\t\t\tenvironment: dbEnv,\n\t\t\tentrypoint: [\"/bin/sh\", \"-c\"],\n\t\t\tcommand: [scriptLines.join(\"\\n\")],\n\t\t\trestart: quotedStr(\"no\"),\n\t\t\tnetworks: [framework.networkName],\n\t\t};\n\n\t\t// Update addon services that need DB to depend on postgres-setup\n\t\tfor (const req of dbReqs) {\n\t\t\tconst svcEntry = services[req.serviceId];\n\t\t\tif (svcEntry) {\n\t\t\t\tconst deps = (svcEntry.depends_on as Record<string, { condition: string }>) || {};\n\t\t\t\tdeps[\"postgres-setup\"] = { condition: \"service_completed_successfully\" };\n\t\t\t\tsvcEntry.depends_on = deps;\n\t\t\t}\n\t\t}\n\t}\n\n\t// 11. Generate secrets and env file\n\tconst envLines: string[] = [\n\t\t\"# ═══════════════════════════════════════════════════════════════════════════════\",\n\t\t\"# OpenClaw Addon Stack Environment\",\n\t\t`# Instance: ${input.instanceId}`,\n\t\t`# Generated at ${new Date().toISOString()}`,\n\t\t\"# ═══════════════════════════════════════════════════════════════════════════════\",\n\t\t\"\",\n\t];\n\n\t// DB passwords first\n\tif (dbReqs.length > 0) {\n\t\tenvLines.push(\"# ── Per-Service Database Passwords ──────────────────────────────────────\");\n\t\tfor (const req of dbReqs) {\n\t\t\tconst secretValue = input.generateSecrets ? generateHexSecret(24) : \"\";\n\t\t\tenvValues.set(req.passwordEnvVar, secretValue);\n\t\t\tif (secretValue) generatedSecretKeys.push(req.passwordEnvVar);\n\t\t\tenvLines.push(\n\t\t\t\t`# PostgreSQL password for ${req.serviceName} (db: ${req.dbName}, user: ${req.dbUser})`,\n\t\t\t);\n\t\t\tenvLines.push(`${req.passwordEnvVar}=${secretValue}`);\n\t\t\tenvLines.push(\"\");\n\t\t}\n\t}\n\n\t// Per-service env vars\n\tconst seenKeys = new Set<string>([...managedKeys, ...dbReqs.map((r) => r.passwordEnvVar)]);\n\tconst envVarGroups: AddonStackResult[\"envVars\"] = [];\n\n\tfor (const svc of deployableServices) {\n\t\tconst def = svc.definition;\n\t\tconst allEnvVars = [...def.environment, ...def.openclawEnvVars];\n\t\tif (allEnvVars.length === 0) continue;\n\n\t\tconst groupVars: AddonStackResult[\"envVars\"][number][\"vars\"] = [];\n\n\t\tenvLines.push(`# ── ${def.icon} ${def.name} ──────────────────────────────────────`);\n\n\t\tfor (const envVar of allEnvVars) {\n\t\t\tif (seenKeys.has(envVar.key)) continue;\n\t\t\tseenKeys.add(envVar.key);\n\n\t\t\t// Check if user provided this credential\n\t\t\tconst userValue = input.credentials[def.id]?.[envVar.key];\n\t\t\tlet actualValue: string;\n\n\t\t\tif (userValue !== undefined) {\n\t\t\t\tactualValue = userValue;\n\t\t\t} else if (envVar.secret) {\n\t\t\t\t// Resolve references like ${N8N_DB_PASSWORD}\n\t\t\t\tif (envVar.defaultValue.startsWith(\"${\") && envVar.defaultValue.endsWith(\"}\")) {\n\t\t\t\t\tconst refKey = envVar.defaultValue.slice(2, -1);\n\t\t\t\t\tactualValue = envValues.get(refKey) || envVar.defaultValue;\n\t\t\t\t} else if (input.generateSecrets) {\n\t\t\t\t\tactualValue = generateHexSecret(24);\n\t\t\t\t\tgeneratedSecretKeys.push(envVar.key);\n\t\t\t\t} else {\n\t\t\t\t\tactualValue = envVar.defaultValue;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tactualValue = envVar.defaultValue;\n\t\t\t}\n\n\t\t\tenvValues.set(envVar.key, actualValue);\n\n\t\t\tenvLines.push(`# ${envVar.description}`);\n\t\t\tenvLines.push(`${envVar.key}=${actualValue}`);\n\t\t\tenvLines.push(\"\");\n\n\t\t\tgroupVars.push({\n\t\t\t\tkey: envVar.key,\n\t\t\t\tdescription: envVar.description,\n\t\t\t\tvalue: actualValue,\n\t\t\t\tsecret: envVar.secret,\n\t\t\t});\n\t\t}\n\n\t\tif (groupVars.length > 0) {\n\t\t\tenvVarGroups.push({\n\t\t\t\tserviceName: def.name,\n\t\t\t\tvars: groupVars,\n\t\t\t});\n\t\t}\n\t}\n\n\t// Apply env quirks after all values are generated\n\tfor (const svc of deployableServices) {\n\t\tapplyEnvQuirks(svc.definition, envValues, input.generateSecrets);\n\t}\n\n\t// Rebuild env lines from envValues (quirks may have modified values or introduced new keys)\n\tconst quirkedKeys = new Set<string>();\n\tconst finalEnvLines: string[] = [];\n\tfor (const line of envLines) {\n\t\tconst trimmed = line.trim();\n\t\tif (!trimmed || trimmed.startsWith(\"#\")) {\n\t\t\tfinalEnvLines.push(line);\n\t\t\tcontinue;\n\t\t}\n\t\tconst eqIdx = trimmed.indexOf(\"=\");\n\t\tif (eqIdx > 0) {\n\t\t\tconst key = trimmed.slice(0, eqIdx);\n\t\t\tquirkedKeys.add(key);\n\t\t\tconst fixedValue = envValues.get(key);\n\t\t\tif (fixedValue !== undefined) {\n\t\t\t\tfinalEnvLines.push(`${key}=${fixedValue}`);\n\t\t\t} else {\n\t\t\t\tfinalEnvLines.push(line);\n\t\t\t}\n\t\t} else {\n\t\t\tfinalEnvLines.push(line);\n\t\t}\n\t}\n\t// Append any new keys introduced by quirks (e.g., must_sync creating a new key)\n\tfor (const [key, value] of envValues) {\n\t\tif (!quirkedKeys.has(key) && !seenKeys.has(key) && !managedKeys.has(key)) {\n\t\t\tfinalEnvLines.push(`# Synced by env quirk`);\n\t\t\tfinalEnvLines.push(`${key}=${value}`);\n\t\t\tfinalEnvLines.push(\"\");\n\t\t}\n\t}\n\tconst envFile = finalEnvLines.join(\"\\n\");\n\n\t// 12. Generate skill files\n\tconst skillFiles = generateSkillFiles(addonResolvedOutput);\n\n\t// 13. Build openclaw config patch\n\tconst skillEntries: Record<string, { enabled: boolean }> = {};\n\tlet skillCount = 0;\n\tfor (const svc of deployableServices) {\n\t\tfor (const skill of svc.definition.skills) {\n\t\t\tif (skill.autoInstall) {\n\t\t\t\tskillEntries[skill.skillId] = { enabled: true };\n\t\t\t\tskillCount++;\n\t\t\t}\n\t\t}\n\t}\n\n\t// 14. Build proxy routes\n\tconst proxyRoutes = buildProxyRoutes(deployableServices);\n\n\t// 14b. Build additional files (e.g. sandbox.toml for opensandbox)\n\tconst additionalFiles: Record<string, string> = {};\n\tif (deployableServices.some((s) => s.definition.id === \"opensandbox\")) {\n\t\tadditionalFiles[\"sandbox.toml\"] = [\n\t\t\t\"[server]\",\n\t\t\t'host = \"0.0.0.0\"',\n\t\t\t\"port = 8080\",\n\t\t\t'log_level = \"INFO\"',\n\t\t\t'api_key = \"${OPEN_SANDBOX_API_KEY}\"',\n\t\t\t\"\",\n\t\t\t\"[runtime]\",\n\t\t\t'type = \"docker\"',\n\t\t\t'execd_image = \"opensandbox/execd:v1.0.6\"',\n\t\t\t\"\",\n\t\t\t\"[docker]\",\n\t\t\t'network_mode = \"bridge\"',\n\t\t\t'drop_capabilities = [\"NET_ADMIN\", \"SYS_ADMIN\", \"SYS_PTRACE\", \"MKNOD\", \"NET_RAW\", \"SYS_RAWIO\"]',\n\t\t\t\"no_new_privileges = true\",\n\t\t\t\"pids_limit = 512\",\n\t\t\t\"\",\n\t\t\t\"[secure_runtime]\",\n\t\t\t'type = \"gvisor\"',\n\t\t\t\"\",\n\t\t].join(\"\\n\");\n\t}\n\n\t// 14c. Build pre-pull images list\n\tconst prePullImages: Array<{ image: string; priority: 1 | 2 | 3 }> = [];\n\tif (deployableServices.some((s) => s.definition.id === \"opensandbox\")) {\n\t\tprePullImages.push(\n\t\t\t// Priority 1: always pulled (core + Homespace)\n\t\t\t{ image: \"opensandbox/server:v1.0.6\", priority: 1 },\n\t\t\t{ image: \"opensandbox/execd:v1.0.6\", priority: 1 },\n\t\t\t{ image: \"opensandbox/desktop:latest\", priority: 1 },\n\t\t\t{ image: \"opensandbox/chrome:latest\", priority: 1 },\n\t\t\t// Priority 2: recommended (common languages)\n\t\t\t{ image: \"opensandbox/code-interpreter:python\", priority: 2 },\n\t\t\t{ image: \"opensandbox/code-interpreter:node\", priority: 2 },\n\t\t\t// Priority 3: optional (full multi-lang and IDE)\n\t\t\t{ image: \"opensandbox/code-interpreter:latest\", priority: 3 },\n\t\t\t{ image: \"opensandbox/vscode:latest\", priority: 3 },\n\t\t);\n\t}\n\n\t// 15. Compose single YAML\n\tconst volumeMap: Record<string, null> = {};\n\tfor (const v of allVolumes) {\n\t\tvolumeMap[v] = null;\n\t}\n\n\tconst composeDoc: Record<string, unknown> = {\n\t\tservices,\n\t};\n\n\tif (Object.keys(volumeMap).length > 0) {\n\t\tcomposeDoc.volumes = volumeMap;\n\t}\n\n\tcomposeDoc.networks = {\n\t\t[framework.networkName]: {\n\t\t\texternal: true,\n\t\t},\n\t};\n\n\tconst composeOverride = stringify(composeDoc, YAML_OPTIONS);\n\n\t// 16. Return result\n\treturn {\n\t\tcomposeOverride,\n\t\tenvFile,\n\t\tenvVars: envVarGroups,\n\t\tskillFiles,\n\t\topenclawConfigPatch: {\n\t\t\tskills: { entries: skillEntries },\n\t\t},\n\t\tproxyRoutes,\n\t\tadditionalFiles,\n\t\tmetadata: {\n\t\t\tserviceCount: Object.keys(services).length,\n\t\t\tskillCount,\n\t\t\testimatedMemoryMB: addonResolvedOutput.estimatedMemoryMB,\n\t\t\tresolvedServices: deployableServices.map((s) => s.definition.id),\n\t\t\tskippedServices,\n\t\t\tgeneratedSecretKeys,\n\t\t\tportAssignments: portConflicts.assignments,\n\t\t\tprePullImages,\n\t\t},\n\t\twarnings,\n\t};\n}\n\n// ── Main: updateAddonStack ───────────────────────────────────────────────────\n\n/**\n * Incrementally updates an existing addon stack by adding or removing services.\n * Preserves existing env values (never overwrites user-customized values).\n *\n * This function never throws.\n */\nexport function updateAddonStack(rawInput: AddonStackUpdateInput): AddonStackUpdateResult {\n\tconst warnings: string[] = [];\n\n\t// 1. Parse & validate\n\tlet input: AddonStackUpdateInput;\n\ttry {\n\t\tinput = AddonStackUpdateInputSchema.parse(rawInput);\n\t} catch (err) {\n\t\treturn emptyUpdateResult(`Invalid input: ${err instanceof Error ? err.message : String(err)}`);\n\t}\n\n\t// 2. Parse existing compose YAML to extract current service list\n\tlet currentServiceIds: string[] = [];\n\ttry {\n\t\tconst existingCompose = parseYaml(input.currentCompose);\n\t\tif (existingCompose?.services && typeof existingCompose.services === \"object\") {\n\t\t\tcurrentServiceIds = Object.keys(existingCompose.services).filter(\n\t\t\t\t(id) => id !== \"postgres-setup\",\n\t\t\t);\n\t\t}\n\t} catch (err) {\n\t\twarnings.push(\n\t\t\t`Failed to parse existing compose YAML: ${err instanceof Error ? err.message : String(err)}`,\n\t\t);\n\t}\n\n\t// 3. Parse existing env into a map\n\tconst existingEnvMap = new Map<string, string>();\n\tfor (const line of input.currentEnv.split(\"\\n\")) {\n\t\tconst trimmed = line.trim();\n\t\tif (!trimmed || trimmed.startsWith(\"#\")) continue;\n\t\tconst eqIdx = trimmed.indexOf(\"=\");\n\t\tif (eqIdx > 0) {\n\t\t\texistingEnvMap.set(trimmed.slice(0, eqIdx), trimmed.slice(eqIdx + 1));\n\t\t}\n\t}\n\n\t// 4. Compute desired service list\n\tconst removeSet = new Set(input.removeServices);\n\tconst desiredServiceIds = [\n\t\t...currentServiceIds.filter((id) => !removeSet.has(id)),\n\t\t...input.addServices.filter((id) => !currentServiceIds.includes(id)),\n\t];\n\n\t// 5. Generate the full target state\n\tconst targetResult = generateAddonStack({\n\t\tinstanceId: input.instanceId,\n\t\tservices: desiredServiceIds,\n\t\tskillPacks: [],\n\t\tplatform: input.platform,\n\t\topenclawVersion: input.openclawVersion,\n\t\texistingServices: input.existingServices,\n\t\treservedPorts: input.reservedPorts,\n\t\tgenerateSecrets: input.generateSecrets,\n\t\tcredentials: input.credentials,\n\t\tportOverrides: input.portOverrides,\n\t\tgpu: input.gpu,\n\t\taiProviders: input.aiProviders,\n\t\tprebuiltImages: input.prebuiltImages,\n\t});\n\n\t// 6. Merge env: preserve existing values, only add new ones\n\tconst mergedEnvLines: string[] = [];\n\tfor (const line of targetResult.envFile.split(\"\\n\")) {\n\t\tconst trimmed = line.trim();\n\t\tif (!trimmed || trimmed.startsWith(\"#\")) {\n\t\t\tmergedEnvLines.push(line);\n\t\t\tcontinue;\n\t\t}\n\t\tconst eqIdx = trimmed.indexOf(\"=\");\n\t\tif (eqIdx > 0) {\n\t\t\tconst key = trimmed.slice(0, eqIdx);\n\t\t\tif (existingEnvMap.has(key)) {\n\t\t\t\t// Preserve existing value\n\t\t\t\tmergedEnvLines.push(`${key}=${existingEnvMap.get(key)}`);\n\t\t\t} else {\n\t\t\t\tmergedEnvLines.push(line);\n\t\t\t}\n\t\t} else {\n\t\t\tmergedEnvLines.push(line);\n\t\t}\n\t}\n\n\t// 7. Compute diffs\n\tconst currentSet = new Set(currentServiceIds);\n\tconst targetSet = new Set(targetResult.metadata.resolvedServices);\n\tconst added = [...targetSet].filter((id) => !currentSet.has(id));\n\tconst removed = [...currentSet].filter((id) => !targetSet.has(id));\n\tconst unchanged = [...currentSet].filter((id) => targetSet.has(id));\n\n\t// 8. Compute skill diffs\n\tconst newSkillFiles: Record<string, string> = {};\n\tconst removedSkillSlugs: string[] = [];\n\n\t// New skills from added services\n\tfor (const id of added) {\n\t\tconst def = getServiceById(id);\n\t\tif (!def) continue;\n\t\tfor (const skill of def.skills) {\n\t\t\tconst skillPath = Object.keys(targetResult.skillFiles).find((path) =>\n\t\t\t\tpath.includes(skill.skillId),\n\t\t\t);\n\t\t\tif (skillPath && targetResult.skillFiles[skillPath]) {\n\t\t\t\tnewSkillFiles[skillPath] = targetResult.skillFiles[skillPath];\n\t\t\t}\n\t\t}\n\t}\n\n\t// Removed skills from removed services\n\tfor (const id of removed) {\n\t\tconst def = getServiceById(id);\n\t\tif (!def) continue;\n\t\tfor (const skill of def.skills) {\n\t\t\tremovedSkillSlugs.push(skill.skillId);\n\t\t}\n\t}\n\n\t// 9. Proxy route diffs\n\tconst addProxyRoutes = targetResult.proxyRoutes.filter((r) => added.includes(r.serviceId));\n\tconst removeProxyRoutes = removed;\n\n\t// 10. Images to pull for new services\n\tconst imagesToPull: string[] = [];\n\tfor (const id of added) {\n\t\tconst def = getServiceById(id);\n\t\tif (def?.image && def?.imageTag) {\n\t\t\timagesToPull.push(`${def.image}:${def.imageTag}`);\n\t\t} else if (def?.prebuiltImage) {\n\t\t\timagesToPull.push(def.prebuiltImage);\n\t\t}\n\t}\n\n\t// 11. Estimate memory delta\n\tlet memoryDelta = 0;\n\tfor (const id of added) {\n\t\tconst def = getServiceById(id);\n\t\tmemoryDelta += def?.minMemoryMB ?? 128;\n\t}\n\tfor (const id of removed) {\n\t\tconst def = getServiceById(id);\n\t\tmemoryDelta -= def?.minMemoryMB ?? 128;\n\t}\n\n\t// Add existing skills to the config patch\n\tconst addSkillEntries: Record<string, { enabled: boolean }> = {};\n\tfor (const id of added) {\n\t\tconst def = getServiceById(id);\n\t\tif (!def) continue;\n\t\tfor (const skill of def.skills) {\n\t\t\tif (skill.autoInstall) {\n\t\t\t\taddSkillEntries[skill.skillId] = { enabled: true };\n\t\t\t}\n\t\t}\n\t}\n\n\treturn {\n\t\tcomposeOverride: targetResult.composeOverride,\n\t\tenvFile: mergedEnvLines.join(\"\\n\"),\n\t\tnewSkillFiles,\n\t\tremovedSkillSlugs,\n\t\topenclawConfigPatch: {\n\t\t\tskills: {\n\t\t\t\tadd: addSkillEntries,\n\t\t\t\tremove: removedSkillSlugs,\n\t\t\t},\n\t\t},\n\t\taddProxyRoutes,\n\t\tremoveProxyRoutes,\n\t\timagesToPull,\n\t\trestartRequired: added, // New services need starting, not restarting\n\t\tmetadata: {\n\t\t\tadded,\n\t\t\tremoved,\n\t\t\tunchanged,\n\t\t\testimatedMemoryDelta: memoryDelta,\n\t\t},\n\t\twarnings: [...warnings, ...targetResult.warnings],\n\t};\n}\n\n// ── Empty Result Helpers ─────────────────────────────────────────────────────\n\nfunction emptyResultBase(): AddonStackResult {\n\treturn {\n\t\tcomposeOverride: \"services: {}\\n\",\n\t\tenvFile: \"\",\n\t\tenvVars: [],\n\t\tskillFiles: {},\n\t\topenclawConfigPatch: { skills: { entries: {} } },\n\t\tproxyRoutes: [],\n\t\tadditionalFiles: {},\n\t\tmetadata: {\n\t\t\tserviceCount: 0,\n\t\t\tskillCount: 0,\n\t\t\testimatedMemoryMB: 0,\n\t\t\tresolvedServices: [],\n\t\t\tskippedServices: [],\n\t\t\tgeneratedSecretKeys: [],\n\t\t\tportAssignments: {},\n\t\t\tprePullImages: [],\n\t\t},\n\t\twarnings: [],\n\t};\n}\n\nfunction emptyResult(warning: string): AddonStackResult {\n\treturn {\n\t\t...emptyResultBase(),\n\t\twarnings: [warning],\n\t};\n}\n\nfunction emptyUpdateResult(warning: string): AddonStackUpdateResult {\n\treturn {\n\t\tcomposeOverride: \"services: {}\\n\",\n\t\tenvFile: \"\",\n\t\tnewSkillFiles: {},\n\t\tremovedSkillSlugs: [],\n\t\topenclawConfigPatch: { skills: { add: {}, remove: [] } },\n\t\taddProxyRoutes: [],\n\t\tremoveProxyRoutes: [],\n\t\timagesToPull: [],\n\t\trestartRequired: [],\n\t\tmetadata: {\n\t\t\tadded: [],\n\t\t\tremoved: [],\n\t\t\tunchanged: [],\n\t\t\testimatedMemoryDelta: 0,\n\t\t},\n\t\twarnings: [warning],\n\t};\n}\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { AddonStackInput, AddonStackResult, AddonStackUpdateInput, AddonStackUpdateResult } from "./types.cjs";
1
+ import { a as AddonStackUpdateResult, i as AddonStackUpdateInput, n as AddonStackInput, r as AddonStackResult } from "./types-Bsn0XzSP.cjs";
2
2
 
3
3
  //#region src/addon-stack.d.ts
4
4
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"addon-stack.d.cts","names":[],"sources":["../src/addon-stack.ts"],"mappings":";;;;;AAiQA;;;;;;;iBAAgB,kBAAA,CAAmB,QAAA,EAAU,eAAA,GAAkB,gBAAA;;AA8iB/D;;;;;iBAAgB,gBAAA,CAAiB,QAAA,EAAU,qBAAA,GAAwB,sBAAA"}
1
+ {"version":3,"file":"addon-stack.d.cts","names":[],"sources":["../src/addon-stack.ts"],"mappings":";;;;;AA8QA;;;;;;;iBAAgB,kBAAA,CAAmB,QAAA,EAAU,eAAA,GAAkB,gBAAA;;AAujB/D;;;;;iBAAgB,gBAAA,CAAiB,QAAA,EAAU,qBAAA,GAAwB,sBAAA"}
@@ -1,4 +1,4 @@
1
- import { AddonStackInput, AddonStackResult, AddonStackUpdateInput, AddonStackUpdateResult } from "./types.mjs";
1
+ import { a as AddonStackUpdateResult, i as AddonStackUpdateInput, n as AddonStackInput, r as AddonStackResult } from "./types-DwTKyCZ9.mjs";
2
2
 
3
3
  //#region src/addon-stack.d.ts
4
4
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"addon-stack.d.mts","names":[],"sources":["../src/addon-stack.ts"],"mappings":";;;;;;AAiQA;;;;;;iBAAgB,kBAAA,CAAmB,QAAA,EAAU,eAAA,GAAkB,gBAAA;;;AA8iB/D;;;;iBAAgB,gBAAA,CAAiB,QAAA,EAAU,qBAAA,GAAwB,sBAAA"}
1
+ {"version":3,"file":"addon-stack.d.mts","names":[],"sources":["../src/addon-stack.ts"],"mappings":";;;;;;AA8QA;;;;;;iBAAgB,kBAAA,CAAmB,QAAA,EAAU,eAAA,GAAkB,gBAAA;;;AAujB/D;;;;iBAAgB,gBAAA,CAAiB,QAAA,EAAU,qBAAA,GAAwB,sBAAA"}