@shadowob/cloud 1.1.6-dev.311

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 (334) hide show
  1. package/README.md +509 -0
  2. package/dist/agent-browser-CERTMCDL.js +117 -0
  3. package/dist/agent-browser-CIRZRIY4.js +118 -0
  4. package/dist/agent-pack-LF3O5TR4.js +1236 -0
  5. package/dist/agent-pack-RQT27V7R.js +1235 -0
  6. package/dist/airtable-BG2Q75G2.js +82 -0
  7. package/dist/airtable-JCQXFM5D.js +83 -0
  8. package/dist/alipay-MZX2XCDB.js +52 -0
  9. package/dist/alipay-TZQI34RB.js +51 -0
  10. package/dist/amap-5RQB3VGC.js +45 -0
  11. package/dist/amap-KPCLZYYL.js +44 -0
  12. package/dist/atlassian-LGOEWYC7.js +54 -0
  13. package/dist/atlassian-TVS2A4IU.js +55 -0
  14. package/dist/baidu-appbuilder-6UMESXHW.js +41 -0
  15. package/dist/baidu-appbuilder-QRRL3ETM.js +42 -0
  16. package/dist/baidu-maps-HEPMVP5D.js +44 -0
  17. package/dist/baidu-maps-HXC4FBVP.js +45 -0
  18. package/dist/baidu-netdisk-G5Q6B5NH.js +45 -0
  19. package/dist/baidu-netdisk-RS2K5W2M.js +44 -0
  20. package/dist/baidu-smartprogram-EWTK5WKK.js +41 -0
  21. package/dist/baidu-smartprogram-JHD3XWF6.js +40 -0
  22. package/dist/browserbase-IUIYVYI7.js +67 -0
  23. package/dist/browserbase-JFO2PCIA.js +68 -0
  24. package/dist/canva-3YOFL7JS.js +62 -0
  25. package/dist/canva-FMYN65SM.js +61 -0
  26. package/dist/chunk-6P2K6QZR.js +529 -0
  27. package/dist/chunk-7VMRQ7MG.js +90 -0
  28. package/dist/chunk-AD3JTIU3.js +17 -0
  29. package/dist/chunk-BF6CV2Y4.js +64 -0
  30. package/dist/chunk-CTNUKOQE.js +439 -0
  31. package/dist/chunk-EEFMJYKB.js +97 -0
  32. package/dist/chunk-EJKFQ35I.js +739 -0
  33. package/dist/chunk-HUICDC56.js +62 -0
  34. package/dist/chunk-JUPAE5IA.js +527 -0
  35. package/dist/chunk-JY2HTT7Q.js +437 -0
  36. package/dist/chunk-KEPTCLUO.js +121 -0
  37. package/dist/chunk-KKK5H7YX.js +3622 -0
  38. package/dist/chunk-POSVEKIY.js +210 -0
  39. package/dist/chunk-QET4LT4J.js +5769 -0
  40. package/dist/chunk-QV4XWO3P.js +30 -0
  41. package/dist/chunk-R52J3PH2.js +120 -0
  42. package/dist/chunk-R5U7XKVJ.js +16 -0
  43. package/dist/chunk-RECNVWMT.js +212 -0
  44. package/dist/chunk-RTPBU5HF.js +92 -0
  45. package/dist/chunk-SUZ2ATT6.js +5774 -0
  46. package/dist/chunk-SVMXSIMG.js +98 -0
  47. package/dist/chunk-TV3CBM7R.js +28 -0
  48. package/dist/chunk-V2LU736V.js +3495 -0
  49. package/dist/chunk-ZUYL3W53.js +741 -0
  50. package/dist/claude-plugin-577TAQVS.js +1463 -0
  51. package/dist/claude-plugin-L3MXJJ6J.js +1464 -0
  52. package/dist/cli.js +7021 -0
  53. package/dist/cloudflare-HBBABPK6.js +114 -0
  54. package/dist/cloudflare-RDFPKMM5.js +115 -0
  55. package/dist/cnb-FLP3QX46.js +44 -0
  56. package/dist/cnb-YAVVEYFB.js +45 -0
  57. package/dist/console/index.html +12 -0
  58. package/dist/console/logo.png +0 -0
  59. package/dist/console/static/css/5079.f9e0918d.css +1 -0
  60. package/dist/console/static/css/index.7f91f806.css +1 -0
  61. package/dist/console/static/font/codicon.5b7d6fac.ttf +0 -0
  62. package/dist/console/static/js/5079.72a51ca2.js +699 -0
  63. package/dist/console/static/js/5079.72a51ca2.js.LICENSE.txt +35 -0
  64. package/dist/console/static/js/7426.f8d483ea.js +1 -0
  65. package/dist/console/static/js/async/1008.4df521b7.js +1 -0
  66. package/dist/console/static/js/async/102.1d473ec7.js +1 -0
  67. package/dist/console/static/js/async/1134.3f9fd9e7.js +1 -0
  68. package/dist/console/static/js/async/1318.4b8e48e7.js +1 -0
  69. package/dist/console/static/js/async/1360.5606da88.js +7 -0
  70. package/dist/console/static/js/async/1546.045f484f.js +1 -0
  71. package/dist/console/static/js/async/1562.187de2a8.js +1 -0
  72. package/dist/console/static/js/async/168.456d4813.js +1 -0
  73. package/dist/console/static/js/async/1750.e6dc2664.js +1 -0
  74. package/dist/console/static/js/async/1994.3fc86066.js +1 -0
  75. package/dist/console/static/js/async/2348.613ae3d9.js +1 -0
  76. package/dist/console/static/js/async/2390.1b890b9d.js +1 -0
  77. package/dist/console/static/js/async/2414.9d040212.js +1 -0
  78. package/dist/console/static/js/async/2454.4c1784ab.js +1 -0
  79. package/dist/console/static/js/async/2498.f5f92030.js +1 -0
  80. package/dist/console/static/js/async/2924.b823cd1a.js +1 -0
  81. package/dist/console/static/js/async/3062.63fddea6.js +1 -0
  82. package/dist/console/static/js/async/3078.dd712008.js +1 -0
  83. package/dist/console/static/js/async/3198.1f307065.js +1 -0
  84. package/dist/console/static/js/async/3246.3d5a899f.js +1 -0
  85. package/dist/console/static/js/async/3286.871676eb.js +1 -0
  86. package/dist/console/static/js/async/342.10bf3b90.js +1 -0
  87. package/dist/console/static/js/async/3446.9681a4d7.js +1 -0
  88. package/dist/console/static/js/async/3698.ccfaabec.js +1 -0
  89. package/dist/console/static/js/async/3790.2a1106a6.js +1 -0
  90. package/dist/console/static/js/async/4231.b29784d4.js +1 -0
  91. package/dist/console/static/js/async/4551.515bd41d.js +1 -0
  92. package/dist/console/static/js/async/4596.40f6e71b.js +1 -0
  93. package/dist/console/static/js/async/4600.4aaebe6d.js +1 -0
  94. package/dist/console/static/js/async/4718.1aae022f.js +1 -0
  95. package/dist/console/static/js/async/4846.a347c020.js +1 -0
  96. package/dist/console/static/js/async/4860.83dadf89.js +1 -0
  97. package/dist/console/static/js/async/500.fcfa37cb.js +1 -0
  98. package/dist/console/static/js/async/5096.b360203d.js +1 -0
  99. package/dist/console/static/js/async/5222.043274fe.js +1 -0
  100. package/dist/console/static/js/async/5362.f498001c.js +1 -0
  101. package/dist/console/static/js/async/54.c94f0755.js +1 -0
  102. package/dist/console/static/js/async/5478.50dd9ef0.js +2 -0
  103. package/dist/console/static/js/async/5478.50dd9ef0.js.LICENSE.txt +3 -0
  104. package/dist/console/static/js/async/5507.a6a1f793.js +1 -0
  105. package/dist/console/static/js/async/5638.bc6b102d.js +1 -0
  106. package/dist/console/static/js/async/5722.e0029049.js +1 -0
  107. package/dist/console/static/js/async/5942.74635c6b.js +1 -0
  108. package/dist/console/static/js/async/5994.1c5629c1.js +1 -0
  109. package/dist/console/static/js/async/6054.6bddf720.js +1 -0
  110. package/dist/console/static/js/async/6118.45e754e5.js +1 -0
  111. package/dist/console/static/js/async/6127.adcbcbb6.js +1 -0
  112. package/dist/console/static/js/async/614.3f434c20.js +1 -0
  113. package/dist/console/static/js/async/6234.ba3b002d.js +1 -0
  114. package/dist/console/static/js/async/6310.6546a9ba.js +1 -0
  115. package/dist/console/static/js/async/6378.9f805419.js +1 -0
  116. package/dist/console/static/js/async/6380.e4433c49.js +1 -0
  117. package/dist/console/static/js/async/6418.f23bcfda.js +1 -0
  118. package/dist/console/static/js/async/6428.77c86114.js +1 -0
  119. package/dist/console/static/js/async/6443.83318a6c.js +1 -0
  120. package/dist/console/static/js/async/6508.2b445d62.js +3 -0
  121. package/dist/console/static/js/async/6542.e82a26c8.js +1 -0
  122. package/dist/console/static/js/async/6544.62111ecb.js +1 -0
  123. package/dist/console/static/js/async/6612.a0c9fcf4.js +1 -0
  124. package/dist/console/static/js/async/6740.695aebf0.js +1 -0
  125. package/dist/console/static/js/async/6822.dbbb32bc.js +1 -0
  126. package/dist/console/static/js/async/6824.ad3540ab.js +1 -0
  127. package/dist/console/static/js/async/6930.585dab94.js +1 -0
  128. package/dist/console/static/js/async/6982.c81b95e6.js +1 -0
  129. package/dist/console/static/js/async/7046.ab2378c1.js +1 -0
  130. package/dist/console/static/js/async/7110.a603277f.js +1 -0
  131. package/dist/console/static/js/async/7142.4a21366f.js +1 -0
  132. package/dist/console/static/js/async/7348.15cc6148.js +1373 -0
  133. package/dist/console/static/js/async/7348.15cc6148.js.LICENSE.txt +14 -0
  134. package/dist/console/static/js/async/7374.b1ac5c44.js +1 -0
  135. package/dist/console/static/js/async/742.847f17ca.js +1 -0
  136. package/dist/console/static/js/async/7446.743954d8.js +1 -0
  137. package/dist/console/static/js/async/7673.59bbbaac.js +1 -0
  138. package/dist/console/static/js/async/7684.c5760c8c.js +1 -0
  139. package/dist/console/static/js/async/7714.c30d0f94.js +1 -0
  140. package/dist/console/static/js/async/8118.36d5a3bf.js +298 -0
  141. package/dist/console/static/js/async/8145.4bcf043a.js +1 -0
  142. package/dist/console/static/js/async/8246.408de938.js +1 -0
  143. package/dist/console/static/js/async/8390.bdae1f7d.js +1 -0
  144. package/dist/console/static/js/async/8422.fd94dbe1.js +1 -0
  145. package/dist/console/static/js/async/8434.94a0e2ae.js +1 -0
  146. package/dist/console/static/js/async/8518.3158de13.js +1 -0
  147. package/dist/console/static/js/async/8564.fc2eb841.js +1 -0
  148. package/dist/console/static/js/async/8678.73af4c9b.js +1 -0
  149. package/dist/console/static/js/async/8694.79747168.js +1 -0
  150. package/dist/console/static/js/async/8756.1de37b83.js +1 -0
  151. package/dist/console/static/js/async/8804.7fe6bdf9.js +3 -0
  152. package/dist/console/static/js/async/8883.e717ee94.js +1 -0
  153. package/dist/console/static/js/async/8886.fe6e876c.js +1 -0
  154. package/dist/console/static/js/async/9030.fc1ae402.js +1 -0
  155. package/dist/console/static/js/async/9094.5598d084.js +1 -0
  156. package/dist/console/static/js/async/9218.ee7b84b7.js +1 -0
  157. package/dist/console/static/js/async/94.9b80bc35.js +1 -0
  158. package/dist/console/static/js/async/9526.92aba34c.js +1 -0
  159. package/dist/console/static/js/async/9762.f83bc4f3.js +1 -0
  160. package/dist/console/static/js/async/984.e11c113a.js +1 -0
  161. package/dist/console/static/js/async/9846.246653cd.js +1 -0
  162. package/dist/console/static/js/index.4487e1ff.js +1 -0
  163. package/dist/console/static/js/lib-react.15d7ca9a.js +2 -0
  164. package/dist/console/static/js/lib-react.15d7ca9a.js.LICENSE.txt +49 -0
  165. package/dist/coze-C6PMDPBI.js +49 -0
  166. package/dist/coze-E6VGRNLV.js +48 -0
  167. package/dist/dashboard.command-J7XOZNXU.js +8 -0
  168. package/dist/dashboard.command-RV2NHDKW.js +7 -0
  169. package/dist/dingtalk-JNRNRN7E.js +77 -0
  170. package/dist/dingtalk-WZGGIAHJ.js +76 -0
  171. package/dist/douyin-miniprogram-AIJPPIZH.js +41 -0
  172. package/dist/douyin-miniprogram-HCYZ5NBW.js +42 -0
  173. package/dist/figma-2YYNSCDX.js +103 -0
  174. package/dist/figma-RYOBMENP.js +102 -0
  175. package/dist/firebase-2IJDDBXX.js +112 -0
  176. package/dist/firebase-OYSY6HPT.js +111 -0
  177. package/dist/firecrawl-2T3SBUW7.js +66 -0
  178. package/dist/firecrawl-IYYXLAZM.js +65 -0
  179. package/dist/flyai-7FJ4TRAG.js +81 -0
  180. package/dist/flyai-QS5Q6FJR.js +82 -0
  181. package/dist/gitagent-MWI75OIX.js +725 -0
  182. package/dist/gitagent-YBMWY7NZ.js +726 -0
  183. package/dist/gitee-3N7OFOM7.js +53 -0
  184. package/dist/gitee-KVNK6KLZ.js +54 -0
  185. package/dist/github-LUEC2LID.js +143 -0
  186. package/dist/github-XRO5Z3GC.js +142 -0
  187. package/dist/google-ads-A3QAJI4D.js +88 -0
  188. package/dist/google-ads-VPKWTX67.js +89 -0
  189. package/dist/google-analytics-C4UR5ZR2.js +50 -0
  190. package/dist/google-analytics-XDYZA2B7.js +49 -0
  191. package/dist/google-workspace-LL3EWVHH.js +320 -0
  192. package/dist/google-workspace-YX35SHHX.js +321 -0
  193. package/dist/huawei-xiaoyi-6BSMGJHR.js +40 -0
  194. package/dist/huawei-xiaoyi-KPWLTSHB.js +41 -0
  195. package/dist/hubspot-DIUHGEDI.js +45 -0
  196. package/dist/hubspot-FTIEMNZO.js +44 -0
  197. package/dist/huggingface-MJCOXA7E.js +116 -0
  198. package/dist/huggingface-UUXK2RHK.js +117 -0
  199. package/dist/index.d.ts +3013 -0
  200. package/dist/index.js +15649 -0
  201. package/dist/inference-ai-image-generation-CMI6R5T3.js +106 -0
  202. package/dist/inference-ai-image-generation-PXV6IG4U.js +107 -0
  203. package/dist/inference-sh-7AZOLEFI.js +94 -0
  204. package/dist/inference-sh-ABQOD3YF.js +95 -0
  205. package/dist/init.command-6E24K4H3.js +9 -0
  206. package/dist/init.command-O4HG4HKR.js +10 -0
  207. package/dist/klaviyo-6K5YEFNH.js +45 -0
  208. package/dist/klaviyo-LDPBWBSS.js +44 -0
  209. package/dist/kuaidi100-HGFM5VK2.js +42 -0
  210. package/dist/kuaidi100-UHPFCVXP.js +41 -0
  211. package/dist/lark-6LNA3LUQ.js +103 -0
  212. package/dist/lark-URVBZNS4.js +102 -0
  213. package/dist/linear-7QFSFPOD.js +57 -0
  214. package/dist/linear-T4ORUP7N.js +56 -0
  215. package/dist/lovart-PDUXRUHJ.js +99 -0
  216. package/dist/lovart-QO3SK55T.js +100 -0
  217. package/dist/meta-ads-SCNFI45S.js +42 -0
  218. package/dist/meta-ads-V6XPZWX3.js +41 -0
  219. package/dist/miclaw-5CNTW7VV.js +36 -0
  220. package/dist/miclaw-TPPPS2WN.js +35 -0
  221. package/dist/model-provider-AVSFJSZP.js +393 -0
  222. package/dist/model-provider-KFB76XV5.js +392 -0
  223. package/dist/notion-FZK76MN2.js +69 -0
  224. package/dist/notion-WFA7KGZZ.js +70 -0
  225. package/dist/oceanengine-3JZUS3PP.js +43 -0
  226. package/dist/oceanengine-5BRIJVJE.js +42 -0
  227. package/dist/opencli-PFXHGCS2.js +81 -0
  228. package/dist/opencli-VIGRJTGH.js +80 -0
  229. package/dist/paypal-33UADIPR.js +54 -0
  230. package/dist/paypal-Z5JYHIWD.js +55 -0
  231. package/dist/playwright-MG5WHK47.js +58 -0
  232. package/dist/playwright-SQAQ3DZG.js +59 -0
  233. package/dist/plugins-HZBWK3WQ.js +120 -0
  234. package/dist/plugins-I4GD5SZX.js +121 -0
  235. package/dist/posthog-MU5MAJOQ.js +79 -0
  236. package/dist/posthog-RJRRKDWB.js +80 -0
  237. package/dist/salesforce-34FVIJTG.js +82 -0
  238. package/dist/salesforce-3QZ6OFVO.js +83 -0
  239. package/dist/sentry-MCIRMACU.js +111 -0
  240. package/dist/sentry-PIWW46VA.js +110 -0
  241. package/dist/seo-suite-4SQ3I67Q.js +54 -0
  242. package/dist/seo-suite-WJXMA3S4.js +55 -0
  243. package/dist/serve.command-5FMIPQRY.js +10 -0
  244. package/dist/serve.command-DNE6GPMK.js +9 -0
  245. package/dist/shadowob-JELOWHWX.js +1068 -0
  246. package/dist/shadowob-PRSMI5MW.js +1069 -0
  247. package/dist/sherlock-2PKY2E2Y.js +66 -0
  248. package/dist/sherlock-C5ZWPPVT.js +67 -0
  249. package/dist/shopify-GL3NFVGE.js +94 -0
  250. package/dist/shopify-R4G3UXM6.js +93 -0
  251. package/dist/skill-discovery-7INAUP4D.js +77 -0
  252. package/dist/skill-discovery-YPXXV622.js +78 -0
  253. package/dist/state-7MCZBTR5.js +17 -0
  254. package/dist/state-FGOFLFBE.js +18 -0
  255. package/dist/stripe-C22RR4ZS.js +83 -0
  256. package/dist/stripe-LJNPQ3CQ.js +82 -0
  257. package/dist/supabase-IRNQ54FJ.js +98 -0
  258. package/dist/supabase-N4ONFJNQ.js +97 -0
  259. package/dist/taobao-aipaas-LRR4GMO3.js +45 -0
  260. package/dist/taobao-aipaas-RVKORSF4.js +46 -0
  261. package/dist/tapd-3JPVJ7XH.js +46 -0
  262. package/dist/tapd-TMQRSMFG.js +47 -0
  263. package/dist/tencent-ads-IGD33LO7.js +42 -0
  264. package/dist/tencent-ads-UHC6OPBV.js +43 -0
  265. package/dist/tencent-docs-C3A4J3CJ.js +47 -0
  266. package/dist/tencent-docs-O2SC4FHL.js +48 -0
  267. package/dist/tencent-maps-HMMWMNF4.js +37 -0
  268. package/dist/tencent-maps-OQOKHVW2.js +36 -0
  269. package/dist/vercel-KOXDDTHX.js +73 -0
  270. package/dist/vercel-OLNVDWMG.js +74 -0
  271. package/dist/webflow-FULU5Q2I.js +114 -0
  272. package/dist/webflow-OMJKZM54.js +115 -0
  273. package/dist/wechat-miniprogram-skyline-KYCDMQNW.js +74 -0
  274. package/dist/wechat-miniprogram-skyline-VR4FVIQL.js +75 -0
  275. package/dist/wechat-pay-BCMAJ6UW.js +50 -0
  276. package/dist/wechat-pay-YQQKXVUI.js +51 -0
  277. package/dist/wonda-NGWIORYN.js +81 -0
  278. package/dist/wonda-RBABXFNM.js +82 -0
  279. package/dist/wordpress-woocommerce-RDIUTHYT.js +57 -0
  280. package/dist/wordpress-woocommerce-RNA5HB3N.js +58 -0
  281. package/dist/wps-DAEFQHDE.js +47 -0
  282. package/dist/wps-LUWHMZQQ.js +48 -0
  283. package/dist/yuque-HCHTJWNI.js +72 -0
  284. package/dist/yuque-KRH5O74J.js +71 -0
  285. package/images/RUNNERS.md +270 -0
  286. package/images/cc-connect-runner/entrypoint.mjs +311 -0
  287. package/images/claude-runner/Dockerfile +88 -0
  288. package/images/claude-runner/RUNNER.md +222 -0
  289. package/images/claude-runner/entrypoint.mjs +2 -0
  290. package/images/codex-runner/Dockerfile +87 -0
  291. package/images/codex-runner/RUNNER.md +226 -0
  292. package/images/codex-runner/entrypoint.mjs +2 -0
  293. package/images/gemini-runner/Dockerfile +87 -0
  294. package/images/gemini-runner/RUNNER.md +218 -0
  295. package/images/gemini-runner/entrypoint.mjs +2 -0
  296. package/images/hermes-runner/Dockerfile +74 -0
  297. package/images/hermes-runner/RUNNER.md +243 -0
  298. package/images/hermes-runner/entrypoint.mjs +283 -0
  299. package/images/openclaw-runner/Dockerfile +212 -0
  300. package/images/openclaw-runner/RUNNER.md +170 -0
  301. package/images/openclaw-runner/entrypoint.mjs +1113 -0
  302. package/images/openclaw-runner/warm-runtime-deps.mjs +95 -0
  303. package/images/opencode-runner/Dockerfile +87 -0
  304. package/images/opencode-runner/RUNNER.md +202 -0
  305. package/images/opencode-runner/entrypoint.mjs +2 -0
  306. package/package.json +121 -0
  307. package/templates/agent-marketplace-buddy.template.json +131 -0
  308. package/templates/ai-werewolf.template.json +92 -0
  309. package/templates/bmad-method-buddy.template.json +123 -0
  310. package/templates/brain-fix.template.json +92 -0
  311. package/templates/claude-ads-buddy.template.json +123 -0
  312. package/templates/claude-financial-services-buddy.template.json +111 -0
  313. package/templates/claude-seo-buddy.template.json +123 -0
  314. package/templates/code-arena.template.json +92 -0
  315. package/templates/daily-brief.template.json +92 -0
  316. package/templates/e-wife.template.json +92 -0
  317. package/templates/everything-claude-code-buddy.template.json +125 -0
  318. package/templates/financial-freedom.template.json +92 -0
  319. package/templates/gitstory.template.json +92 -0
  320. package/templates/google-workspace-buddy.template.json +88 -0
  321. package/templates/gsd-buddy.template.json +119 -0
  322. package/templates/gstack-buddy.template.json +143 -0
  323. package/templates/gstack.template.json +92 -0
  324. package/templates/little-match-girl.template.json +114 -0
  325. package/templates/lovart-buddy.template.json +110 -0
  326. package/templates/marketingskills-buddy.template.json +102 -0
  327. package/templates/retire-buddy.template.json +92 -0
  328. package/templates/scientific-skills-buddy.template.json +119 -0
  329. package/templates/seomachine-buddy.template.json +113 -0
  330. package/templates/shadow-server-app-demo.template.json +105 -0
  331. package/templates/slavingia-skills-buddy.template.json +102 -0
  332. package/templates/superclaude-buddy.template.json +146 -0
  333. package/templates/superpowers-buddy.template.json +108 -0
  334. package/templates/world-pulse.template.json +92 -0
@@ -0,0 +1,3013 @@
1
+ import { spawn, ChildProcess } from 'node:child_process';
2
+ import { z } from 'zod';
3
+ import { Command } from 'commander';
4
+ import { tags } from 'typia';
5
+ import * as _pulumi_pulumi_automation_stack_js from '@pulumi/pulumi/automation/stack.js';
6
+ import * as automation from '@pulumi/pulumi/automation/index.js';
7
+ import * as pulumi from '@pulumi/pulumi';
8
+
9
+ interface DeploymentRuntimeContext {
10
+ locale?: string;
11
+ timezone?: string;
12
+ }
13
+
14
+ /**
15
+ * Provision state — persists provisioned resource IDs to disk.
16
+ *
17
+ * State is saved to `.shadowob/provision-state.json` relative to the config file.
18
+ * This allows follow-up commands (status, logs, scale, down) to reference
19
+ * real IDs without re-provisioning.
20
+ *
21
+ * State file is gitignored (.shadowob/).
22
+ */
23
+ interface ProvisionState {
24
+ /** ISO timestamp of when provisioning last ran */
25
+ provisionedAt: string;
26
+ /** Stack name used during deployment (if any) */
27
+ stackName?: string;
28
+ /** K8s namespace deployed to (if any) */
29
+ namespace?: string;
30
+ /**
31
+ * Plugin-keyed state blobs. Each plugin owns its own schema under its plugin ID.
32
+ * e.g. plugins.shadowob = { servers: {...}, channels: {...}, buddies: {...} }
33
+ */
34
+ plugins: Record<string, Record<string, unknown>>;
35
+ }
36
+
37
+ declare const CLOUD_SAAS_RUNTIME_KEY = "__shadowobRuntime";
38
+ declare function validateCloudSaasConfigSnapshot(configSnapshot: unknown): Record<string, unknown>;
39
+ declare function prepareCloudSaasConfigSnapshot(configSnapshot: unknown, envVars?: Record<string, string>, context?: DeploymentRuntimeContext): Record<string, unknown>;
40
+ declare function attachCloudSaasProvisionState(configSnapshot: unknown, provisionState: ProvisionState): Record<string, unknown>;
41
+ declare function extractCloudSaasRuntime(configSnapshot: unknown): {
42
+ configSnapshot: Record<string, unknown> | null;
43
+ envVars: Record<string, string>;
44
+ context: DeploymentRuntimeContext;
45
+ provisionState: ProvisionState | null;
46
+ };
47
+ declare function resolveCloudSaasShadowRuntime(envVars?: Record<string, string>, processEnv?: Record<string, string | undefined>): {
48
+ shadowUrl?: string;
49
+ podShadowUrl?: string;
50
+ shadowToken?: string;
51
+ };
52
+ declare function redactCloudSaasConfigSnapshot(configSnapshot: unknown): unknown;
53
+ declare function sanitizeCloudSaasDeployment<T extends {
54
+ configSnapshot?: unknown;
55
+ }>(deployment: T): T;
56
+
57
+ declare function loadCloudConfigSchema(): Record<string, unknown>;
58
+
59
+ interface CloudConfigValidationSummary {
60
+ valid: boolean;
61
+ agents: number;
62
+ configurations: number;
63
+ violations: Array<{
64
+ path: string;
65
+ prefix: string;
66
+ }>;
67
+ extendsErrors: string[];
68
+ templateRefs: {
69
+ env: number;
70
+ secret: number;
71
+ file: number;
72
+ };
73
+ }
74
+ declare function summarizeCloudConfigValidation(configData: unknown): CloudConfigValidationSummary;
75
+
76
+ /**
77
+ * OpenClaw official config types.
78
+ * Based on https://docs.openclaw.ai/gateway/configuration-reference
79
+ */
80
+
81
+ /**
82
+ * OpenClaw model configuration.
83
+ * Accepts "provider/model" string form or object with primary + fallbacks.
84
+ */
85
+ interface OpenClawModelConfig {
86
+ /** Primary model in "provider/model" format */
87
+ primary: string;
88
+ /** Ordered fallback models */
89
+ fallbacks?: string[];
90
+ }
91
+ /**
92
+ * OpenClaw model catalog entry with alias and params.
93
+ */
94
+ interface OpenClawModelEntry {
95
+ /** Shortcut alias for /model command */
96
+ alias?: string;
97
+ /** Provider-specific params (temperature, maxTokens, etc.) */
98
+ params?: Record<string, unknown>;
99
+ }
100
+ /**
101
+ * OpenClaw agent defaults configuration.
102
+ */
103
+ interface OpenClawAgentDefaults {
104
+ /** Default workspace path */
105
+ workspace?: string;
106
+ /** Repository root for system prompt */
107
+ repoRoot?: string;
108
+ /** Skip bootstrap file creation */
109
+ skipBootstrap?: boolean;
110
+ /** Max chars per bootstrap file */
111
+ bootstrapMaxChars?: number & tags.Type<'uint32'>;
112
+ /** Max total bootstrap chars */
113
+ bootstrapTotalMaxChars?: number & tags.Type<'uint32'>;
114
+ /** Model config — string or { primary, fallbacks } */
115
+ model?: string | OpenClawModelConfig;
116
+ /** Image model config */
117
+ imageModel?: string | OpenClawModelConfig;
118
+ /** PDF model config */
119
+ pdfModel?: string | OpenClawModelConfig;
120
+ /** Image generation model config */
121
+ imageGenerationModel?: string | OpenClawModelConfig;
122
+ /** Model catalog keyed by "provider/model" */
123
+ models?: Record<string, OpenClawModelEntry>;
124
+ /** Default thinking level */
125
+ thinkingDefault?: 'off' | 'minimal' | 'low' | 'medium' | 'high' | 'xhigh' | 'adaptive';
126
+ /** Default verbose level */
127
+ verboseDefault?: 'off' | 'on' | 'full';
128
+ /** Default elevated-output level */
129
+ elevatedDefault?: 'off' | 'on' | 'ask' | 'full';
130
+ /** Timeout in seconds */
131
+ timeoutSeconds?: number & tags.Type<'uint32'>;
132
+ /** Media max size in MB */
133
+ mediaMaxMb?: number & tags.Type<'uint32'>;
134
+ /** Context token limit */
135
+ contextTokens?: number & tags.Type<'uint32'>;
136
+ /** Max concurrent agent runs */
137
+ maxConcurrent?: number & tags.Type<'uint32'>;
138
+ /** User timezone */
139
+ userTimezone?: string;
140
+ /** Timezone for inbound message envelope timestamps */
141
+ envelopeTimezone?: string;
142
+ /** Whether to include absolute timestamps in inbound message envelopes */
143
+ envelopeTimestamp?: 'on' | 'off';
144
+ /** Whether to include elapsed time suffixes in inbound message envelopes */
145
+ envelopeElapsed?: 'on' | 'off';
146
+ /** Time format */
147
+ timeFormat?: 'auto' | '12' | '24';
148
+ /** Heartbeat config */
149
+ heartbeat?: OpenClawHeartbeatConfig;
150
+ /** Compaction config */
151
+ compaction?: OpenClawCompactionConfig;
152
+ /** Sandbox config */
153
+ sandbox?: Record<string, unknown>;
154
+ /** Subagent defaults */
155
+ subagents?: OpenClawSubagentDefaults;
156
+ }
157
+ interface OpenClawHeartbeatConfig {
158
+ /** Interval duration string (e.g. "30m") */
159
+ every?: string;
160
+ /** Model for heartbeat runs */
161
+ model?: string;
162
+ /** Heartbeat prompt */
163
+ prompt?: string;
164
+ /** Session key */
165
+ session?: string;
166
+ /** Delivery target */
167
+ to?: string;
168
+ /** Target channel */
169
+ target?: string;
170
+ }
171
+ interface OpenClawCompactionConfig {
172
+ /** Compaction mode */
173
+ mode?: 'default' | 'safeguard';
174
+ /** Timeout in seconds */
175
+ timeoutSeconds?: number & tags.Type<'uint32'>;
176
+ /** Identifier policy */
177
+ identifierPolicy?: 'strict' | 'off' | 'custom';
178
+ /** Custom instructions for identifier preservation */
179
+ identifierInstructions?: string;
180
+ /** Model for compaction summarization */
181
+ model?: string;
182
+ }
183
+ interface OpenClawSubagentDefaults {
184
+ /** Default model for sub-agents */
185
+ model?: string;
186
+ /** Max concurrent sub-agents */
187
+ maxConcurrent?: number & tags.Type<'uint32'>;
188
+ /** Run timeout in seconds */
189
+ runTimeoutSeconds?: number & tags.Type<'uint32'>;
190
+ }
191
+ /**
192
+ * OpenClaw ACP runtime config for an agent.
193
+ */
194
+ interface OpenClawAcpRuntime {
195
+ /** ACP harness agent id (e.g. "claude", "codex") */
196
+ agent: string;
197
+ /** ACP backend id */
198
+ backend?: string;
199
+ /** Session mode */
200
+ mode?: 'persistent' | 'ephemeral';
201
+ /** Working directory inside the harness */
202
+ cwd?: string;
203
+ }
204
+ /**
205
+ * OpenClaw agent identity config.
206
+ */
207
+ interface OpenClawAgentIdentity {
208
+ /** Agent display name */
209
+ name?: string;
210
+ /** Theme description */
211
+ theme?: string;
212
+ /** Emoji identifier */
213
+ emoji?: string;
214
+ /** Avatar path or URL */
215
+ avatar?: string;
216
+ }
217
+ /**
218
+ * OpenClaw per-agent configuration (agents.list[] entry).
219
+ */
220
+ interface OpenClawAgentConfig {
221
+ /** Stable agent id (required) */
222
+ id: string;
223
+ /** Whether this is the default agent */
224
+ default?: boolean;
225
+ /** Agent display name */
226
+ name?: string;
227
+ /** Workspace path */
228
+ workspace?: string;
229
+ /** Agent dir override */
230
+ agentDir?: string;
231
+ /** Model override */
232
+ model?: string | OpenClawModelConfig;
233
+ /** Per-agent thinking level */
234
+ thinkingDefault?: 'off' | 'minimal' | 'low' | 'medium' | 'high' | 'xhigh' | 'adaptive';
235
+ /** Per-agent params merged over model catalog */
236
+ params?: Record<string, unknown>;
237
+ /** Agent identity */
238
+ identity?: OpenClawAgentIdentity;
239
+ /** Group chat mention patterns */
240
+ groupChat?: {
241
+ mentionPatterns?: string[];
242
+ };
243
+ /** Runtime descriptor */
244
+ runtime?: {
245
+ type: 'acp' | 'subagent';
246
+ acp?: OpenClawAcpRuntime;
247
+ };
248
+ /** Subagent allow rules */
249
+ subagents?: {
250
+ allowAgents?: string[];
251
+ };
252
+ /** Tool restrictions */
253
+ tools?: {
254
+ profile?: 'minimal' | 'coding' | 'messaging' | 'full' | 'dangerously-skip-permissions' | 'approve-reads' | 'approve-all' | 'deny-all';
255
+ allow?: string[];
256
+ deny?: string[];
257
+ elevated?: {
258
+ enabled?: boolean;
259
+ };
260
+ };
261
+ /** Sandbox config override */
262
+ sandbox?: Record<string, unknown>;
263
+ /** System prompt (convenience, non-standard) */
264
+ systemPrompt?: string;
265
+ /** Final instructions text (mapped from personality + systemPrompt) */
266
+ instructions?: string;
267
+ }
268
+ /**
269
+ * OpenClaw agents section.
270
+ */
271
+ interface OpenClawAgentsConfig {
272
+ /** Agent defaults */
273
+ defaults?: OpenClawAgentDefaults;
274
+ /** Per-agent list */
275
+ list?: OpenClawAgentConfig[];
276
+ }
277
+ /**
278
+ * OpenClaw ACP global config.
279
+ */
280
+ interface OpenClawAcpConfig {
281
+ /** Enable ACP feature */
282
+ enabled?: boolean;
283
+ /** Dispatch toggle */
284
+ dispatch?: {
285
+ enabled?: boolean;
286
+ };
287
+ /** Default ACP runtime backend id */
288
+ backend?: string;
289
+ /** Default ACP target agent id */
290
+ defaultAgent?: string;
291
+ /** Allowed agent ids for ACP sessions */
292
+ allowedAgents?: string[];
293
+ /** Max concurrent ACP sessions */
294
+ maxConcurrentSessions?: number & tags.Type<'uint32'>;
295
+ /** Stream config */
296
+ stream?: {
297
+ coalesceIdleMs?: number;
298
+ maxChunkChars?: number;
299
+ repeatSuppression?: boolean;
300
+ deliveryMode?: 'live' | 'final_only';
301
+ maxOutputChars?: number;
302
+ maxSessionUpdateChars?: number;
303
+ };
304
+ /** Runtime TTL */
305
+ runtime?: {
306
+ ttlMinutes?: number;
307
+ };
308
+ }
309
+ /**
310
+ * OpenClaw binding entry for multi-agent routing.
311
+ */
312
+ interface OpenClawBinding {
313
+ /** Agent to route to */
314
+ agentId: string;
315
+ /** Binding type */
316
+ type?: 'route' | 'acp';
317
+ /** Match criteria */
318
+ match: {
319
+ /** Channel name (e.g. "telegram", "discord", "shadowob") */
320
+ channel: string;
321
+ /** Account id or "*" for any */
322
+ accountId?: string;
323
+ /** Peer matching */
324
+ peer?: {
325
+ kind?: 'direct' | 'group' | 'channel';
326
+ id?: string;
327
+ };
328
+ /** Guild ID (Discord) */
329
+ guildId?: string;
330
+ /** Team ID (Teams) */
331
+ teamId?: string;
332
+ };
333
+ /** ACP binding config (only for type: "acp") */
334
+ acp?: {
335
+ mode?: string;
336
+ label?: string;
337
+ cwd?: string;
338
+ backend?: string;
339
+ };
340
+ }
341
+ /**
342
+ * OpenClaw channel-level DM/group policies.
343
+ */
344
+ interface OpenClawChannelBase {
345
+ /** Whether channel is enabled */
346
+ enabled?: boolean;
347
+ /** Channel-specific feature gates such as inline buttons or file uploads */
348
+ capabilities?: OpenClawChannelCapabilities;
349
+ /** DM policy */
350
+ dmPolicy?: 'pairing' | 'allowlist' | 'open' | 'disabled';
351
+ /** Allowed senders */
352
+ allowFrom?: string[];
353
+ /** Group policy */
354
+ groupPolicy?: 'allowlist' | 'open' | 'disabled';
355
+ /** History limit */
356
+ historyLimit?: number & tags.Type<'uint32'>;
357
+ /** Media max size in MB */
358
+ mediaMaxMb?: number & tags.Type<'uint32'>;
359
+ /** Streaming mode */
360
+ streaming?: 'off' | 'partial' | 'block' | 'progress';
361
+ /** Config writes toggle */
362
+ configWrites?: boolean;
363
+ }
364
+ interface OpenClawChannelCapabilities {
365
+ /** Inline button scope: off, DM-only, group-only, all, or allowlist */
366
+ inlineButtons?: 'off' | 'dm' | 'group' | 'all' | 'allowlist' | boolean;
367
+ /** Native interactive message support */
368
+ interactive?: boolean;
369
+ /** Native form message support */
370
+ forms?: boolean;
371
+ /** Plugin-specific feature gates */
372
+ [key: string]: unknown;
373
+ }
374
+ /**
375
+ * OpenClaw channels section — each channel key matches official docs.
376
+ */
377
+ interface OpenClawChannelsConfig {
378
+ /** Channel defaults */
379
+ defaults?: {
380
+ groupPolicy?: 'allowlist' | 'open' | 'disabled';
381
+ heartbeat?: {
382
+ showOk?: boolean;
383
+ showAlerts?: boolean;
384
+ useIndicator?: boolean;
385
+ };
386
+ };
387
+ /** Model overrides by channel ID */
388
+ modelByChannel?: Record<string, Record<string, string>>;
389
+ /** Telegram config */
390
+ telegram?: OpenClawChannelBase & {
391
+ botToken?: string;
392
+ groups?: Record<string, unknown>;
393
+ customCommands?: Array<{
394
+ command: string;
395
+ description: string;
396
+ }>;
397
+ replyToMode?: 'off' | 'first' | 'all';
398
+ linkPreview?: boolean;
399
+ };
400
+ /** Discord config */
401
+ discord?: OpenClawChannelBase & {
402
+ token?: string;
403
+ allowBots?: boolean | 'mentions';
404
+ guilds?: Record<string, unknown>;
405
+ replyToMode?: 'off' | 'first' | 'all';
406
+ textChunkLimit?: number;
407
+ chunkMode?: 'length' | 'newline';
408
+ };
409
+ /** Slack config */
410
+ slack?: OpenClawChannelBase & {
411
+ botToken?: string;
412
+ appToken?: string;
413
+ channels?: Record<string, unknown>;
414
+ allowBots?: boolean;
415
+ };
416
+ /** WhatsApp config */
417
+ whatsapp?: OpenClawChannelBase & {
418
+ textChunkLimit?: number;
419
+ chunkMode?: 'length' | 'newline';
420
+ sendReadReceipts?: boolean;
421
+ groups?: Record<string, unknown>;
422
+ };
423
+ /** Shadow/ShadowOB channel config */
424
+ shadowob?: OpenClawChannelBase & {
425
+ enabled?: boolean;
426
+ capabilities?: OpenClawChannelCapabilities;
427
+ accounts?: Record<string, {
428
+ token?: string;
429
+ serverUrl?: string;
430
+ enabled?: boolean;
431
+ capabilities?: OpenClawChannelCapabilities;
432
+ }>;
433
+ };
434
+ /** Additional channels (Google Chat, Signal, iMessage, etc.) */
435
+ [key: string]: unknown;
436
+ }
437
+ /**
438
+ * OpenClaw tools section.
439
+ */
440
+ interface OpenClawToolsConfig {
441
+ /** Tool profile */
442
+ profile?: 'minimal' | 'coding' | 'messaging' | 'full' | 'dangerously-skip-permissions' | 'approve-reads' | 'approve-all' | 'deny-all';
443
+ /** Allow specific tools */
444
+ allow?: string[];
445
+ /** Deny specific tools */
446
+ deny?: string[];
447
+ /** Read-only tools (approve-reads level) */
448
+ readOnly?: string[];
449
+ /** Behavior when approval is needed but no human is present */
450
+ nonInteractive?: 'deny' | 'fail';
451
+ /** Elevated exec config */
452
+ elevated?: {
453
+ enabled?: boolean;
454
+ allowFrom?: Record<string, string[]>;
455
+ };
456
+ /** Exec config */
457
+ exec?: {
458
+ backgroundMs?: number;
459
+ timeoutSec?: number;
460
+ };
461
+ /** Web tools config */
462
+ web?: {
463
+ search?: {
464
+ enabled?: boolean;
465
+ apiKey?: string;
466
+ maxResults?: number;
467
+ };
468
+ fetch?: {
469
+ enabled?: boolean;
470
+ maxChars?: number;
471
+ };
472
+ };
473
+ /** Sandbox tools */
474
+ sandbox?: Record<string, unknown>;
475
+ }
476
+ /**
477
+ * OpenClaw custom provider config.
478
+ */
479
+ interface OpenClawProviderConfig {
480
+ /** Provider ID */
481
+ id?: string;
482
+ /** API adapter type */
483
+ api?: string;
484
+ /** API key or SecretRef */
485
+ apiKey?: string;
486
+ /** Auth strategy */
487
+ auth?: string;
488
+ /** Upstream base URL */
489
+ baseUrl?: string;
490
+ /** Extra static headers */
491
+ headers?: Record<string, string>;
492
+ /** Transport overrides (e.g. allowPrivateNetwork for proxy environments) */
493
+ request?: {
494
+ allowPrivateNetwork?: boolean;
495
+ };
496
+ /** Provider model catalog */
497
+ models?: Array<{
498
+ id: string;
499
+ name?: string;
500
+ reasoning?: boolean;
501
+ input?: string[];
502
+ contextWindow?: number;
503
+ maxTokens?: number;
504
+ cost?: {
505
+ input?: number;
506
+ output?: number;
507
+ cacheRead?: number;
508
+ cacheWrite?: number;
509
+ };
510
+ }>;
511
+ }
512
+ /**
513
+ * OpenClaw models section.
514
+ */
515
+ interface OpenClawModelsConfig {
516
+ /** Merge mode */
517
+ mode?: 'merge' | 'replace';
518
+ /** Custom providers */
519
+ providers?: Record<string, OpenClawProviderConfig>;
520
+ }
521
+ /**
522
+ * OpenClaw plugins section.
523
+ */
524
+ interface OpenClawPluginsConfig {
525
+ /** Global enable/disable */
526
+ enabled?: boolean;
527
+ /** Plugin allowlist */
528
+ allow?: string[];
529
+ /** Plugin denylist */
530
+ deny?: string[];
531
+ /** Plugin load paths */
532
+ load?: {
533
+ paths?: string[];
534
+ };
535
+ /** Per-plugin config */
536
+ entries?: Record<string, {
537
+ enabled?: boolean;
538
+ config?: Record<string, unknown>;
539
+ hooks?: {
540
+ allowPromptInjection?: boolean;
541
+ };
542
+ }>;
543
+ }
544
+ /**
545
+ * OpenClaw skills section.
546
+ * Matches https://docs.openclaw.ai/gateway/configuration-reference#skills
547
+ */
548
+ interface OpenClawSkillsConfig {
549
+ /** Allowed bundled skills */
550
+ allowBundled?: string[];
551
+ /** Extra skill directories */
552
+ load?: {
553
+ extraDirs?: string[];
554
+ };
555
+ /** Installation preferences */
556
+ install?: {
557
+ preferBrew?: boolean;
558
+ nodeManager?: 'npm' | 'pnpm' | 'yarn';
559
+ };
560
+ /** Per-skill config */
561
+ entries?: Record<string, {
562
+ enabled?: boolean;
563
+ apiKey?: string;
564
+ env?: Record<string, string>;
565
+ config?: Record<string, unknown>;
566
+ }>;
567
+ }
568
+ /**
569
+ * OpenClaw gateway section.
570
+ */
571
+ interface OpenClawGatewayConfig {
572
+ /** Gateway mode */
573
+ mode?: 'local' | 'remote';
574
+ /** Gateway port */
575
+ port?: number & tags.Type<'uint32'>;
576
+ /** Bind address */
577
+ bind?: string;
578
+ /** Auth config */
579
+ auth?: {
580
+ mode?: 'none' | 'token' | 'password' | 'trusted-proxy';
581
+ token?: string;
582
+ password?: string;
583
+ allowTailscale?: boolean;
584
+ };
585
+ /** TLS config */
586
+ tls?: {
587
+ enabled?: boolean;
588
+ certPath?: string;
589
+ keyPath?: string;
590
+ };
591
+ /** Reload behavior */
592
+ reload?: {
593
+ mode?: 'off' | 'restart' | 'hot' | 'hybrid';
594
+ debounceMs?: number;
595
+ };
596
+ }
597
+ /**
598
+ * OpenClaw session section.
599
+ */
600
+ interface OpenClawSessionConfig {
601
+ /** Session scope */
602
+ scope?: string;
603
+ /** DM session scope */
604
+ dmScope?: 'main' | 'per-peer' | 'per-channel-peer' | 'per-account-channel-peer';
605
+ /** Session reset config */
606
+ reset?: {
607
+ mode?: 'daily' | 'idle';
608
+ atHour?: number;
609
+ idleMinutes?: number;
610
+ };
611
+ /** Reset by chat type */
612
+ resetByType?: Record<string, {
613
+ mode?: 'daily' | 'idle';
614
+ atHour?: number;
615
+ idleMinutes?: number;
616
+ }>;
617
+ /** Reset triggers */
618
+ resetTriggers?: string[];
619
+ /** Session store path */
620
+ store?: string;
621
+ /** Thread bindings */
622
+ threadBindings?: {
623
+ enabled?: boolean;
624
+ idleHours?: number;
625
+ maxAgeHours?: number;
626
+ };
627
+ }
628
+ /**
629
+ * OpenClaw logging section.
630
+ * Matches https://docs.openclaw.ai/gateway/configuration-reference#logging
631
+ */
632
+ interface OpenClawLoggingConfig {
633
+ /** Log level */
634
+ level?: string;
635
+ /** Log file path */
636
+ file?: string;
637
+ /** Console log level */
638
+ consoleLevel?: string;
639
+ /** Console output style */
640
+ consoleStyle?: 'pretty' | 'compact' | 'json';
641
+ /** Redact sensitive data from tool output */
642
+ redactSensitive?: 'off' | 'tools';
643
+ }
644
+ /**
645
+ * OpenClaw messages section.
646
+ * Matches https://docs.openclaw.ai/gateway/configuration-reference#messages
647
+ */
648
+ interface OpenClawMessagesConfig {
649
+ /** Response prefix */
650
+ responsePrefix?: string;
651
+ /** Ack reaction emoji */
652
+ ackReaction?: string;
653
+ /** Ack reaction scope */
654
+ ackReactionScope?: 'group-mentions' | 'group-all' | 'direct' | 'all';
655
+ /** Remove ack after reply */
656
+ removeAckAfterReply?: boolean;
657
+ /** Message queue config */
658
+ queue?: {
659
+ mode?: 'collect' | 'steer' | 'followup' | 'queue' | 'interrupt';
660
+ debounceMs?: number;
661
+ cap?: number;
662
+ };
663
+ /** Group chat config */
664
+ groupChat?: {
665
+ historyLimit?: number;
666
+ };
667
+ }
668
+ /**
669
+ * Full OpenClaw config (openclaw.json format).
670
+ * Matches https://docs.openclaw.ai/gateway/configuration-reference
671
+ */
672
+ interface OpenClawConfig {
673
+ /** Agents section */
674
+ agents?: OpenClawAgentsConfig;
675
+ /** Multi-agent routing bindings */
676
+ bindings?: OpenClawBinding[];
677
+ /** Channel configs */
678
+ channels?: OpenClawChannelsConfig;
679
+ /** ACP config */
680
+ acp?: OpenClawAcpConfig;
681
+ /** Session config */
682
+ session?: OpenClawSessionConfig;
683
+ /** Messages config */
684
+ messages?: OpenClawMessagesConfig;
685
+ /** Tools config */
686
+ tools?: OpenClawToolsConfig;
687
+ /** Custom model providers */
688
+ models?: OpenClawModelsConfig;
689
+ /** Plugin config */
690
+ plugins?: OpenClawPluginsConfig;
691
+ /** Skill config */
692
+ skills?: OpenClawSkillsConfig;
693
+ /** Gateway config */
694
+ gateway?: OpenClawGatewayConfig;
695
+ /** Logging config */
696
+ logging?: OpenClawLoggingConfig;
697
+ /** Environment variables */
698
+ env?: Record<string, unknown>;
699
+ /** Additional top-level fields */
700
+ [key: string]: unknown;
701
+ }
702
+
703
+ /**
704
+ * GitAgent source and manifest types.
705
+ * Based on the gitagent standard (MIT): https://github.com/open-gitagent/gitagent
706
+ */
707
+
708
+ /**
709
+ * Git repository reference for an agent source.
710
+ */
711
+ interface GitSource {
712
+ /** Repository URL (https or ssh) */
713
+ url: string;
714
+ /** Branch, tag, or full SHA. Defaults to "main" */
715
+ ref?: string;
716
+ /**
717
+ * Subdirectory inside the repository that contains the agent definition
718
+ * (e.g. "agents/my-agent" in a monorepo). Defaults to repo root.
719
+ */
720
+ dir?: string;
721
+ /** Shallow clone depth. Defaults to 1 */
722
+ depth?: number & tags.Type<'uint32'>;
723
+ /**
724
+ * Name of a K8s Secret that contains an SSH private key for private repos.
725
+ * The secret must have a key named `ssh-privatekey`.
726
+ */
727
+ sshKeySecret?: string;
728
+ /**
729
+ * Name of a K8s Secret (or literal token via ${env:VAR}) for HTTPS auth.
730
+ * Used as: git clone https://<token>@host/repo
731
+ */
732
+ tokenSecret?: string;
733
+ }
734
+ /**
735
+ * How the agent source overlay is handled.
736
+ * - "init-container": At pod startup, an init container clones the repo and
737
+ * copies files to a shared EmptyDir volume. No build step required.
738
+ * - "build-image": Files are baked into the container image at `shadowob-cloud build` time
739
+ * using a multi-stage Dockerfile (no runtime git access in K8s).
740
+ */
741
+ type AgentSourceStrategy = 'init-container' | 'build-image';
742
+ /**
743
+ * Agent file source specification.
744
+ * Points the agent at a git repository (or local path) that follows the
745
+ * gitagent directory layout: SOUL.md, RULES.md, agent.yaml, skills/, tools/,
746
+ * hooks/, skillflows/, memory/, compliance/, etc.
747
+ */
748
+ interface AgentSource {
749
+ /** Git repository source */
750
+ git?: GitSource;
751
+ /**
752
+ * Local filesystem path (dev/CI mode).
753
+ * Resolved at `shadowob-cloud up` time and baked into a ConfigMap or
754
+ * used for local adapter pre-population.
755
+ */
756
+ path?: string;
757
+ /**
758
+ * Strategy for delivering source files into the container.
759
+ * Default: "init-container"
760
+ */
761
+ strategy?: AgentSourceStrategy;
762
+ /**
763
+ * Path inside the container where the agent source is mounted.
764
+ * OpenClaw reads SOUL.md, RULES.md, skills/, etc. from this directory.
765
+ * Default: "/agent"
766
+ */
767
+ mountPath?: string;
768
+ /**
769
+ * Specific file/directory patterns to copy from the source.
770
+ * Default: all standard gitagent files (SOUL.md, RULES.md, skills/, etc.)
771
+ * Use this to limit what gets overlaid.
772
+ */
773
+ include?: string[];
774
+ /**
775
+ * When true, the mounted directory is treated as a gitagent standard layout.
776
+ * The adapter will:
777
+ * - set OpenClaw's agentDir to mountPath (reads SOUL.md, RULES.md automatically)
778
+ * - parse agent.yaml model config and merge into agent.model
779
+ * - parse hooks/hooks.yaml and map to OpenClaw hooks
780
+ * - enumerate skillflows/*.yaml and map to agent.workflows
781
+ * - configure compliance from compliance/regulatory-map.yaml
782
+ * Default: true
783
+ */
784
+ gitagent?: boolean;
785
+ /**
786
+ * When strategy is "build-image": Docker registry to push the built image to.
787
+ * e.g. "ghcr.io/my-org/my-agent:latest"
788
+ * If omitted, uses a local image name based on agentId.
789
+ */
790
+ imageTag?: string;
791
+ }
792
+
793
+ /**
794
+ * Managed agents types — vault, permissions, networking.
795
+ */
796
+ /** Permission level for agent tools — maps to ACPX permission modes. */
797
+ type PermissionLevel = 'always-allow' | 'approve-reads' | 'always-ask' | 'deny-all';
798
+ /**
799
+ * Per-tool permission policy for an agent.
800
+ * Inspired by Claude Managed Agents' toolset-level permission control.
801
+ */
802
+ interface AgentPermissions {
803
+ /** Default permission level for all tools */
804
+ default: PermissionLevel;
805
+ /** Per-tool overrides — key is tool name, supports glob patterns (e.g. "mcp-*") */
806
+ tools?: Record<string, PermissionLevel>;
807
+ /** Behaviour when the agent runs non-interactively (no human in the loop) */
808
+ nonInteractive?: 'deny' | 'fail';
809
+ }
810
+ /**
811
+ * Per-agent networking policy configuration.
812
+ * Generates K8s NetworkPolicy resources to control egress.
813
+ */
814
+ interface AgentNetworking {
815
+ /** Network policy type */
816
+ type: 'unrestricted' | 'limited' | 'deny-all';
817
+ /** Allowed egress domains (requires Cilium for FQDN-level enforcement) */
818
+ allowedHosts?: string[];
819
+ /** Allow egress to MCP server endpoints (auto-extracted from agent config) */
820
+ allowMcpServers?: boolean;
821
+ /** Allow egress to package manager registries (npm, pypi, etc.) */
822
+ allowPackageManagers?: boolean;
823
+ }
824
+ /**
825
+ * Vault provider secret source — where to read a secret value from.
826
+ */
827
+ interface VaultSecretSource {
828
+ /** API key or token value (template ref: ${env:...}, ${file:...}, ${k8s:ns/secret/key}) */
829
+ apiKey?: string;
830
+ }
831
+ /**
832
+ * Vault configuration — per-agent secret isolation.
833
+ * Each vault generates an isolated K8s Secret containing only the keys an agent needs.
834
+ */
835
+ interface VaultConfig {
836
+ /** Provider API keys for this vault */
837
+ providers?: Record<string, VaultSecretSource>;
838
+ /** Additional named secrets */
839
+ secrets?: Record<string, string>;
840
+ }
841
+
842
+ /**
843
+ * Shadow plugin config types — servers, channels, buddies, bindings.
844
+ * Also defines the universal UseEntry type for the "use" pattern.
845
+ */
846
+
847
+ /**
848
+ * A single plugin declaration in the `use` array.
849
+ *
850
+ * @example
851
+ * { "plugin": "shadowob", "options": { "baseURL": "${env:SHADOWOB_BASE_URL}" } }
852
+ * { "plugin": "gitagent", "options": { "repo": "github.com/user/repo" } }
853
+ */
854
+ interface UseEntry {
855
+ /** Plugin identifier (e.g. "shadowob", "gitagent", "slack") */
856
+ plugin: string;
857
+ /** Plugin-specific options */
858
+ options?: Record<string, unknown>;
859
+ }
860
+
861
+ /**
862
+ * Agent runtime types.
863
+ */
864
+ type AgentRuntime = 'openclaw' | 'claude-code' | 'codex' | 'gemini' | 'opencode' | 'hermes';
865
+ /**
866
+ * Agent model configuration — mirrors gitagent's model section.
867
+ * Specifies primary model with ordered fallbacks and inference constraints.
868
+ */
869
+ interface AgentModel {
870
+ /** Primary model in "provider/model" format (e.g. "anthropic/claude-sonnet-4-5") */
871
+ preferred: string;
872
+ /** Ordered fallback models tried if primary is unavailable */
873
+ fallbacks?: string[];
874
+ /** Inference constraints */
875
+ constraints?: {
876
+ /** Sampling temperature 0.0–2.0 */
877
+ temperature?: number & tags.Minimum<0> & tags.Maximum<2>;
878
+ /** Max output tokens */
879
+ maxTokens?: number & tags.Type<'uint32'>;
880
+ /** Top-p sampling parameter */
881
+ topP?: number & tags.Minimum<0> & tags.Maximum<1>;
882
+ /** Thinking depth level */
883
+ thinkingLevel?: 'off' | 'minimal' | 'low' | 'medium' | 'high' | 'xhigh' | 'adaptive';
884
+ };
885
+ }
886
+ /**
887
+ * Agent identity / soul — who the agent is.
888
+ * Mirrors gitagent's SOUL.md concept, expressed inline in the config.
889
+ */
890
+ interface AgentIdentity {
891
+ /** Display name for the agent */
892
+ name?: string;
893
+ /** One-line description of what this agent does */
894
+ description?: string;
895
+ /**
896
+ * Personality, communication style, values, domain expertise.
897
+ * Free-form text injected before the main system prompt.
898
+ * Equivalent to SOUL.md content.
899
+ */
900
+ personality?: string;
901
+ /**
902
+ * Full system prompt override. When set, replaces any inherited prompt.
903
+ * If `personality` is also set, it is prepended to this value.
904
+ *
905
+ * **Priority** (highest to lowest):
906
+ * 1. `identity.systemPrompt` — overrides everything
907
+ * 2. `configuration.openclaw.agents[].systemPrompt` — OpenClaw agent level
908
+ * 3. `OpenClawAgentConfig.systemPrompt` — convenience field in config preset
909
+ *
910
+ * When `identity.personality` is also set, final prompt is:
911
+ * `${personality}\n\n${systemPrompt}`
912
+ */
913
+ systemPrompt?: string;
914
+ }
915
+ /**
916
+ * A single step in an agent workflow (SkillsFlow-style).
917
+ */
918
+ interface AgentWorkflowStep {
919
+ /** Skill name to invoke */
920
+ skill?: string;
921
+ /** Sub-agent ID to delegate to */
922
+ agent?: string;
923
+ /** Tool name to call */
924
+ tool?: string;
925
+ /** Step IDs that must complete before this step runs */
926
+ dependsOn?: string[];
927
+ /** Input mappings — supports ${{ steps.X.outputs.Y }} template syntax */
928
+ inputs?: Record<string, string>;
929
+ /** Per-step prompt injection — extra guidance appended to the step context */
930
+ prompt?: string;
931
+ /** Conditions that must be true for this step to run */
932
+ conditions?: string[];
933
+ }
934
+ /**
935
+ * Deterministic multi-step workflow — mirrors gitagent's SkillsFlow / workflows/*.yaml.
936
+ * Chains skills, agents, and tools with explicit dependencies and data flow.
937
+ */
938
+ interface AgentWorkflowDef {
939
+ /** Workflow identifier */
940
+ name: string;
941
+ /** Human-readable description */
942
+ description?: string;
943
+ /** Events or cron expressions that trigger this workflow */
944
+ triggers?: string[];
945
+ /** Cron schedule (e.g. "0 9 * * *" for 9am daily) */
946
+ schedule?: string;
947
+ /** Ordered/parallel steps keyed by step ID */
948
+ steps: Record<string, AgentWorkflowStep>;
949
+ /** Error handling config */
950
+ errorHandling?: {
951
+ onFailure?: 'retry' | 'notify' | 'abort';
952
+ notifyChannel?: string;
953
+ maxRetries?: number & tags.Type<'uint32'>;
954
+ };
955
+ }
956
+ /**
957
+ * Agent compliance/risk policy.
958
+ * Mirrors gitagent compliance fields in camelCase for internal usage.
959
+ */
960
+ interface AgentCompliance {
961
+ /** Risk tier for this agent's tasks */
962
+ riskTier?: 'low' | 'standard' | 'high' | 'critical';
963
+ /** Regulatory / governance frameworks to align with */
964
+ frameworks?: string[];
965
+ /** Human supervision level */
966
+ humanInTheLoop?: 'always' | 'conditional' | 'advisory' | 'none';
967
+ /** Enable audit logging */
968
+ auditLogging?: boolean;
969
+ /** Retention period for audit records (e.g. 90d) */
970
+ retentionPeriod?: string;
971
+ }
972
+ /**
973
+ * Team / agent pack metadata — groups agents into a cohesive named team.
974
+ * Inspired by CrewClaw's "Agent Packs" concept.
975
+ *
976
+ * @deprecated Template metadata should use top-level `title` and `description`.
977
+ */
978
+ interface TeamConfig {
979
+ /** Team display name */
980
+ name: string;
981
+ /** What this team does — appears in console and CLI output */
982
+ description?: string;
983
+ /** Default model applied to agents that don't set `agent.model` */
984
+ defaultModel?: AgentModel;
985
+ /** Default compliance policy applied to agents that don't set `agent.compliance` */
986
+ defaultCompliance?: AgentCompliance;
987
+ }
988
+ /**
989
+ * K8s resource requests/limits.
990
+ */
991
+ interface K8sResources {
992
+ cpu?: string;
993
+ memory?: string;
994
+ }
995
+ /**
996
+ * Shared workspace configuration — creates a PersistentVolumeClaim
997
+ * that is mounted into every agent container, so agents share a
998
+ * distributed filesystem that OpenClaw can discover.
999
+ */
1000
+ interface SharedWorkspaceConfig {
1001
+ /** Enable shared workspace across agents */
1002
+ enabled: boolean;
1003
+ /** Storage size (e.g. "5Gi") */
1004
+ storageSize?: string;
1005
+ /** Storage class name (empty for cluster default) */
1006
+ storageClassName?: string;
1007
+ /** Mount path inside containers */
1008
+ mountPath?: string;
1009
+ /** Access mode */
1010
+ accessMode?: 'ReadWriteOnce' | 'ReadWriteMany' | 'ReadOnlyMany';
1011
+ }
1012
+ type CloudWorkloadBackend = 'agent-sandbox' | 'deployment';
1013
+ type SandboxBackupDriver = 'volumeSnapshot' | 'restic';
1014
+ type SandboxWarmPoolUpdateStrategy = 'OnReplenish' | 'Recreate';
1015
+ interface AgentSandboxStateConfig {
1016
+ /** Enable the per-agent OpenClaw state PVC. Defaults to true for agent-sandbox. */
1017
+ enabled?: boolean;
1018
+ /** PVC size for /home/shadow/.openclaw. */
1019
+ size?: string;
1020
+ /** Storage class name (empty for cluster default). */
1021
+ storageClassName?: string;
1022
+ /** Access mode for the state PVC. */
1023
+ accessMode?: 'ReadWriteOnce' | 'ReadWriteMany' | 'ReadOnlyMany';
1024
+ }
1025
+ interface AgentSandboxLifecycleConfig {
1026
+ /** Enable Cloud-side automatic pause after idleSeconds. */
1027
+ autoPause?: boolean;
1028
+ /** Idle duration before automatic pause. */
1029
+ idleSeconds?: number & tags.Type<'uint32'>;
1030
+ /** Create a backup before pause. */
1031
+ backupBeforePause?: boolean;
1032
+ /** agent-sandbox shutdown policy. */
1033
+ shutdownPolicy?: 'Delete' | 'Retain';
1034
+ }
1035
+ interface AgentSandboxBackupConfig {
1036
+ /** Enable state backup. */
1037
+ enabled?: boolean;
1038
+ /** Preferred backup driver. */
1039
+ driver?: SandboxBackupDriver;
1040
+ /** Optional schedule expression interpreted by the Cloud control plane. */
1041
+ schedule?: string;
1042
+ /** Number of backups to retain. */
1043
+ retention?: number & tags.Type<'uint32'>;
1044
+ }
1045
+ interface AgentSandboxWarmPoolConfig {
1046
+ /**
1047
+ * Enable SandboxWarmPool. Disabled by default because current per-agent
1048
+ * Secret/env injection is not compatible with warm-pool adoption.
1049
+ */
1050
+ enabled?: boolean;
1051
+ /** Number of prewarmed sandboxes. */
1052
+ replicas?: number & tags.Type<'uint32'>;
1053
+ /** Warm-pool update strategy. */
1054
+ updateStrategy?: SandboxWarmPoolUpdateStrategy;
1055
+ }
1056
+ interface AgentSandboxConfig {
1057
+ /** RuntimeClass used by sandbox pods. Defaults to gvisor. */
1058
+ runtimeClassName?: string;
1059
+ /** Per-agent OpenClaw state volume config. */
1060
+ state?: AgentSandboxStateConfig;
1061
+ /** Pause/resume lifecycle config. */
1062
+ lifecycle?: AgentSandboxLifecycleConfig;
1063
+ /** Backup/restore config. */
1064
+ backup?: AgentSandboxBackupConfig;
1065
+ /** Warm pool config. */
1066
+ warmPool?: AgentSandboxWarmPoolConfig;
1067
+ }
1068
+ /**
1069
+ * Agent-level configuration that can extend a base config.
1070
+ */
1071
+ interface AgentConfiguration {
1072
+ /** Base configuration ID to extend from registry.configurations */
1073
+ extends?: string;
1074
+ /**
1075
+ * Model preferences resolved from registry.configurations preset.
1076
+ * Populated after extends resolution; lower priority than agent.model.
1077
+ */
1078
+ model?: AgentModel;
1079
+ /** OpenClaw config overrides (official format) */
1080
+ openclaw?: Partial<OpenClawConfig>;
1081
+ /** Additional pass-through fields */
1082
+ [key: string]: unknown;
1083
+ }
1084
+ /**
1085
+ * Agent deployment definition.
1086
+ */
1087
+ interface AgentDeployment {
1088
+ /** Unique agent ID */
1089
+ id: string;
1090
+ /** Runtime type */
1091
+ runtime: AgentRuntime;
1092
+ /** Custom container image */
1093
+ image?: string;
1094
+ /** Number of replicas */
1095
+ replicas?: number & tags.Minimum<0> & tags.Type<'uint32'>;
1096
+ /** Agent configuration (can extend a base config) */
1097
+ configuration: AgentConfiguration;
1098
+ /** K8s resource constraints */
1099
+ resources?: {
1100
+ requests?: K8sResources;
1101
+ limits?: K8sResources;
1102
+ };
1103
+ /** Extra environment variables */
1104
+ env?: Record<string, string>;
1105
+ /**
1106
+ * Agent identity / soul — who this agent is.
1107
+ * systemPrompt and personality are merged into the OpenClaw system prompt.
1108
+ * Equivalent to SOUL.md in the gitagent standard.
1109
+ */
1110
+ identity?: AgentIdentity;
1111
+ /**
1112
+ * Model preferences — overrides registry and team defaults.
1113
+ * Mirrors gitagent's `model` section: preferred primary + ordered fallbacks.
1114
+ */
1115
+ model?: AgentModel;
1116
+ /**
1117
+ * Compliance/risk policy for this agent.
1118
+ * Falls back to team.defaultCompliance when omitted.
1119
+ */
1120
+ compliance?: AgentCompliance;
1121
+ /**
1122
+ * Deterministic multi-step workflows this agent can run.
1123
+ * Mirrors gitagent's SkillsFlow workflows/*.yaml.
1124
+ */
1125
+ workflows?: AgentWorkflowDef[];
1126
+ /**
1127
+ * Per-agent plugin declarations (webpack-style "use" pattern).
1128
+ * Each entry specifies a plugin and its options.
1129
+ *
1130
+ * @example
1131
+ * [
1132
+ * { "plugin": "gitagent", "options": { "repo": "github.com/user/repo" } },
1133
+ * { "plugin": "stripe", "options": { "apiKey": "${vault:STRIPE_KEY}" } }
1134
+ * ]
1135
+ */
1136
+ use?: UseEntry[];
1137
+ /** Short description shown in console and CLI output */
1138
+ description?: string;
1139
+ /**
1140
+ * Agent source overlay — pulls files from a git repository or local path
1141
+ * into the container using the gitagent directory convention.
1142
+ *
1143
+ * When set, the agent container will have SOUL.md, RULES.md, skills/,
1144
+ * tools/, hooks/, etc. available at `source.mountPath` (default: /agent).
1145
+ * OpenClaw's agentDir is automatically configured to read from this path.
1146
+ *
1147
+ * Supports two strategies:
1148
+ * - "init-container": Runtime git clone via K8s init container (default)
1149
+ * - "build-image": Bake files into Docker image layer at build time
1150
+ */
1151
+ source?: AgentSource;
1152
+ /**
1153
+ * Vault reference — which vault to use for this agent's secrets.
1154
+ * Defaults to "default". Each vault generates an isolated K8s Secret.
1155
+ */
1156
+ vault?: string;
1157
+ /**
1158
+ * Per-tool permission policy.
1159
+ * Controls which tools can auto-execute vs. require human approval.
1160
+ * Maps to ACPX permission modes in the generated OpenClaw config.
1161
+ */
1162
+ permissions?: AgentPermissions;
1163
+ /**
1164
+ * Network egress policy for this agent's pods.
1165
+ * Generates a K8s NetworkPolicy resource.
1166
+ */
1167
+ networking?: AgentNetworking;
1168
+ /** agent-sandbox backend options. */
1169
+ sandbox?: AgentSandboxConfig;
1170
+ /**
1171
+ * Agent configuration version (semver).
1172
+ * Recorded in K8s Deployment annotations for rollback tracking.
1173
+ */
1174
+ version?: string;
1175
+ /** Change description for this version (stored in K8s annotations) */
1176
+ changelog?: string;
1177
+ }
1178
+ /**
1179
+ * Deployments section.
1180
+ */
1181
+ interface DeploymentsConfig {
1182
+ /** K8s namespace */
1183
+ namespace?: string;
1184
+ /** Kubernetes workload backend. Defaults to agent-sandbox for new deployments. */
1185
+ backend?: CloudWorkloadBackend;
1186
+ /** Default agent-sandbox options inherited by agents. */
1187
+ sandbox?: AgentSandboxConfig;
1188
+ /** Agent deployments */
1189
+ agents: AgentDeployment[];
1190
+ }
1191
+ /**
1192
+ * Registry configuration preset.
1193
+ */
1194
+ interface Configuration {
1195
+ /** Unique configuration ID */
1196
+ id: string;
1197
+ /**
1198
+ * Base configuration to inherit from.
1199
+ * Resolved recursively — child fields override parent.
1200
+ */
1201
+ extends?: string;
1202
+ /**
1203
+ * Model preset for agents using this configuration.
1204
+ * After extends resolution, merged into AgentConfiguration.model.
1205
+ * Priority: agent.model > configuration.model > team.defaultModel.
1206
+ */
1207
+ model?: AgentModel;
1208
+ /** OpenClaw config values */
1209
+ openclaw?: Partial<OpenClawConfig>;
1210
+ /** Additional pass-through fields */
1211
+ [key: string]: unknown;
1212
+ }
1213
+ /**
1214
+ * Registry section — reusable model provider, configuration presets, and vault definitions.
1215
+ */
1216
+ interface RegistryConfig {
1217
+ /** Custom LLM provider configurations */
1218
+ providers?: OpenClawProviderConfig[];
1219
+ /** Reusable configuration presets */
1220
+ configurations?: Configuration[];
1221
+ /**
1222
+ * Vault definitions for secret isolation.
1223
+ * Each agent references a vault by name (default: "default").
1224
+ * Per-agent K8s Secrets are generated with only the relevant keys.
1225
+ */
1226
+ vaults?: Record<string, VaultConfig>;
1227
+ }
1228
+ /**
1229
+ * Cloud-level skill entry — specifies a skill to load
1230
+ * from a registry or directory into the agent containers.
1231
+ */
1232
+ interface CloudSkillEntry {
1233
+ /** Skill identifier (npm package name or local directory name) */
1234
+ name: string;
1235
+ /** Skill source: "bundled" (built-in), "npm" (install from registry), or "path" (local directory) */
1236
+ source?: 'bundled' | 'npm' | 'path';
1237
+ /** For npm: package version. For path: directory on the host. */
1238
+ version?: string;
1239
+ /** For path source: the local directory path */
1240
+ path?: string;
1241
+ /** Whether skill is enabled */
1242
+ enabled?: boolean;
1243
+ /** Environment variables for this skill */
1244
+ env?: Record<string, string>;
1245
+ /** API key for this skill */
1246
+ apiKey?: string;
1247
+ }
1248
+ /**
1249
+ * Cloud-level skills configuration — manages skill installation
1250
+ * and distribution across agent containers.
1251
+ */
1252
+ interface CloudSkillsConfig {
1253
+ /** Directory inside the container where skills are installed */
1254
+ installDir?: string;
1255
+ /** Skills to distribute to agents */
1256
+ entries?: CloudSkillEntry[];
1257
+ }
1258
+
1259
+ /**
1260
+ * Top-level CloudConfig — the root shadowob-cloud.json schema.
1261
+ */
1262
+
1263
+ /**
1264
+ * Plugin instance config (legacy map form).
1265
+ * Kept for backward compatibility with existing templates and builder logic.
1266
+ */
1267
+ interface CloudPluginInstanceConfig {
1268
+ enabled?: boolean;
1269
+ config?: Record<string, unknown>;
1270
+ agents?: Record<string, {
1271
+ enabled?: boolean;
1272
+ config?: Record<string, unknown>;
1273
+ }>;
1274
+ secrets?: Record<string, string>;
1275
+ [key: string]: unknown;
1276
+ }
1277
+ /**
1278
+ * Top-level shadowob-cloud.json config.
1279
+ *
1280
+ * @title Shadow Cloud Configuration
1281
+ * @description Configuration file for deploying OpenClaw AI agents to Kubernetes.
1282
+ */
1283
+ interface CloudConfig {
1284
+ /** Config version */
1285
+ version: string;
1286
+ /** Stable kebab-case config/template slug */
1287
+ name?: string;
1288
+ /** Human-readable title for this deployment config (shown in console) */
1289
+ title?: string;
1290
+ /** Description of the customer value this agent team provides */
1291
+ description?: string;
1292
+ /** Deployment environment */
1293
+ environment?: 'development' | 'staging' | 'production';
1294
+ /** Active locale for i18n resolution (e.g. "en", "zh-CN"). Defaults to "en". */
1295
+ locale?: string;
1296
+ /**
1297
+ * Internationalization dictionary.
1298
+ * Keyed by locale → key → translated string.
1299
+ *
1300
+ * Template strings can reference translations via `${i18n:key}`.
1301
+ * The active locale is determined by `config.locale`.
1302
+ *
1303
+ * @example
1304
+ * {
1305
+ * "en": { "title": "Research Team", "description": "AI research agents" },
1306
+ * "zh-CN": { "title": "研究团队", "description": "AI 研究 Agent 集群" }
1307
+ * }
1308
+ */
1309
+ i18n?: Record<string, Record<string, string>>;
1310
+ /**
1311
+ * Team / agent pack definition.
1312
+ * Groups agents with shared defaults.
1313
+ *
1314
+ * @deprecated Template metadata should use top-level `title` and `description`.
1315
+ */
1316
+ team?: TeamConfig;
1317
+ /**
1318
+ * Global plugin declarations — webpack-style "use" pattern.
1319
+ * Each entry specifies a plugin id and optional configuration.
1320
+ *
1321
+ * @example
1322
+ * [
1323
+ * { "plugin": "shadowob", "options": { "baseURL": "${env:SHADOWOB_BASE_URL}" } },
1324
+ * { "plugin": "slack", "options": { "token": "${vault:SLACK_TOKEN}" } }
1325
+ * ]
1326
+ */
1327
+ use?: UseEntry[];
1328
+ /**
1329
+ * Legacy plugin declarations map.
1330
+ * Prefer `use`, but keep this field for compatibility during migration.
1331
+ */
1332
+ plugins?: Record<string, CloudPluginInstanceConfig>;
1333
+ /**
1334
+ * Reusable provider/configuration registry.
1335
+ * Also contains vault definitions (registry.vaults) for secret isolation.
1336
+ */
1337
+ registry?: RegistryConfig;
1338
+ /** K8s deployment definitions */
1339
+ deployments?: DeploymentsConfig;
1340
+ /** Shared workspace (distributed filesystem across agents) */
1341
+ workspace?: SharedWorkspaceConfig;
1342
+ /** Cloud-level skills registry */
1343
+ skills?: CloudSkillsConfig;
1344
+ }
1345
+
1346
+ /**
1347
+ * Core plugin system types — ModernJS-style setup(api) pattern.
1348
+ *
1349
+ * Every plugin calls definePlugin(manifest, setup) and exports the result.
1350
+ *
1351
+ * The setup function receives a PluginAPI object and registers hooks + capabilities
1352
+ * imperatively. This keeps all plugin logic in a single closure, enables conditional
1353
+ * hook registration, and makes plugin options natural via closure capture.
1354
+ *
1355
+ * @example
1356
+ * // Skill plugin with custom health check
1357
+ * export default definePlugin(manifest, (api) => {
1358
+ * api.addSkills({ bundled: ['github'] })
1359
+ * api.addCLI([{ name: 'gh', command: 'gh', description: 'GitHub CLI' }])
1360
+ * api.onBuildEnv((ctx) => ({ GITHUB_TOKEN: ctx.secrets.GITHUB_TOKEN }))
1361
+ * api.onHealthCheck(async (ctx) => ({ healthy: true, message: 'OK' }))
1362
+ * })
1363
+ *
1364
+ * @example
1365
+ * // Channel plugin with provision lifecycle
1366
+ * export default definePlugin(manifest, (api) => {
1367
+ * api.onBuildConfig(buildSlackConfig)
1368
+ * api.onProvision(async (ctx) => { ... })
1369
+ * api.onHealthCheck(async (ctx) => { ... })
1370
+ * })
1371
+ *
1372
+ * @example
1373
+ * // Use factory shorthand for standard patterns
1374
+ * export default defineSkillPlugin(manifest, {
1375
+ * skills: { bundled: ['github'], entries: [...] },
1376
+ * cli: [{ name: 'gh', command: 'gh', description: 'GitHub CLI' }],
1377
+ * })
1378
+ */
1379
+
1380
+ type PluginCategory = 'communication' | 'project-management' | 'ai-provider' | 'devops' | 'database' | 'productivity' | 'automation' | 'crm' | 'finance' | 'analytics' | 'media' | 'email' | 'calendar' | 'search' | 'code' | 'other';
1381
+ type PluginCapability = 'channel' | 'tool' | 'notification' | 'webhook' | 'data-source' | 'action' | 'auth-provider' | 'skill' | 'cli' | 'mcp' | 'config-builder' | 'config-resolver';
1382
+ type PluginAuthType = 'oauth2' | 'api-key' | 'token' | 'basic' | 'none';
1383
+ interface PluginAuthField {
1384
+ key: string;
1385
+ label: string;
1386
+ description?: string;
1387
+ required: boolean;
1388
+ sensitive: boolean;
1389
+ placeholder?: string;
1390
+ validation?: string;
1391
+ helpUrl?: string;
1392
+ }
1393
+ interface PluginOAuthConfig {
1394
+ authorizationUrl: string;
1395
+ tokenUrl: string;
1396
+ scopes: string[];
1397
+ pkce?: boolean;
1398
+ }
1399
+ interface PluginAuth {
1400
+ type: PluginAuthType;
1401
+ fields: PluginAuthField[];
1402
+ oauth?: PluginOAuthConfig;
1403
+ }
1404
+ interface PluginManifest {
1405
+ id: string;
1406
+ name: string;
1407
+ description: string;
1408
+ version: string;
1409
+ category: PluginCategory;
1410
+ icon: string;
1411
+ website?: string;
1412
+ docs?: string;
1413
+ auth: PluginAuth;
1414
+ config?: Record<string, unknown>;
1415
+ capabilities: PluginCapability[];
1416
+ tags: string[];
1417
+ popularity?: number;
1418
+ }
1419
+ type PluginMCPTransport = 'stdio' | 'sse' | 'http' | 'streamable-http';
1420
+ /** MCP server config (prefer skills+cli for most integrations). */
1421
+ interface PluginMCPServer {
1422
+ id?: string;
1423
+ transport: PluginMCPTransport;
1424
+ /** Command used by stdio MCP servers. */
1425
+ command?: string;
1426
+ args?: string[];
1427
+ /** URL used by remote HTTP, streamable HTTP, or SSE MCP servers. */
1428
+ url?: string;
1429
+ headers?: Record<string, string>;
1430
+ env?: Record<string, string>;
1431
+ description?: string;
1432
+ requiredEnv?: string[];
1433
+ auth?: {
1434
+ type: 'none' | 'bearer' | 'oauth2';
1435
+ tokenEnvKey?: string;
1436
+ scopes?: string[];
1437
+ };
1438
+ }
1439
+ interface PluginRuntimeDependency {
1440
+ id: string;
1441
+ kind: 'npm-global' | 'system-package' | 'binary' | 'shell';
1442
+ packages?: string[];
1443
+ command?: string[];
1444
+ targetPath?: string;
1445
+ binPath?: string;
1446
+ description?: string;
1447
+ }
1448
+ interface PluginRuntimeSource {
1449
+ id: string;
1450
+ kind: 'git' | 'local' | 'http-archive';
1451
+ url?: string;
1452
+ ref?: string;
1453
+ from?: string;
1454
+ targetPath: string;
1455
+ include?: string[];
1456
+ includePattern?: string;
1457
+ description?: string;
1458
+ }
1459
+ type ModelTag = 'default' | 'fast' | 'flash' | 'reasoning' | 'vision' | 'tools';
1460
+ interface ProviderModelEntry {
1461
+ /** Model ID within the provider. */
1462
+ id: string;
1463
+ /** Display name. Defaults to id. */
1464
+ name?: string;
1465
+ /** Capability tags used by selector plugins such as model-provider. */
1466
+ tags?: ModelTag[];
1467
+ contextWindow?: number;
1468
+ maxTokens?: number;
1469
+ cost?: {
1470
+ inputPerMillion?: number;
1471
+ outputPerMillion?: number;
1472
+ currency?: string;
1473
+ };
1474
+ capabilities?: {
1475
+ vision?: boolean;
1476
+ tools?: boolean;
1477
+ reasoning?: boolean;
1478
+ };
1479
+ }
1480
+ interface ProviderCatalog {
1481
+ /** Provider ID used in model refs, e.g. anthropic/claude-sonnet-4-5. */
1482
+ id: string;
1483
+ /** Provider API adapter identifier. */
1484
+ api: string;
1485
+ baseUrl?: string;
1486
+ /** Primary env var used to authenticate this provider. */
1487
+ envKey: string;
1488
+ /** Compatible aliases to sniff before falling back to envKey. */
1489
+ envKeyAliases?: string[];
1490
+ /** Optional base URL override env var. */
1491
+ baseUrlEnvKey?: string;
1492
+ /** Optional default model override env var. */
1493
+ modelEnvKey?: string;
1494
+ /** Lower number means higher selector priority. */
1495
+ priority?: number;
1496
+ /** Enables local env sniffing when no community profile is connected. Defaults to true. */
1497
+ allowEnvDetection?: boolean;
1498
+ models: ProviderModelEntry[];
1499
+ }
1500
+ interface PluginSecretField {
1501
+ key: string;
1502
+ label?: string;
1503
+ description?: string;
1504
+ required?: boolean;
1505
+ sensitive?: boolean;
1506
+ placeholder?: string;
1507
+ helpUrl?: string;
1508
+ /** Legacy or compatible env names that should resolve to this canonical field. */
1509
+ aliases?: string[];
1510
+ /** Whether this value must be present in the runtime container env. Defaults to true. */
1511
+ runtime?: boolean;
1512
+ }
1513
+ interface PluginOpenClawManifestPatch {
1514
+ /** Extension folder under /app/extensions, e.g. "shadowob". */
1515
+ extensionId?: string;
1516
+ /** Absolute manifest path, or path relative to /app. Prefer extensionId. */
1517
+ manifestPath?: string;
1518
+ /** Generic deep-merge patch for manifest fields. */
1519
+ merge?: Record<string, unknown>;
1520
+ channelEnvVars?: Record<string, string[]>;
1521
+ channelConfigs?: Record<string, unknown>;
1522
+ }
1523
+ type PluginRuntimeArtifactKind = 'shadow.slashCommands' | (string & {});
1524
+ interface PluginRuntimeArtifact {
1525
+ /** Stable consumer-facing artifact kind, e.g. "shadow.slashCommands". */
1526
+ kind: PluginRuntimeArtifactKind;
1527
+ /** Runtime-readable absolute path produced by the plugin. */
1528
+ path: string;
1529
+ /** Optional media type or format hint for future consumers. */
1530
+ mediaType?: string;
1531
+ }
1532
+ interface PluginCredentialFile {
1533
+ /** Env var containing file contents, e.g. GOOGLE_WORKSPACE_CLI_CREDENTIALS_JSON. */
1534
+ envKey: string;
1535
+ /** Absolute path to materialize inside the runtime container. */
1536
+ path: string;
1537
+ /** Octal file mode. Defaults to 0600. */
1538
+ mode?: string;
1539
+ }
1540
+ interface PluginVerificationCheck {
1541
+ id: string;
1542
+ label: string;
1543
+ kind: 'command' | 'http' | 'mcp-tool';
1544
+ command?: string[];
1545
+ http?: {
1546
+ method?: 'GET' | 'POST';
1547
+ url: string;
1548
+ headers?: Record<string, string>;
1549
+ body?: unknown;
1550
+ expectStatus?: number | number[];
1551
+ expectJsonPath?: string;
1552
+ };
1553
+ mcp?: {
1554
+ serverId: string;
1555
+ toolName: string;
1556
+ args?: unknown;
1557
+ };
1558
+ timeoutMs?: number;
1559
+ risk?: 'safe' | 'read' | 'write';
1560
+ /** All listed env vars must be present before running this check. */
1561
+ requiredEnv?: string[];
1562
+ /** At least one listed env var must be present before running this check. */
1563
+ requiredEnvAny?: string[];
1564
+ cleanup?: PluginVerificationCheck;
1565
+ }
1566
+ interface PluginShadowobRuntimeAccount {
1567
+ buddyId: string;
1568
+ buddyName?: string;
1569
+ buddyDescription?: string;
1570
+ tokenEnvKey: string;
1571
+ replyPolicy?: {
1572
+ mode: string;
1573
+ custom?: Record<string, unknown>;
1574
+ };
1575
+ }
1576
+ interface PluginShadowobRuntime {
1577
+ enabled: boolean;
1578
+ serverUrlEnvKey: string;
1579
+ accounts: PluginShadowobRuntimeAccount[];
1580
+ defaultAccountEnvKey?: string;
1581
+ capabilities?: Record<string, unknown>;
1582
+ }
1583
+ interface PluginRuntimeExtension {
1584
+ openclaw?: {
1585
+ manifestPatches?: PluginOpenClawManifestPatch[];
1586
+ };
1587
+ shadowob?: PluginShadowobRuntime;
1588
+ artifacts?: PluginRuntimeArtifact[];
1589
+ runtimeDependencies?: PluginRuntimeDependency[];
1590
+ skillSources?: PluginRuntimeSource[];
1591
+ subagentSources?: PluginRuntimeSource[];
1592
+ mcpServers?: PluginMCPServer[];
1593
+ credentialFiles?: PluginCredentialFile[];
1594
+ verificationChecks?: PluginVerificationCheck[];
1595
+ }
1596
+
1597
+ interface PluginCatalogEntry {
1598
+ id: string;
1599
+ name: string;
1600
+ description: string;
1601
+ category: PluginCategory;
1602
+ capabilities: PluginCapability[];
1603
+ tags: string[];
1604
+ authType: PluginManifest['auth']['type'];
1605
+ requiredFields: Array<{
1606
+ key: string;
1607
+ label: string;
1608
+ description?: string;
1609
+ sensitive: boolean;
1610
+ }>;
1611
+ }
1612
+ declare function listPluginCatalogs(): PluginCatalogEntry[];
1613
+
1614
+ interface PluginLibraryEntry {
1615
+ id: string;
1616
+ name: string;
1617
+ description: string;
1618
+ version: string;
1619
+ category: PluginCategory;
1620
+ capabilities: PluginCapability[];
1621
+ tags: string[];
1622
+ authType: PluginManifest['auth']['type'];
1623
+ website?: string;
1624
+ docs?: string;
1625
+ popularity?: number;
1626
+ manifest: PluginManifest;
1627
+ requiredFields: Array<{
1628
+ key: string;
1629
+ label: string;
1630
+ description?: string;
1631
+ sensitive: boolean;
1632
+ }>;
1633
+ readme: {
1634
+ title: string;
1635
+ excerpt: string;
1636
+ headings: string[];
1637
+ };
1638
+ searchText: string;
1639
+ }
1640
+ interface PluginLibrarySearchResult extends PluginLibraryEntry {
1641
+ score: number;
1642
+ matchedTerms: string[];
1643
+ }
1644
+ declare function listPluginLibrary(): PluginLibraryEntry[];
1645
+ declare function searchPluginLibrary(query: string, options?: {
1646
+ limit?: number;
1647
+ includeIds?: string[];
1648
+ }): PluginLibrarySearchResult[];
1649
+ declare function getPluginLibraryEntry(id: string): PluginLibraryEntry | undefined;
1650
+
1651
+ interface ProviderCatalogEntry {
1652
+ pluginId: string;
1653
+ pluginName: string;
1654
+ provider: ProviderCatalog;
1655
+ secretFields: PluginSecretField[];
1656
+ }
1657
+ declare function listProviderCatalogs(): Promise<ProviderCatalogEntry[]>;
1658
+
1659
+ interface RuntimeEnvField {
1660
+ key: string;
1661
+ label: string;
1662
+ description?: string;
1663
+ required: boolean;
1664
+ sensitive: boolean;
1665
+ placeholder?: string;
1666
+ source: 'template' | 'plugin';
1667
+ sourceId: string;
1668
+ sourceLabel: string;
1669
+ helpUrl?: string;
1670
+ }
1671
+ interface RuntimeEnvRefPolicy {
1672
+ /** Env ref aliases that should be satisfied by a canonical field. */
1673
+ aliases: Record<string, string>;
1674
+ /** Env refs intentionally ignored by active plugins. */
1675
+ ignoredKeys: string[];
1676
+ /** Env refs that should not be exposed as standalone deploy fields. */
1677
+ hiddenKeys: string[];
1678
+ }
1679
+ /**
1680
+ * Collect runtime env keys a SaaS deployment may need from the plugin graph.
1681
+ *
1682
+ * This intentionally returns key names only. Values still come from the user's
1683
+ * encrypted Cloud env store, explicit deploy input, or local process.env fallback.
1684
+ */
1685
+ declare function collectRuntimeEnvRequirements(configSnapshot: unknown): Promise<string[]>;
1686
+ declare function collectRuntimeEnvRefPolicy(configSnapshot: unknown): Promise<RuntimeEnvRefPolicy>;
1687
+ declare function applyRuntimeEnvRefPolicy(envVars: Record<string, string>, policy: Pick<RuntimeEnvRefPolicy, 'aliases' | 'ignoredKeys'>): Record<string, string>;
1688
+ /**
1689
+ * Collect user-fillable runtime env slots for the deploy UI.
1690
+ *
1691
+ * This includes direct `${env:VAR}` template references plus fields declared by
1692
+ * plugins used by the template. The richer metadata lets Cloud render labels,
1693
+ * descriptions, sensitivity, required state, and placeholders without
1694
+ * hardcoding per-plugin forms.
1695
+ */
1696
+ declare function collectRuntimeEnvFields(configSnapshot: unknown): Promise<RuntimeEnvField[]>;
1697
+
1698
+ interface TemplateEnvRefPolicy {
1699
+ aliases?: Record<string, string>;
1700
+ ignoredKeys?: string[];
1701
+ }
1702
+ declare function extractRequiredEnvVars(config: unknown, policy?: TemplateEnvRefPolicy): string[];
1703
+
1704
+ interface TemplateLibraryEntry {
1705
+ slug: string;
1706
+ title: string;
1707
+ description: string;
1708
+ category: string;
1709
+ plugins: string[];
1710
+ channels: string[];
1711
+ buddyNames: string[];
1712
+ agentCount: number;
1713
+ systemPromptExcerpt: string;
1714
+ valid: boolean;
1715
+ validation: CloudConfigValidationSummary;
1716
+ searchText: string;
1717
+ }
1718
+ interface TemplateLibrarySearchResult extends TemplateLibraryEntry {
1719
+ score: number;
1720
+ matchedTerms: string[];
1721
+ }
1722
+ declare function listTemplateLibrary(): TemplateLibraryEntry[];
1723
+ declare function searchTemplateLibrary(query: string, options?: {
1724
+ limit?: number;
1725
+ }): TemplateLibrarySearchResult[];
1726
+
1727
+ type BillingUnit = 'usd' | 'shrimp';
1728
+ interface ProviderUsageSummary {
1729
+ provider: string;
1730
+ amountUsd: number | null;
1731
+ usageLabel: string | null;
1732
+ raw: string | null;
1733
+ inputTokens: number | null;
1734
+ outputTokens: number | null;
1735
+ totalTokens: number | null;
1736
+ }
1737
+ interface AgentCostSummary {
1738
+ agentName: string;
1739
+ podName: string | null;
1740
+ totalUsd: number | null;
1741
+ billingAmount: number | null;
1742
+ billingUnit: BillingUnit;
1743
+ totalTokens: number | null;
1744
+ providers: ProviderUsageSummary[];
1745
+ source: 'json' | 'text' | 'telemetry' | 'unavailable';
1746
+ message: string | null;
1747
+ }
1748
+ interface NamespaceCostSummary {
1749
+ namespace: string;
1750
+ totalUsd: number | null;
1751
+ billingAmount: number | null;
1752
+ billingUnit: BillingUnit;
1753
+ totalTokens: number | null;
1754
+ agents: AgentCostSummary[];
1755
+ availableAgents: number;
1756
+ unavailableAgents: number;
1757
+ generatedAt: string;
1758
+ }
1759
+ interface CostOverviewSummary {
1760
+ totalUsd: number | null;
1761
+ billingAmount: number | null;
1762
+ billingUnit: BillingUnit;
1763
+ totalTokens: number | null;
1764
+ namespaces: Array<{
1765
+ namespace: string;
1766
+ totalUsd: number | null;
1767
+ billingAmount: number | null;
1768
+ billingUnit: BillingUnit;
1769
+ totalTokens: number | null;
1770
+ agentCount: number;
1771
+ availableAgents: number;
1772
+ unavailableAgents: number;
1773
+ }>;
1774
+ generatedAt: string;
1775
+ }
1776
+ interface UsageCostPodSummary {
1777
+ name: string;
1778
+ status: string;
1779
+ age: string;
1780
+ }
1781
+ interface UsageCostExecResult {
1782
+ stdout: string;
1783
+ stderr: string;
1784
+ exitCode: number;
1785
+ }
1786
+ interface UsageCostRuntime {
1787
+ listPods(namespace: string, kubeconfig?: string): UsageCostPodSummary[];
1788
+ execInPod(opts: {
1789
+ namespace: string;
1790
+ pod: string;
1791
+ command: string[];
1792
+ kubeconfig?: string;
1793
+ timeout?: number;
1794
+ }): UsageCostExecResult;
1795
+ }
1796
+ interface ParsedUsageSnapshot {
1797
+ totalUsd: number | null;
1798
+ totalTokens: number | null;
1799
+ providers: ProviderUsageSummary[];
1800
+ source: 'json' | 'text';
1801
+ }
1802
+ declare const OPENCLAW_USAGE_COMMANDS: string[][];
1803
+ declare function parseOpenClawUsageOutput(stdout: string, stderr?: string): ParsedUsageSnapshot | null;
1804
+ declare function collectAgentUsage(opts: {
1805
+ namespace: string;
1806
+ agentName: string;
1807
+ runtime: UsageCostRuntime;
1808
+ kubeconfig?: string;
1809
+ }): Omit<AgentCostSummary, 'billingAmount' | 'billingUnit'>;
1810
+ declare function collectNamespaceCost(opts: {
1811
+ namespace: string;
1812
+ agentNames: string[];
1813
+ billingAmount: number | null;
1814
+ billingUnit: BillingUnit;
1815
+ runtime: UsageCostRuntime;
1816
+ kubeconfig?: string;
1817
+ }): NamespaceCostSummary;
1818
+ declare function summarizeCostOverview(summaries: NamespaceCostSummary[], billingUnit: BillingUnit): CostOverviewSummary;
1819
+
1820
+ /**
1821
+ * Runtime kubectl helper set used by SaaS orchestration and APIs.
1822
+ *
1823
+ * This module supports both explicit kubeconfig content and ambient kubeconfig
1824
+ * discovery from process env / local defaults. It also rewrites localhost
1825
+ * kubeconfig endpoints for containerized runtime access where needed.
1826
+ */
1827
+
1828
+ interface K8sPodSummary {
1829
+ name: string;
1830
+ ready: string;
1831
+ status: string;
1832
+ restarts: number;
1833
+ age: string;
1834
+ containers: string[];
1835
+ }
1836
+ interface K8sExecResult {
1837
+ stdout: string;
1838
+ stderr: string;
1839
+ exitCode: number;
1840
+ }
1841
+ type AgentSandboxRuntimeState = 'running' | 'paused' | 'resuming' | 'failed' | 'unknown';
1842
+ interface AgentSandboxStatus {
1843
+ name: string;
1844
+ sandboxName: string;
1845
+ replicas: number;
1846
+ ready: boolean;
1847
+ runtimeState: AgentSandboxRuntimeState;
1848
+ }
1849
+ interface VolumeSnapshotReadyStatus {
1850
+ ready: boolean;
1851
+ error?: string;
1852
+ }
1853
+ declare function resolveSandboxNameAsync(namespace: string, agentName: string, kubeconfig?: string): Promise<string>;
1854
+ declare function getAgentSandboxStatusAsync(namespace: string, agentName: string, kubeconfig?: string): Promise<AgentSandboxStatus>;
1855
+ declare function scaleAgentSandboxAsync(namespace: string, agentName: string, replicas: 0 | 1, kubeconfig?: string): Promise<void>;
1856
+ declare function waitForAgentSandboxReady(options: {
1857
+ namespace: string;
1858
+ agentName: string;
1859
+ kubeconfig?: string;
1860
+ timeoutMs?: number;
1861
+ intervalMs?: number;
1862
+ }): Promise<AgentSandboxStatus>;
1863
+ declare function waitForAgentSandboxPaused(options: {
1864
+ namespace: string;
1865
+ agentName: string;
1866
+ kubeconfig?: string;
1867
+ timeoutMs?: number;
1868
+ intervalMs?: number;
1869
+ }): Promise<AgentSandboxStatus>;
1870
+ declare function createVolumeSnapshotBackupAsync(options: {
1871
+ namespace: string;
1872
+ snapshotName: string;
1873
+ pvcName: string;
1874
+ volumeSnapshotClassName?: string;
1875
+ kubeconfig?: string;
1876
+ }): Promise<void>;
1877
+ declare function isVolumeSnapshotApiAvailable(options?: {
1878
+ kubeconfig?: string;
1879
+ }): Promise<boolean>;
1880
+ type PvcVolumeSnapshotCapability = {
1881
+ storageClassName: string | null;
1882
+ provisioner: string | null;
1883
+ isCsi: boolean;
1884
+ volumeSnapshotClassName: string | null;
1885
+ };
1886
+ declare function isPvcBackedByCsiProvisioner(options: {
1887
+ namespace: string;
1888
+ pvcName: string;
1889
+ kubeconfig?: string;
1890
+ }): Promise<boolean>;
1891
+ declare function getPvcVolumeSnapshotCapability(options: {
1892
+ namespace: string;
1893
+ pvcName: string;
1894
+ kubeconfig?: string;
1895
+ }): Promise<PvcVolumeSnapshotCapability>;
1896
+ declare function resolveVolumeSnapshotClassForPvc(options: {
1897
+ namespace: string;
1898
+ pvcName: string;
1899
+ kubeconfig?: string;
1900
+ }): Promise<string | null>;
1901
+ declare function getVolumeSnapshotReadyStatus(options: {
1902
+ namespace: string;
1903
+ snapshotName: string;
1904
+ kubeconfig?: string;
1905
+ }): Promise<VolumeSnapshotReadyStatus>;
1906
+ declare function waitForVolumeSnapshotReady(options: {
1907
+ namespace: string;
1908
+ snapshotName: string;
1909
+ kubeconfig?: string;
1910
+ timeoutMs?: number;
1911
+ intervalMs?: number;
1912
+ }): Promise<VolumeSnapshotReadyStatus>;
1913
+ declare function restorePvcFromVolumeSnapshot(options: {
1914
+ namespace: string;
1915
+ pvcName: string;
1916
+ snapshotName: string;
1917
+ kubeconfig?: string;
1918
+ accessModes?: string[];
1919
+ storage?: string;
1920
+ storageClassName?: string;
1921
+ timeoutMs?: number;
1922
+ }): Promise<void>;
1923
+ declare function listPods(namespace: string, kubeconfig?: string): K8sPodSummary[];
1924
+ declare function listPodsAsync(namespace: string, kubeconfig?: string): Promise<K8sPodSummary[]>;
1925
+ declare function spawnPodLogStream(opts: {
1926
+ namespace: string;
1927
+ pod: string;
1928
+ container?: string;
1929
+ follow?: boolean;
1930
+ tail?: number;
1931
+ kubeconfig?: string;
1932
+ }): {
1933
+ proc: ReturnType<typeof spawn>;
1934
+ cleanup: () => void;
1935
+ };
1936
+ declare function readPodLogs(opts: {
1937
+ namespace: string;
1938
+ pod: string;
1939
+ container?: string;
1940
+ tail?: number;
1941
+ timestamps?: boolean;
1942
+ kubeconfig?: string;
1943
+ timeout?: number;
1944
+ }): string;
1945
+ declare function readPodLogsAsync(opts: {
1946
+ namespace: string;
1947
+ pod: string;
1948
+ container?: string;
1949
+ tail?: number;
1950
+ timestamps?: boolean;
1951
+ kubeconfig?: string;
1952
+ timeout?: number;
1953
+ }): Promise<string>;
1954
+ declare function execInPod(opts: {
1955
+ namespace: string;
1956
+ pod: string;
1957
+ command: string[];
1958
+ container?: string;
1959
+ kubeconfig?: string;
1960
+ timeout?: number;
1961
+ }): K8sExecResult;
1962
+ declare function execInPodAsync(opts: {
1963
+ namespace: string;
1964
+ pod: string;
1965
+ command: string[];
1966
+ container?: string;
1967
+ kubeconfig?: string;
1968
+ timeout?: number;
1969
+ }): Promise<K8sExecResult>;
1970
+ declare function execInPodWithInputAsync(opts: {
1971
+ namespace: string;
1972
+ pod: string;
1973
+ command: string[];
1974
+ input: Buffer | string;
1975
+ container?: string;
1976
+ kubeconfig?: string;
1977
+ timeout?: number;
1978
+ }): Promise<K8sExecResult>;
1979
+ declare function applyKubernetesManifestAsync(manifest: Record<string, unknown>, kubeconfig?: string, timeout?: number): Promise<void>;
1980
+ declare function deleteKubernetesResourceAsync(options: {
1981
+ namespace: string;
1982
+ kind: string;
1983
+ name: string;
1984
+ kubeconfig?: string;
1985
+ timeoutMs?: number;
1986
+ }): Promise<void>;
1987
+ declare function waitForPodReadyAsync(options: {
1988
+ namespace: string;
1989
+ pod: string;
1990
+ kubeconfig?: string;
1991
+ timeoutMs?: number;
1992
+ }): Promise<void>;
1993
+ declare function listManagedNamespaces(kubeconfig?: string): string[] | null;
1994
+ declare function namespaceExists(namespace: string, kubeconfig?: string): boolean | null;
1995
+ declare function deleteNamespace(namespace: string, kubeconfig?: string): void;
1996
+
1997
+ /**
1998
+ * Cluster config schema — defines the shape of cluster.json.
1999
+ *
2000
+ * cluster.json describes bare servers to bootstrap into a k3s cluster.
2001
+ * Credentials use ${env:VAR} template syntax so secrets are never stored on disk.
2002
+ */
2003
+
2004
+ declare const NodeConfigSchema: z.ZodEffects<z.ZodObject<{
2005
+ /** Node role in the cluster */
2006
+ role: z.ZodEnum<["master", "worker"]>;
2007
+ /** Public IP or hostname */
2008
+ host: z.ZodString;
2009
+ /** SSH port (default: 22) */
2010
+ port: z.ZodDefault<z.ZodNumber>;
2011
+ /** SSH username */
2012
+ user: z.ZodString;
2013
+ /** Path to SSH private key (supports ~) — mutually inclusive with or exclusive of password */
2014
+ sshKeyPath: z.ZodOptional<z.ZodString>;
2015
+ /** SSH password — use ${env:VAR} to avoid storing plaintext */
2016
+ password: z.ZodOptional<z.ZodString>;
2017
+ }, "strip", z.ZodTypeAny, {
2018
+ host: string;
2019
+ port: number;
2020
+ user: string;
2021
+ role: "master" | "worker";
2022
+ password?: string | undefined;
2023
+ sshKeyPath?: string | undefined;
2024
+ }, {
2025
+ host: string;
2026
+ user: string;
2027
+ role: "master" | "worker";
2028
+ password?: string | undefined;
2029
+ port?: number | undefined;
2030
+ sshKeyPath?: string | undefined;
2031
+ }>, {
2032
+ host: string;
2033
+ port: number;
2034
+ user: string;
2035
+ role: "master" | "worker";
2036
+ password?: string | undefined;
2037
+ sshKeyPath?: string | undefined;
2038
+ }, {
2039
+ host: string;
2040
+ user: string;
2041
+ role: "master" | "worker";
2042
+ password?: string | undefined;
2043
+ port?: number | undefined;
2044
+ sshKeyPath?: string | undefined;
2045
+ }>;
2046
+ type NodeConfig = z.infer<typeof NodeConfigSchema>;
2047
+ declare const ClusterConfigSchema: z.ZodEffects<z.ZodObject<{
2048
+ $schema: z.ZodOptional<z.ZodString>;
2049
+ /** Cluster name — used as --cluster value */
2050
+ name: z.ZodString;
2051
+ /** Provider type (default: ssh) */
2052
+ provider: z.ZodDefault<z.ZodEnum<["ssh"]>>;
2053
+ /** List of nodes */
2054
+ nodes: z.ZodArray<z.ZodEffects<z.ZodObject<{
2055
+ /** Node role in the cluster */
2056
+ role: z.ZodEnum<["master", "worker"]>;
2057
+ /** Public IP or hostname */
2058
+ host: z.ZodString;
2059
+ /** SSH port (default: 22) */
2060
+ port: z.ZodDefault<z.ZodNumber>;
2061
+ /** SSH username */
2062
+ user: z.ZodString;
2063
+ /** Path to SSH private key (supports ~) — mutually inclusive with or exclusive of password */
2064
+ sshKeyPath: z.ZodOptional<z.ZodString>;
2065
+ /** SSH password — use ${env:VAR} to avoid storing plaintext */
2066
+ password: z.ZodOptional<z.ZodString>;
2067
+ }, "strip", z.ZodTypeAny, {
2068
+ host: string;
2069
+ port: number;
2070
+ user: string;
2071
+ role: "master" | "worker";
2072
+ password?: string | undefined;
2073
+ sshKeyPath?: string | undefined;
2074
+ }, {
2075
+ host: string;
2076
+ user: string;
2077
+ role: "master" | "worker";
2078
+ password?: string | undefined;
2079
+ port?: number | undefined;
2080
+ sshKeyPath?: string | undefined;
2081
+ }>, {
2082
+ host: string;
2083
+ port: number;
2084
+ user: string;
2085
+ role: "master" | "worker";
2086
+ password?: string | undefined;
2087
+ sshKeyPath?: string | undefined;
2088
+ }, {
2089
+ host: string;
2090
+ user: string;
2091
+ role: "master" | "worker";
2092
+ password?: string | undefined;
2093
+ port?: number | undefined;
2094
+ sshKeyPath?: string | undefined;
2095
+ }>, "many">;
2096
+ /** Optional k3s installer settings for restricted networks or pinned versions. */
2097
+ install: z.ZodOptional<z.ZodObject<{
2098
+ /** k3s release version. Example: v1.35.4+k3s1 */
2099
+ k3sVersion: z.ZodOptional<z.ZodString>;
2100
+ /** k3s release channel used when k3sVersion is omitted. */
2101
+ k3sChannel: z.ZodOptional<z.ZodString>;
2102
+ /** k3s channel endpoint used by the official install script. */
2103
+ k3sChannelUrl: z.ZodOptional<z.ZodString>;
2104
+ /** k3s release artifact URL prefix. */
2105
+ k3sArtifactUrl: z.ZodOptional<z.ZodString>;
2106
+ /** Common mirror shortcut. "cn" maps to Rancher's China mirror. */
2107
+ k3sMirror: z.ZodOptional<z.ZodString>;
2108
+ /** Registry prefix used by k3s for bundled system images. */
2109
+ systemDefaultRegistry: z.ZodOptional<z.ZodString>;
2110
+ /** Sandbox pause image used by k3s/containerd. Useful when Docker Hub is unreachable. */
2111
+ pauseImage: z.ZodOptional<z.ZodString>;
2112
+ }, "strip", z.ZodTypeAny, {
2113
+ k3sVersion?: string | undefined;
2114
+ k3sChannel?: string | undefined;
2115
+ k3sChannelUrl?: string | undefined;
2116
+ k3sArtifactUrl?: string | undefined;
2117
+ k3sMirror?: string | undefined;
2118
+ systemDefaultRegistry?: string | undefined;
2119
+ pauseImage?: string | undefined;
2120
+ }, {
2121
+ k3sVersion?: string | undefined;
2122
+ k3sChannel?: string | undefined;
2123
+ k3sChannelUrl?: string | undefined;
2124
+ k3sArtifactUrl?: string | undefined;
2125
+ k3sMirror?: string | undefined;
2126
+ systemDefaultRegistry?: string | undefined;
2127
+ pauseImage?: string | undefined;
2128
+ }>>;
2129
+ }, "strip", z.ZodTypeAny, {
2130
+ name: string;
2131
+ provider: "ssh";
2132
+ nodes: {
2133
+ host: string;
2134
+ port: number;
2135
+ user: string;
2136
+ role: "master" | "worker";
2137
+ password?: string | undefined;
2138
+ sshKeyPath?: string | undefined;
2139
+ }[];
2140
+ install?: {
2141
+ k3sVersion?: string | undefined;
2142
+ k3sChannel?: string | undefined;
2143
+ k3sChannelUrl?: string | undefined;
2144
+ k3sArtifactUrl?: string | undefined;
2145
+ k3sMirror?: string | undefined;
2146
+ systemDefaultRegistry?: string | undefined;
2147
+ pauseImage?: string | undefined;
2148
+ } | undefined;
2149
+ $schema?: string | undefined;
2150
+ }, {
2151
+ name: string;
2152
+ nodes: {
2153
+ host: string;
2154
+ user: string;
2155
+ role: "master" | "worker";
2156
+ password?: string | undefined;
2157
+ port?: number | undefined;
2158
+ sshKeyPath?: string | undefined;
2159
+ }[];
2160
+ provider?: "ssh" | undefined;
2161
+ install?: {
2162
+ k3sVersion?: string | undefined;
2163
+ k3sChannel?: string | undefined;
2164
+ k3sChannelUrl?: string | undefined;
2165
+ k3sArtifactUrl?: string | undefined;
2166
+ k3sMirror?: string | undefined;
2167
+ systemDefaultRegistry?: string | undefined;
2168
+ pauseImage?: string | undefined;
2169
+ } | undefined;
2170
+ $schema?: string | undefined;
2171
+ }>, {
2172
+ name: string;
2173
+ provider: "ssh";
2174
+ nodes: {
2175
+ host: string;
2176
+ port: number;
2177
+ user: string;
2178
+ role: "master" | "worker";
2179
+ password?: string | undefined;
2180
+ sshKeyPath?: string | undefined;
2181
+ }[];
2182
+ install?: {
2183
+ k3sVersion?: string | undefined;
2184
+ k3sChannel?: string | undefined;
2185
+ k3sChannelUrl?: string | undefined;
2186
+ k3sArtifactUrl?: string | undefined;
2187
+ k3sMirror?: string | undefined;
2188
+ systemDefaultRegistry?: string | undefined;
2189
+ pauseImage?: string | undefined;
2190
+ } | undefined;
2191
+ $schema?: string | undefined;
2192
+ }, {
2193
+ name: string;
2194
+ nodes: {
2195
+ host: string;
2196
+ user: string;
2197
+ role: "master" | "worker";
2198
+ password?: string | undefined;
2199
+ port?: number | undefined;
2200
+ sshKeyPath?: string | undefined;
2201
+ }[];
2202
+ provider?: "ssh" | undefined;
2203
+ install?: {
2204
+ k3sVersion?: string | undefined;
2205
+ k3sChannel?: string | undefined;
2206
+ k3sChannelUrl?: string | undefined;
2207
+ k3sArtifactUrl?: string | undefined;
2208
+ k3sMirror?: string | undefined;
2209
+ systemDefaultRegistry?: string | undefined;
2210
+ pauseImage?: string | undefined;
2211
+ } | undefined;
2212
+ $schema?: string | undefined;
2213
+ }>;
2214
+ type ClusterConfig = z.infer<typeof ClusterConfigSchema>;
2215
+ /** Persisted to ~/.shadow-cloud/clusters/<name>.json after successful init */
2216
+ interface ClusterMeta {
2217
+ name: string;
2218
+ masterHost: string;
2219
+ nodeCount: number;
2220
+ createdAt: string;
2221
+ kubeconfigPath: string;
2222
+ }
2223
+
2224
+ /**
2225
+ * Kubeconfig management — store and retrieve kubeconfigs for registered clusters.
2226
+ *
2227
+ * Kubeconfigs are stored at ~/.shadow-cloud/clusters/<name>.yaml
2228
+ * Metadata is stored at ~/.shadow-cloud/clusters/<name>.json
2229
+ */
2230
+
2231
+ /**
2232
+ * Load the kubeconfig path for a named cluster.
2233
+ * Throws if the cluster is not registered.
2234
+ */
2235
+ declare function loadKubeconfigPath(clusterName: string): string;
2236
+
2237
+ /**
2238
+ * Cluster config parser — read, validate, and resolve cluster.json.
2239
+ *
2240
+ * Supports ${env:VAR} template syntax in password fields.
2241
+ */
2242
+
2243
+ /**
2244
+ * Read and validate cluster.json from the given path.
2245
+ * Performs schema validation but does NOT resolve env vars yet
2246
+ * (credentials are resolved lazily at connection time via resolveNodeCredentials).
2247
+ */
2248
+ declare function readClusterConfig(filePath: string): ClusterConfig;
2249
+
2250
+ type NamedEnvVar = {
2251
+ name?: unknown;
2252
+ };
2253
+ declare const RESERVED_RUNTIME_ENV_KEYS: Set<string>;
2254
+ declare function isReservedRuntimeEnvKey(key: string): boolean;
2255
+ declare function assertNoReservedEnvOverrides<T extends NamedEnvVar>(baseEnvVars: T[], candidateEnvVars: T[], source: string): void;
2256
+
2257
+ /**
2258
+ * Logger interface — used by service layer for dependency injection.
2259
+ * Services depend on this interface, not the concrete implementation.
2260
+ */
2261
+ interface Logger {
2262
+ info(msg: string): void;
2263
+ success(msg: string): void;
2264
+ warn(msg: string): void;
2265
+ error(msg: string): void;
2266
+ step(msg: string): void;
2267
+ dim(msg: string): void;
2268
+ table(rows: Array<Record<string, string>>): void;
2269
+ }
2270
+
2271
+ /**
2272
+ * Cluster status — check SSH connectivity and k3s service state for each node.
2273
+ */
2274
+
2275
+ interface NodeStatus {
2276
+ host: string;
2277
+ role: NodeConfig['role'];
2278
+ reachable: boolean;
2279
+ k3sRunning?: boolean;
2280
+ k3sVersion?: string;
2281
+ error?: string;
2282
+ }
2283
+ interface ClusterStatus {
2284
+ clusterName: string;
2285
+ nodes: NodeStatus[];
2286
+ }
2287
+
2288
+ /**
2289
+ * ClusterService — orchestrates cluster lifecycle operations.
2290
+ *
2291
+ * Thin service layer that delegates to cluster/* modules.
2292
+ * Registered in the ServiceContainer for CLI command use.
2293
+ */
2294
+
2295
+ declare class ClusterService {
2296
+ /**
2297
+ * Bootstrap a k3s cluster on bare servers.
2298
+ */
2299
+ init(config: ClusterConfig, onLog?: (msg: string) => void, force?: boolean): Promise<ClusterMeta>;
2300
+ /**
2301
+ * Check SSH connectivity and k3s status on all nodes.
2302
+ */
2303
+ status(config: ClusterConfig): Promise<ClusterStatus>;
2304
+ /**
2305
+ * Uninstall k3s from all nodes and clean up local files.
2306
+ */
2307
+ destroy(config: ClusterConfig, onLog?: (msg: string) => void): Promise<void>;
2308
+ /**
2309
+ * List all clusters with stored kubeconfigs.
2310
+ */
2311
+ listClusters(): ClusterMeta[];
2312
+ /**
2313
+ * Resolve the kubeconfig file path for a named cluster.
2314
+ * Throws if the cluster is not registered.
2315
+ */
2316
+ resolveKubeconfig(clusterName: string): string;
2317
+ }
2318
+
2319
+ type RuntimeKind = 'openclaw' | 'cc-connect' | 'hermes';
2320
+ type RuntimeEnv = Record<string, string | undefined>;
2321
+ interface RuntimePackageBuildContext {
2322
+ agent: AgentDeployment;
2323
+ config: CloudConfig;
2324
+ cwd?: string;
2325
+ runtimeEnv: RuntimeEnv;
2326
+ runtimeExtensions: PluginRuntimeExtension;
2327
+ runtimeContext?: DeploymentRuntimeContext;
2328
+ }
2329
+ interface RuntimePackageBuildResult {
2330
+ openclawConfig?: OpenClawConfig;
2331
+ configData: Record<string, string>;
2332
+ pluginResources: Record<string, unknown>[];
2333
+ provisionSecrets?: Record<string, string>;
2334
+ }
2335
+ interface RuntimeContainerSpec {
2336
+ homeDir: string;
2337
+ healthPort: number;
2338
+ statePath: string;
2339
+ logPath: string;
2340
+ env: Array<{
2341
+ name: string;
2342
+ value: string;
2343
+ }>;
2344
+ }
2345
+ /**
2346
+ * Runtime adapter interface — one per supported runtime type. Package generation
2347
+ * lives with the concrete runtime so the shared infra layer does not know native
2348
+ * config details for Claude, Codex, OpenCode, Gemini, Hermes, or OpenClaw.
2349
+ */
2350
+ interface RuntimeAdapter {
2351
+ /** Runtime identifier (matches AgentRuntime type) */
2352
+ readonly id: AgentRuntime;
2353
+ /** Human-readable name */
2354
+ readonly name: string;
2355
+ /** Native runner package family. */
2356
+ readonly runtimeKind: RuntimeKind;
2357
+ /** Default container image when not overridden by user */
2358
+ readonly defaultImage: string;
2359
+ /** Kubernetes/container layout for this runtime. */
2360
+ readonly container: RuntimeContainerSpec;
2361
+ /** Build the runtime's ConfigMap payload and plugin resource artifacts. */
2362
+ buildPackage(context: RuntimePackageBuildContext): RuntimePackageBuildResult;
2363
+ }
2364
+
2365
+ /**
2366
+ * Template engine — resolves ${env:VAR}, ${secret:NAME}, ${file:PATH},
2367
+ * ${vault:KEY}, ${config:path.to.value}, and ${i18n:key} in config values.
2368
+ */
2369
+ interface TemplateContext {
2370
+ /** Environment variables (defaults to process.env) */
2371
+ env?: Record<string, string | undefined>;
2372
+ /** Pre-loaded secret values */
2373
+ secrets?: Record<string, string>;
2374
+ /** Vault secret values — resolved from registry.vaults */
2375
+ vaultSecrets?: Record<string, string>;
2376
+ /** The full config object (for ${config:path} resolution) */
2377
+ configRoot?: Record<string, unknown>;
2378
+ /** i18n dictionary for the active locale */
2379
+ i18nDict?: Record<string, string>;
2380
+ }
2381
+
2382
+ /**
2383
+ * Config parser — reads shadowob-cloud.json, validates with typia,
2384
+ * expands 'extends' references, resolves template variables,
2385
+ * and builds official OpenClaw config format.
2386
+ */
2387
+
2388
+ /**
2389
+ * Expand the 'extends' field in an agent configuration by merging
2390
+ * with the referenced base configuration from registry.configurations.
2391
+ * Supports chained Configuration extends (Configuration → Configuration).
2392
+ */
2393
+ declare function expandExtends(agentConfig: AgentConfiguration, configurations: Configuration[]): AgentConfiguration;
2394
+
2395
+ /**
2396
+ * Config security — inline key detection and validation.
2397
+ *
2398
+ * Scans shadowob-cloud.json for hardcoded API keys that should use
2399
+ * ${env:...} or ${secret:...} template references instead.
2400
+ */
2401
+ interface SecurityViolation {
2402
+ path: string;
2403
+ value: string;
2404
+ prefix: string;
2405
+ message: string;
2406
+ }
2407
+
2408
+ declare class ConfigService {
2409
+ /** Parse and validate a cloud config file using typia. */
2410
+ parseFile(filePath: string): Promise<CloudConfig>;
2411
+ /** Expand 'extends' references and resolve template variables. */
2412
+ resolve(config: CloudConfig, cwd?: string, templateCtx?: TemplateContext): Promise<CloudConfig>;
2413
+ /** Build OpenClaw config for a specific agent. */
2414
+ buildOpenClawConfig(agent: AgentDeployment, config: CloudConfig, cwd?: string, env?: Record<string, string | undefined>, runtimeContext?: DeploymentRuntimeContext): OpenClawConfig;
2415
+ /**
2416
+ * Full validation: parse + security check + collect template refs.
2417
+ * Returns the parsed config and any security violations found.
2418
+ */
2419
+ validate(filePath: string): Promise<{
2420
+ config: CloudConfig;
2421
+ violations: SecurityViolation[];
2422
+ }>;
2423
+ /**
2424
+ * Parse, validate, and resolve in one call.
2425
+ * Convenience for callers that need the final resolved config.
2426
+ */
2427
+ resolveFromFile(filePath: string, templateCtx?: TemplateContext): Promise<CloudConfig>;
2428
+ /** Detect inline API keys in config (SEC-01). */
2429
+ validateSecurity(config: CloudConfig): SecurityViolation[];
2430
+ /** Collect all ${env:...} and ${secret:...} references. */
2431
+ collectTemplateRefs(config: CloudConfig): {
2432
+ type: "env" | "secret" | "file" | "vault" | "config";
2433
+ key: string;
2434
+ raw: string;
2435
+ }[];
2436
+ /** Deep merge two objects (arrays replaced, not merged). */
2437
+ deepMerge<T extends Record<string, unknown>>(base: T, override: Partial<T>): T;
2438
+ /** Expand 'extends' in an agent configuration. */
2439
+ expandExtends(agentConfig: Parameters<typeof expandExtends>[0], configs: Configuration[]): AgentConfiguration;
2440
+ }
2441
+
2442
+ /**
2443
+ * kubectl operational commands — deployments, pods, logs, scaling.
2444
+ *
2445
+ * All functions shell out to `kubectl` for runtime cluster operations
2446
+ * (as opposed to Pulumi which handles declarative infrastructure).
2447
+ */
2448
+
2449
+ interface PodStatus {
2450
+ name: string;
2451
+ ready: string;
2452
+ status: string;
2453
+ restarts: string;
2454
+ age: string;
2455
+ }
2456
+ interface DeploymentStatus {
2457
+ name: string;
2458
+ ready: string;
2459
+ upToDate: string;
2460
+ available: string;
2461
+ age: string;
2462
+ workloadKind?: 'deployment' | 'agent-sandbox';
2463
+ runtimeState?: 'running' | 'paused' | 'resuming' | 'failed' | 'unknown';
2464
+ sandboxName?: string;
2465
+ serviceFQDN?: string;
2466
+ statePvc?: string;
2467
+ pausedAt?: string;
2468
+ lastActiveAt?: string;
2469
+ }
2470
+ interface CommandResult {
2471
+ stdout: string;
2472
+ stderr: string;
2473
+ exitCode: number;
2474
+ }
2475
+
2476
+ /**
2477
+ * Pulumi automation API client — stack lifecycle management.
2478
+ *
2479
+ * Uses Pulumi's programmatic automation API for creating, deploying,
2480
+ * and destroying K8s stacks without requiring the Pulumi CLI.
2481
+ */
2482
+
2483
+ interface StackOptions {
2484
+ projectName?: string;
2485
+ stackName: string;
2486
+ config: CloudConfig;
2487
+ namespace: string;
2488
+ shadowServerUrl?: string;
2489
+ /** Per-deployment runtime env resolved from SaaS/user input. */
2490
+ runtimeEnvVars?: Record<string, string>;
2491
+ /** Browser/deployment locale and timezone context. */
2492
+ runtimeContext?: DeploymentRuntimeContext;
2493
+ /** Directory to store Pulumi local state — defaults to ~/.shadowob/pulumi */
2494
+ stateDir?: string;
2495
+ /** kubectl context for K8s provider */
2496
+ kubeContext?: string;
2497
+ /** Path to a kubeconfig YAML file — takes precedence over kubeContext when set */
2498
+ kubeConfigPath?: string;
2499
+ /** Image pull policy for containers */
2500
+ imagePullPolicy?: 'Always' | 'IfNotPresent' | 'Never';
2501
+ }
2502
+ /**
2503
+ * Create or select a Pulumi stack for shadowob-cloud deployments.
2504
+ * Uses a local file backend by default for reproducible, offline operation.
2505
+ */
2506
+ declare function getOrCreateStack(options: StackOptions): Promise<automation.Stack>;
2507
+
2508
+ declare class K8sService {
2509
+ /**
2510
+ * Deploy config to K8s in one call: create stack + deploy.
2511
+ * Returns stack outputs on success.
2512
+ */
2513
+ deploy(options: StackOptions & {
2514
+ dryRun?: boolean;
2515
+ onOutput?: (out: string) => void;
2516
+ }): Promise<_pulumi_pulumi_automation_stack_js.OutputMap>;
2517
+ /**
2518
+ * Setup a local kind cluster, creating it if needed.
2519
+ * Optionally loads an image into the cluster.
2520
+ */
2521
+ setupLocalCluster(imageName?: string): void;
2522
+ getOrCreateStack(options: StackOptions): Promise<_pulumi_pulumi_automation_stack_js.Stack>;
2523
+ deployStack(stack: Awaited<ReturnType<typeof getOrCreateStack>>, options?: {
2524
+ dryRun?: boolean;
2525
+ onOutput?: (out: string) => void;
2526
+ }): Promise<_pulumi_pulumi_automation_stack_js.PreviewResult | _pulumi_pulumi_automation_stack_js.UpResult>;
2527
+ destroyStack(stack: Awaited<ReturnType<typeof getOrCreateStack>>, options?: {
2528
+ onOutput?: (out: string) => void;
2529
+ }): Promise<_pulumi_pulumi_automation_stack_js.DestroyResult>;
2530
+ getStackOutputs(stack: Awaited<ReturnType<typeof getOrCreateStack>>): Promise<_pulumi_pulumi_automation_stack_js.OutputMap>;
2531
+ getDeployments(namespace: string): DeploymentStatus[];
2532
+ getPods(namespace: string): PodStatus[];
2533
+ streamLogs(namespace: string, podName: string, options?: {
2534
+ follow?: boolean;
2535
+ tail?: number;
2536
+ }): ChildProcess;
2537
+ readLogs(namespace: string, podName: string, options?: {
2538
+ tail?: number;
2539
+ timestamps?: boolean;
2540
+ }): string;
2541
+ execInPod(namespace: string, podName: string, command: string[], options?: {
2542
+ timeout?: number;
2543
+ }): CommandResult;
2544
+ scaleDeployment(namespace: string, name: string, replicas: number): void;
2545
+ scaleAgentSandbox(namespace: string, name: string, replicas: number): void;
2546
+ pauseAgentSandbox(namespace: string, name: string): void;
2547
+ resumeAgentSandbox(namespace: string, name: string): void;
2548
+ createVolumeSnapshotBackup(options: {
2549
+ namespace: string;
2550
+ snapshotName: string;
2551
+ pvcName: string;
2552
+ volumeSnapshotClassName?: string;
2553
+ }): void;
2554
+ createVolumeSnapshotBackupAndWait(options: {
2555
+ namespace: string;
2556
+ snapshotName: string;
2557
+ pvcName: string;
2558
+ volumeSnapshotClassName?: string;
2559
+ timeoutMs?: number;
2560
+ }): Promise<void>;
2561
+ waitForAgentSandboxReady(options: {
2562
+ namespace: string;
2563
+ agentName: string;
2564
+ kubeconfig?: string;
2565
+ timeoutMs?: number;
2566
+ intervalMs?: number;
2567
+ }): Promise<AgentSandboxStatus>;
2568
+ waitForAgentSandboxPaused(options: {
2569
+ namespace: string;
2570
+ agentName: string;
2571
+ kubeconfig?: string;
2572
+ timeoutMs?: number;
2573
+ intervalMs?: number;
2574
+ }): Promise<AgentSandboxStatus>;
2575
+ restorePvcFromVolumeSnapshot(options: {
2576
+ namespace: string;
2577
+ pvcName: string;
2578
+ snapshotName: string;
2579
+ timeoutMs?: number;
2580
+ }): Promise<void>;
2581
+ /**
2582
+ * List namespaces labeled `managed-by=shadowob-cloud-cli` on the cluster.
2583
+ */
2584
+ getManagedNamespaces(): string[];
2585
+ /**
2586
+ * Delete a namespace and all its resources.
2587
+ */
2588
+ deleteNamespace(namespace: string): void;
2589
+ /**
2590
+ * Rollout restart all deployments in a namespace.
2591
+ */
2592
+ rolloutRestartAll(namespace: string): void;
2593
+ /**
2594
+ * Rollback all deployments in a namespace to the previous revision.
2595
+ */
2596
+ rolloutUndoAll(namespace: string): void;
2597
+ isToolInstalled(cmd: string): boolean;
2598
+ isKubeReachable(): boolean;
2599
+ kindClusterExists(): boolean;
2600
+ createKindCluster(): void;
2601
+ deleteKindCluster(): void;
2602
+ loadImageToKind(imageName: string): void;
2603
+ }
2604
+
2605
+ /**
2606
+ * Pulumi program — deploys K8s resources from resolved cloud config.
2607
+ */
2608
+
2609
+ interface InfraOptions {
2610
+ config: CloudConfig;
2611
+ namespace: string;
2612
+ shadowServerUrl?: string;
2613
+ /** Per-deployment runtime env resolved from SaaS/user input. */
2614
+ runtimeEnvVars?: Record<string, string>;
2615
+ /** Browser/deployment locale and timezone context. */
2616
+ runtimeContext?: DeploymentRuntimeContext;
2617
+ /** kubectl context for K8s provider — defaults to KUBECONFIG_CONTEXT or 'rancher-desktop' */
2618
+ kubeContext?: string;
2619
+ /** Path to a kubeconfig YAML file — takes precedence over kubeContext when set */
2620
+ kubeConfigPath?: string;
2621
+ /**
2622
+ * Image pull policy for all agent containers.
2623
+ * Default: 'IfNotPresent' for the official OpenClaw runner and immutable/local tags,
2624
+ * and 'Always' for other mutable registry tags.
2625
+ */
2626
+ imagePullPolicy?: 'Always' | 'IfNotPresent' | 'Never';
2627
+ }
2628
+
2629
+ declare class ManifestService {
2630
+ /** Build K8s resource definitions as plain objects (serializable to YAML/JSON). */
2631
+ build(options: InfraOptions): Array<Record<string, unknown>>;
2632
+ /** Create a Pulumi program function for programmatic deployments. */
2633
+ createProgram(options: InfraOptions): () => Promise<Record<string, pulumi.Output<string>>>;
2634
+ }
2635
+
2636
+ /**
2637
+ * DeployService — deployment orchestration.
2638
+ *
2639
+ * Contains the core deploy/destroy workflow extracted from CLI commands.
2640
+ * This is the primary service for deploying agents to Kubernetes.
2641
+ */
2642
+
2643
+ interface DeployOptions {
2644
+ filePath: string;
2645
+ namespace?: string;
2646
+ stack?: string;
2647
+ shadowUrl?: string;
2648
+ shadowToken?: string;
2649
+ dryRun?: boolean;
2650
+ skipProvision?: boolean;
2651
+ outputDir?: string;
2652
+ k8sContext?: string;
2653
+ stateDir?: string;
2654
+ imagePullPolicy?: 'Always' | 'IfNotPresent' | 'Never';
2655
+ k8sShadowUrl?: string;
2656
+ local?: boolean;
2657
+ onOutput?: (out: string) => void;
2658
+ /** Per-request env overrides used for template/plugin resolution. Never mutates process.env. */
2659
+ runtimeEnvVars?: Record<string, string>;
2660
+ /** Browser/deployment locale and timezone context. */
2661
+ runtimeContext?: DeploymentRuntimeContext;
2662
+ /** Named cluster — resolves to kubeconfig in ~/.shadow-cloud/clusters/<name>.yaml */
2663
+ cluster?: string;
2664
+ /** Explicit path to a kubeconfig file (overrides cluster and k8sContext) */
2665
+ kubeConfigPath?: string;
2666
+ /**
2667
+ * Optional callback invoked once the Pulumi Stack object exists.
2668
+ * Callers can store the reference and later invoke `stack.cancel()` to
2669
+ * abort an in-progress `up` operation cooperatively.
2670
+ */
2671
+ onStackReady?: (stack: {
2672
+ cancel: () => Promise<void>;
2673
+ }) => void;
2674
+ /**
2675
+ * Optional cooperative-cancel checker. Polled at safe boundaries; if it
2676
+ * returns `true`, the deploy aborts before performing further side-effects.
2677
+ */
2678
+ isCancelled?: () => boolean;
2679
+ /**
2680
+ * Initial provision state supplied by SaaS/database callers. CLI callers
2681
+ * still use the on-disk state file next to the config.
2682
+ */
2683
+ initialProvisionState?: ProvisionState | null;
2684
+ /**
2685
+ * Called whenever plugin provisioning produces a new durable state snapshot.
2686
+ * SaaS uses this to persist Shadow server/channel/buddy IDs before Pulumi
2687
+ * starts mutating Kubernetes.
2688
+ */
2689
+ onProvisionState?: (state: ProvisionState) => void | Promise<void>;
2690
+ }
2691
+ interface DeployResult {
2692
+ namespace: string;
2693
+ agentCount: number;
2694
+ config: CloudConfig;
2695
+ manifests?: Array<Record<string, unknown>>;
2696
+ outputs?: Record<string, unknown>;
2697
+ provisionState?: ProvisionState;
2698
+ }
2699
+ interface DestroyOptions {
2700
+ filePath?: string;
2701
+ namespace?: string;
2702
+ stack?: string;
2703
+ k8sContext?: string;
2704
+ kubeConfigPath?: string;
2705
+ config?: CloudConfig;
2706
+ onStackReady?: (stack: {
2707
+ cancel: () => Promise<void>;
2708
+ }) => void;
2709
+ isCancelled?: () => boolean;
2710
+ }
2711
+ declare class DeployService {
2712
+ private configService;
2713
+ private manifestService;
2714
+ private k8s;
2715
+ private logger;
2716
+ constructor(configService: ConfigService, manifestService: ManifestService, k8s: K8sService, logger: Logger);
2717
+ /**
2718
+ * Deploy or update agents to Kubernetes.
2719
+ *
2720
+ * Orchestrates: parse → provision → resolve → manifest/deploy.
2721
+ * Throws on errors instead of calling process.exit().
2722
+ */
2723
+ up(options: DeployOptions): Promise<DeployResult>;
2724
+ /**
2725
+ * Destroy agent cluster from Kubernetes.
2726
+ * Throws on errors instead of calling process.exit().
2727
+ */
2728
+ destroy(options: DestroyOptions): Promise<void>;
2729
+ }
2730
+
2731
+ interface DeploymentRuntimeCluster {
2732
+ id?: string | null;
2733
+ name?: string | null;
2734
+ kubeconfig?: string | null;
2735
+ }
2736
+ interface DeployFromSnapshotOptions extends Omit<DeployOptions, 'filePath' | 'k8sContext' | 'shadowUrl' | 'shadowToken' | 'cluster' | 'kubeConfigPath'> {
2737
+ configSnapshot: unknown;
2738
+ runtimeEnvVars?: Record<string, string>;
2739
+ runtimeContext?: DeploymentRuntimeContext;
2740
+ shadowUrl?: string;
2741
+ shadowToken?: string;
2742
+ cluster?: DeploymentRuntimeCluster | null;
2743
+ provisionState?: ProvisionState | null;
2744
+ onProvisionState?: (state: ProvisionState) => void | Promise<void>;
2745
+ }
2746
+ interface DestroyRuntimeOptions {
2747
+ namespace: string;
2748
+ stack?: string;
2749
+ cluster?: DeploymentRuntimeCluster | null;
2750
+ configSnapshot?: unknown;
2751
+ onStackReady?: (stack: {
2752
+ cancel: () => Promise<void>;
2753
+ }) => void;
2754
+ isCancelled?: () => boolean;
2755
+ }
2756
+ declare function rewriteLoopbackKubeconfig(kubeconfigYaml: string, loopbackHost?: string | undefined): string;
2757
+ declare class DeploymentRuntimeService {
2758
+ private readonly deployService;
2759
+ constructor(deployService: DeployService);
2760
+ deployFromSnapshot(options: DeployFromSnapshotOptions): Promise<DeployResult>;
2761
+ destroy(options: DestroyRuntimeOptions): Promise<void>;
2762
+ private withResolvedContext;
2763
+ }
2764
+
2765
+ /**
2766
+ * ImageService — Docker image build and push operations.
2767
+ *
2768
+ * Manages building, tagging, and pushing container images
2769
+ * for agent runtimes.
2770
+ */
2771
+
2772
+ declare const IMAGES: readonly ["openclaw-runner", "claude-runner", "codex-runner", "gemini-runner", "opencode-runner"];
2773
+ interface ImageBuildOptions {
2774
+ name: string;
2775
+ tag?: string;
2776
+ noCache?: boolean;
2777
+ intoK8s?: boolean;
2778
+ push?: boolean;
2779
+ platform?: string;
2780
+ }
2781
+ declare class ImageService {
2782
+ private imagesDir;
2783
+ private logger;
2784
+ constructor(logger: Logger, imagesDir?: string);
2785
+ /** Get the images directory path. */
2786
+ getImagesDir(): string;
2787
+ /** Get the container registry URL. */
2788
+ getRegistry(): string;
2789
+ /** Get all available image names. */
2790
+ getAvailableImages(): readonly string[];
2791
+ /** Get a local image tag. */
2792
+ getLocalTag(name: string, tag: string): string;
2793
+ /** Build a Docker image with streaming output. */
2794
+ build(options: ImageBuildOptions): Promise<void>;
2795
+ /** Push an image to the registry. */
2796
+ push(name: string, tag?: string): Promise<void>;
2797
+ /** List available image definitions with their status. */
2798
+ list(): Array<{
2799
+ name: string;
2800
+ hasDockerfile: boolean;
2801
+ }>;
2802
+ private getBuildContext;
2803
+ private dockerBuild;
2804
+ private spawnProcess;
2805
+ }
2806
+
2807
+ /**
2808
+ * RuntimeService — runtime adapter registry access.
2809
+ *
2810
+ * Wraps runtimes/index.ts for querying registered runtime adapters.
2811
+ */
2812
+
2813
+ declare class RuntimeService {
2814
+ /** Get a runtime adapter by ID. Throws if not found. */
2815
+ get(id: string): RuntimeAdapter;
2816
+ /** Get all registered runtime adapters. */
2817
+ getAll(): RuntimeAdapter[];
2818
+ /** Get all registered runtime IDs. */
2819
+ getIds(): string[];
2820
+ }
2821
+
2822
+ /**
2823
+ * TemplateDao — file-based template data access.
2824
+ *
2825
+ * All I/O is async. Supports two on-disk layouts:
2826
+ * Folder: templates/<slug>/shadowob-cloud.json (+ optional index.json)
2827
+ * Flat: templates/<slug>.template.json
2828
+ *
2829
+ * Folder layout takes priority over flat when both exist for the same slug.
2830
+ */
2831
+ interface TemplateRecord {
2832
+ slug: string;
2833
+ isFolder: boolean;
2834
+ configPath: string;
2835
+ indexPath: string | null;
2836
+ dir: string;
2837
+ }
2838
+ declare class TemplateDao {
2839
+ readonly templatesDir: string;
2840
+ constructor(templatesDir: string);
2841
+ /** Discover all available template slugs. Folder layout takes priority. */
2842
+ findAll(): Promise<TemplateRecord[]>;
2843
+ /** Find a single template by slug. Returns null if not found. */
2844
+ findBySlug(slug: string): Promise<TemplateRecord | null>;
2845
+ /** Read and parse a JSON/JSONC file. Returns null on error. */
2846
+ readJson<T = Record<string, unknown>>(filePath: string): Promise<T | null>;
2847
+ /** Get file mtime as ISO string. Returns null if file not found. */
2848
+ mtime(filePath: string): Promise<string | null>;
2849
+ /** Copy a template folder (or single file) to destDir. */
2850
+ copyTo(slug: string, destDir: string): Promise<void>;
2851
+ private exists;
2852
+ }
2853
+
2854
+ /**
2855
+ * TemplateService — template discovery and metadata.
2856
+ *
2857
+ * All I/O is delegated to TemplateDao. This service handles
2858
+ * business logic: i18n resolution, sorting, metadata mapping.
2859
+ */
2860
+
2861
+ interface TemplateMeta {
2862
+ /** Stable kebab-case template slug */
2863
+ name: string;
2864
+ /** Locale-aware display title */
2865
+ title: string;
2866
+ /** Relative path to the config file from templatesDir */
2867
+ file: string;
2868
+ /** Locale-aware customer value proposition */
2869
+ description: string;
2870
+ agentCount: number;
2871
+ namespace: string;
2872
+ /** Absolute path to the directory containing the config (for relative path resolution) */
2873
+ dir: string;
2874
+ }
2875
+ declare class TemplateService {
2876
+ private readonly dao;
2877
+ constructor(dao: TemplateDao);
2878
+ /** Get the templates directory path. */
2879
+ getDir(): string;
2880
+ /** Discover all available config templates. */
2881
+ discover(locale?: string): Promise<TemplateMeta[]>;
2882
+ /**
2883
+ * Read a template config by name.
2884
+ * Prefers folder layout over flat files.
2885
+ */
2886
+ getTemplate(name: string): Promise<unknown | null>;
2887
+ /**
2888
+ * Get the absolute path to a template's config file.
2889
+ * Useful for resolving relative paths (e.g. gitagent source.path).
2890
+ */
2891
+ getTemplatePath(name: string): Promise<string | null>;
2892
+ /** List templates metadata (alias for discover). */
2893
+ list(locale?: string): Promise<TemplateMeta[]>;
2894
+ }
2895
+
2896
+ /**
2897
+ * TemplateI18nService — locale-aware presentation metadata for built-in templates.
2898
+ *
2899
+ * The raw TemplateService owns template discovery and config loading.
2900
+ * This service owns all console-facing copy (overview, highlights, requirements,
2901
+ * categories, deploy-time labels, etc.) so the dashboard can pass locale in
2902
+ * requests and keep presentation logic on the backend.
2903
+ */
2904
+
2905
+ type TemplateCategoryId = 'devops' | 'security' | 'support' | 'research' | 'monitoring' | 'business' | 'demo';
2906
+ type TemplateDifficulty = 'beginner' | 'intermediate' | 'advanced';
2907
+ interface TemplateCategoryInfo {
2908
+ id: TemplateCategoryId | 'all';
2909
+ label: string;
2910
+ emoji: string;
2911
+ description: string;
2912
+ }
2913
+ interface TemplateCatalogSummary {
2914
+ /** Stable kebab-case template slug */
2915
+ name: string;
2916
+ /** Locale-aware display title */
2917
+ title: string;
2918
+ description: string;
2919
+ agentCount: number;
2920
+ namespace: string;
2921
+ category: TemplateCategoryId;
2922
+ emoji: string;
2923
+ featured: boolean;
2924
+ popularity: number;
2925
+ difficulty: TemplateDifficulty;
2926
+ estimatedDeployTime: string;
2927
+ overview: string[];
2928
+ features: string[];
2929
+ highlights: string[];
2930
+ }
2931
+ interface TemplateCatalogDetail extends TemplateCatalogSummary {
2932
+ file: string;
2933
+ lastUpdated: string | null;
2934
+ useCases: string[];
2935
+ requirements: string[];
2936
+ requiredEnvVars: string[];
2937
+ }
2938
+ interface TemplateCatalogResponse {
2939
+ templates: TemplateCatalogSummary[];
2940
+ categories: TemplateCategoryInfo[];
2941
+ }
2942
+ declare class TemplateI18nService {
2943
+ private templateService;
2944
+ constructor(templateService: TemplateService);
2945
+ getCategories(locale?: string): TemplateCategoryInfo[];
2946
+ listCatalog(locale?: string): Promise<TemplateCatalogResponse>;
2947
+ getTemplateDetail(name: string, locale?: string): Promise<TemplateCatalogDetail | null>;
2948
+ private buildSummary;
2949
+ private resolveCopy;
2950
+ private safeStat;
2951
+ }
2952
+
2953
+ declare class UsageCostService {
2954
+ private k8s;
2955
+ private readonly cacheTtlMs;
2956
+ private readonly namespaceCache;
2957
+ constructor(k8s: K8sService, cacheTtlMs?: number);
2958
+ collectNamespace(namespace: string): NamespaceCostSummary;
2959
+ collectOverview(namespaces: string[]): CostOverviewSummary;
2960
+ private getRuntime;
2961
+ }
2962
+
2963
+ /**
2964
+ * IoC Container — service registry and dependency injection.
2965
+ *
2966
+ * All services are registered here and injected via constructor.
2967
+ * Use createContainer() to get a fully-wired ServiceContainer.
2968
+ *
2969
+ * For SDK use: import { createContainer } from '@shadowob/cloud/services/container'
2970
+ * For testing: pass overrides to createContainer({ logger: mockLogger })
2971
+ */
2972
+
2973
+ /**
2974
+ * Service container interface — all services accessible via a single object.
2975
+ */
2976
+ interface ServiceContainer {
2977
+ logger: Logger;
2978
+ config: ConfigService;
2979
+ manifest: ManifestService;
2980
+ deploy: DeployService;
2981
+ deploymentRuntime: DeploymentRuntimeService;
2982
+ template: TemplateService;
2983
+ templateI18n: TemplateI18nService;
2984
+ runtime: RuntimeService;
2985
+ image: ImageService;
2986
+ k8s: K8sService;
2987
+ usageCost: UsageCostService;
2988
+ cluster: ClusterService;
2989
+ }
2990
+ /**
2991
+ * Create a fully-wired service container.
2992
+ *
2993
+ * @param overrides - Optional partial overrides for testing or custom configurations.
2994
+ * Override individual services or the logger.
2995
+ */
2996
+ declare function createContainer(overrides?: Partial<ServiceContainer>): ServiceContainer;
2997
+
2998
+ /**
2999
+ * CLI Interface — registers all commands on the Commander program.
3000
+ *
3001
+ * This is the thin interface layer. Each command only:
3002
+ * 1. Defines options and arguments
3003
+ * 2. Parses and validates input
3004
+ * 3. Delegates to the service container
3005
+ * 4. Handles output formatting and process.exit
3006
+ */
3007
+
3008
+ /**
3009
+ * Create the CLI program with all commands registered.
3010
+ */
3011
+ declare function createCLI(container: ServiceContainer): Command;
3012
+
3013
+ export { type AgentCostSummary, type AgentSandboxRuntimeState, type AgentSandboxStatus, type BillingUnit, CLOUD_SAAS_RUNTIME_KEY, type ClusterConfig, type ClusterMeta, ClusterService, ConfigService, type CostOverviewSummary, type DeployFromSnapshotOptions, type DeployOptions, type DeployResult, DeployService, type DeploymentRuntimeCluster, type DeploymentRuntimeContext, DeploymentRuntimeService, type DestroyRuntimeOptions, IMAGES, type ImageBuildOptions, ImageService, type K8sExecResult, type K8sPodSummary, K8sService, ManifestService, type NamespaceCostSummary, OPENCLAW_USAGE_COMMANDS, type PluginCatalogEntry, type PluginLibraryEntry, type PluginLibrarySearchResult, type ProviderCatalogEntry, type ProviderUsageSummary, type PvcVolumeSnapshotCapability, RESERVED_RUNTIME_ENV_KEYS, type RuntimeEnvField, type RuntimeEnvRefPolicy, RuntimeService, type ServiceContainer, type TemplateCatalogDetail, type TemplateCatalogResponse, type TemplateCatalogSummary, type TemplateCategoryId, type TemplateCategoryInfo, type TemplateDifficulty, TemplateI18nService, type TemplateLibraryEntry, type TemplateLibrarySearchResult, type TemplateMeta, TemplateService, UsageCostService, type VolumeSnapshotReadyStatus, applyKubernetesManifestAsync, applyRuntimeEnvRefPolicy, assertNoReservedEnvOverrides, attachCloudSaasProvisionState, collectAgentUsage, collectNamespaceCost, collectRuntimeEnvFields, collectRuntimeEnvRefPolicy, collectRuntimeEnvRequirements, createCLI, createContainer, createVolumeSnapshotBackupAsync, deleteKubernetesResourceAsync, deleteNamespace, execInPod, execInPodAsync, execInPodWithInputAsync, extractCloudSaasRuntime, extractRequiredEnvVars, getAgentSandboxStatusAsync, getPluginLibraryEntry, getPvcVolumeSnapshotCapability, getVolumeSnapshotReadyStatus, isPvcBackedByCsiProvisioner, isReservedRuntimeEnvKey, isVolumeSnapshotApiAvailable, listManagedNamespaces, listPluginCatalogs, listPluginLibrary, listPods, listPodsAsync, listProviderCatalogs, listTemplateLibrary, loadCloudConfigSchema, loadKubeconfigPath, namespaceExists, parseOpenClawUsageOutput, prepareCloudSaasConfigSnapshot, readClusterConfig, readPodLogs, readPodLogsAsync, redactCloudSaasConfigSnapshot, resolveCloudSaasShadowRuntime, resolveSandboxNameAsync, resolveVolumeSnapshotClassForPvc, restorePvcFromVolumeSnapshot, rewriteLoopbackKubeconfig, sanitizeCloudSaasDeployment, scaleAgentSandboxAsync, searchPluginLibrary, searchTemplateLibrary, spawnPodLogStream, summarizeCloudConfigValidation, summarizeCostOverview, validateCloudSaasConfigSnapshot, waitForAgentSandboxPaused, waitForAgentSandboxReady, waitForPodReadyAsync, waitForVolumeSnapshotReady };