@aquaclawai/aquarium 1.0.0

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 (517) hide show
  1. package/dist/agent-types/claude-code/index.d.ts +2 -0
  2. package/dist/agent-types/claude-code/index.d.ts.map +1 -0
  3. package/dist/agent-types/claude-code/index.js +2 -0
  4. package/dist/agent-types/claude-code/index.js.map +1 -0
  5. package/dist/agent-types/claude-code/manifest.d.ts +3 -0
  6. package/dist/agent-types/claude-code/manifest.d.ts.map +1 -0
  7. package/dist/agent-types/claude-code/manifest.js +45 -0
  8. package/dist/agent-types/claude-code/manifest.js.map +1 -0
  9. package/dist/agent-types/openclaw/adapter.d.ts +3 -0
  10. package/dist/agent-types/openclaw/adapter.d.ts.map +1 -0
  11. package/dist/agent-types/openclaw/adapter.js +714 -0
  12. package/dist/agent-types/openclaw/adapter.js.map +1 -0
  13. package/dist/agent-types/openclaw/gateway-rpc.d.ts +21 -0
  14. package/dist/agent-types/openclaw/gateway-rpc.d.ts.map +1 -0
  15. package/dist/agent-types/openclaw/gateway-rpc.js +202 -0
  16. package/dist/agent-types/openclaw/gateway-rpc.js.map +1 -0
  17. package/dist/agent-types/openclaw/index.d.ts +3 -0
  18. package/dist/agent-types/openclaw/index.d.ts.map +1 -0
  19. package/dist/agent-types/openclaw/index.js +3 -0
  20. package/dist/agent-types/openclaw/index.js.map +1 -0
  21. package/dist/agent-types/openclaw/manifest.d.ts +137 -0
  22. package/dist/agent-types/openclaw/manifest.d.ts.map +1 -0
  23. package/dist/agent-types/openclaw/manifest.js +191 -0
  24. package/dist/agent-types/openclaw/manifest.js.map +1 -0
  25. package/dist/agent-types/openclaw/provider-registry.d.ts +46 -0
  26. package/dist/agent-types/openclaw/provider-registry.d.ts.map +1 -0
  27. package/dist/agent-types/openclaw/provider-registry.js +108 -0
  28. package/dist/agent-types/openclaw/provider-registry.js.map +1 -0
  29. package/dist/agent-types/openclaw/reverse-adapter.d.ts +7 -0
  30. package/dist/agent-types/openclaw/reverse-adapter.d.ts.map +1 -0
  31. package/dist/agent-types/openclaw/reverse-adapter.js +528 -0
  32. package/dist/agent-types/openclaw/reverse-adapter.js.map +1 -0
  33. package/dist/agent-types/openclaw/security-profiles.d.ts +21 -0
  34. package/dist/agent-types/openclaw/security-profiles.d.ts.map +1 -0
  35. package/dist/agent-types/openclaw/security-profiles.js +251 -0
  36. package/dist/agent-types/openclaw/security-profiles.js.map +1 -0
  37. package/dist/agent-types/openclaw/workspace-templates.d.ts +2 -0
  38. package/dist/agent-types/openclaw/workspace-templates.d.ts.map +1 -0
  39. package/dist/agent-types/openclaw/workspace-templates.js +363 -0
  40. package/dist/agent-types/openclaw/workspace-templates.js.map +1 -0
  41. package/dist/agent-types/opencode/index.d.ts +2 -0
  42. package/dist/agent-types/opencode/index.d.ts.map +1 -0
  43. package/dist/agent-types/opencode/index.js +2 -0
  44. package/dist/agent-types/opencode/index.js.map +1 -0
  45. package/dist/agent-types/opencode/manifest.d.ts +3 -0
  46. package/dist/agent-types/opencode/manifest.d.ts.map +1 -0
  47. package/dist/agent-types/opencode/manifest.js +63 -0
  48. package/dist/agent-types/opencode/manifest.js.map +1 -0
  49. package/dist/agent-types/registry.d.ts +4 -0
  50. package/dist/agent-types/registry.d.ts.map +1 -0
  51. package/dist/agent-types/registry.js +24 -0
  52. package/dist/agent-types/registry.js.map +1 -0
  53. package/dist/agent-types/types.d.ts +169 -0
  54. package/dist/agent-types/types.d.ts.map +1 -0
  55. package/dist/agent-types/types.js +2 -0
  56. package/dist/agent-types/types.js.map +1 -0
  57. package/dist/cli.d.ts +3 -0
  58. package/dist/cli.d.ts.map +1 -0
  59. package/dist/cli.js +72 -0
  60. package/dist/cli.js.map +1 -0
  61. package/dist/config.d.ts +68 -0
  62. package/dist/config.d.ts.map +1 -0
  63. package/dist/config.js +98 -0
  64. package/dist/config.js.map +1 -0
  65. package/dist/db/adapter.d.ts +21 -0
  66. package/dist/db/adapter.d.ts.map +1 -0
  67. package/dist/db/adapter.js +11 -0
  68. package/dist/db/adapter.js.map +1 -0
  69. package/dist/db/index.d.ts +4 -0
  70. package/dist/db/index.d.ts.map +1 -0
  71. package/dist/db/index.js +5 -0
  72. package/dist/db/index.js.map +1 -0
  73. package/dist/db/knexfile.d.ts +5 -0
  74. package/dist/db/knexfile.d.ts.map +1 -0
  75. package/dist/db/knexfile.js +34 -0
  76. package/dist/db/knexfile.js.map +1 -0
  77. package/dist/db/migration-helpers.d.ts +45 -0
  78. package/dist/db/migration-helpers.d.ts.map +1 -0
  79. package/dist/db/migration-helpers.js +90 -0
  80. package/dist/db/migration-helpers.js.map +1 -0
  81. package/dist/db/migrations/001_initial.d.ts +4 -0
  82. package/dist/db/migrations/001_initial.d.ts.map +1 -0
  83. package/dist/db/migrations/001_initial.js +56 -0
  84. package/dist/db/migrations/001_initial.js.map +1 -0
  85. package/dist/db/migrations/002_instance_config.d.ts +4 -0
  86. package/dist/db/migrations/002_instance_config.d.ts.map +1 -0
  87. package/dist/db/migrations/002_instance_config.js +12 -0
  88. package/dist/db/migrations/002_instance_config.js.map +1 -0
  89. package/dist/db/migrations/003_instance_status_message.d.ts +4 -0
  90. package/dist/db/migrations/003_instance_status_message.d.ts.map +1 -0
  91. package/dist/db/migrations/003_instance_status_message.js +11 -0
  92. package/dist/db/migrations/003_instance_status_message.js.map +1 -0
  93. package/dist/db/migrations/004_templates.d.ts +4 -0
  94. package/dist/db/migrations/004_templates.d.ts.map +1 -0
  95. package/dist/db/migrations/004_templates.js +95 -0
  96. package/dist/db/migrations/004_templates.js.map +1 -0
  97. package/dist/db/migrations/005_group_chats.d.ts +4 -0
  98. package/dist/db/migrations/005_group_chats.d.ts.map +1 -0
  99. package/dist/db/migrations/005_group_chats.js +66 -0
  100. package/dist/db/migrations/005_group_chats.js.map +1 -0
  101. package/dist/db/migrations/006_template_setup.d.ts +4 -0
  102. package/dist/db/migrations/006_template_setup.d.ts.map +1 -0
  103. package/dist/db/migrations/006_template_setup.js +14 -0
  104. package/dist/db/migrations/006_template_setup.js.map +1 -0
  105. package/dist/db/migrations/007_group_chat_v2.d.ts +4 -0
  106. package/dist/db/migrations/007_group_chat_v2.d.ts.map +1 -0
  107. package/dist/db/migrations/007_group_chat_v2.js +59 -0
  108. package/dist/db/migrations/007_group_chat_v2.js.map +1 -0
  109. package/dist/db/migrations/008_default_provider_openrouter.d.ts +4 -0
  110. package/dist/db/migrations/008_default_provider_openrouter.d.ts.map +1 -0
  111. package/dist/db/migrations/008_default_provider_openrouter.js +33 -0
  112. package/dist/db/migrations/008_default_provider_openrouter.js.map +1 -0
  113. package/dist/db/migrations/009_opencode_default_provider_openrouter.d.ts +4 -0
  114. package/dist/db/migrations/009_opencode_default_provider_openrouter.d.ts.map +1 -0
  115. package/dist/db/migrations/009_opencode_default_provider_openrouter.js +33 -0
  116. package/dist/db/migrations/009_opencode_default_provider_openrouter.js.map +1 -0
  117. package/dist/db/migrations/010_fix_null_default_provider.d.ts +4 -0
  118. package/dist/db/migrations/010_fix_null_default_provider.d.ts.map +1 -0
  119. package/dist/db/migrations/010_fix_null_default_provider.js +24 -0
  120. package/dist/db/migrations/010_fix_null_default_provider.js.map +1 -0
  121. package/dist/db/migrations/011_snapshots.d.ts +4 -0
  122. package/dist/db/migrations/011_snapshots.d.ts.map +1 -0
  123. package/dist/db/migrations/011_snapshots.js +27 -0
  124. package/dist/db/migrations/011_snapshots.js.map +1 -0
  125. package/dist/db/migrations/013_official_templates.d.ts +4 -0
  126. package/dist/db/migrations/013_official_templates.d.ts.map +1 -0
  127. package/dist/db/migrations/013_official_templates.js +173 -0
  128. package/dist/db/migrations/013_official_templates.js.map +1 -0
  129. package/dist/db/migrations/014_notifications.d.ts +4 -0
  130. package/dist/db/migrations/014_notifications.d.ts.map +1 -0
  131. package/dist/db/migrations/014_notifications.js +45 -0
  132. package/dist/db/migrations/014_notifications.js.map +1 -0
  133. package/dist/db/migrations/015_security_profile.d.ts +4 -0
  134. package/dist/db/migrations/015_security_profile.d.ts.map +1 -0
  135. package/dist/db/migrations/015_security_profile.js +14 -0
  136. package/dist/db/migrations/015_security_profile.js.map +1 -0
  137. package/dist/db/migrations/016_template_security.d.ts +4 -0
  138. package/dist/db/migrations/016_template_security.d.ts.map +1 -0
  139. package/dist/db/migrations/016_template_security.js +12 -0
  140. package/dist/db/migrations/016_template_security.js.map +1 -0
  141. package/dist/db/migrations/017_auth_events.d.ts +4 -0
  142. package/dist/db/migrations/017_auth_events.d.ts.map +1 -0
  143. package/dist/db/migrations/017_auth_events.js +19 -0
  144. package/dist/db/migrations/017_auth_events.js.map +1 -0
  145. package/dist/db/migrations/018_skill_market.d.ts +4 -0
  146. package/dist/db/migrations/018_skill_market.d.ts.map +1 -0
  147. package/dist/db/migrations/018_skill_market.js +21 -0
  148. package/dist/db/migrations/018_skill_market.js.map +1 -0
  149. package/dist/db/migrations/019_credential_audit_log.d.ts +4 -0
  150. package/dist/db/migrations/019_credential_audit_log.d.ts.map +1 -0
  151. package/dist/db/migrations/019_credential_audit_log.js +19 -0
  152. package/dist/db/migrations/019_credential_audit_log.js.map +1 -0
  153. package/dist/db/migrations/020_template_security_score.d.ts +4 -0
  154. package/dist/db/migrations/020_template_security_score.d.ts.map +1 -0
  155. package/dist/db/migrations/020_template_security_score.js +31 -0
  156. package/dist/db/migrations/020_template_security_score.js.map +1 -0
  157. package/dist/db/migrations/021_credential_enhancements.d.ts +4 -0
  158. package/dist/db/migrations/021_credential_enhancements.d.ts.map +1 -0
  159. package/dist/db/migrations/021_credential_enhancements.js +15 -0
  160. package/dist/db/migrations/021_credential_enhancements.js.map +1 -0
  161. package/dist/db/migrations/021_user_roles.d.ts +4 -0
  162. package/dist/db/migrations/021_user_roles.d.ts.map +1 -0
  163. package/dist/db/migrations/021_user_roles.js +11 -0
  164. package/dist/db/migrations/021_user_roles.js.map +1 -0
  165. package/dist/db/migrations/022_config_hash.d.ts +4 -0
  166. package/dist/db/migrations/022_config_hash.d.ts.map +1 -0
  167. package/dist/db/migrations/022_config_hash.js +11 -0
  168. package/dist/db/migrations/022_config_hash.js.map +1 -0
  169. package/dist/db/migrations/023_account_security.d.ts +4 -0
  170. package/dist/db/migrations/023_account_security.d.ts.map +1 -0
  171. package/dist/db/migrations/023_account_security.js +22 -0
  172. package/dist/db/migrations/023_account_security.js.map +1 -0
  173. package/dist/db/migrations/024_wizard_configs.d.ts +4 -0
  174. package/dist/db/migrations/024_wizard_configs.d.ts.map +1 -0
  175. package/dist/db/migrations/024_wizard_configs.js +165 -0
  176. package/dist/db/migrations/024_wizard_configs.js.map +1 -0
  177. package/dist/db/migrations/025_auth_dual_mode.d.ts +4 -0
  178. package/dist/db/migrations/025_auth_dual_mode.d.ts.map +1 -0
  179. package/dist/db/migrations/025_auth_dual_mode.js +19 -0
  180. package/dist/db/migrations/025_auth_dual_mode.js.map +1 -0
  181. package/dist/db/migrations/027_add_avatar_to_instances.d.ts +4 -0
  182. package/dist/db/migrations/027_add_avatar_to_instances.d.ts.map +1 -0
  183. package/dist/db/migrations/027_add_avatar_to_instances.js +11 -0
  184. package/dist/db/migrations/027_add_avatar_to_instances.js.map +1 -0
  185. package/dist/db/migrations/027_add_clerk_id.d.ts +4 -0
  186. package/dist/db/migrations/027_add_clerk_id.d.ts.map +1 -0
  187. package/dist/db/migrations/027_add_clerk_id.js +11 -0
  188. package/dist/db/migrations/027_add_clerk_id.js.map +1 -0
  189. package/dist/db/migrations/028_template_plugin_dependencies.d.ts +4 -0
  190. package/dist/db/migrations/028_template_plugin_dependencies.d.ts.map +1 -0
  191. package/dist/db/migrations/028_template_plugin_dependencies.js +18 -0
  192. package/dist/db/migrations/028_template_plugin_dependencies.js.map +1 -0
  193. package/dist/db/migrations/029_remap_orphan_config_keys.d.ts +21 -0
  194. package/dist/db/migrations/029_remap_orphan_config_keys.d.ts.map +1 -0
  195. package/dist/db/migrations/029_remap_orphan_config_keys.js +63 -0
  196. package/dist/db/migrations/029_remap_orphan_config_keys.js.map +1 -0
  197. package/dist/db/migrations/030_extend_notification_types.d.ts +4 -0
  198. package/dist/db/migrations/030_extend_notification_types.d.ts.map +1 -0
  199. package/dist/db/migrations/030_extend_notification_types.js +10 -0
  200. package/dist/db/migrations/030_extend_notification_types.js.map +1 -0
  201. package/dist/db/migrations/031_default_security_profile_developer.d.ts +9 -0
  202. package/dist/db/migrations/031_default_security_profile_developer.d.ts.map +1 -0
  203. package/dist/db/migrations/031_default_security_profile_developer.js +22 -0
  204. package/dist/db/migrations/031_default_security_profile_developer.js.map +1 -0
  205. package/dist/db/migrations/032_geo_template.d.ts +4 -0
  206. package/dist/db/migrations/032_geo_template.d.ts.map +1 -0
  207. package/dist/db/migrations/032_geo_template.js +133 -0
  208. package/dist/db/migrations/032_geo_template.js.map +1 -0
  209. package/dist/db/migrations/033_jinko_travel_template.d.ts +4 -0
  210. package/dist/db/migrations/033_jinko_travel_template.d.ts.map +1 -0
  211. package/dist/db/migrations/033_jinko_travel_template.js +126 -0
  212. package/dist/db/migrations/033_jinko_travel_template.js.map +1 -0
  213. package/dist/db/postgres-adapter.d.ts +13 -0
  214. package/dist/db/postgres-adapter.d.ts.map +1 -0
  215. package/dist/db/postgres-adapter.js +27 -0
  216. package/dist/db/postgres-adapter.js.map +1 -0
  217. package/dist/db/run-migrations.d.ts +2 -0
  218. package/dist/db/run-migrations.d.ts.map +1 -0
  219. package/dist/db/run-migrations.js +26 -0
  220. package/dist/db/run-migrations.js.map +1 -0
  221. package/dist/db/sqlite-adapter.d.ts +13 -0
  222. package/dist/db/sqlite-adapter.d.ts.map +1 -0
  223. package/dist/db/sqlite-adapter.js +29 -0
  224. package/dist/db/sqlite-adapter.js.map +1 -0
  225. package/dist/ee/litellm/litellm-key-manager.d.ts +16 -0
  226. package/dist/ee/litellm/litellm-key-manager.d.ts.map +1 -0
  227. package/dist/ee/litellm/litellm-key-manager.js +16 -0
  228. package/dist/ee/litellm/litellm-key-manager.js.map +1 -0
  229. package/dist/ee/litellm/litellm-model-seeder.d.ts +6 -0
  230. package/dist/ee/litellm/litellm-model-seeder.d.ts.map +1 -0
  231. package/dist/ee/litellm/litellm-model-seeder.js +6 -0
  232. package/dist/ee/litellm/litellm-model-seeder.js.map +1 -0
  233. package/dist/index.ce.d.ts +2 -0
  234. package/dist/index.ce.d.ts.map +1 -0
  235. package/dist/index.ce.js +12 -0
  236. package/dist/index.ce.js.map +1 -0
  237. package/dist/middleware/auth.d.ts +30 -0
  238. package/dist/middleware/auth.d.ts.map +1 -0
  239. package/dist/middleware/auth.js +86 -0
  240. package/dist/middleware/auth.js.map +1 -0
  241. package/dist/middleware/dynamic-middleware.d.ts +7 -0
  242. package/dist/middleware/dynamic-middleware.d.ts.map +1 -0
  243. package/dist/middleware/dynamic-middleware.js +46 -0
  244. package/dist/middleware/dynamic-middleware.js.map +1 -0
  245. package/dist/middleware/log-redaction.d.ts +2 -0
  246. package/dist/middleware/log-redaction.d.ts.map +1 -0
  247. package/dist/middleware/log-redaction.js +56 -0
  248. package/dist/middleware/log-redaction.js.map +1 -0
  249. package/dist/routes/admin.d.ts +3 -0
  250. package/dist/routes/admin.d.ts.map +1 -0
  251. package/dist/routes/admin.js +491 -0
  252. package/dist/routes/admin.js.map +1 -0
  253. package/dist/routes/agent-types.d.ts +3 -0
  254. package/dist/routes/agent-types.d.ts.map +1 -0
  255. package/dist/routes/agent-types.js +85 -0
  256. package/dist/routes/agent-types.js.map +1 -0
  257. package/dist/routes/auth.d.ts +3 -0
  258. package/dist/routes/auth.d.ts.map +1 -0
  259. package/dist/routes/auth.js +242 -0
  260. package/dist/routes/auth.js.map +1 -0
  261. package/dist/routes/channels.d.ts +3 -0
  262. package/dist/routes/channels.d.ts.map +1 -0
  263. package/dist/routes/channels.js +527 -0
  264. package/dist/routes/channels.js.map +1 -0
  265. package/dist/routes/credentials.d.ts +3 -0
  266. package/dist/routes/credentials.d.ts.map +1 -0
  267. package/dist/routes/credentials.js +81 -0
  268. package/dist/routes/credentials.js.map +1 -0
  269. package/dist/routes/dashboard.d.ts +3 -0
  270. package/dist/routes/dashboard.d.ts.map +1 -0
  271. package/dist/routes/dashboard.js +75 -0
  272. package/dist/routes/dashboard.js.map +1 -0
  273. package/dist/routes/exec-approval.d.ts +3 -0
  274. package/dist/routes/exec-approval.d.ts.map +1 -0
  275. package/dist/routes/exec-approval.js +60 -0
  276. package/dist/routes/exec-approval.js.map +1 -0
  277. package/dist/routes/group-chats.d.ts +3 -0
  278. package/dist/routes/group-chats.d.ts.map +1 -0
  279. package/dist/routes/group-chats.js +190 -0
  280. package/dist/routes/group-chats.js.map +1 -0
  281. package/dist/routes/instance-files.d.ts +3 -0
  282. package/dist/routes/instance-files.d.ts.map +1 -0
  283. package/dist/routes/instance-files.js +255 -0
  284. package/dist/routes/instance-files.js.map +1 -0
  285. package/dist/routes/instance-proxy.d.ts +40 -0
  286. package/dist/routes/instance-proxy.d.ts.map +1 -0
  287. package/dist/routes/instance-proxy.js +318 -0
  288. package/dist/routes/instance-proxy.js.map +1 -0
  289. package/dist/routes/instances.d.ts +3 -0
  290. package/dist/routes/instances.d.ts.map +1 -0
  291. package/dist/routes/instances.js +325 -0
  292. package/dist/routes/instances.js.map +1 -0
  293. package/dist/routes/metadata.d.ts +3 -0
  294. package/dist/routes/metadata.d.ts.map +1 -0
  295. package/dist/routes/metadata.js +13 -0
  296. package/dist/routes/metadata.js.map +1 -0
  297. package/dist/routes/notifications.d.ts +3 -0
  298. package/dist/routes/notifications.d.ts.map +1 -0
  299. package/dist/routes/notifications.js +104 -0
  300. package/dist/routes/notifications.js.map +1 -0
  301. package/dist/routes/oauth.d.ts +3 -0
  302. package/dist/routes/oauth.d.ts.map +1 -0
  303. package/dist/routes/oauth.js +516 -0
  304. package/dist/routes/oauth.js.map +1 -0
  305. package/dist/routes/rpc-proxy.d.ts +3 -0
  306. package/dist/routes/rpc-proxy.d.ts.map +1 -0
  307. package/dist/routes/rpc-proxy.js +116 -0
  308. package/dist/routes/rpc-proxy.js.map +1 -0
  309. package/dist/routes/security.d.ts +3 -0
  310. package/dist/routes/security.d.ts.map +1 -0
  311. package/dist/routes/security.js +43 -0
  312. package/dist/routes/security.js.map +1 -0
  313. package/dist/routes/skills.d.ts +3 -0
  314. package/dist/routes/skills.d.ts.map +1 -0
  315. package/dist/routes/skills.js +48 -0
  316. package/dist/routes/skills.js.map +1 -0
  317. package/dist/routes/snapshots.d.ts +3 -0
  318. package/dist/routes/snapshots.d.ts.map +1 -0
  319. package/dist/routes/snapshots.js +99 -0
  320. package/dist/routes/snapshots.js.map +1 -0
  321. package/dist/routes/system-config.d.ts +3 -0
  322. package/dist/routes/system-config.d.ts.map +1 -0
  323. package/dist/routes/system-config.js +75 -0
  324. package/dist/routes/system-config.js.map +1 -0
  325. package/dist/routes/templates.d.ts +3 -0
  326. package/dist/routes/templates.d.ts.map +1 -0
  327. package/dist/routes/templates.js +256 -0
  328. package/dist/routes/templates.js.map +1 -0
  329. package/dist/routes/ui-proxy.d.ts +3 -0
  330. package/dist/routes/ui-proxy.d.ts.map +1 -0
  331. package/dist/routes/ui-proxy.js +90 -0
  332. package/dist/routes/ui-proxy.js.map +1 -0
  333. package/dist/routes/user-credentials.d.ts +3 -0
  334. package/dist/routes/user-credentials.d.ts.map +1 -0
  335. package/dist/routes/user-credentials.js +85 -0
  336. package/dist/routes/user-credentials.js.map +1 -0
  337. package/dist/routes/users.d.ts +3 -0
  338. package/dist/routes/users.d.ts.map +1 -0
  339. package/dist/routes/users.js +30 -0
  340. package/dist/routes/users.js.map +1 -0
  341. package/dist/runtime/docker.d.ts +37 -0
  342. package/dist/runtime/docker.d.ts.map +1 -0
  343. package/dist/runtime/docker.js +612 -0
  344. package/dist/runtime/docker.js.map +1 -0
  345. package/dist/runtime/factory.d.ts +4 -0
  346. package/dist/runtime/factory.d.ts.map +1 -0
  347. package/dist/runtime/factory.js +21 -0
  348. package/dist/runtime/factory.js.map +1 -0
  349. package/dist/runtime/kubernetes.d.ts +34 -0
  350. package/dist/runtime/kubernetes.d.ts.map +1 -0
  351. package/dist/runtime/kubernetes.js +513 -0
  352. package/dist/runtime/kubernetes.js.map +1 -0
  353. package/dist/runtime/types.d.ts +81 -0
  354. package/dist/runtime/types.d.ts.map +1 -0
  355. package/dist/runtime/types.js +2 -0
  356. package/dist/runtime/types.js.map +1 -0
  357. package/dist/server-core.d.ts +26 -0
  358. package/dist/server-core.d.ts.map +1 -0
  359. package/dist/server-core.js +184 -0
  360. package/dist/server-core.js.map +1 -0
  361. package/dist/services/config-diff.d.ts +6 -0
  362. package/dist/services/config-diff.d.ts.map +1 -0
  363. package/dist/services/config-diff.js +85 -0
  364. package/dist/services/config-diff.js.map +1 -0
  365. package/dist/services/config-field-meta.d.ts +22 -0
  366. package/dist/services/config-field-meta.d.ts.map +1 -0
  367. package/dist/services/config-field-meta.js +177 -0
  368. package/dist/services/config-field-meta.js.map +1 -0
  369. package/dist/services/config-validator.d.ts +8 -0
  370. package/dist/services/config-validator.d.ts.map +1 -0
  371. package/dist/services/config-validator.js +59 -0
  372. package/dist/services/config-validator.js.map +1 -0
  373. package/dist/services/credential-audit.d.ts +13 -0
  374. package/dist/services/credential-audit.d.ts.map +1 -0
  375. package/dist/services/credential-audit.js +18 -0
  376. package/dist/services/credential-audit.js.map +1 -0
  377. package/dist/services/credential-store.d.ts +28 -0
  378. package/dist/services/credential-store.d.ts.map +1 -0
  379. package/dist/services/credential-store.js +99 -0
  380. package/dist/services/credential-store.js.map +1 -0
  381. package/dist/services/dlp-scanner.d.ts +9 -0
  382. package/dist/services/dlp-scanner.d.ts.map +1 -0
  383. package/dist/services/dlp-scanner.js +90 -0
  384. package/dist/services/dlp-scanner.js.map +1 -0
  385. package/dist/services/gateway-event-relay.d.ts +53 -0
  386. package/dist/services/gateway-event-relay.d.ts.map +1 -0
  387. package/dist/services/gateway-event-relay.js +519 -0
  388. package/dist/services/gateway-event-relay.js.map +1 -0
  389. package/dist/services/group-chat-manager.d.ts +17 -0
  390. package/dist/services/group-chat-manager.d.ts.map +1 -0
  391. package/dist/services/group-chat-manager.js +613 -0
  392. package/dist/services/group-chat-manager.js.map +1 -0
  393. package/dist/services/health-monitor.d.ts +3 -0
  394. package/dist/services/health-monitor.d.ts.map +1 -0
  395. package/dist/services/health-monitor.js +342 -0
  396. package/dist/services/health-monitor.js.map +1 -0
  397. package/dist/services/instance-manager.d.ts +20 -0
  398. package/dist/services/instance-manager.d.ts.map +1 -0
  399. package/dist/services/instance-manager.js +833 -0
  400. package/dist/services/instance-manager.js.map +1 -0
  401. package/dist/services/metadata-store.d.ts +3 -0
  402. package/dist/services/metadata-store.d.ts.map +1 -0
  403. package/dist/services/metadata-store.js +34 -0
  404. package/dist/services/metadata-store.js.map +1 -0
  405. package/dist/services/notification-store.d.ts +24 -0
  406. package/dist/services/notification-store.d.ts.map +1 -0
  407. package/dist/services/notification-store.js +216 -0
  408. package/dist/services/notification-store.js.map +1 -0
  409. package/dist/services/openrouter-models.d.ts +13 -0
  410. package/dist/services/openrouter-models.d.ts.map +1 -0
  411. package/dist/services/openrouter-models.js +46 -0
  412. package/dist/services/openrouter-models.js.map +1 -0
  413. package/dist/services/output-filter.d.ts +8 -0
  414. package/dist/services/output-filter.d.ts.map +1 -0
  415. package/dist/services/output-filter.js +230 -0
  416. package/dist/services/output-filter.js.map +1 -0
  417. package/dist/services/prompt-guard.d.ts +6 -0
  418. package/dist/services/prompt-guard.d.ts.map +1 -0
  419. package/dist/services/prompt-guard.js +165 -0
  420. package/dist/services/prompt-guard.js.map +1 -0
  421. package/dist/services/security-event-service.d.ts +11 -0
  422. package/dist/services/security-event-service.d.ts.map +1 -0
  423. package/dist/services/security-event-service.js +201 -0
  424. package/dist/services/security-event-service.js.map +1 -0
  425. package/dist/services/snapshot-store.d.ts +21 -0
  426. package/dist/services/snapshot-store.d.ts.map +1 -0
  427. package/dist/services/snapshot-store.js +330 -0
  428. package/dist/services/snapshot-store.js.map +1 -0
  429. package/dist/services/system-config.d.ts +15 -0
  430. package/dist/services/system-config.d.ts.map +1 -0
  431. package/dist/services/system-config.js +80 -0
  432. package/dist/services/system-config.js.map +1 -0
  433. package/dist/services/template-file-format.d.ts +32 -0
  434. package/dist/services/template-file-format.d.ts.map +1 -0
  435. package/dist/services/template-file-format.js +125 -0
  436. package/dist/services/template-file-format.js.map +1 -0
  437. package/dist/services/template-store.d.ts +21 -0
  438. package/dist/services/template-store.d.ts.map +1 -0
  439. package/dist/services/template-store.js +701 -0
  440. package/dist/services/template-store.js.map +1 -0
  441. package/dist/services/user-credential-store.d.ts +20 -0
  442. package/dist/services/user-credential-store.d.ts.map +1 -0
  443. package/dist/services/user-credential-store.js +243 -0
  444. package/dist/services/user-credential-store.js.map +1 -0
  445. package/dist/services/wizard-config-store.d.ts +38 -0
  446. package/dist/services/wizard-config-store.d.ts.map +1 -0
  447. package/dist/services/wizard-config-store.js +70 -0
  448. package/dist/services/wizard-config-store.js.map +1 -0
  449. package/dist/web-dist/assets/AdminPage-BrAU67Dg.js +1 -0
  450. package/dist/web-dist/assets/AgentAvatar-BKJckc1W.js +1 -0
  451. package/dist/web-dist/assets/AgentAvatar-Cq-M5jMd.css +1 -0
  452. package/dist/web-dist/assets/AppLayout-Bf0v_2wK.css +1 -0
  453. package/dist/web-dist/assets/AppLayout-DXgV0atq.js +1 -0
  454. package/dist/web-dist/assets/AssistantChatPage-uVLgKLay.js +6 -0
  455. package/dist/web-dist/assets/AssistantEditPage-Bab1X-DA.js +1 -0
  456. package/dist/web-dist/assets/AssistantVersionsPage-BQRw3BUF.js +1 -0
  457. package/dist/web-dist/assets/AvatarPicker-DmnkD8Rb.js +1 -0
  458. package/dist/web-dist/assets/AvatarPicker-LHUepNFa.css +1 -0
  459. package/dist/web-dist/assets/CeAuthProvider-38_x9VGA.js +1 -0
  460. package/dist/web-dist/assets/ChatHubPage-2l4cKq0x.css +1 -0
  461. package/dist/web-dist/assets/ChatHubPage-B2WduoUM.js +1 -0
  462. package/dist/web-dist/assets/ChatTab-CHpjEu8M.js +6 -0
  463. package/dist/web-dist/assets/CreateWizardPage-DFEQ3VX3.js +47 -0
  464. package/dist/web-dist/assets/CreateWizardPage-IqNXDOER.css +1 -0
  465. package/dist/web-dist/assets/CredentialsPage-CDeXpnLG.js +1 -0
  466. package/dist/web-dist/assets/CredentialsPage-aI4kLoJD.css +1 -0
  467. package/dist/web-dist/assets/DocsAboutPage-CMbxiw1u.js +26 -0
  468. package/dist/web-dist/assets/DocsChannelsPage-CtmKYKK_.js +1 -0
  469. package/dist/web-dist/assets/DocsGettingStartedPage-CpM7o8sw.js +1 -0
  470. package/dist/web-dist/assets/DocsGroupChatsPage-7w-RVSJR.js +1 -0
  471. package/dist/web-dist/assets/DocsHomePage-BGEU5xBg.js +1 -0
  472. package/dist/web-dist/assets/DocsInstancesPage-Sewnw_x7.js +1 -0
  473. package/dist/web-dist/assets/DocsLayout-S7-ONZwP.js +1 -0
  474. package/dist/web-dist/assets/DocsProvidersPage-MeWneL5K.js +1 -0
  475. package/dist/web-dist/assets/DocsSkillsPage-CzsHPXxE.js +1 -0
  476. package/dist/web-dist/assets/DocsTemplatesPage-BXASAEoO.js +1 -0
  477. package/dist/web-dist/assets/DocsWorkspacePage-qYNeK_YS.js +24 -0
  478. package/dist/web-dist/assets/ExportWizardPage-BhNvovbU.js +3 -0
  479. package/dist/web-dist/assets/ExportWizardPage-Cp-KSYUy.css +1 -0
  480. package/dist/web-dist/assets/GoogleOAuthCallback-CBvLawe2.js +1 -0
  481. package/dist/web-dist/assets/GroupChatPage-rMfhmtsX.js +1 -0
  482. package/dist/web-dist/assets/GroupChatsListPage-BOwxHFfA.js +1 -0
  483. package/dist/web-dist/assets/InstancePage-BBL68DKB.js +1 -0
  484. package/dist/web-dist/assets/InstancePage-CzysRY40.css +1 -0
  485. package/dist/web-dist/assets/MyAssistantsPage-B808ZfHg.css +1 -0
  486. package/dist/web-dist/assets/MyAssistantsPage-q3-hNMth.js +1 -0
  487. package/dist/web-dist/assets/ProfilePage-Dx8YdU59.js +1 -0
  488. package/dist/web-dist/assets/ProfilePage-JMOkUDx7.css +1 -0
  489. package/dist/web-dist/assets/SessionDrawer-Ba7pbZDJ.css +1 -0
  490. package/dist/web-dist/assets/SessionDrawer-CXzEQAfF.js +1 -0
  491. package/dist/web-dist/assets/SystemConfigPage-4dvxADwi.js +1 -0
  492. package/dist/web-dist/assets/SystemConfigPage-DRqVfLGt.css +1 -0
  493. package/dist/web-dist/assets/TemplatesPage-DqXuG-Gy.css +1 -0
  494. package/dist/web-dist/assets/TemplatesPage-HMS__ODO.js +1 -0
  495. package/dist/web-dist/assets/TestLoginPage-xVQL0lYP.js +1 -0
  496. package/dist/web-dist/assets/ThemeToggle-DymKEYXG.js +1 -0
  497. package/dist/web-dist/assets/WorkbenchPage-Bymo4SSt.css +1 -0
  498. package/dist/web-dist/assets/WorkbenchPage-ST3hVrbL.js +33 -0
  499. package/dist/web-dist/assets/api-B5psysvQ.js +1 -0
  500. package/dist/web-dist/assets/clock-dRyRszad.js +1 -0
  501. package/dist/web-dist/assets/createLucideIcon-DiGX-lN4.js +1 -0
  502. package/dist/web-dist/assets/group-chat-9BaA9G_8.css +1 -0
  503. package/dist/web-dist/assets/index-BqzqZJ96.js +26 -0
  504. package/dist/web-dist/assets/index-DyrDN1Of.css +1 -0
  505. package/dist/web-dist/assets/index-wWimwgy7.js +1 -0
  506. package/dist/web-dist/assets/provider-display-BgrE7u33.js +1 -0
  507. package/dist/web-dist/assets/types-1lNWpzYk.js +57 -0
  508. package/dist/web-dist/assets/types-B6ttO-6G.css +1 -0
  509. package/dist/web-dist/assets/useTranslation-B-8kenfJ.js +1 -0
  510. package/dist/web-dist/assets/zap-CVBnETFW.js +1 -0
  511. package/dist/web-dist/index.html +31 -0
  512. package/dist/web-dist/vite.svg +1 -0
  513. package/dist/ws/index.d.ts +7 -0
  514. package/dist/ws/index.d.ts.map +1 -0
  515. package/dist/ws/index.js +112 -0
  516. package/dist/ws/index.js.map +1 -0
  517. package/package.json +54 -0
@@ -0,0 +1,833 @@
1
+ import { randomUUID, createHash } from 'crypto';
2
+ import { db } from '../db/index.js';
3
+ import { config } from '../config.js';
4
+ import { getAgentType } from '../agent-types/registry.js';
5
+ import { getRuntimeEngine } from '../runtime/factory.js';
6
+ import { getDecryptedCredentials } from './credential-store.js';
7
+ import { broadcast } from '../ws/index.js';
8
+ import { connectGateway, disconnectGateway } from './gateway-event-relay.js';
9
+ import { validateConfigPatch } from './config-validator.js';
10
+ import { litellmKeyManager } from '../ee/litellm/litellm-key-manager.js';
11
+ import { safeAutoSnapshot } from './snapshot-store.js';
12
+ import { buildCredentialIndex, clearCredentialIndex, buildWorkspaceContentIndex, clearWorkspaceContentIndex } from './output-filter.js';
13
+ import { preloadDlpConfig, evictDlpConfig } from './gateway-event-relay.js';
14
+ import { scanContent } from './dlp-scanner.js';
15
+ import { createNotification } from './notification-store.js';
16
+ // ── helpers ──
17
+ function computeConfigHash(configFiles) {
18
+ const openclawJson = configFiles.get('openclaw.json');
19
+ if (!openclawJson)
20
+ return null;
21
+ return createHash('sha256').update(openclawJson).digest('hex');
22
+ }
23
+ function toInstance(row) {
24
+ const rawConfig = row.config;
25
+ let config = {};
26
+ if (typeof rawConfig === 'string') {
27
+ try {
28
+ config = JSON.parse(rawConfig);
29
+ }
30
+ catch {
31
+ config = {};
32
+ }
33
+ }
34
+ else if (rawConfig && typeof rawConfig === 'object') {
35
+ config = rawConfig;
36
+ }
37
+ return {
38
+ id: row.id,
39
+ userId: row.user_id,
40
+ name: row.name,
41
+ agentType: row.agent_type,
42
+ imageTag: row.image_tag,
43
+ status: row.status,
44
+ statusMessage: row.status_message || null,
45
+ deploymentTarget: row.deployment_target,
46
+ runtimeId: row.runtime_id || null,
47
+ controlEndpoint: row.control_endpoint || null,
48
+ authToken: row.auth_token,
49
+ config,
50
+ templateId: row.template_id || null,
51
+ templateVersion: row.template_version || null,
52
+ billingMode: row.billing_mode || undefined,
53
+ securityProfile: row.security_profile || 'standard',
54
+ proxyKeyId: row.proxy_key_id || null,
55
+ litellmKeyHash: row.litellm_key_hash || null,
56
+ avatar: row.avatar || null,
57
+ createdAt: String(row.created_at),
58
+ updatedAt: String(row.updated_at),
59
+ };
60
+ }
61
+ async function updateStatus(id, status, extra = {}, statusMessage) {
62
+ await db('instances').where({ id }).update({ status, status_message: statusMessage ?? null, updated_at: db.fn.now(), ...extra });
63
+ broadcast(id, { type: 'instance:status', instanceId: id, payload: { status, statusMessage: statusMessage ?? null } });
64
+ }
65
+ async function addEvent(instanceId, eventType, metadata = {}) {
66
+ await db('instance_events').insert({ instance_id: instanceId, event_type: eventType, metadata: JSON.stringify(metadata) });
67
+ }
68
+ export async function addSecurityEvent(instanceId, result) {
69
+ await addEvent(instanceId, 'security:prompt_injection_detected', {
70
+ severity: result.maxSeverity,
71
+ matchCount: result.matches.length,
72
+ categories: [...new Set(result.matches.map(m => m.category))],
73
+ patternIds: result.matches.map(m => m.patternId),
74
+ durationMs: result.durationMs,
75
+ });
76
+ }
77
+ export async function addOutputFilterEvent(instanceId, result) {
78
+ await addEvent(instanceId, 'security:output_filtered', {
79
+ mode: result.mode,
80
+ matchCount: result.matches.length,
81
+ categories: [...new Set(result.matches.map(m => m.category))],
82
+ durationMs: result.durationMs,
83
+ });
84
+ }
85
+ function buildSpec(instance, manifest, env) {
86
+ // Agent-type-specific image overrides via env vars (e.g. OPENCLAW_IMAGE=openclaw-gateway:2026.3.2-p1)
87
+ const imageOverride = instance.agentType === 'openclaw' ? config.docker.openclawImage : '';
88
+ // If imageTag contains ':' it's a custom image reference (e.g. "openclaw-gateway-clawra:2026.2.12-p1")
89
+ // used by templates that require a specialised Docker image.
90
+ const isCustomImage = instance.imageTag.includes(':');
91
+ const image = imageOverride
92
+ ? imageOverride
93
+ : isCustomImage
94
+ ? instance.imageTag
95
+ : manifest.image.registry
96
+ ? `${manifest.image.registry}${manifest.image.repository}:${instance.imageTag}`
97
+ : `${manifest.image.repository}:${instance.imageTag}`;
98
+ const containerName = `${instance.agentType}-${instance.id.slice(0, 8)}`;
99
+ return {
100
+ name: containerName,
101
+ image,
102
+ ports: manifest.ports.map(p => ({ name: p.name, containerPort: p.containerPort, protocol: p.protocol })),
103
+ env: Object.fromEntries(Object.entries(env).filter(([_, v]) => v !== undefined)),
104
+ secrets: {},
105
+ volumes: manifest.volumes.map(v => ({ name: v.name, mountPath: v.mountPath, size: v.defaultSize })),
106
+ resources: manifest.resources,
107
+ securityContext: manifest.securityContext,
108
+ healthCheck: manifest.healthCheck?.type === 'http' || manifest.healthCheck?.type === 'tcp'
109
+ ? { type: manifest.healthCheck.type, port: manifest.healthCheck.port, path: manifest.healthCheck.path, initialDelaySeconds: manifest.healthCheck.initialDelaySeconds, periodSeconds: manifest.healthCheck.periodSeconds }
110
+ : undefined,
111
+ labels: {
112
+ 'platform.io/agent-type': instance.agentType,
113
+ 'platform.io/instance-id': instance.id,
114
+ 'platform.io/user-id': instance.userId,
115
+ },
116
+ };
117
+ }
118
+ // ── public API ──
119
+ export async function createInstance(userId, req) {
120
+ const { manifest } = getAgentType(req.agentType);
121
+ const imageTag = req.imageTag || manifest.image.defaultTag;
122
+ const deploymentTarget = req.deploymentTarget || config.defaultDeploymentTarget;
123
+ const authToken = randomUUID();
124
+ const [row] = await db('instances')
125
+ .insert({
126
+ user_id: userId,
127
+ name: req.name,
128
+ agent_type: req.agentType,
129
+ image_tag: imageTag,
130
+ deployment_target: deploymentTarget,
131
+ billing_mode: req.billingMode === 'byok' ? 'byok' : 'platform',
132
+ security_profile: req.securityProfile || 'standard',
133
+ auth_token: authToken,
134
+ config: JSON.stringify(req.config || {}),
135
+ avatar: req.avatar || null,
136
+ })
137
+ .returning('*');
138
+ const instance = toInstance(row);
139
+ await addEvent(instance.id, 'created');
140
+ return instance;
141
+ }
142
+ const WORKSPACE_FILE_KEYS = [
143
+ { key: 'agentsmd', filename: 'workspace/AGENTS.md' },
144
+ { key: 'soulmd', filename: 'workspace/SOUL.md' },
145
+ { key: 'identitymd', filename: 'workspace/IDENTITY.md' },
146
+ { key: 'usermd', filename: 'workspace/USER.md' },
147
+ { key: 'toolsmd', filename: 'workspace/TOOLS.md' },
148
+ { key: 'bootstrapmd', filename: 'workspace/BOOTSTRAP.md' },
149
+ { key: 'heartbeatmd', filename: 'workspace/HEARTBEAT.md' },
150
+ { key: 'memorymd', filename: 'workspace/MEMORY.md' },
151
+ ];
152
+ export async function syncWorkspaceFromContainer(instanceId) {
153
+ const row = await db('instances').where({ id: instanceId }).first();
154
+ if (!row)
155
+ return;
156
+ const instance = toInstance(row);
157
+ if (!instance.runtimeId || instance.status !== 'running')
158
+ return;
159
+ try {
160
+ const { manifest } = getAgentType(instance.agentType);
161
+ const engine = getRuntimeEngine(instance.deploymentTarget);
162
+ if (!engine.readFile)
163
+ return;
164
+ const volumeMountPath = manifest.volumes[0]?.mountPath || '/home/node/.openclaw';
165
+ const currentConfig = (instance.config || {});
166
+ let changed = false;
167
+ for (const wf of WORKSPACE_FILE_KEYS) {
168
+ try {
169
+ const content = await engine.readFile(instance.runtimeId, `${volumeMountPath}/${wf.filename}`);
170
+ if (content !== null && content !== currentConfig[wf.key]) {
171
+ currentConfig[wf.key] = content;
172
+ changed = true;
173
+ }
174
+ }
175
+ catch {
176
+ // skip — file may not exist yet
177
+ }
178
+ }
179
+ if (changed) {
180
+ await db('instances').where({ id: instanceId }).update({ config: JSON.stringify(currentConfig), updated_at: db.fn.now() });
181
+ }
182
+ // DLP scan workspace files for leaked secrets
183
+ for (const wf of WORKSPACE_FILE_KEYS) {
184
+ const fileContent = currentConfig[wf.key];
185
+ if (typeof fileContent !== 'string' || !fileContent)
186
+ continue;
187
+ const findings = scanContent(fileContent, wf.filename);
188
+ if (findings.length > 0) {
189
+ const findingSummary = findings.map(f => `${f.patternName} (line ${f.lineNumber})`).join(', ');
190
+ await addEvent(instanceId, 'security:dlp_alert', {
191
+ filename: wf.filename,
192
+ findingCount: findings.length,
193
+ patterns: findings.map(f => ({ pattern: f.patternName, line: f.lineNumber, redacted: f.redacted })),
194
+ });
195
+ await createNotification({
196
+ userId: instance.userId,
197
+ instanceId,
198
+ type: 'dlp_alert',
199
+ severity: 'warn',
200
+ title: `Potential secret detected in ${wf.filename}`,
201
+ body: `DLP scan found ${findings.length} potential secret(s): ${findingSummary}`,
202
+ });
203
+ console.warn(`[syncWorkspace] DLP alert for ${instanceId}: ${findingSummary}`);
204
+ }
205
+ }
206
+ }
207
+ catch (err) {
208
+ console.error(`[syncWorkspace] Failed for ${instanceId}:`, err);
209
+ }
210
+ }
211
+ export async function reseedConfigFiles(instanceId) {
212
+ const row = await db('instances').where({ id: instanceId }).first();
213
+ if (!row)
214
+ return;
215
+ const instance = toInstance(row);
216
+ if (!instance.runtimeId || instance.status !== 'running')
217
+ return;
218
+ try {
219
+ const { manifest, adapter } = getAgentType(instance.agentType);
220
+ const engine = getRuntimeEngine(instance.deploymentTarget);
221
+ if (!adapter?.seedConfig || !engine.writeFiles)
222
+ return;
223
+ const creds = await getDecryptedCredentials(instanceId);
224
+ const userConfig = instance.config || {};
225
+ // Platform-mode: the LiteLLM virtual key is only available at startup
226
+ // (it's generated by litellm-key-manager and not persisted in the DB).
227
+ // During reseed, recover it from the on-disk auth-profiles.json so that
228
+ // seedConfig can produce a correct litellm-routed openclaw.json instead
229
+ // of falling back to the BYOK/openrouter code path.
230
+ let litellmKey;
231
+ if (instance.billingMode === 'platform' && engine.readFile) {
232
+ try {
233
+ const volumeMountPath = manifest.volumes[0]?.mountPath || '/home/node/.openclaw';
234
+ const raw = await engine.readFile(instance.runtimeId, `${volumeMountPath}/auth-profiles.json`);
235
+ if (raw) {
236
+ const parsed = JSON.parse(raw);
237
+ const litellmProfile = parsed.profiles?.['litellm:default'];
238
+ if (litellmProfile) {
239
+ // For images that use secretRef, the actual key lives in the
240
+ // container env var — seedConfig only needs a truthy value to
241
+ // enter the platform code path (it writes keyRef, not the raw key).
242
+ litellmKey = litellmProfile.apiKey || (litellmProfile.keyRef ? 'secret-ref-placeholder' : undefined);
243
+ }
244
+ }
245
+ }
246
+ catch {
247
+ // Can't read auth-profiles.json — litellmKey stays undefined,
248
+ // seedConfig will fall back to BYOK path.
249
+ }
250
+ }
251
+ const configFiles = await adapter.seedConfig({ instance, userConfig, credentials: creds, litellmKey });
252
+ if (configFiles.size === 0)
253
+ return;
254
+ const volumeMountPath = manifest.volumes[0]?.mountPath || '/home/node/.openclaw';
255
+ let filesToWrite = configFiles;
256
+ if (adapter.categorizeConfigFiles) {
257
+ const { alwaysOverwrite } = adapter.categorizeConfigFiles(configFiles);
258
+ filesToWrite = alwaysOverwrite;
259
+ }
260
+ if (filesToWrite.size > 0) {
261
+ await engine.writeFiles(instance.runtimeId, volumeMountPath, filesToWrite);
262
+ console.log(`[reseedConfig] Re-seeded ${filesToWrite.size} config file(s) for ${instanceId}`);
263
+ }
264
+ // Read back the on-disk openclaw.json to compute the hash.
265
+ // The gateway may normalise the file after we write it (e.g. inject
266
+ // plugins.load.paths), so hashing our in-memory version can drift.
267
+ let configHash = null;
268
+ if (engine.readFile) {
269
+ try {
270
+ await new Promise(r => setTimeout(r, 3000));
271
+ const diskContent = await engine.readFile(instance.runtimeId, `${volumeMountPath}/openclaw.json`);
272
+ if (diskContent) {
273
+ configHash = createHash('sha256').update(diskContent).digest('hex');
274
+ }
275
+ }
276
+ catch {
277
+ configHash = computeConfigHash(configFiles);
278
+ }
279
+ }
280
+ else {
281
+ configHash = computeConfigHash(configFiles);
282
+ }
283
+ if (configHash) {
284
+ await db('instances').where({ id: instanceId }).update({ config_hash: configHash });
285
+ }
286
+ // Refresh workspace content index with final seeded content (CIT-182)
287
+ const seededWorkspaceFiles = {};
288
+ for (const [path, content] of configFiles) {
289
+ if (path.startsWith('workspace/') && content.length > 0) {
290
+ seededWorkspaceFiles[path] = content;
291
+ }
292
+ }
293
+ if (Object.keys(seededWorkspaceFiles).length > 0) {
294
+ buildWorkspaceContentIndex(instanceId, seededWorkspaceFiles);
295
+ }
296
+ }
297
+ catch (err) {
298
+ console.error(`[reseedConfig] Failed for ${instanceId}:`, err);
299
+ }
300
+ }
301
+ export async function cloneInstance(sourceId, userId) {
302
+ const source = await getInstance(sourceId, userId);
303
+ if (!source)
304
+ throw new Error('Instance not found');
305
+ const authToken = randomUUID();
306
+ // Deep copy config but strip runtime-specific keys
307
+ const sourceConfig = (source.config && typeof source.config === 'object')
308
+ ? JSON.parse(JSON.stringify(source.config))
309
+ : {};
310
+ delete sourceConfig.__setupCommands;
311
+ const [row] = await db('instances')
312
+ .insert({
313
+ user_id: userId,
314
+ name: `Clone of ${source.name}`,
315
+ agent_type: source.agentType,
316
+ image_tag: source.imageTag,
317
+ deployment_target: source.deploymentTarget,
318
+ billing_mode: source.billingMode || 'platform',
319
+ security_profile: source.securityProfile || 'standard',
320
+ auth_token: authToken,
321
+ config: JSON.stringify(sourceConfig),
322
+ })
323
+ .returning('*');
324
+ const cloned = toInstance(row);
325
+ await addEvent(cloned.id, 'cloned', { sourceInstanceId: sourceId });
326
+ return cloned;
327
+ }
328
+ export async function getInstance(id, userId) {
329
+ const row = await db('instances').where({ id, user_id: userId }).first();
330
+ return row ? toInstance(row) : null;
331
+ }
332
+ export async function listInstances(userId) {
333
+ const rows = await db('instances').where({ user_id: userId }).orderBy('created_at', 'desc');
334
+ return rows.map(toInstance);
335
+ }
336
+ export async function updateSecurityProfile(id, userId, profile) {
337
+ const instance = await getInstance(id, userId);
338
+ if (!instance)
339
+ throw new Error('Instance not found');
340
+ await db('instances').where({ id, user_id: userId })
341
+ .update({ security_profile: profile, updated_at: db.fn.now() });
342
+ const updated = await getInstance(id, userId);
343
+ if (!updated)
344
+ throw new Error('Instance not found after update');
345
+ if (updated.status === 'running') {
346
+ await reseedConfigFiles(id);
347
+ const { adapter } = getAgentType(updated.agentType);
348
+ if (adapter?.translateRPC && updated.controlEndpoint) {
349
+ try {
350
+ const cfg = await adapter.translateRPC({
351
+ method: 'config.get',
352
+ params: {},
353
+ endpoint: updated.controlEndpoint,
354
+ token: updated.authToken,
355
+ instanceId: id,
356
+ });
357
+ if (cfg?.hash) {
358
+ // Gateway 2026.3.13+ expects { raw: <full JSON string> }
359
+ const engine2 = getRuntimeEngine(updated.deploymentTarget);
360
+ const { manifest: m2 } = getAgentType(updated.agentType);
361
+ let rawConfig;
362
+ if (engine2.readFile && updated.runtimeId) {
363
+ const volPath = m2.volumes[0]?.mountPath || '/home/node/.openclaw';
364
+ try {
365
+ rawConfig = await engine2.readFile(updated.runtimeId, `${volPath}/openclaw.json`);
366
+ }
367
+ catch { /* fallback */ }
368
+ }
369
+ await adapter.translateRPC({
370
+ method: 'config.patch',
371
+ params: {
372
+ ...(rawConfig ? { raw: rawConfig } : { patch: {} }),
373
+ baseHash: cfg.hash,
374
+ note: `Platform: security profile → ${profile}`,
375
+ restartDelayMs: 2000,
376
+ },
377
+ endpoint: updated.controlEndpoint,
378
+ token: updated.authToken,
379
+ instanceId: id,
380
+ });
381
+ }
382
+ }
383
+ catch (err) {
384
+ console.error(`[security-profile] config.patch failed for ${id}:`, err);
385
+ }
386
+ }
387
+ }
388
+ return updated;
389
+ }
390
+ export async function startInstance(id, userId) {
391
+ const instance = await getInstance(id, userId);
392
+ if (!instance)
393
+ throw new Error('Instance not found');
394
+ if (instance.status !== 'created' && instance.status !== 'stopped' && instance.status !== 'error') {
395
+ throw new Error(`Cannot start instance in state: ${instance.status}`);
396
+ }
397
+ await updateStatus(id, 'starting');
398
+ await addEvent(id, 'starting');
399
+ // Run the heavy provisioning work in the background so the HTTP response
400
+ // returns immediately. The frontend already tracks status via WebSocket.
401
+ startInstanceAsync(id, userId, instance).catch(() => {
402
+ // errors handled inside — this catch prevents unhandled-rejection noise
403
+ });
404
+ return (await getInstance(id, userId));
405
+ }
406
+ async function startInstanceAsync(id, userId, instance) {
407
+ const { manifest, adapter } = getAgentType(instance.agentType);
408
+ const engine = getRuntimeEngine(instance.deploymentTarget);
409
+ let litellmKey;
410
+ try {
411
+ const creds = await getDecryptedCredentials(id);
412
+ buildCredentialIndex(id, creds.map(c => c.value));
413
+ preloadDlpConfig(id, instance.securityProfile ?? 'standard');
414
+ // Platform Mode: create LiteLLM virtual key for this instance.
415
+ // This MUST succeed — without a valid key the adapter falls back to
416
+ // BYOK mode which produces a broken config (no provider credentials).
417
+ if (instance.billingMode === 'platform') {
418
+ const userRow = await db('users').where('id', userId).select('email').first();
419
+ if (!userRow?.email) {
420
+ throw new Error('Platform billing requires a user email for LiteLLM key generation');
421
+ }
422
+ const result = await litellmKeyManager.createKeyForInstance({
423
+ instanceId: id,
424
+ userId,
425
+ userEmail: userRow.email,
426
+ });
427
+ litellmKey = result.virtualKey;
428
+ }
429
+ let env = {};
430
+ if (adapter?.resolveEnv) {
431
+ env = await adapter.resolveEnv({ instance, credentials: creds, litellmKey });
432
+ }
433
+ // Build spec
434
+ const spec = buildSpec(instance, manifest, env);
435
+ // Start container
436
+ const result = await engine.start(spec);
437
+ // Record runtime info immediately so the health monitor can track it
438
+ const controlEndpoint = result.endpoints[manifest.ports[0]?.name] || null;
439
+ await updateStatus(id, 'starting', {
440
+ runtime_id: result.runtimeId,
441
+ control_endpoint: controlEndpoint,
442
+ }, 'Provisioning pod...');
443
+ // Seed config files into running container
444
+ const userConfig = instance.config || {};
445
+ if (adapter?.seedConfig && engine.writeFiles) {
446
+ await updateStatus(id, 'starting', {}, 'Waiting for pod ready...');
447
+ const configFiles = await adapter.seedConfig({ instance, userConfig, credentials: creds, litellmKey });
448
+ if (configFiles.size > 0) {
449
+ const volumeMountPath = manifest.volumes[0]?.mountPath || '/home/node/.openclaw';
450
+ let filesToWrite = configFiles;
451
+ if (adapter.categorizeConfigFiles && engine.listFiles) {
452
+ const { alwaysOverwrite, seedIfAbsent } = adapter.categorizeConfigFiles(configFiles);
453
+ const existingFiles = await engine.listFiles(result.runtimeId, `${volumeMountPath}/workspace`).catch(() => []);
454
+ filesToWrite = new Map(alwaysOverwrite);
455
+ for (const [path, content] of seedIfAbsent) {
456
+ const filename = path.split('/').pop() || path;
457
+ if (!existingFiles.includes(filename)) {
458
+ filesToWrite.set(path, content);
459
+ }
460
+ }
461
+ }
462
+ if (filesToWrite.size > 0) {
463
+ await updateStatus(id, 'starting', {}, 'Seeding config files...');
464
+ await engine.writeFiles(result.runtimeId, volumeMountPath, filesToWrite);
465
+ }
466
+ // Store SHA-256 hash of openclaw.json for integrity verification
467
+ const configHash = computeConfigHash(configFiles);
468
+ if (configHash) {
469
+ await db('instances').where({ id }).update({ config_hash: configHash });
470
+ }
471
+ // Build workspace content index from final seeded files (CIT-182:
472
+ // must use post-seedConfig content so injected security paragraphs are indexed)
473
+ const seededWorkspaceFiles = {};
474
+ for (const [path, content] of configFiles) {
475
+ if (path.startsWith('workspace/') && content.length > 0) {
476
+ seededWorkspaceFiles[path] = content;
477
+ }
478
+ }
479
+ buildWorkspaceContentIndex(id, seededWorkspaceFiles);
480
+ }
481
+ }
482
+ // Execute template setup commands inside the container
483
+ const setupCommands = userConfig.__setupCommands;
484
+ if (setupCommands && setupCommands.length > 0 && engine.exec) {
485
+ await updateStatus(id, 'starting', {}, 'Running setup commands...');
486
+ for (const cmd of setupCommands) {
487
+ try {
488
+ const execResult = await engine.exec(result.runtimeId, cmd.command, {
489
+ workDir: cmd.workDir,
490
+ timeout: cmd.timeout,
491
+ });
492
+ if (execResult.exitCode !== 0) {
493
+ console.warn(`[startInstance] Setup command failed (exit ${execResult.exitCode}): ${cmd.command.join(' ')}`, execResult.stderr);
494
+ }
495
+ }
496
+ catch (err) {
497
+ console.warn(`[startInstance] Setup command error: ${cmd.command.join(' ')}`, err);
498
+ }
499
+ }
500
+ }
501
+ // K8s pods take minutes to become ready; health monitor transitions starting→running
502
+ const isK8s = instance.deploymentTarget === 'kubernetes';
503
+ if (!isK8s) {
504
+ await updateStatus(id, 'running', {});
505
+ }
506
+ await addEvent(id, 'started', { runtimeId: result.runtimeId });
507
+ // Eagerly establish persistent gateway connection (don't wait for 10s poll)
508
+ if (controlEndpoint && instance.authToken) {
509
+ connectGateway(id, controlEndpoint, instance.authToken);
510
+ }
511
+ }
512
+ catch (err) {
513
+ const message = err instanceof Error ? err.message : String(err);
514
+ console.error(`[startInstance] Failed for ${id}:`, message);
515
+ await updateStatus(id, 'error');
516
+ await addEvent(id, 'error', { message });
517
+ clearCredentialIndex(id);
518
+ clearWorkspaceContentIndex(id);
519
+ evictDlpConfig(id);
520
+ if (litellmKey && instance.billingMode === 'platform') {
521
+ try {
522
+ await litellmKeyManager.revokeKeyForInstance(id);
523
+ }
524
+ catch (revokeErr) {
525
+ console.warn('[startInstance] Failed to revoke LiteLLM key during error cleanup:', revokeErr);
526
+ }
527
+ }
528
+ }
529
+ }
530
+ export async function stopInstance(id, userId) {
531
+ const instance = await getInstance(id, userId);
532
+ if (!instance)
533
+ throw new Error('Instance not found');
534
+ if (instance.status !== 'running' && instance.status !== 'starting' && instance.status !== 'error') {
535
+ throw new Error(`Cannot stop instance in state: ${instance.status}`);
536
+ }
537
+ await updateStatus(id, 'stopping');
538
+ stopInstanceAsync(id, userId, instance).catch(() => { });
539
+ return (await getInstance(id, userId));
540
+ }
541
+ async function stopInstanceAsync(id, userId, instance) {
542
+ disconnectGateway(id);
543
+ clearCredentialIndex(id);
544
+ clearWorkspaceContentIndex(id);
545
+ evictDlpConfig(id);
546
+ const engine = getRuntimeEngine(instance.deploymentTarget);
547
+ try {
548
+ if (instance.runtimeId) {
549
+ await engine.stop(instance.runtimeId);
550
+ await engine.delete(instance.runtimeId);
551
+ }
552
+ await updateStatus(id, 'stopped', { runtime_id: null, control_endpoint: null });
553
+ await addEvent(id, 'stopped');
554
+ // Platform Mode: revoke LiteLLM virtual key
555
+ if (instance.billingMode === 'platform') {
556
+ try {
557
+ await litellmKeyManager.revokeKeyForInstance(id);
558
+ }
559
+ catch (err) {
560
+ console.warn(`[stopInstance] LiteLLM key revocation failed for ${id}:`, err);
561
+ }
562
+ }
563
+ }
564
+ catch (err) {
565
+ const message = err instanceof Error ? err.message : String(err);
566
+ console.error(`[stopInstance] Failed for ${id}:`, message);
567
+ await updateStatus(id, 'error');
568
+ await addEvent(id, 'error', { message });
569
+ }
570
+ }
571
+ export async function restartInstance(id, userId) {
572
+ const instance = await getInstance(id, userId);
573
+ if (!instance)
574
+ throw new Error('Instance not found');
575
+ await safeAutoSnapshot(id, userId, '重启实例');
576
+ if (instance.status === 'running' || instance.status === 'starting' || instance.status === 'error') {
577
+ // Stop synchronously so we don't start a new pod while the old one is still running
578
+ const engine = getRuntimeEngine(instance.deploymentTarget);
579
+ try {
580
+ if (instance.runtimeId) {
581
+ await engine.stop(instance.runtimeId);
582
+ await engine.delete(instance.runtimeId);
583
+ }
584
+ await updateStatus(instance.id, 'stopped', { runtime_id: null, control_endpoint: null });
585
+ }
586
+ catch {
587
+ // best effort — proceed to start anyway
588
+ }
589
+ }
590
+ return startInstance(id, userId);
591
+ }
592
+ export async function updateInstanceConfig(id, userId, config) {
593
+ const instance = await getInstance(id, userId);
594
+ if (!instance)
595
+ throw new Error('Instance not found');
596
+ const changedFiles = Object.keys(config).join(', ');
597
+ await safeAutoSnapshot(id, userId, '修改配置: ' + changedFiles);
598
+ const patch = { config: JSON.stringify(config), updated_at: db.fn.now() };
599
+ // Sync platform-level fields from config JSONB to their dedicated columns
600
+ if (config.billingMode === 'platform' || config.billingMode === 'byok') {
601
+ patch.billing_mode = config.billingMode;
602
+ }
603
+ // Sync agentName to the instance name column so dashboard reflects the updated name
604
+ if (typeof config.agentName === 'string' && config.agentName.trim()) {
605
+ patch.name = config.agentName;
606
+ }
607
+ await db('instances').where({ id }).update(patch);
608
+ return (await getInstance(id, userId));
609
+ }
610
+ // ── config.patch hot-reload ──
611
+ function deepMerge(target, source) {
612
+ const result = { ...target };
613
+ for (const key of Object.keys(source)) {
614
+ if (source[key] && typeof source[key] === 'object' && !Array.isArray(source[key]) &&
615
+ result[key] && typeof result[key] === 'object' && !Array.isArray(result[key])) {
616
+ result[key] = deepMerge(result[key], source[key]);
617
+ }
618
+ else {
619
+ result[key] = source[key];
620
+ }
621
+ }
622
+ return result;
623
+ }
624
+ export async function patchGatewayConfig(instanceId, userId, configPatch, note) {
625
+ // 1. DB-first: fetch instance, deep-merge config, persist
626
+ const instance = await getInstance(instanceId, userId);
627
+ if (!instance)
628
+ throw new Error('Instance not found');
629
+ await safeAutoSnapshot(instanceId, userId, '修改 Gateway 配置');
630
+ const mergedConfig = deepMerge((instance.config || {}), configPatch);
631
+ // Validate merged config against gateway schema before persisting to DB
632
+ const fetchSchema = async () => {
633
+ if (instance.status !== 'running' || !instance.controlEndpoint)
634
+ return null;
635
+ try {
636
+ const { adapter } = getAgentType(instance.agentType);
637
+ if (!adapter?.translateRPC)
638
+ return null;
639
+ const result = await adapter.translateRPC({
640
+ method: 'config.schema',
641
+ params: {},
642
+ endpoint: instance.controlEndpoint,
643
+ token: instance.authToken,
644
+ instanceId,
645
+ });
646
+ return result?.schema ?? null;
647
+ }
648
+ catch {
649
+ return null;
650
+ }
651
+ };
652
+ const validation = await validateConfigPatch(instanceId, mergedConfig, fetchSchema, { skipFullSchemaValidation: true });
653
+ if (!validation.valid) {
654
+ throw new Error('Config validation failed: ' + (validation.errors?.join('; ') ?? 'Unknown error'));
655
+ }
656
+ await updateInstanceConfig(instanceId, userId, mergedConfig);
657
+ // 2. Gateway push (only if running)
658
+ if (instance.status !== 'running' || !instance.controlEndpoint) {
659
+ return;
660
+ }
661
+ try {
662
+ const { adapter } = getAgentType(instance.agentType);
663
+ if (!adapter?.translateRPC)
664
+ return;
665
+ const endpoint = instance.controlEndpoint;
666
+ const token = instance.authToken;
667
+ const MAX_RETRIES = 3;
668
+ for (let attempt = 1; attempt <= MAX_RETRIES; attempt++) {
669
+ // Fetch current config hash
670
+ const cfgResult = await adapter.translateRPC({
671
+ method: 'config.get',
672
+ params: {},
673
+ endpoint,
674
+ token,
675
+ instanceId,
676
+ });
677
+ const baseHash = cfgResult?.hash;
678
+ // Gateway 2026.3.13+ expects { raw: <full JSON string> } instead of { patch: <object> }.
679
+ // Re-seed config files to disk first, then read the full config to send as raw.
680
+ await reseedConfigFiles(instanceId);
681
+ // Read the seeded config file content
682
+ const { manifest: m2, adapter: a2 } = getAgentType(instance.agentType);
683
+ const engine2 = getRuntimeEngine(instance.deploymentTarget);
684
+ let rawConfig;
685
+ if (a2?.seedConfig && engine2.readFile && instance.runtimeId) {
686
+ const volumeMountPath = m2.volumes[0]?.mountPath || '/home/node/.openclaw';
687
+ try {
688
+ rawConfig = await engine2.readFile(instance.runtimeId, `${volumeMountPath}/openclaw.json`);
689
+ }
690
+ catch { /* fallback: send without raw */ }
691
+ }
692
+ try {
693
+ await adapter.translateRPC({
694
+ method: 'config.patch',
695
+ params: {
696
+ ...(rawConfig ? { raw: rawConfig } : { patch: configPatch }),
697
+ baseHash,
698
+ note: note || 'Platform config update',
699
+ restartDelayMs: 2000,
700
+ },
701
+ endpoint,
702
+ token,
703
+ instanceId,
704
+ });
705
+ console.log(`[config-patch] Pushed config.patch for ${instanceId}`);
706
+ return;
707
+ }
708
+ catch (patchErr) {
709
+ const errMsg = patchErr instanceof Error ? patchErr.message : String(patchErr);
710
+ if ((errMsg.includes('config changed') || errMsg.includes('CONFLICT')) && attempt < MAX_RETRIES) {
711
+ console.warn(`[config-patch] baseHash conflict for ${instanceId}, retrying (${attempt}/${MAX_RETRIES})`);
712
+ continue;
713
+ }
714
+ throw patchErr;
715
+ }
716
+ }
717
+ }
718
+ catch (err) {
719
+ // Gateway push failure is non-critical -- DB is already updated.
720
+ // Config will be picked up on next reseedConfigFiles.
721
+ console.error(`[config-patch] Gateway push failed for ${instanceId}:`, err);
722
+ }
723
+ }
724
+ export async function deleteInstance(id, userId, purge = false) {
725
+ const instance = await getInstance(id, userId);
726
+ if (!instance)
727
+ throw new Error('Instance not found');
728
+ disconnectGateway(id);
729
+ clearCredentialIndex(id);
730
+ clearWorkspaceContentIndex(id);
731
+ evictDlpConfig(id);
732
+ const engine = getRuntimeEngine(instance.deploymentTarget);
733
+ if (instance.runtimeId) {
734
+ try {
735
+ if (purge) {
736
+ await engine.purge(instance.runtimeId);
737
+ }
738
+ else {
739
+ await engine.stop(instance.runtimeId);
740
+ await engine.delete(instance.runtimeId);
741
+ }
742
+ }
743
+ catch {
744
+ // Best effort cleanup
745
+ }
746
+ }
747
+ await addEvent(id, purge ? 'purged' : 'deleted');
748
+ await db('instances').where({ id, user_id: userId }).delete();
749
+ }
750
+ export async function getInstanceEvents(id, userId, eventType) {
751
+ const instance = await getInstance(id, userId);
752
+ if (!instance)
753
+ throw new Error('Instance not found');
754
+ let query = db('instance_events').where({ instance_id: id });
755
+ if (eventType) {
756
+ query = query.where('event_type', eventType);
757
+ }
758
+ const rows = await query.orderBy('created_at', 'desc').limit(100);
759
+ return rows.map((row) => ({
760
+ id: row.id,
761
+ instanceId: row.instance_id,
762
+ eventType: row.event_type,
763
+ metadata: (typeof row.metadata === 'string' ? JSON.parse(row.metadata) : row.metadata ?? {}),
764
+ createdAt: row.created_at.toISOString(),
765
+ }));
766
+ }
767
+ export async function reconcileInstances() {
768
+ const activeInstances = await db('instances').whereIn('status', ['running', 'starting']);
769
+ for (const row of activeInstances) {
770
+ const instance = toInstance(row);
771
+ if (!instance.runtimeId) {
772
+ await updateStatus(instance.id, 'stopped', { runtime_id: null, control_endpoint: null });
773
+ continue;
774
+ }
775
+ try {
776
+ const engine = getRuntimeEngine(instance.deploymentTarget);
777
+ const status = await engine.getStatus(instance.runtimeId);
778
+ if (status.phase === 'running') {
779
+ await engine.ensureLiteLLMConnected?.(instance.id);
780
+ }
781
+ else if (status.phase === 'stopped' || status.phase === 'not_found') {
782
+ await updateStatus(instance.id, 'stopped', { runtime_id: null, control_endpoint: null });
783
+ }
784
+ else if (status.phase === 'error') {
785
+ await updateStatus(instance.id, 'error');
786
+ }
787
+ }
788
+ catch {
789
+ await updateStatus(instance.id, 'error');
790
+ }
791
+ }
792
+ }
793
+ export async function verifyLiveStatus(instance) {
794
+ if (instance.status !== 'running' && instance.status !== 'starting') {
795
+ return instance;
796
+ }
797
+ if (!instance.runtimeId) {
798
+ return instance;
799
+ }
800
+ try {
801
+ const engine = getRuntimeEngine(instance.deploymentTarget);
802
+ const runtimeStatus = await engine.getStatus(instance.runtimeId);
803
+ if (runtimeStatus.phase === 'running') {
804
+ if (instance.status === 'running')
805
+ return instance;
806
+ if (instance.status === 'starting') {
807
+ await updateStatus(instance.id, 'running');
808
+ return { ...instance, status: 'running', statusMessage: null };
809
+ }
810
+ }
811
+ if (runtimeStatus.phase === 'starting') {
812
+ const statusMessage = runtimeStatus.message || 'Starting...';
813
+ if (instance.status !== 'starting' || instance.statusMessage !== statusMessage) {
814
+ await updateStatus(instance.id, 'starting', {}, statusMessage);
815
+ }
816
+ return { ...instance, status: 'starting', statusMessage };
817
+ }
818
+ if (runtimeStatus.phase === 'stopped' || runtimeStatus.phase === 'not_found') {
819
+ await updateStatus(instance.id, 'stopped', { runtime_id: null, control_endpoint: null });
820
+ return { ...instance, status: 'stopped', runtimeId: null, controlEndpoint: null, statusMessage: null };
821
+ }
822
+ if (runtimeStatus.phase === 'error') {
823
+ const statusMessage = runtimeStatus.message || null;
824
+ await updateStatus(instance.id, 'error', {}, statusMessage ?? undefined);
825
+ return { ...instance, status: 'error', statusMessage };
826
+ }
827
+ }
828
+ catch (err) {
829
+ console.error(`[verifyLiveStatus] Runtime check failed for ${instance.id}:`, err);
830
+ }
831
+ return instance;
832
+ }
833
+ //# sourceMappingURL=instance-manager.js.map