jishushell 0.6.5 → 0.7.3

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 (1207) hide show
  1. package/apps/anythingllm-container.yaml +16 -170
  2. package/apps/browserless-chromium-container.yaml +16 -10
  3. package/apps/filebrowser-container.yaml +15 -9
  4. package/apps/hermes-container.yaml +20 -5
  5. package/apps/immich-container-lite.yaml +337 -0
  6. package/apps/immich-container.yaml +371 -0
  7. package/apps/jishu-kb-container.yaml +50 -177
  8. package/apps/ollama-binary.yaml +33 -28
  9. package/apps/ollama-cpu-container.yaml +6 -0
  10. package/apps/ollama-with-hollama-binary.yaml +35 -28
  11. package/apps/openclaw-binary.yaml +35 -15
  12. package/apps/openclaw-container.yaml +29 -11
  13. package/apps/openclaw-with-ollama-container.yaml +9 -2
  14. package/apps/openclaw-with-searxng-container.yaml +38 -6
  15. package/apps/searxng-container.yaml +31 -6
  16. package/apps/weknora-container.yaml +26 -21
  17. package/dependencies/jishushell-panel-0.7.3.tgz +0 -0
  18. package/dist/cli/app.js +244 -213
  19. package/dist/cli/app.js.map +1 -1
  20. package/dist/cli/backup.js +15 -12
  21. package/dist/cli/backup.js.map +1 -1
  22. package/dist/cli/core.d.ts +4 -3
  23. package/dist/cli/core.js +392 -227
  24. package/dist/cli/core.js.map +1 -1
  25. package/dist/cli/doctor.d.ts +1 -1
  26. package/dist/cli/doctor.js +113 -10
  27. package/dist/cli/doctor.js.map +1 -1
  28. package/dist/cli/job.js +62 -14
  29. package/dist/cli/job.js.map +1 -1
  30. package/dist/cli/llm.js +80 -11
  31. package/dist/cli/llm.js.map +1 -1
  32. package/dist/cli/managed-list.d.ts +1 -3
  33. package/dist/cli/managed-list.js +18 -16
  34. package/dist/cli/managed-list.js.map +1 -1
  35. package/dist/cli/migrate.d.ts +2 -0
  36. package/dist/cli/migrate.js +160 -0
  37. package/dist/cli/migrate.js.map +1 -0
  38. package/dist/cli.js +1 -0
  39. package/dist/cli.js.map +1 -1
  40. package/dist/config.d.ts +32 -20
  41. package/dist/config.js +132 -51
  42. package/dist/config.js.map +1 -1
  43. package/dist/control.d.ts +6 -6
  44. package/dist/control.js +31 -23
  45. package/dist/control.js.map +1 -1
  46. package/dist/core.d.ts +5 -5
  47. package/dist/core.js +5 -5
  48. package/dist/core.js.map +1 -1
  49. package/dist/install.d.ts +2 -2
  50. package/dist/install.js +78 -37
  51. package/dist/install.js.map +1 -1
  52. package/dist/routes/admin.d.ts +2 -0
  53. package/dist/routes/admin.js +72 -0
  54. package/dist/routes/admin.js.map +1 -0
  55. package/dist/routes/apps.d.ts +1 -1
  56. package/dist/routes/apps.js +101 -193
  57. package/dist/routes/apps.js.map +1 -1
  58. package/dist/routes/auth.js +1 -1
  59. package/dist/routes/auth.js.map +1 -1
  60. package/dist/routes/backup.js +1 -1
  61. package/dist/routes/backup.js.map +1 -1
  62. package/dist/routes/docker.d.ts +2 -0
  63. package/dist/routes/docker.js +58 -0
  64. package/dist/routes/docker.js.map +1 -0
  65. package/dist/routes/external-mounts.d.ts +1 -1
  66. package/dist/routes/external-mounts.js +1 -1
  67. package/dist/routes/external-mounts.js.map +1 -1
  68. package/dist/routes/file-mounts.d.ts +4 -3
  69. package/dist/routes/file-mounts.js +49 -31
  70. package/dist/routes/file-mounts.js.map +1 -1
  71. package/dist/routes/files-organize.d.ts +2 -2
  72. package/dist/routes/files-organize.js +5 -5
  73. package/dist/routes/files-organize.js.map +1 -1
  74. package/dist/routes/files.d.ts +1 -1
  75. package/dist/routes/files.js +1 -1
  76. package/dist/routes/files.js.map +1 -1
  77. package/dist/routes/instances.d.ts +0 -8
  78. package/dist/routes/instances.js +202 -1560
  79. package/dist/routes/instances.js.map +1 -1
  80. package/dist/routes/integration-apps.d.ts +14 -0
  81. package/dist/routes/integration-apps.js +81 -0
  82. package/dist/routes/integration-apps.js.map +1 -0
  83. package/dist/routes/integrations.d.ts +9 -0
  84. package/dist/routes/integrations.js +12 -0
  85. package/dist/routes/integrations.js.map +1 -0
  86. package/dist/routes/llm-proxy.js +26 -3
  87. package/dist/routes/llm-proxy.js.map +1 -1
  88. package/dist/routes/setup.js +53 -38
  89. package/dist/routes/setup.js.map +1 -1
  90. package/dist/routes/system.js +108 -68
  91. package/dist/routes/system.js.map +1 -1
  92. package/dist/routes/webdav.d.ts +1 -1
  93. package/dist/routes/webdav.js +2 -2
  94. package/dist/routes/webdav.js.map +1 -1
  95. package/dist/server.d.ts +6 -0
  96. package/dist/server.js +368 -233
  97. package/dist/server.js.map +1 -1
  98. package/dist/services/app-common/app-compiler.js +186 -0
  99. package/dist/services/app-common/app-compiler.js.map +1 -0
  100. package/dist/services/app-common/app-shared.d.ts +15 -0
  101. package/dist/services/app-common/app-shared.js +64 -0
  102. package/dist/services/app-common/app-shared.js.map +1 -0
  103. package/dist/services/app-common/capability-service.d.ts +45 -0
  104. package/dist/services/app-common/capability-service.js +331 -0
  105. package/dist/services/app-common/capability-service.js.map +1 -0
  106. package/dist/services/app-common/catalog-service.d.ts +59 -0
  107. package/dist/services/app-common/catalog-service.js +318 -0
  108. package/dist/services/app-common/catalog-service.js.map +1 -0
  109. package/dist/services/app-common/create-pipeline.d.ts +26 -0
  110. package/dist/services/app-common/create-pipeline.js +298 -0
  111. package/dist/services/app-common/create-pipeline.js.map +1 -0
  112. package/dist/services/app-common/delete-service.d.ts +5 -0
  113. package/dist/services/app-common/delete-service.js +109 -0
  114. package/dist/services/app-common/delete-service.js.map +1 -0
  115. package/dist/services/app-common/execution-owner.d.ts +23 -0
  116. package/dist/services/app-common/execution-owner.js +124 -0
  117. package/dist/services/app-common/execution-owner.js.map +1 -0
  118. package/dist/services/app-common/execution-service.d.ts +23 -0
  119. package/dist/services/app-common/execution-service.js +105 -0
  120. package/dist/services/app-common/execution-service.js.map +1 -0
  121. package/dist/services/app-common/id-normalizer.d.ts +31 -0
  122. package/dist/services/app-common/id-normalizer.js +83 -0
  123. package/dist/services/app-common/id-normalizer.js.map +1 -0
  124. package/dist/services/app-common/install-store.d.ts +34 -0
  125. package/dist/services/app-common/install-store.js +261 -0
  126. package/dist/services/app-common/install-store.js.map +1 -0
  127. package/dist/services/app-common/instance-store.d.ts +78 -0
  128. package/dist/services/app-common/instance-store.js +498 -0
  129. package/dist/services/app-common/instance-store.js.map +1 -0
  130. package/dist/services/app-common/integration-refs.d.ts +17 -0
  131. package/dist/services/app-common/integration-refs.js +47 -0
  132. package/dist/services/app-common/integration-refs.js.map +1 -0
  133. package/dist/services/app-common/lifecycle-pipeline.d.ts +62 -0
  134. package/dist/services/app-common/lifecycle-pipeline.js +317 -0
  135. package/dist/services/app-common/lifecycle-pipeline.js.map +1 -0
  136. package/dist/services/app-common/lifecycle-scripts.d.ts +38 -0
  137. package/dist/services/app-common/lifecycle-scripts.js +935 -0
  138. package/dist/services/app-common/lifecycle-scripts.js.map +1 -0
  139. package/dist/services/app-common/lifecycle-service.d.ts +68 -0
  140. package/dist/services/app-common/lifecycle-service.js +475 -0
  141. package/dist/services/app-common/lifecycle-service.js.map +1 -0
  142. package/dist/services/app-common/ownership.d.ts +3 -0
  143. package/dist/services/app-common/ownership.js +11 -0
  144. package/dist/services/app-common/ownership.js.map +1 -0
  145. package/dist/services/app-common/paths.d.ts +29 -0
  146. package/dist/services/app-common/paths.js +34 -0
  147. package/dist/services/app-common/paths.js.map +1 -0
  148. package/dist/services/app-common/platform-transform.d.ts +32 -0
  149. package/dist/services/app-common/platform-transform.js +65 -0
  150. package/dist/services/app-common/platform-transform.js.map +1 -0
  151. package/dist/services/app-common/provide-resolver.d.ts +29 -0
  152. package/dist/services/app-common/provide-resolver.js +129 -0
  153. package/dist/services/app-common/provide-resolver.js.map +1 -0
  154. package/dist/services/app-common/remote-spec.d.ts +14 -0
  155. package/dist/services/app-common/remote-spec.js +58 -0
  156. package/dist/services/app-common/remote-spec.js.map +1 -0
  157. package/dist/services/app-common/runtime-builder.d.ts +1 -0
  158. package/dist/services/app-common/runtime-builder.js +2 -0
  159. package/dist/services/app-common/runtime-builder.js.map +1 -0
  160. package/dist/services/app-common/runtime-facts.d.ts +19 -0
  161. package/dist/services/app-common/runtime-facts.js +128 -0
  162. package/dist/services/app-common/runtime-facts.js.map +1 -0
  163. package/dist/services/app-common/service.d.ts +9 -0
  164. package/dist/services/app-common/service.js +10 -0
  165. package/dist/services/app-common/service.js.map +1 -0
  166. package/dist/services/app-common/spec-materializer.d.ts +8 -0
  167. package/dist/services/app-common/spec-materializer.js +295 -0
  168. package/dist/services/app-common/spec-materializer.js.map +1 -0
  169. package/dist/services/app-common/status-refresh.d.ts +33 -0
  170. package/dist/services/app-common/status-refresh.js +771 -0
  171. package/dist/services/app-common/status-refresh.js.map +1 -0
  172. package/dist/services/app-common/task-service.d.ts +29 -0
  173. package/dist/services/app-common/task-service.js +93 -0
  174. package/dist/services/app-common/task-service.js.map +1 -0
  175. package/dist/services/app-common/terminal-session-manager.js +157 -0
  176. package/dist/services/app-common/terminal-session-manager.js.map +1 -0
  177. package/dist/services/app-modules/browserless/routes.d.ts +9 -0
  178. package/dist/services/app-modules/browserless/routes.js +519 -0
  179. package/dist/services/app-modules/browserless/routes.js.map +1 -0
  180. package/dist/services/app-modules/routes.d.ts +2 -0
  181. package/dist/services/app-modules/routes.js +5 -0
  182. package/dist/services/app-modules/routes.js.map +1 -0
  183. package/dist/services/backup/backup-admin.d.ts +95 -0
  184. package/dist/services/backup/backup-admin.js +246 -0
  185. package/dist/services/backup/backup-admin.js.map +1 -0
  186. package/dist/services/backup/backup-manager.d.ts +264 -0
  187. package/dist/services/backup/backup-manager.js +2318 -0
  188. package/dist/services/backup/backup-manager.js.map +1 -0
  189. package/dist/services/backup/backup-verify.js +240 -0
  190. package/dist/services/backup/backup-verify.js.map +1 -0
  191. package/dist/services/capabilities/browser-policy.d.ts +14 -0
  192. package/dist/services/capabilities/browser-policy.js +141 -0
  193. package/dist/services/capabilities/browser-policy.js.map +1 -0
  194. package/dist/services/capabilities/contract.d.ts +49 -0
  195. package/dist/services/capabilities/contract.js +119 -0
  196. package/dist/services/capabilities/contract.js.map +1 -0
  197. package/dist/services/capabilities/endpoint-validator.d.ts +42 -0
  198. package/dist/services/capabilities/endpoint-validator.js +113 -0
  199. package/dist/services/capabilities/endpoint-validator.js.map +1 -0
  200. package/dist/services/capabilities/health.d.ts +16 -0
  201. package/dist/services/capabilities/health.js +121 -0
  202. package/dist/services/capabilities/health.js.map +1 -0
  203. package/dist/services/capabilities/registry.d.ts +56 -0
  204. package/dist/services/capabilities/registry.js +222 -0
  205. package/dist/services/capabilities/registry.js.map +1 -0
  206. package/dist/services/capabilities/sync.d.ts +7 -0
  207. package/dist/services/capabilities/sync.js +223 -0
  208. package/dist/services/capabilities/sync.js.map +1 -0
  209. package/dist/services/capability-proxy/html-rewriters/browserless.d.ts +1 -0
  210. package/dist/services/capability-proxy/html-rewriters/browserless.js +83 -0
  211. package/dist/services/capability-proxy/html-rewriters/browserless.js.map +1 -0
  212. package/dist/services/capability-proxy/html-rewriters/index.d.ts +12 -0
  213. package/dist/services/capability-proxy/html-rewriters/index.js +25 -0
  214. package/dist/services/capability-proxy/html-rewriters/index.js.map +1 -0
  215. package/dist/services/capability-proxy/html-rewriters/jishukb.d.ts +1 -0
  216. package/dist/services/capability-proxy/html-rewriters/jishukb.js +161 -0
  217. package/dist/services/capability-proxy/html-rewriters/jishukb.js.map +1 -0
  218. package/dist/services/capability-proxy/http.d.ts +7 -0
  219. package/dist/services/capability-proxy/http.js +555 -0
  220. package/dist/services/capability-proxy/http.js.map +1 -0
  221. package/dist/services/capability-proxy/terminal.d.ts +4 -0
  222. package/dist/services/capability-proxy/terminal.js +179 -0
  223. package/dist/services/capability-proxy/terminal.js.map +1 -0
  224. package/dist/services/connections/admin.d.ts +80 -0
  225. package/dist/services/connections/admin.js +337 -0
  226. package/dist/services/connections/admin.js.map +1 -0
  227. package/dist/services/connections/apply.d.ts +104 -0
  228. package/dist/services/connections/apply.js +415 -0
  229. package/dist/services/connections/apply.js.map +1 -0
  230. package/dist/services/connections/resolver.d.ts +82 -0
  231. package/dist/services/connections/resolver.js +289 -0
  232. package/dist/services/connections/resolver.js.map +1 -0
  233. package/dist/services/connections/transactor.d.ts +39 -0
  234. package/dist/services/connections/transactor.js +307 -0
  235. package/dist/services/connections/transactor.js.map +1 -0
  236. package/dist/services/files/bootstrap.d.ts +7 -0
  237. package/dist/services/files/bootstrap.js +16 -0
  238. package/dist/services/files/bootstrap.js.map +1 -0
  239. package/dist/services/files/external-mounts.js +187 -0
  240. package/dist/services/files/external-mounts.js.map +1 -0
  241. package/dist/services/files/files-manager.d.ts +265 -0
  242. package/dist/services/files/files-manager.js +1189 -0
  243. package/dist/services/files/files-manager.js.map +1 -0
  244. package/dist/services/files/files-mounts.d.ts +42 -0
  245. package/dist/services/files/files-mounts.js +207 -0
  246. package/dist/services/files/files-mounts.js.map +1 -0
  247. package/dist/services/files/organize/applier.js +218 -0
  248. package/dist/services/files/organize/applier.js.map +1 -0
  249. package/dist/services/files/organize/rules.js +286 -0
  250. package/dist/services/files/organize/rules.js.map +1 -0
  251. package/dist/services/files/organize/scanner.js +366 -0
  252. package/dist/services/files/organize/scanner.js.map +1 -0
  253. package/dist/services/files/organize/store.js +82 -0
  254. package/dist/services/files/organize/store.js.map +1 -0
  255. package/dist/services/files/photos/upload-page.d.ts +2 -0
  256. package/dist/services/files/photos/upload-page.js +248 -0
  257. package/dist/services/files/photos/upload-page.js.map +1 -0
  258. package/dist/services/files/photos/upload-store.d.ts +74 -0
  259. package/dist/services/files/photos/upload-store.js +432 -0
  260. package/dist/services/files/photos/upload-store.js.map +1 -0
  261. package/dist/services/files/webdav/server.d.ts +47 -0
  262. package/dist/services/files/webdav/server.js +329 -0
  263. package/dist/services/files/webdav/server.js.map +1 -0
  264. package/dist/services/files/webdav/xml-builder.js.map +1 -0
  265. package/dist/services/http/proxy-utils.d.ts +7 -0
  266. package/dist/services/http/proxy-utils.js +29 -0
  267. package/dist/services/http/proxy-utils.js.map +1 -0
  268. package/dist/services/http/request-utils.d.ts +3 -0
  269. package/dist/services/http/request-utils.js +23 -0
  270. package/dist/services/http/request-utils.js.map +1 -0
  271. package/dist/services/instances/admin.d.ts +23 -0
  272. package/dist/services/instances/admin.js +218 -0
  273. package/dist/services/instances/admin.js.map +1 -0
  274. package/dist/services/instances/clone.d.ts +26 -0
  275. package/dist/services/instances/clone.js +78 -0
  276. package/dist/services/instances/clone.js.map +1 -0
  277. package/dist/services/instances/config-admin.d.ts +17 -0
  278. package/dist/services/instances/config-admin.js +181 -0
  279. package/dist/services/instances/config-admin.js.map +1 -0
  280. package/dist/services/instances/manager.d.ts +232 -0
  281. package/dist/services/instances/manager.js +1342 -0
  282. package/dist/services/instances/manager.js.map +1 -0
  283. package/dist/services/instances/pairing.d.ts +17 -0
  284. package/dist/services/instances/pairing.js +53 -0
  285. package/dist/services/instances/pairing.js.map +1 -0
  286. package/dist/services/instances/passwords.js +173 -0
  287. package/dist/services/instances/passwords.js.map +1 -0
  288. package/dist/services/instances/status.d.ts +2 -0
  289. package/dist/services/instances/status.js +11 -0
  290. package/dist/services/instances/status.js.map +1 -0
  291. package/dist/services/instances/types.d.ts +21 -0
  292. package/dist/services/instances/types.js +2 -0
  293. package/dist/services/instances/types.js.map +1 -0
  294. package/dist/services/integrations/anythingllm/integration.d.ts +25 -0
  295. package/dist/services/integrations/anythingllm/integration.js +251 -0
  296. package/dist/services/integrations/anythingllm/integration.js.map +1 -0
  297. package/dist/services/integrations/catalog.d.ts +3 -0
  298. package/dist/services/integrations/catalog.js +73 -0
  299. package/dist/services/integrations/catalog.js.map +1 -0
  300. package/dist/services/integrations/custom/integration.d.ts +28 -0
  301. package/dist/services/integrations/custom/integration.js +179 -0
  302. package/dist/services/integrations/custom/integration.js.map +1 -0
  303. package/dist/services/integrations/hermes/integration.d.ts +194 -0
  304. package/dist/services/integrations/hermes/integration.js +1668 -0
  305. package/dist/services/integrations/hermes/integration.js.map +1 -0
  306. package/dist/services/integrations/immich/client.d.ts +93 -0
  307. package/dist/services/integrations/immich/client.js +458 -0
  308. package/dist/services/integrations/immich/client.js.map +1 -0
  309. package/dist/services/integrations/immich/config.d.ts +15 -0
  310. package/dist/services/integrations/immich/config.js +178 -0
  311. package/dist/services/integrations/immich/config.js.map +1 -0
  312. package/dist/services/integrations/immich/discovery.d.ts +9 -0
  313. package/dist/services/integrations/immich/discovery.js +101 -0
  314. package/dist/services/integrations/immich/discovery.js.map +1 -0
  315. package/dist/services/integrations/immich/gallery-renderer.d.ts +5 -0
  316. package/dist/services/integrations/immich/gallery-renderer.js +150 -0
  317. package/dist/services/integrations/immich/gallery-renderer.js.map +1 -0
  318. package/dist/services/integrations/immich/immich-shim.d.ts +11 -0
  319. package/dist/services/integrations/immich/immich-shim.js +439 -0
  320. package/dist/services/integrations/immich/immich-shim.js.map +1 -0
  321. package/dist/services/integrations/immich/integration.d.ts +18 -0
  322. package/dist/services/integrations/immich/integration.js +64 -0
  323. package/dist/services/integrations/immich/integration.js.map +1 -0
  324. package/dist/services/integrations/immich/photo-library.d.ts +4 -0
  325. package/dist/services/integrations/immich/photo-library.js +63 -0
  326. package/dist/services/integrations/immich/photo-library.js.map +1 -0
  327. package/dist/services/integrations/immich/review-executor.d.ts +3 -0
  328. package/dist/services/integrations/immich/review-executor.js +41 -0
  329. package/dist/services/integrations/immich/review-executor.js.map +1 -0
  330. package/dist/services/integrations/immich/review-session-service.d.ts +27 -0
  331. package/dist/services/integrations/immich/review-session-service.js +206 -0
  332. package/dist/services/integrations/immich/review-session-service.js.map +1 -0
  333. package/dist/services/integrations/immich/review-store.d.ts +47 -0
  334. package/dist/services/integrations/immich/review-store.js +347 -0
  335. package/dist/services/integrations/immich/review-store.js.map +1 -0
  336. package/dist/services/integrations/immich/routes.d.ts +7 -0
  337. package/dist/services/integrations/immich/routes.js +363 -0
  338. package/dist/services/integrations/immich/routes.js.map +1 -0
  339. package/dist/services/integrations/immich/types.d.ts +186 -0
  340. package/dist/services/integrations/immich/types.js +2 -0
  341. package/dist/services/integrations/immich/types.js.map +1 -0
  342. package/dist/services/integrations/index.d.ts +41 -0
  343. package/dist/services/integrations/index.js +60 -0
  344. package/dist/services/integrations/index.js.map +1 -0
  345. package/dist/services/integrations/installable/catalog.d.ts +33 -0
  346. package/dist/services/integrations/installable/catalog.js +88 -0
  347. package/dist/services/integrations/installable/catalog.js.map +1 -0
  348. package/dist/services/integrations/installable/index.d.ts +35 -0
  349. package/dist/services/integrations/installable/index.js +170 -0
  350. package/dist/services/integrations/installable/index.js.map +1 -0
  351. package/dist/services/integrations/installable/installers/integration-probes.d.ts +50 -0
  352. package/dist/services/integrations/installable/installers/integration-probes.js +231 -0
  353. package/dist/services/integrations/installable/installers/integration-probes.js.map +1 -0
  354. package/dist/services/integrations/installable/installers/integration.d.ts +30 -0
  355. package/dist/services/integrations/installable/installers/integration.js +283 -0
  356. package/dist/services/integrations/installable/installers/integration.js.map +1 -0
  357. package/dist/services/integrations/installable/installers/registry-probe.js.map +1 -0
  358. package/dist/services/integrations/installable/installers/shell-script.d.ts +46 -0
  359. package/dist/services/integrations/installable/installers/shell-script.js +487 -0
  360. package/dist/services/integrations/installable/installers/shell-script.js.map +1 -0
  361. package/dist/services/integrations/installable/types.d.ts +130 -0
  362. package/dist/services/integrations/installable/types.js +19 -0
  363. package/dist/services/integrations/installable/types.js.map +1 -0
  364. package/dist/services/integrations/jishukb/integration.d.ts +24 -0
  365. package/dist/services/integrations/jishukb/integration.js +300 -0
  366. package/dist/services/integrations/jishukb/integration.js.map +1 -0
  367. package/dist/services/integrations/openclaw/anythingllm-shim.d.ts +46 -0
  368. package/dist/services/integrations/openclaw/anythingllm-shim.js +281 -0
  369. package/dist/services/integrations/openclaw/anythingllm-shim.js.map +1 -0
  370. package/dist/services/integrations/openclaw/drive-shim.js +490 -0
  371. package/dist/services/integrations/openclaw/drive-shim.js.map +1 -0
  372. package/dist/services/integrations/openclaw/integration.d.ts +438 -0
  373. package/dist/services/integrations/openclaw/integration.js +4629 -0
  374. package/dist/services/integrations/openclaw/integration.js.map +1 -0
  375. package/dist/services/integrations/openclaw/jishukb-native-mcp.d.ts +58 -0
  376. package/dist/services/integrations/openclaw/jishukb-native-mcp.js +373 -0
  377. package/dist/services/integrations/openclaw/jishukb-native-mcp.js.map +1 -0
  378. package/dist/services/integrations/openclaw/jishukb-shim.d.ts +52 -0
  379. package/dist/services/integrations/openclaw/jishukb-shim.js +1357 -0
  380. package/dist/services/integrations/openclaw/jishukb-shim.js.map +1 -0
  381. package/dist/services/integrations/openclaw/mcporter-lite.js +276 -0
  382. package/dist/services/integrations/openclaw/mcporter-lite.js.map +1 -0
  383. package/dist/services/integrations/openclaw/mcporter.d.ts +59 -0
  384. package/dist/services/integrations/openclaw/mcporter.js +143 -0
  385. package/dist/services/integrations/openclaw/mcporter.js.map +1 -0
  386. package/dist/services/integrations/openclaw/native-mcp.d.ts +48 -0
  387. package/dist/services/integrations/openclaw/native-mcp.js +125 -0
  388. package/dist/services/integrations/openclaw/native-mcp.js.map +1 -0
  389. package/dist/services/integrations/openclaw/routes.d.ts +21 -0
  390. package/dist/services/integrations/openclaw/routes.js +1194 -0
  391. package/dist/services/integrations/openclaw/routes.js.map +1 -0
  392. package/dist/services/integrations/registry.d.ts +17 -0
  393. package/dist/services/integrations/registry.js +36 -0
  394. package/dist/services/integrations/registry.js.map +1 -0
  395. package/dist/services/integrations/routes.d.ts +2 -0
  396. package/dist/services/integrations/routes.js +9 -0
  397. package/dist/services/integrations/routes.js.map +1 -0
  398. package/dist/services/integrations/types.d.ts +457 -0
  399. package/dist/services/integrations/types.js +2 -0
  400. package/dist/services/integrations/types.js.map +1 -0
  401. package/dist/services/legacy-migrator/classifier.d.ts +44 -0
  402. package/dist/services/legacy-migrator/classifier.js +309 -0
  403. package/dist/services/legacy-migrator/classifier.js.map +1 -0
  404. package/dist/services/legacy-migrator/executor.d.ts +42 -0
  405. package/dist/services/legacy-migrator/executor.js +637 -0
  406. package/dist/services/legacy-migrator/executor.js.map +1 -0
  407. package/dist/services/legacy-migrator/index.d.ts +31 -0
  408. package/dist/services/legacy-migrator/index.js +34 -0
  409. package/dist/services/legacy-migrator/index.js.map +1 -0
  410. package/dist/services/legacy-migrator/planner.d.ts +8 -0
  411. package/dist/services/legacy-migrator/planner.js +154 -0
  412. package/dist/services/legacy-migrator/planner.js.map +1 -0
  413. package/dist/services/legacy-migrator/provider-settings.d.ts +6 -0
  414. package/dist/services/legacy-migrator/provider-settings.js +72 -0
  415. package/dist/services/legacy-migrator/provider-settings.js.map +1 -0
  416. package/dist/services/legacy-migrator/report.d.ts +9 -0
  417. package/dist/services/legacy-migrator/report.js +99 -0
  418. package/dist/services/legacy-migrator/report.js.map +1 -0
  419. package/dist/services/legacy-migrator/scanner.d.ts +13 -0
  420. package/dist/services/legacy-migrator/scanner.js +157 -0
  421. package/dist/services/legacy-migrator/scanner.js.map +1 -0
  422. package/dist/services/legacy-migrator/types.d.ts +97 -0
  423. package/dist/services/legacy-migrator/types.js +23 -0
  424. package/dist/services/legacy-migrator/types.js.map +1 -0
  425. package/dist/services/llm-proxy/instance-proxy.d.ts +17 -1
  426. package/dist/services/llm-proxy/instance-proxy.js +171 -44
  427. package/dist/services/llm-proxy/instance-proxy.js.map +1 -1
  428. package/dist/services/llm-proxy/probe.js +5 -14
  429. package/dist/services/llm-proxy/probe.js.map +1 -1
  430. package/dist/services/llm-proxy/providers.js +23 -31
  431. package/dist/services/llm-proxy/providers.js.map +1 -1
  432. package/dist/services/llm-proxy/ssrf.d.ts +11 -4
  433. package/dist/services/llm-proxy/ssrf.js +45 -7
  434. package/dist/services/llm-proxy/ssrf.js.map +1 -1
  435. package/dist/services/llm-proxy/validate-key.js +16 -37
  436. package/dist/services/llm-proxy/validate-key.js.map +1 -1
  437. package/dist/services/repair/runtime-repair.d.ts +22 -0
  438. package/dist/services/repair/runtime-repair.js +374 -0
  439. package/dist/services/repair/runtime-repair.js.map +1 -0
  440. package/dist/services/runtime/docker-network.d.ts +8 -0
  441. package/dist/services/runtime/docker-network.js +123 -0
  442. package/dist/services/runtime/docker-network.js.map +1 -0
  443. package/dist/services/runtime/driver-registry.d.ts +25 -0
  444. package/dist/services/runtime/driver-registry.js +22 -0
  445. package/dist/services/runtime/driver-registry.js.map +1 -0
  446. package/dist/services/runtime/drivers/nomad.d.ts +261 -0
  447. package/dist/services/runtime/drivers/nomad.js +3122 -0
  448. package/dist/services/runtime/drivers/nomad.js.map +1 -0
  449. package/dist/services/runtime/errors.d.ts +3 -3
  450. package/dist/services/runtime/errors.js +3 -3
  451. package/dist/services/runtime/instance.d.ts +14 -16
  452. package/dist/services/runtime/instance.js +93 -123
  453. package/dist/services/runtime/instance.js.map +1 -1
  454. package/dist/services/runtime/job-id.d.ts +1 -1
  455. package/dist/services/runtime/job-id.js +1 -1
  456. package/dist/services/runtime/mcp-shims/firewall.d.ts +2 -2
  457. package/dist/services/runtime/mcp-shims/firewall.js +2 -2
  458. package/dist/services/runtime/mcp-shims/searxng-shim.d.ts +3 -5
  459. package/dist/services/runtime/mcp-shims/searxng-shim.js +3 -5
  460. package/dist/services/runtime/mcp-shims/searxng-shim.js.map +1 -1
  461. package/dist/services/runtime/mcp-shims/write-mcp-entry.d.ts +20 -20
  462. package/dist/services/runtime/mcp-shims/write-mcp-entry.js +16 -16
  463. package/dist/services/runtime/mcp-shims/write-mcp-entry.js.map +1 -1
  464. package/dist/services/runtime/ownership-marker.d.ts +83 -0
  465. package/dist/services/runtime/ownership-marker.js +109 -0
  466. package/dist/services/runtime/ownership-marker.js.map +1 -0
  467. package/dist/services/runtime/service-manager.d.ts +2 -0
  468. package/dist/services/runtime/service-manager.js +18 -0
  469. package/dist/services/runtime/service-manager.js.map +1 -0
  470. package/dist/services/runtime/types.d.ts +23 -501
  471. package/dist/services/runtime/types.js +0 -12
  472. package/dist/services/runtime/types.js.map +1 -1
  473. package/dist/services/runtime/workload-compiler.d.ts +17 -0
  474. package/dist/services/runtime/workload-compiler.js +550 -0
  475. package/dist/services/runtime/workload-compiler.js.map +1 -0
  476. package/dist/services/runtime/workload-types.d.ts +11 -0
  477. package/dist/services/runtime/workload-types.js +2 -0
  478. package/dist/services/runtime/workload-types.js.map +1 -0
  479. package/dist/services/setup/core-manager.d.ts +50 -0
  480. package/dist/services/setup/core-manager.js +456 -0
  481. package/dist/services/setup/core-manager.js.map +1 -0
  482. package/dist/services/setup/plugin-installer.js +136 -0
  483. package/dist/services/setup/plugin-installer.js.map +1 -0
  484. package/dist/services/setup/setup-manager.d.ts +158 -0
  485. package/dist/services/setup/setup-manager.js +2724 -0
  486. package/dist/services/setup/setup-manager.js.map +1 -0
  487. package/dist/services/system/cli-command.d.ts +5 -0
  488. package/dist/services/system/cli-command.js +18 -0
  489. package/dist/services/system/cli-command.js.map +1 -0
  490. package/dist/services/system/macos-launchd.js +312 -0
  491. package/dist/services/system/macos-launchd.js.map +1 -0
  492. package/dist/services/system/repair-orchestrator.d.ts +71 -0
  493. package/dist/services/system/repair-orchestrator.js +412 -0
  494. package/dist/services/system/repair-orchestrator.js.map +1 -0
  495. package/dist/services/system/runtime-ownership.d.ts +36 -0
  496. package/dist/services/system/runtime-ownership.js +250 -0
  497. package/dist/services/system/runtime-ownership.js.map +1 -0
  498. package/dist/services/system/system-monitor.js +96 -0
  499. package/dist/services/system/system-monitor.js.map +1 -0
  500. package/dist/services/system/system-ollama-provider.d.ts +14 -0
  501. package/dist/services/system/system-ollama-provider.js +129 -0
  502. package/dist/services/system/system-ollama-provider.js.map +1 -0
  503. package/dist/services/system/system-reconciler.d.ts +59 -0
  504. package/dist/services/system/system-reconciler.js +763 -0
  505. package/dist/services/system/system-reconciler.js.map +1 -0
  506. package/dist/services/system/update-manager.d.ts +43 -0
  507. package/dist/services/system/update-manager.js +315 -0
  508. package/dist/services/system/update-manager.js.map +1 -0
  509. package/dist/services/system/upgrade-finalize.d.ts +80 -0
  510. package/dist/services/system/upgrade-finalize.js +507 -0
  511. package/dist/services/system/upgrade-finalize.js.map +1 -0
  512. package/dist/services/tasks/registry.d.ts +44 -0
  513. package/dist/services/tasks/registry.js +90 -0
  514. package/dist/services/tasks/registry.js.map +1 -0
  515. package/dist/services/telemetry/activation.d.ts +6 -2
  516. package/dist/services/telemetry/activation.js +6 -2
  517. package/dist/services/telemetry/activation.js.map +1 -1
  518. package/dist/services/telemetry/heartbeat.d.ts +6 -2
  519. package/dist/services/telemetry/heartbeat.js +6 -2
  520. package/dist/services/telemetry/heartbeat.js.map +1 -1
  521. package/dist/services/workspaces/builder.d.ts +29 -0
  522. package/dist/services/workspaces/builder.js +186 -0
  523. package/dist/services/workspaces/builder.js.map +1 -0
  524. package/dist/types.d.ts +350 -48
  525. package/dist/utils/instance-lock.d.ts +2 -2
  526. package/dist/utils/instance-lock.js +2 -2
  527. package/dist/utils/path-safety.js +1 -1
  528. package/dist/utils/service-user.d.ts +13 -0
  529. package/dist/utils/service-user.js +129 -0
  530. package/dist/utils/service-user.js.map +1 -0
  531. package/install/jishu-install.sh +107 -27
  532. package/install/jishu-uninstall.sh +8 -0
  533. package/install/post-install.sh +162 -185
  534. package/install/post-uninstall.sh +6 -0
  535. package/node_modules/@fastify/static/.github/workflows/ci.yml +1 -1
  536. package/node_modules/@fastify/static/.github/workflows/lock-threads.yml +19 -0
  537. package/node_modules/@fastify/static/LICENSE +1 -3
  538. package/node_modules/@fastify/static/example/server-benchmark.js +39 -0
  539. package/node_modules/@fastify/static/index.js +169 -23
  540. package/node_modules/@fastify/static/lib/dirList.js +20 -6
  541. package/node_modules/@fastify/static/package.json +10 -8
  542. package/node_modules/@fastify/static/test/dir-list.test.js +82 -0
  543. package/node_modules/@fastify/static/test/static.test.js +326 -4
  544. package/node_modules/@fastify/static/types/index.d.ts +0 -4
  545. package/node_modules/@fastify/static/types/index.test-d.ts +1 -1
  546. package/node_modules/brace-expansion/dist/commonjs/index.js +24 -14
  547. package/node_modules/brace-expansion/dist/commonjs/index.js.map +1 -1
  548. package/node_modules/brace-expansion/dist/esm/index.js +24 -14
  549. package/node_modules/brace-expansion/dist/esm/index.js.map +1 -1
  550. package/node_modules/brace-expansion/package.json +2 -2
  551. package/node_modules/content-disposition/README.md +21 -22
  552. package/node_modules/content-disposition/index.js +122 -44
  553. package/node_modules/content-disposition/package.json +16 -20
  554. package/node_modules/fast-uri/index.js +1 -1
  555. package/node_modules/fast-uri/package.json +1 -1
  556. package/node_modules/fast-uri/test/security.test.js +28 -0
  557. package/node_modules/fastify/SECURITY.md +1 -1
  558. package/node_modules/fastify/SPONSORS.md +6 -4
  559. package/node_modules/fastify/docs/Guides/Database.md +0 -28
  560. package/node_modules/fastify/docs/Guides/Ecosystem.md +13 -2
  561. package/node_modules/fastify/docs/Guides/Serverless.md +2 -2
  562. package/node_modules/fastify/docs/Guides/Write-Plugin.md +1 -1
  563. package/node_modules/fastify/docs/Reference/Encapsulation.md +27 -26
  564. package/node_modules/fastify/docs/Reference/Errors.md +10 -4
  565. package/node_modules/fastify/docs/Reference/HTTP2.md +10 -10
  566. package/node_modules/fastify/docs/Reference/Hooks.md +4 -4
  567. package/node_modules/fastify/docs/Reference/Index.md +14 -16
  568. package/node_modules/fastify/docs/Reference/LTS.md +12 -13
  569. package/node_modules/fastify/docs/Reference/Lifecycle.md +9 -8
  570. package/node_modules/fastify/docs/Reference/Logging.md +44 -39
  571. package/node_modules/fastify/docs/Reference/Middleware.md +21 -25
  572. package/node_modules/fastify/docs/Reference/Principles.md +2 -2
  573. package/node_modules/fastify/docs/Reference/Reply.md +6 -1
  574. package/node_modules/fastify/docs/Reference/Request.md +27 -16
  575. package/node_modules/fastify/docs/Reference/Routes.md +5 -2
  576. package/node_modules/fastify/docs/Reference/Server.md +31 -3
  577. package/node_modules/fastify/docs/Reference/Type-Providers.md +29 -5
  578. package/node_modules/fastify/docs/Reference/Validation-and-Serialization.md +15 -2
  579. package/node_modules/fastify/docs/Reference/Warnings.md +7 -6
  580. package/node_modules/fastify/eslint.config.js +7 -2
  581. package/node_modules/fastify/fastify.d.ts +8 -3
  582. package/node_modules/fastify/fastify.js +43 -14
  583. package/node_modules/fastify/lib/content-type-parser.js +13 -1
  584. package/node_modules/fastify/lib/decorate.js +11 -3
  585. package/node_modules/fastify/lib/error-handler.js +4 -3
  586. package/node_modules/fastify/lib/error-serializer.js +59 -59
  587. package/node_modules/fastify/lib/errors.js +16 -1
  588. package/node_modules/fastify/lib/four-oh-four.js +14 -9
  589. package/node_modules/fastify/lib/handle-request.js +11 -5
  590. package/node_modules/fastify/lib/plugin-override.js +2 -1
  591. package/node_modules/fastify/lib/plugin-utils.js +5 -5
  592. package/node_modules/fastify/lib/reply.js +63 -8
  593. package/node_modules/fastify/lib/request.js +14 -4
  594. package/node_modules/fastify/lib/route.js +20 -6
  595. package/node_modules/fastify/lib/schema-controller.js +1 -1
  596. package/node_modules/fastify/lib/schemas.js +37 -30
  597. package/node_modules/fastify/lib/symbols.js +3 -1
  598. package/node_modules/fastify/lib/validation.js +1 -13
  599. package/node_modules/fastify/lib/warnings.js +3 -3
  600. package/node_modules/fastify/package.json +13 -15
  601. package/node_modules/fastify/scripts/validate-ecosystem-links.js +1 -0
  602. package/node_modules/fastify/test/bundler/esbuild/package.json +1 -1
  603. package/node_modules/fastify/test/close-pipelining.test.js +1 -2
  604. package/node_modules/fastify/test/custom-http-server.test.js +38 -0
  605. package/node_modules/fastify/test/decorator-instance-properties.test.js +63 -0
  606. package/node_modules/fastify/test/diagnostics-channel/async-error-handler.test.js +74 -0
  607. package/node_modules/fastify/test/hooks.test.js +23 -0
  608. package/node_modules/fastify/test/http-methods/get.test.js +1 -1
  609. package/node_modules/fastify/test/http2/plain.test.js +135 -0
  610. package/node_modules/fastify/test/http2/secure-with-fallback.test.js +1 -1
  611. package/node_modules/fastify/test/https/https.test.js +1 -2
  612. package/node_modules/fastify/test/internals/errors.test.js +31 -1
  613. package/node_modules/fastify/test/internals/plugin.test.js +3 -1
  614. package/node_modules/fastify/test/internals/request.test.js +27 -3
  615. package/node_modules/fastify/test/internals/schema-controller-perf.test.js +33 -0
  616. package/node_modules/fastify/test/logger/logging.test.js +18 -1
  617. package/node_modules/fastify/test/logger/options.test.js +38 -1
  618. package/node_modules/fastify/test/reply-error.test.js +1 -1
  619. package/node_modules/fastify/test/reply-trailers.test.js +70 -0
  620. package/node_modules/fastify/test/request-media-type.test.js +105 -0
  621. package/node_modules/fastify/test/route-prefix.test.js +34 -0
  622. package/node_modules/fastify/test/router-options.test.js +222 -11
  623. package/node_modules/fastify/test/schema-serialization.test.js +108 -0
  624. package/node_modules/fastify/test/schema-validation.test.js +24 -0
  625. package/node_modules/fastify/test/scripts/validate-ecosystem-links.test.js +40 -57
  626. package/node_modules/fastify/test/throw.test.js +14 -0
  627. package/node_modules/fastify/test/trust-proxy.test.js +21 -0
  628. package/node_modules/fastify/test/types/content-type-parser.tst.ts +70 -0
  629. package/node_modules/fastify/test/types/decorate-request-reply.tst.ts +18 -0
  630. package/node_modules/fastify/test/types/dummy-plugin.mts +9 -0
  631. package/node_modules/fastify/test/types/errors.tst.ts +91 -0
  632. package/node_modules/fastify/test/types/fastify.tst.ts +351 -0
  633. package/node_modules/fastify/test/types/hooks.tst.ts +578 -0
  634. package/node_modules/fastify/test/types/instance.tst.ts +597 -0
  635. package/node_modules/fastify/test/types/logger.tst.ts +276 -0
  636. package/node_modules/fastify/test/types/plugin.tst.ts +96 -0
  637. package/node_modules/fastify/test/types/register.tst.ts +245 -0
  638. package/node_modules/fastify/test/types/reply.tst.ts +297 -0
  639. package/node_modules/fastify/test/types/request.tst.ts +199 -0
  640. package/node_modules/fastify/test/types/route.tst.ts +576 -0
  641. package/node_modules/fastify/test/types/schema.tst.ts +135 -0
  642. package/node_modules/fastify/test/types/serverFactory.tst.ts +37 -0
  643. package/node_modules/fastify/test/types/tsconfig.json +9 -0
  644. package/node_modules/fastify/test/types/type-provider.tst.ts +1219 -0
  645. package/node_modules/fastify/test/types/using.tst.ts +14 -0
  646. package/node_modules/fastify/types/errors.d.ts +3 -0
  647. package/node_modules/fastify/types/request.d.ts +23 -2
  648. package/node_modules/glob/README.md +39 -130
  649. package/node_modules/glob/dist/commonjs/glob.d.ts +8 -0
  650. package/node_modules/glob/dist/commonjs/glob.d.ts.map +1 -1
  651. package/node_modules/glob/dist/commonjs/glob.js +2 -1
  652. package/node_modules/glob/dist/commonjs/glob.js.map +1 -1
  653. package/node_modules/glob/dist/commonjs/index.min.js +4 -0
  654. package/node_modules/glob/dist/commonjs/index.min.js.map +7 -0
  655. package/node_modules/glob/dist/commonjs/pattern.d.ts +3 -0
  656. package/node_modules/glob/dist/commonjs/pattern.d.ts.map +1 -1
  657. package/node_modules/glob/dist/commonjs/pattern.js +4 -0
  658. package/node_modules/glob/dist/commonjs/pattern.js.map +1 -1
  659. package/node_modules/glob/dist/esm/glob.d.ts +8 -0
  660. package/node_modules/glob/dist/esm/glob.d.ts.map +1 -1
  661. package/node_modules/glob/dist/esm/glob.js +2 -1
  662. package/node_modules/glob/dist/esm/glob.js.map +1 -1
  663. package/node_modules/glob/dist/esm/index.min.js +4 -0
  664. package/node_modules/glob/dist/esm/index.min.js.map +7 -0
  665. package/node_modules/glob/dist/esm/pattern.d.ts +3 -0
  666. package/node_modules/glob/dist/esm/pattern.d.ts.map +1 -1
  667. package/node_modules/glob/dist/esm/pattern.js +4 -0
  668. package/node_modules/glob/dist/esm/pattern.js.map +1 -1
  669. package/node_modules/glob/package.json +38 -37
  670. package/node_modules/jishushell-panel/README.md +4 -4
  671. package/node_modules/jishushell-panel/output/dist/server.js +17 -6
  672. package/node_modules/jishushell-panel/output/dist/server.js.map +1 -1
  673. package/node_modules/jishushell-panel/output/public/assets/ApiKeyField-Ce5d1xna.js +1 -0
  674. package/node_modules/jishushell-panel/output/public/assets/Dashboard-BXame3yg.js +1 -0
  675. package/node_modules/jishushell-panel/output/public/assets/HermesChatPanel-BHZtPCJd.js +1 -0
  676. package/node_modules/jishushell-panel/output/public/assets/HermesConfigForm-CB3GbNX9.js +4 -0
  677. package/node_modules/jishushell-panel/output/public/assets/InitPassword-Boab9F6g.js +1 -0
  678. package/node_modules/jishushell-panel/output/public/assets/InstanceDetail-DrIWCqo-.js +14 -0
  679. package/node_modules/jishushell-panel/output/public/assets/Login-CzpOkNau.js +1 -0
  680. package/node_modules/jishushell-panel/output/public/assets/NewInstance-CANXyCcL.js +1 -0
  681. package/node_modules/jishushell-panel/output/public/assets/ProviderRecommendations-BABo9VOC.js +1 -0
  682. package/node_modules/jishushell-panel/output/public/assets/Settings-CKp5XxFh.js +1 -0
  683. package/node_modules/jishushell-panel/output/public/assets/Setup-C7xVDPow.js +1 -0
  684. package/node_modules/jishushell-panel/output/public/assets/WeixinLoginPanel-B765Xz4C.js +1 -0
  685. package/node_modules/jishushell-panel/output/public/assets/api-C70Gt678.js +4 -0
  686. package/node_modules/jishushell-panel/output/public/assets/index-Bs6DSbiR.js +23 -0
  687. package/node_modules/jishushell-panel/output/public/assets/index-DnnqTf7s.css +1 -0
  688. package/node_modules/jishushell-panel/output/public/assets/registry-sWIZsIEF.js +2 -0
  689. package/node_modules/jishushell-panel/output/public/assets/rolldown-runtime-QTnfLwEv.js +1 -0
  690. package/node_modules/jishushell-panel/output/public/assets/setup-task-q21GnI0E.js +1 -0
  691. package/node_modules/jishushell-panel/output/public/assets/usePolling-D4IDOQd_.js +1 -0
  692. package/node_modules/jishushell-panel/output/public/assets/vendor-i18n-Df8aUdv8.js +1 -0
  693. package/node_modules/jishushell-panel/output/public/assets/vendor-react-0L0rjmYG.js +8 -0
  694. package/node_modules/jishushell-panel/output/public/index.html +6 -4
  695. package/node_modules/jishushell-panel/package.json +2 -2
  696. package/node_modules/semver/classes/range.js +17 -4
  697. package/node_modules/semver/package.json +2 -2
  698. package/package.json +12 -64
  699. package/scripts/check-app-path-boundaries.mjs +121 -0
  700. package/scripts/check-app-spec.mjs +123 -29
  701. package/scripts/check-architecture-boundaries.mjs +178 -0
  702. package/scripts/check-colima-launchd.mjs +10 -8
  703. package/scripts/check-integration-isolation.ts +541 -0
  704. package/scripts/check-new-file-tests.mjs +11 -3
  705. package/scripts/check-open-core-boundaries.mjs +60 -10
  706. package/scripts/check-test-layering.sh +1 -1
  707. package/scripts/fixtures/instances/hermes-sample/instance.json +3 -2
  708. package/scripts/fixtures/instances/legacy-openclaw-sample/instance.json +1 -1
  709. package/scripts/local-web-upgrade-test.README +4 -3
  710. package/scripts/local-web-upgrade-test.example.env +2 -2
  711. package/scripts/local-web-upgrade-test.sh +14 -1
  712. package/scripts/pack-gui-and-send-pi.sh +43 -0
  713. package/scripts/perf/instances.js +1 -1
  714. package/scripts/prune-open-core-dist.mjs +89 -2
  715. package/scripts/smoke/hermes-bootstrap.sh +5 -5
  716. package/templates/hermes-entrypoint.sh +19 -29
  717. package/apps/openwebui-container.yaml +0 -97
  718. package/apps/playwright-container.yaml +0 -126
  719. package/dependencies/jishushell-panel-0.6.5.tgz +0 -0
  720. package/dist/crypto-shim.d.ts +0 -1
  721. package/dist/crypto-shim.js +0 -2
  722. package/dist/crypto-shim.js.map +0 -1
  723. package/dist/routes/agent-apps.d.ts +0 -14
  724. package/dist/routes/agent-apps.js +0 -77
  725. package/dist/routes/agent-apps.js.map +0 -1
  726. package/dist/routes/internal.d.ts +0 -2
  727. package/dist/routes/internal.js +0 -55
  728. package/dist/routes/internal.js.map +0 -1
  729. package/dist/routes/openclaw-routes.d.ts +0 -22
  730. package/dist/routes/openclaw-routes.js +0 -1020
  731. package/dist/routes/openclaw-routes.js.map +0 -1
  732. package/dist/routes/runtime.d.ts +0 -15
  733. package/dist/routes/runtime.js +0 -76
  734. package/dist/routes/runtime.js.map +0 -1
  735. package/dist/services/agent-apps/catalog.d.ts +0 -33
  736. package/dist/services/agent-apps/catalog.js +0 -88
  737. package/dist/services/agent-apps/catalog.js.map +0 -1
  738. package/dist/services/agent-apps/index.d.ts +0 -36
  739. package/dist/services/agent-apps/index.js +0 -171
  740. package/dist/services/agent-apps/index.js.map +0 -1
  741. package/dist/services/agent-apps/installers/adapter-probes.d.ts +0 -49
  742. package/dist/services/agent-apps/installers/adapter-probes.js +0 -230
  743. package/dist/services/agent-apps/installers/adapter-probes.js.map +0 -1
  744. package/dist/services/agent-apps/installers/adapter.d.ts +0 -30
  745. package/dist/services/agent-apps/installers/adapter.js +0 -171
  746. package/dist/services/agent-apps/installers/adapter.js.map +0 -1
  747. package/dist/services/agent-apps/installers/registry-probe.js.map +0 -1
  748. package/dist/services/agent-apps/installers/shell-script.d.ts +0 -47
  749. package/dist/services/agent-apps/installers/shell-script.js +0 -488
  750. package/dist/services/agent-apps/installers/shell-script.js.map +0 -1
  751. package/dist/services/agent-apps/types.d.ts +0 -128
  752. package/dist/services/agent-apps/types.js +0 -17
  753. package/dist/services/agent-apps/types.js.map +0 -1
  754. package/dist/services/app/app-compiler.js +0 -185
  755. package/dist/services/app/app-compiler.js.map +0 -1
  756. package/dist/services/app/app-manager.d.ts +0 -184
  757. package/dist/services/app/app-manager.js +0 -2933
  758. package/dist/services/app/app-manager.js.map +0 -1
  759. package/dist/services/app/custom-manager.d.ts +0 -27
  760. package/dist/services/app/custom-manager.js +0 -382
  761. package/dist/services/app/custom-manager.js.map +0 -1
  762. package/dist/services/app/hermes-agent-manager.d.ts +0 -20
  763. package/dist/services/app/hermes-agent-manager.js +0 -299
  764. package/dist/services/app/hermes-agent-manager.js.map +0 -1
  765. package/dist/services/app/id-normalizer.d.ts +0 -27
  766. package/dist/services/app/id-normalizer.js +0 -77
  767. package/dist/services/app/id-normalizer.js.map +0 -1
  768. package/dist/services/app/ollama-manager.d.ts +0 -18
  769. package/dist/services/app/ollama-manager.js +0 -224
  770. package/dist/services/app/ollama-manager.js.map +0 -1
  771. package/dist/services/app/openclaw-manager.d.ts +0 -63
  772. package/dist/services/app/openclaw-manager.js +0 -1215
  773. package/dist/services/app/openclaw-manager.js.map +0 -1
  774. package/dist/services/app/paths.d.ts +0 -27
  775. package/dist/services/app/paths.js +0 -40
  776. package/dist/services/app/paths.js.map +0 -1
  777. package/dist/services/app/platform-transform.d.ts +0 -32
  778. package/dist/services/app/platform-transform.js +0 -65
  779. package/dist/services/app/platform-transform.js.map +0 -1
  780. package/dist/services/app/provide-resolver.d.ts +0 -29
  781. package/dist/services/app/provide-resolver.js +0 -135
  782. package/dist/services/app/provide-resolver.js.map +0 -1
  783. package/dist/services/app/registry.d.ts +0 -17
  784. package/dist/services/app/registry.js +0 -31
  785. package/dist/services/app/registry.js.map +0 -1
  786. package/dist/services/app/remote-spec.d.ts +0 -14
  787. package/dist/services/app/remote-spec.js +0 -58
  788. package/dist/services/app/remote-spec.js.map +0 -1
  789. package/dist/services/app/terminal-session-manager.js +0 -157
  790. package/dist/services/app/terminal-session-manager.js.map +0 -1
  791. package/dist/services/app/types.d.ts +0 -74
  792. package/dist/services/app/types.js +0 -16
  793. package/dist/services/app/types.js.map +0 -1
  794. package/dist/services/app-config-admin.d.ts +0 -17
  795. package/dist/services/app-config-admin.js +0 -177
  796. package/dist/services/app-config-admin.js.map +0 -1
  797. package/dist/services/app-create-from-installed.d.ts +0 -23
  798. package/dist/services/app-create-from-installed.js +0 -75
  799. package/dist/services/app-create-from-installed.js.map +0 -1
  800. package/dist/services/app-passwords.js +0 -173
  801. package/dist/services/app-passwords.js.map +0 -1
  802. package/dist/services/backup-admin.d.ts +0 -101
  803. package/dist/services/backup-admin.js +0 -259
  804. package/dist/services/backup-admin.js.map +0 -1
  805. package/dist/services/backup-manager.d.ts +0 -264
  806. package/dist/services/backup-manager.js +0 -2263
  807. package/dist/services/backup-manager.js.map +0 -1
  808. package/dist/services/backup-verify.js +0 -240
  809. package/dist/services/backup-verify.js.map +0 -1
  810. package/dist/services/capability-endpoint-validator.d.ts +0 -41
  811. package/dist/services/capability-endpoint-validator.js +0 -114
  812. package/dist/services/capability-endpoint-validator.js.map +0 -1
  813. package/dist/services/capability-health.d.ts +0 -16
  814. package/dist/services/capability-health.js +0 -121
  815. package/dist/services/capability-health.js.map +0 -1
  816. package/dist/services/capability-registry.d.ts +0 -29
  817. package/dist/services/capability-registry.js +0 -176
  818. package/dist/services/capability-registry.js.map +0 -1
  819. package/dist/services/capability-sync.d.ts +0 -4
  820. package/dist/services/capability-sync.js +0 -220
  821. package/dist/services/capability-sync.js.map +0 -1
  822. package/dist/services/connection-admin.d.ts +0 -74
  823. package/dist/services/connection-admin.js +0 -287
  824. package/dist/services/connection-admin.js.map +0 -1
  825. package/dist/services/connection-apply.d.ts +0 -91
  826. package/dist/services/connection-apply.js +0 -471
  827. package/dist/services/connection-apply.js.map +0 -1
  828. package/dist/services/connection-resolver.d.ts +0 -65
  829. package/dist/services/connection-resolver.js +0 -281
  830. package/dist/services/connection-resolver.js.map +0 -1
  831. package/dist/services/connection-transactor.d.ts +0 -39
  832. package/dist/services/connection-transactor.js +0 -354
  833. package/dist/services/connection-transactor.js.map +0 -1
  834. package/dist/services/core-manager.d.ts +0 -50
  835. package/dist/services/core-manager.js +0 -411
  836. package/dist/services/core-manager.js.map +0 -1
  837. package/dist/services/external-mounts.js +0 -187
  838. package/dist/services/external-mounts.js.map +0 -1
  839. package/dist/services/files-manager.d.ts +0 -252
  840. package/dist/services/files-manager.js +0 -1156
  841. package/dist/services/files-manager.js.map +0 -1
  842. package/dist/services/files-mounts.d.ts +0 -42
  843. package/dist/services/files-mounts.js +0 -207
  844. package/dist/services/files-mounts.js.map +0 -1
  845. package/dist/services/instance-admin.d.ts +0 -26
  846. package/dist/services/instance-admin.js +0 -218
  847. package/dist/services/instance-admin.js.map +0 -1
  848. package/dist/services/instance-manager.d.ts +0 -192
  849. package/dist/services/instance-manager.js +0 -1289
  850. package/dist/services/instance-manager.js.map +0 -1
  851. package/dist/services/macos-launchd.js +0 -312
  852. package/dist/services/macos-launchd.js.map +0 -1
  853. package/dist/services/nomad-manager.d.ts +0 -307
  854. package/dist/services/nomad-manager.js +0 -3958
  855. package/dist/services/nomad-manager.js.map +0 -1
  856. package/dist/services/organize/applier.js +0 -218
  857. package/dist/services/organize/applier.js.map +0 -1
  858. package/dist/services/organize/rules.js +0 -286
  859. package/dist/services/organize/rules.js.map +0 -1
  860. package/dist/services/organize/scanner.js +0 -366
  861. package/dist/services/organize/scanner.js.map +0 -1
  862. package/dist/services/organize/store.js +0 -82
  863. package/dist/services/organize/store.js.map +0 -1
  864. package/dist/services/plugin-installer.js +0 -128
  865. package/dist/services/plugin-installer.js.map +0 -1
  866. package/dist/services/process-manager.d.ts +0 -25
  867. package/dist/services/process-manager.js +0 -568
  868. package/dist/services/process-manager.js.map +0 -1
  869. package/dist/services/runtime/adapters/custom.d.ts +0 -20
  870. package/dist/services/runtime/adapters/custom.js +0 -188
  871. package/dist/services/runtime/adapters/custom.js.map +0 -1
  872. package/dist/services/runtime/adapters/hermes.d.ts +0 -204
  873. package/dist/services/runtime/adapters/hermes.js +0 -1684
  874. package/dist/services/runtime/adapters/hermes.js.map +0 -1
  875. package/dist/services/runtime/adapters/openclaw-mcporter.d.ts +0 -45
  876. package/dist/services/runtime/adapters/openclaw-mcporter.js +0 -108
  877. package/dist/services/runtime/adapters/openclaw-mcporter.js.map +0 -1
  878. package/dist/services/runtime/adapters/openclaw.d.ts +0 -426
  879. package/dist/services/runtime/adapters/openclaw.js +0 -3975
  880. package/dist/services/runtime/adapters/openclaw.js.map +0 -1
  881. package/dist/services/runtime/index.d.ts +0 -34
  882. package/dist/services/runtime/index.js +0 -51
  883. package/dist/services/runtime/index.js.map +0 -1
  884. package/dist/services/runtime/mcp-shims/anythingllm-shim.d.ts +0 -46
  885. package/dist/services/runtime/mcp-shims/anythingllm-shim.js +0 -281
  886. package/dist/services/runtime/mcp-shims/anythingllm-shim.js.map +0 -1
  887. package/dist/services/runtime/mcp-shims/drive-shim.js +0 -490
  888. package/dist/services/runtime/mcp-shims/drive-shim.js.map +0 -1
  889. package/dist/services/runtime/mcp-shims/jishukb-shim.d.ts +0 -48
  890. package/dist/services/runtime/mcp-shims/jishukb-shim.js +0 -723
  891. package/dist/services/runtime/mcp-shims/jishukb-shim.js.map +0 -1
  892. package/dist/services/runtime/mcp-shims/mcporter-lite.js +0 -276
  893. package/dist/services/runtime/mcp-shims/mcporter-lite.js.map +0 -1
  894. package/dist/services/runtime/migrations.d.ts +0 -23
  895. package/dist/services/runtime/migrations.js +0 -125
  896. package/dist/services/runtime/migrations.js.map +0 -1
  897. package/dist/services/runtime/registry.d.ts +0 -13
  898. package/dist/services/runtime/registry.js +0 -32
  899. package/dist/services/runtime/registry.js.map +0 -1
  900. package/dist/services/runtime-identity.d.ts +0 -13
  901. package/dist/services/runtime-identity.js +0 -166
  902. package/dist/services/runtime-identity.js.map +0 -1
  903. package/dist/services/runtime-repair.d.ts +0 -52
  904. package/dist/services/runtime-repair.js +0 -352
  905. package/dist/services/runtime-repair.js.map +0 -1
  906. package/dist/services/setup-manager.d.ts +0 -158
  907. package/dist/services/setup-manager.js +0 -2740
  908. package/dist/services/setup-manager.js.map +0 -1
  909. package/dist/services/suggestions.d.ts +0 -27
  910. package/dist/services/suggestions.js +0 -133
  911. package/dist/services/suggestions.js.map +0 -1
  912. package/dist/services/system-monitor.js +0 -79
  913. package/dist/services/system-monitor.js.map +0 -1
  914. package/dist/services/system-ollama-provider.d.ts +0 -14
  915. package/dist/services/system-ollama-provider.js +0 -125
  916. package/dist/services/system-ollama-provider.js.map +0 -1
  917. package/dist/services/system-reconciler.d.ts +0 -72
  918. package/dist/services/system-reconciler.js +0 -600
  919. package/dist/services/system-reconciler.js.map +0 -1
  920. package/dist/services/task-registry.d.ts +0 -44
  921. package/dist/services/task-registry.js +0 -76
  922. package/dist/services/task-registry.js.map +0 -1
  923. package/dist/services/types-shim.d.ts +0 -16
  924. package/dist/services/types-shim.js +0 -2
  925. package/dist/services/types-shim.js.map +0 -1
  926. package/dist/services/update-manager.d.ts +0 -47
  927. package/dist/services/update-manager.js +0 -351
  928. package/dist/services/update-manager.js.map +0 -1
  929. package/dist/services/webdav/server.d.ts +0 -24
  930. package/dist/services/webdav/server.js +0 -420
  931. package/dist/services/webdav/server.js.map +0 -1
  932. package/dist/services/webdav/xml-builder.js.map +0 -1
  933. package/dist/services/workspace-builder.d.ts +0 -29
  934. package/dist/services/workspace-builder.js +0 -188
  935. package/dist/services/workspace-builder.js.map +0 -1
  936. package/node_modules/@fastify/static/.github/stale.yml +0 -21
  937. package/node_modules/@isaacs/cliui/LICENSE.md +0 -63
  938. package/node_modules/@isaacs/cliui/README.md +0 -151
  939. package/node_modules/@isaacs/cliui/dist/commonjs/ansi-regex/index.d.ts +0 -4
  940. package/node_modules/@isaacs/cliui/dist/commonjs/ansi-regex/index.d.ts.map +0 -1
  941. package/node_modules/@isaacs/cliui/dist/commonjs/ansi-regex/index.js +0 -16
  942. package/node_modules/@isaacs/cliui/dist/commonjs/ansi-regex/index.js.map +0 -1
  943. package/node_modules/@isaacs/cliui/dist/commonjs/ansi-styles/index.d.ts +0 -34
  944. package/node_modules/@isaacs/cliui/dist/commonjs/ansi-styles/index.d.ts.map +0 -1
  945. package/node_modules/@isaacs/cliui/dist/commonjs/ansi-styles/index.js +0 -170
  946. package/node_modules/@isaacs/cliui/dist/commonjs/ansi-styles/index.js.map +0 -1
  947. package/node_modules/@isaacs/cliui/dist/commonjs/eastasianwidth/index.d.ts +0 -6
  948. package/node_modules/@isaacs/cliui/dist/commonjs/eastasianwidth/index.d.ts.map +0 -1
  949. package/node_modules/@isaacs/cliui/dist/commonjs/eastasianwidth/index.js +0 -307
  950. package/node_modules/@isaacs/cliui/dist/commonjs/eastasianwidth/index.js.map +0 -1
  951. package/node_modules/@isaacs/cliui/dist/commonjs/emoji-regex/index.d.ts +0 -2
  952. package/node_modules/@isaacs/cliui/dist/commonjs/emoji-regex/index.d.ts.map +0 -1
  953. package/node_modules/@isaacs/cliui/dist/commonjs/emoji-regex/index.js +0 -7
  954. package/node_modules/@isaacs/cliui/dist/commonjs/emoji-regex/index.js.map +0 -1
  955. package/node_modules/@isaacs/cliui/dist/commonjs/index.d.ts +0 -41
  956. package/node_modules/@isaacs/cliui/dist/commonjs/index.d.ts.map +0 -1
  957. package/node_modules/@isaacs/cliui/dist/commonjs/index.js +0 -322
  958. package/node_modules/@isaacs/cliui/dist/commonjs/index.js.map +0 -1
  959. package/node_modules/@isaacs/cliui/dist/commonjs/index.min.js +0 -12
  960. package/node_modules/@isaacs/cliui/dist/commonjs/index.min.js.map +0 -7
  961. package/node_modules/@isaacs/cliui/dist/commonjs/package.json +0 -3
  962. package/node_modules/@isaacs/cliui/dist/commonjs/string-width/index.d.ts +0 -5
  963. package/node_modules/@isaacs/cliui/dist/commonjs/string-width/index.d.ts.map +0 -1
  964. package/node_modules/@isaacs/cliui/dist/commonjs/string-width/index.js +0 -49
  965. package/node_modules/@isaacs/cliui/dist/commonjs/string-width/index.js.map +0 -1
  966. package/node_modules/@isaacs/cliui/dist/commonjs/strip-ansi/index.d.ts +0 -2
  967. package/node_modules/@isaacs/cliui/dist/commonjs/strip-ansi/index.d.ts.map +0 -1
  968. package/node_modules/@isaacs/cliui/dist/commonjs/strip-ansi/index.js +0 -8
  969. package/node_modules/@isaacs/cliui/dist/commonjs/strip-ansi/index.js.map +0 -1
  970. package/node_modules/@isaacs/cliui/dist/commonjs/wrap-ansi/index.d.ts +0 -7
  971. package/node_modules/@isaacs/cliui/dist/commonjs/wrap-ansi/index.d.ts.map +0 -1
  972. package/node_modules/@isaacs/cliui/dist/commonjs/wrap-ansi/index.js +0 -176
  973. package/node_modules/@isaacs/cliui/dist/commonjs/wrap-ansi/index.js.map +0 -1
  974. package/node_modules/@isaacs/cliui/dist/esm/ansi-regex/index.d.ts +0 -4
  975. package/node_modules/@isaacs/cliui/dist/esm/ansi-regex/index.d.ts.map +0 -1
  976. package/node_modules/@isaacs/cliui/dist/esm/ansi-regex/index.js +0 -12
  977. package/node_modules/@isaacs/cliui/dist/esm/ansi-regex/index.js.map +0 -1
  978. package/node_modules/@isaacs/cliui/dist/esm/ansi-styles/index.d.ts +0 -34
  979. package/node_modules/@isaacs/cliui/dist/esm/ansi-styles/index.d.ts.map +0 -1
  980. package/node_modules/@isaacs/cliui/dist/esm/ansi-styles/index.js +0 -167
  981. package/node_modules/@isaacs/cliui/dist/esm/ansi-styles/index.js.map +0 -1
  982. package/node_modules/@isaacs/cliui/dist/esm/eastasianwidth/index.d.ts +0 -6
  983. package/node_modules/@isaacs/cliui/dist/esm/eastasianwidth/index.d.ts.map +0 -1
  984. package/node_modules/@isaacs/cliui/dist/esm/eastasianwidth/index.js +0 -299
  985. package/node_modules/@isaacs/cliui/dist/esm/eastasianwidth/index.js.map +0 -1
  986. package/node_modules/@isaacs/cliui/dist/esm/emoji-regex/index.d.ts +0 -2
  987. package/node_modules/@isaacs/cliui/dist/esm/emoji-regex/index.d.ts.map +0 -1
  988. package/node_modules/@isaacs/cliui/dist/esm/emoji-regex/index.js +0 -3
  989. package/node_modules/@isaacs/cliui/dist/esm/emoji-regex/index.js.map +0 -1
  990. package/node_modules/@isaacs/cliui/dist/esm/index.d.ts +0 -41
  991. package/node_modules/@isaacs/cliui/dist/esm/index.d.ts.map +0 -1
  992. package/node_modules/@isaacs/cliui/dist/esm/index.js +0 -317
  993. package/node_modules/@isaacs/cliui/dist/esm/index.js.map +0 -1
  994. package/node_modules/@isaacs/cliui/dist/esm/index.min.js +0 -12
  995. package/node_modules/@isaacs/cliui/dist/esm/index.min.js.map +0 -7
  996. package/node_modules/@isaacs/cliui/dist/esm/package.json +0 -3
  997. package/node_modules/@isaacs/cliui/dist/esm/string-width/index.d.ts +0 -5
  998. package/node_modules/@isaacs/cliui/dist/esm/string-width/index.d.ts.map +0 -1
  999. package/node_modules/@isaacs/cliui/dist/esm/string-width/index.js +0 -46
  1000. package/node_modules/@isaacs/cliui/dist/esm/string-width/index.js.map +0 -1
  1001. package/node_modules/@isaacs/cliui/dist/esm/strip-ansi/index.d.ts +0 -2
  1002. package/node_modules/@isaacs/cliui/dist/esm/strip-ansi/index.d.ts.map +0 -1
  1003. package/node_modules/@isaacs/cliui/dist/esm/strip-ansi/index.js +0 -4
  1004. package/node_modules/@isaacs/cliui/dist/esm/strip-ansi/index.js.map +0 -1
  1005. package/node_modules/@isaacs/cliui/dist/esm/wrap-ansi/index.d.ts +0 -7
  1006. package/node_modules/@isaacs/cliui/dist/esm/wrap-ansi/index.d.ts.map +0 -1
  1007. package/node_modules/@isaacs/cliui/dist/esm/wrap-ansi/index.js +0 -172
  1008. package/node_modules/@isaacs/cliui/dist/esm/wrap-ansi/index.js.map +0 -1
  1009. package/node_modules/@isaacs/cliui/package.json +0 -163
  1010. package/node_modules/content-disposition/HISTORY.md +0 -60
  1011. package/node_modules/cross-spawn/LICENSE +0 -21
  1012. package/node_modules/cross-spawn/README.md +0 -89
  1013. package/node_modules/cross-spawn/index.js +0 -39
  1014. package/node_modules/cross-spawn/lib/enoent.js +0 -59
  1015. package/node_modules/cross-spawn/lib/parse.js +0 -91
  1016. package/node_modules/cross-spawn/lib/util/escape.js +0 -47
  1017. package/node_modules/cross-spawn/lib/util/readShebang.js +0 -23
  1018. package/node_modules/cross-spawn/lib/util/resolveCommand.js +0 -52
  1019. package/node_modules/cross-spawn/package.json +0 -73
  1020. package/node_modules/fastify/test/types/content-type-parser.test-d.ts +0 -72
  1021. package/node_modules/fastify/test/types/decorate-request-reply.test-d.ts +0 -18
  1022. package/node_modules/fastify/test/types/dummy-plugin.ts +0 -9
  1023. package/node_modules/fastify/test/types/errors.test-d.ts +0 -90
  1024. package/node_modules/fastify/test/types/fastify.test-d.ts +0 -352
  1025. package/node_modules/fastify/test/types/hooks.test-d.ts +0 -550
  1026. package/node_modules/fastify/test/types/import.ts +0 -2
  1027. package/node_modules/fastify/test/types/instance.test-d.ts +0 -588
  1028. package/node_modules/fastify/test/types/logger.test-d.ts +0 -277
  1029. package/node_modules/fastify/test/types/plugin.test-d.ts +0 -97
  1030. package/node_modules/fastify/test/types/register.test-d.ts +0 -237
  1031. package/node_modules/fastify/test/types/reply.test-d.ts +0 -254
  1032. package/node_modules/fastify/test/types/request.test-d.ts +0 -188
  1033. package/node_modules/fastify/test/types/route.test-d.ts +0 -553
  1034. package/node_modules/fastify/test/types/schema.test-d.ts +0 -135
  1035. package/node_modules/fastify/test/types/serverFactory.test-d.ts +0 -37
  1036. package/node_modules/fastify/test/types/type-provider.test-d.ts +0 -1213
  1037. package/node_modules/fastify/test/types/using.test-d.ts +0 -17
  1038. package/node_modules/foreground-child/LICENSE +0 -15
  1039. package/node_modules/foreground-child/README.md +0 -128
  1040. package/node_modules/foreground-child/dist/commonjs/all-signals.d.ts +0 -2
  1041. package/node_modules/foreground-child/dist/commonjs/all-signals.d.ts.map +0 -1
  1042. package/node_modules/foreground-child/dist/commonjs/all-signals.js +0 -58
  1043. package/node_modules/foreground-child/dist/commonjs/all-signals.js.map +0 -1
  1044. package/node_modules/foreground-child/dist/commonjs/index.d.ts +0 -58
  1045. package/node_modules/foreground-child/dist/commonjs/index.d.ts.map +0 -1
  1046. package/node_modules/foreground-child/dist/commonjs/index.js +0 -123
  1047. package/node_modules/foreground-child/dist/commonjs/index.js.map +0 -1
  1048. package/node_modules/foreground-child/dist/commonjs/package.json +0 -3
  1049. package/node_modules/foreground-child/dist/commonjs/proxy-signals.d.ts +0 -6
  1050. package/node_modules/foreground-child/dist/commonjs/proxy-signals.d.ts.map +0 -1
  1051. package/node_modules/foreground-child/dist/commonjs/proxy-signals.js +0 -38
  1052. package/node_modules/foreground-child/dist/commonjs/proxy-signals.js.map +0 -1
  1053. package/node_modules/foreground-child/dist/commonjs/watchdog.d.ts +0 -10
  1054. package/node_modules/foreground-child/dist/commonjs/watchdog.d.ts.map +0 -1
  1055. package/node_modules/foreground-child/dist/commonjs/watchdog.js +0 -50
  1056. package/node_modules/foreground-child/dist/commonjs/watchdog.js.map +0 -1
  1057. package/node_modules/foreground-child/dist/esm/all-signals.d.ts +0 -2
  1058. package/node_modules/foreground-child/dist/esm/all-signals.d.ts.map +0 -1
  1059. package/node_modules/foreground-child/dist/esm/all-signals.js +0 -52
  1060. package/node_modules/foreground-child/dist/esm/all-signals.js.map +0 -1
  1061. package/node_modules/foreground-child/dist/esm/index.d.ts +0 -58
  1062. package/node_modules/foreground-child/dist/esm/index.d.ts.map +0 -1
  1063. package/node_modules/foreground-child/dist/esm/index.js +0 -115
  1064. package/node_modules/foreground-child/dist/esm/index.js.map +0 -1
  1065. package/node_modules/foreground-child/dist/esm/package.json +0 -3
  1066. package/node_modules/foreground-child/dist/esm/proxy-signals.d.ts +0 -6
  1067. package/node_modules/foreground-child/dist/esm/proxy-signals.d.ts.map +0 -1
  1068. package/node_modules/foreground-child/dist/esm/proxy-signals.js +0 -34
  1069. package/node_modules/foreground-child/dist/esm/proxy-signals.js.map +0 -1
  1070. package/node_modules/foreground-child/dist/esm/watchdog.d.ts +0 -10
  1071. package/node_modules/foreground-child/dist/esm/watchdog.d.ts.map +0 -1
  1072. package/node_modules/foreground-child/dist/esm/watchdog.js +0 -46
  1073. package/node_modules/foreground-child/dist/esm/watchdog.js.map +0 -1
  1074. package/node_modules/foreground-child/package.json +0 -106
  1075. package/node_modules/glob/dist/esm/bin.d.mts +0 -3
  1076. package/node_modules/glob/dist/esm/bin.d.mts.map +0 -1
  1077. package/node_modules/glob/dist/esm/bin.mjs +0 -346
  1078. package/node_modules/glob/dist/esm/bin.mjs.map +0 -1
  1079. package/node_modules/isexe/.npmignore +0 -2
  1080. package/node_modules/isexe/LICENSE +0 -15
  1081. package/node_modules/isexe/README.md +0 -51
  1082. package/node_modules/isexe/index.js +0 -57
  1083. package/node_modules/isexe/mode.js +0 -41
  1084. package/node_modules/isexe/package.json +0 -31
  1085. package/node_modules/isexe/test/basic.js +0 -221
  1086. package/node_modules/isexe/windows.js +0 -42
  1087. package/node_modules/jackspeak/LICENSE.md +0 -55
  1088. package/node_modules/jackspeak/README.md +0 -394
  1089. package/node_modules/jackspeak/dist/commonjs/index.d.ts +0 -323
  1090. package/node_modules/jackspeak/dist/commonjs/index.d.ts.map +0 -1
  1091. package/node_modules/jackspeak/dist/commonjs/index.js +0 -944
  1092. package/node_modules/jackspeak/dist/commonjs/index.js.map +0 -1
  1093. package/node_modules/jackspeak/dist/commonjs/index.min.js +0 -33
  1094. package/node_modules/jackspeak/dist/commonjs/index.min.js.map +0 -7
  1095. package/node_modules/jackspeak/dist/commonjs/package.json +0 -3
  1096. package/node_modules/jackspeak/dist/esm/index.d.ts +0 -323
  1097. package/node_modules/jackspeak/dist/esm/index.d.ts.map +0 -1
  1098. package/node_modules/jackspeak/dist/esm/index.js +0 -936
  1099. package/node_modules/jackspeak/dist/esm/index.js.map +0 -1
  1100. package/node_modules/jackspeak/dist/esm/index.min.js +0 -33
  1101. package/node_modules/jackspeak/dist/esm/index.min.js.map +0 -7
  1102. package/node_modules/jackspeak/dist/esm/package.json +0 -3
  1103. package/node_modules/jackspeak/package.json +0 -115
  1104. package/node_modules/jishushell-panel/output/public/assets/ApiKeyField-D1i7zWXR.js +0 -1
  1105. package/node_modules/jishushell-panel/output/public/assets/Dashboard-sWIvL43F.js +0 -1
  1106. package/node_modules/jishushell-panel/output/public/assets/HermesChatPanel-DQ8RyvQY.js +0 -1
  1107. package/node_modules/jishushell-panel/output/public/assets/HermesConfigForm-tIbPP1sB.js +0 -4
  1108. package/node_modules/jishushell-panel/output/public/assets/InitPassword-C3Slq3Dd.js +0 -1
  1109. package/node_modules/jishushell-panel/output/public/assets/InstanceDetail-7JqY9tq4.js +0 -92
  1110. package/node_modules/jishushell-panel/output/public/assets/Login-BXLDJlQN.js +0 -1
  1111. package/node_modules/jishushell-panel/output/public/assets/NewInstance-dLc5Xrpx.js +0 -1
  1112. package/node_modules/jishushell-panel/output/public/assets/ProviderRecommendations-DIAXxesl.js +0 -1
  1113. package/node_modules/jishushell-panel/output/public/assets/Settings-Bd5utbBh.js +0 -1
  1114. package/node_modules/jishushell-panel/output/public/assets/Setup-Yn9_20FL.js +0 -1
  1115. package/node_modules/jishushell-panel/output/public/assets/WeixinLoginPanel-C21doQTJ.js +0 -9
  1116. package/node_modules/jishushell-panel/output/public/assets/index-CCkaIEjn.js +0 -20
  1117. package/node_modules/jishushell-panel/output/public/assets/index-D7qxy-Vh.css +0 -1
  1118. package/node_modules/jishushell-panel/output/public/assets/registry-B2ZQZXWL.js +0 -2
  1119. package/node_modules/jishushell-panel/output/public/assets/usePolling-BFZm4do_.js +0 -1
  1120. package/node_modules/jishushell-panel/output/public/assets/vendor-i18n-DqPtOicc.js +0 -9
  1121. package/node_modules/jishushell-panel/output/public/assets/vendor-react-DW5juQin.js +0 -59
  1122. package/node_modules/package-json-from-dist/LICENSE.md +0 -63
  1123. package/node_modules/package-json-from-dist/README.md +0 -110
  1124. package/node_modules/package-json-from-dist/dist/commonjs/index.d.ts +0 -89
  1125. package/node_modules/package-json-from-dist/dist/commonjs/index.d.ts.map +0 -1
  1126. package/node_modules/package-json-from-dist/dist/commonjs/index.js +0 -134
  1127. package/node_modules/package-json-from-dist/dist/commonjs/index.js.map +0 -1
  1128. package/node_modules/package-json-from-dist/dist/commonjs/package.json +0 -3
  1129. package/node_modules/package-json-from-dist/dist/esm/index.d.ts +0 -89
  1130. package/node_modules/package-json-from-dist/dist/esm/index.d.ts.map +0 -1
  1131. package/node_modules/package-json-from-dist/dist/esm/index.js +0 -129
  1132. package/node_modules/package-json-from-dist/dist/esm/index.js.map +0 -1
  1133. package/node_modules/package-json-from-dist/dist/esm/package.json +0 -3
  1134. package/node_modules/package-json-from-dist/package.json +0 -68
  1135. package/node_modules/path-key/index.d.ts +0 -40
  1136. package/node_modules/path-key/index.js +0 -16
  1137. package/node_modules/path-key/license +0 -9
  1138. package/node_modules/path-key/package.json +0 -39
  1139. package/node_modules/path-key/readme.md +0 -61
  1140. package/node_modules/safe-buffer/LICENSE +0 -21
  1141. package/node_modules/safe-buffer/README.md +0 -584
  1142. package/node_modules/safe-buffer/index.d.ts +0 -187
  1143. package/node_modules/safe-buffer/index.js +0 -65
  1144. package/node_modules/safe-buffer/package.json +0 -51
  1145. package/node_modules/shebang-command/index.js +0 -19
  1146. package/node_modules/shebang-command/license +0 -9
  1147. package/node_modules/shebang-command/package.json +0 -34
  1148. package/node_modules/shebang-command/readme.md +0 -34
  1149. package/node_modules/shebang-regex/index.d.ts +0 -22
  1150. package/node_modules/shebang-regex/index.js +0 -2
  1151. package/node_modules/shebang-regex/license +0 -9
  1152. package/node_modules/shebang-regex/package.json +0 -35
  1153. package/node_modules/shebang-regex/readme.md +0 -33
  1154. package/node_modules/signal-exit/LICENSE.txt +0 -16
  1155. package/node_modules/signal-exit/README.md +0 -74
  1156. package/node_modules/signal-exit/dist/cjs/browser.d.ts +0 -12
  1157. package/node_modules/signal-exit/dist/cjs/browser.d.ts.map +0 -1
  1158. package/node_modules/signal-exit/dist/cjs/browser.js +0 -10
  1159. package/node_modules/signal-exit/dist/cjs/browser.js.map +0 -1
  1160. package/node_modules/signal-exit/dist/cjs/index.d.ts +0 -48
  1161. package/node_modules/signal-exit/dist/cjs/index.d.ts.map +0 -1
  1162. package/node_modules/signal-exit/dist/cjs/index.js +0 -279
  1163. package/node_modules/signal-exit/dist/cjs/index.js.map +0 -1
  1164. package/node_modules/signal-exit/dist/cjs/package.json +0 -3
  1165. package/node_modules/signal-exit/dist/cjs/signals.d.ts +0 -29
  1166. package/node_modules/signal-exit/dist/cjs/signals.d.ts.map +0 -1
  1167. package/node_modules/signal-exit/dist/cjs/signals.js +0 -42
  1168. package/node_modules/signal-exit/dist/cjs/signals.js.map +0 -1
  1169. package/node_modules/signal-exit/dist/mjs/browser.d.ts +0 -12
  1170. package/node_modules/signal-exit/dist/mjs/browser.d.ts.map +0 -1
  1171. package/node_modules/signal-exit/dist/mjs/browser.js +0 -4
  1172. package/node_modules/signal-exit/dist/mjs/browser.js.map +0 -1
  1173. package/node_modules/signal-exit/dist/mjs/index.d.ts +0 -48
  1174. package/node_modules/signal-exit/dist/mjs/index.d.ts.map +0 -1
  1175. package/node_modules/signal-exit/dist/mjs/index.js +0 -275
  1176. package/node_modules/signal-exit/dist/mjs/index.js.map +0 -1
  1177. package/node_modules/signal-exit/dist/mjs/package.json +0 -3
  1178. package/node_modules/signal-exit/dist/mjs/signals.d.ts +0 -29
  1179. package/node_modules/signal-exit/dist/mjs/signals.d.ts.map +0 -1
  1180. package/node_modules/signal-exit/dist/mjs/signals.js +0 -39
  1181. package/node_modules/signal-exit/dist/mjs/signals.js.map +0 -1
  1182. package/node_modules/signal-exit/package.json +0 -106
  1183. package/node_modules/which/CHANGELOG.md +0 -166
  1184. package/node_modules/which/LICENSE +0 -15
  1185. package/node_modules/which/README.md +0 -54
  1186. package/node_modules/which/bin/node-which +0 -52
  1187. package/node_modules/which/package.json +0 -43
  1188. package/node_modules/which/which.js +0 -125
  1189. package/scripts/check-adapter-isolation.ts +0 -293
  1190. /package/dist/services/{app → app-common}/app-compiler.d.ts +0 -0
  1191. /package/dist/services/{app → app-common}/terminal-session-manager.d.ts +0 -0
  1192. /package/dist/services/{backup-verify.d.ts → backup/backup-verify.d.ts} +0 -0
  1193. /package/dist/services/{external-mounts.d.ts → files/external-mounts.d.ts} +0 -0
  1194. /package/dist/services/{organize → files/organize}/applier.d.ts +0 -0
  1195. /package/dist/services/{organize → files/organize}/rules.d.ts +0 -0
  1196. /package/dist/services/{organize → files/organize}/scanner.d.ts +0 -0
  1197. /package/dist/services/{organize → files/organize}/store.d.ts +0 -0
  1198. /package/dist/services/{webdav → files/webdav}/xml-builder.d.ts +0 -0
  1199. /package/dist/services/{webdav → files/webdav}/xml-builder.js +0 -0
  1200. /package/dist/services/{app-passwords.d.ts → instances/passwords.d.ts} +0 -0
  1201. /package/dist/services/{agent-apps → integrations/installable}/installers/registry-probe.d.ts +0 -0
  1202. /package/dist/services/{agent-apps → integrations/installable}/installers/registry-probe.js +0 -0
  1203. /package/dist/services/{runtime/mcp-shims → integrations/openclaw}/drive-shim.d.ts +0 -0
  1204. /package/dist/services/{runtime/mcp-shims → integrations/openclaw}/mcporter-lite.d.ts +0 -0
  1205. /package/dist/services/{plugin-installer.d.ts → setup/plugin-installer.d.ts} +0 -0
  1206. /package/dist/services/{macos-launchd.d.ts → system/macos-launchd.d.ts} +0 -0
  1207. /package/dist/services/{system-monitor.d.ts → system/system-monitor.d.ts} +0 -0
@@ -1,1075 +1,33 @@
1
- import { getServiceManagerType } from "../config.js";
2
- import { assertNotLocked } from "../services/backup-manager.js";
3
- import * as instanceManager from "../services/app/app-manager.js";
4
- import { cleanupInstance as cleanupProxyInstance, getLastProxyError, invalidateConfigCache, } from "../services/llm-proxy/instance-proxy.js";
5
- import { createInstance, isInstanceAdminError, validateId, } from "../services/instance-admin.js";
6
- import { getConnectionStatus, getConnectionSummary, isConnectionAdminError, replaceConnections, } from "../services/connection-admin.js";
7
- import { getAppConfigMeta, isAppConfigAdminError, readAppConfig, writeAppConfig, } from "../services/app-config-admin.js";
8
- import { augmentInstanceMetadata, getInstanceCapabilities, resolveAgentType, } from "../services/runtime/instance.js";
9
- import { getAdapter, hasAdapter } from "../services/runtime/index.js";
10
- import { invalidateRuntimeIdentity, resolveRuntimeIdentity, } from "../services/runtime-identity.js";
11
- import { acknowledgeRuntimeRestartAdvisory } from "../services/system-reconciler.js";
12
- import { assertTerminalSessionOwner, getTerminalSession, getTerminalSessionEvents, sendTerminalSessionInput, startTerminalSession, stopTerminalSession, subscribeTerminalSession, } from "../services/app/terminal-session-manager.js";
13
- import { TtlMap } from "../utils/ttl-cache.js";
14
- import { writeSecretFile } from "../utils/fs.js";
15
- import { Readable } from "node:stream";
16
- export { validateId };
17
- // Hop-by-hop headers that must not be forwarded by a proxy (RFC 2616 §13.5.1).
18
- // Exported for adapter-owned route modules that implement their own HTTP proxies.
19
- export const HOP_BY_HOP = new Set([
20
- "connection", "keep-alive", "proxy-authenticate", "proxy-authorization",
21
- "te", "trailer", "transfer-encoding", "upgrade",
22
- ]);
23
- /**
24
- * Strip the panel session cookie (`jishushell_session`) from a cookie header
25
- * value, preserving any other cookies for upstream forwarding.
26
- */
27
- function stripPanelSessionCookie(value) {
28
- if (value === undefined)
29
- return undefined;
30
- const cookie = Array.isArray(value) ? value.join("; ") : value;
31
- const preserved = cookie
32
- .split(";")
33
- .map((part) => part.trim())
34
- .filter((part) => part && !/^jishushell_session=/i.test(part));
35
- return preserved.length ? preserved.join("; ") : undefined;
36
- }
37
- function readHeaderValue(value) {
38
- const header = Array.isArray(value) ? value[0] : value;
39
- return typeof header === "string" && header.trim() ? header.trim() : null;
40
- }
41
- function parseHttpOrigin(value) {
42
- if (!value)
43
- return null;
44
- try {
45
- const parsed = new URL(value);
46
- return parsed.protocol === "http:" || parsed.protocol === "https:" ? parsed.origin : null;
47
- }
48
- catch {
49
- return null;
50
- }
51
- }
52
- export function inferRequestOrigin(request) {
53
- // Only trust browser-sent Origin/Referer for auto-allowlisting. Host and
54
- // X-Forwarded-* are proxy metadata and should not become persisted origin
55
- // policy by themselves.
56
- return (parseHttpOrigin(readHeaderValue(request?.headers?.origin))
57
- ?? parseHttpOrigin(readHeaderValue(request?.headers?.referer)));
58
- }
59
- function capabilityProxyPath(instanceId, capability) {
60
- return `/api/instances/${encodeURIComponent(instanceId)}/provides/${encodeURIComponent(capability)}`;
61
- }
62
- function joinProxyPath(basePath, suffix) {
63
- const normalizedBase = basePath.replace(/\/+$/, "");
64
- const normalizedSuffix = suffix.replace(/^\/+/, "");
65
- if (!normalizedSuffix)
66
- return normalizedBase;
67
- return `${normalizedBase}/${normalizedSuffix}`;
68
- }
69
- function canonicalCapabilityProxyBase(basePath, capabilityPath) {
70
- const normalizedCapabilityPath = typeof capabilityPath === "string" ? capabilityPath.trim() : "";
71
- const needsTrailingSlash = !normalizedCapabilityPath || normalizedCapabilityPath.endsWith("/");
72
- return needsTrailingSlash ? `${basePath}/` : basePath;
73
- }
74
- function rewriteCapabilityLocation(basePath, canonicalBasePath, pathname, search = "", hash = "") {
75
- const rewrittenPath = pathname === "/"
76
- ? canonicalBasePath
77
- : joinProxyPath(basePath, pathname);
78
- return `${rewrittenPath}${search}${hash}`;
79
- }
80
- function joinUpstreamPath(basePath, suffix) {
81
- const normalizedBase = typeof basePath === "string" && basePath.trim()
82
- ? (basePath.startsWith("/") ? basePath : `/${basePath}`)
83
- : "/";
84
- const normalizedSuffix = suffix.replace(/^\/+/, "");
85
- if (!normalizedSuffix)
86
- return normalizedBase;
87
- return `${normalizedBase.replace(/\/+$/, "")}/${normalizedSuffix}`;
88
- }
89
- function shouldRewriteProxyResponse(contentType) {
90
- const value = (contentType ?? "").toLowerCase();
91
- return value.includes("text/html") || value.includes("text/css");
92
- }
93
- function browserlessDebuggerBootstrap(instanceId) {
94
- const apiProxyPath = `${capabilityProxyPath(instanceId, "browserless-api")}`;
95
- const escapedPath = JSON.stringify(apiProxyPath + "/");
96
- const escapedProxyBase = JSON.stringify(apiProxyPath);
97
- const escapedWorkerPrelude = JSON.stringify([
98
- "(function(){",
99
- `var P=${escapedProxyBase};`,
100
- "var _WS=self.WebSocket;",
101
- "if(typeof _WS!=='function')return;",
102
- "self.WebSocket=function(url,protocols){",
103
- "try{var p=new URL(url,self.location.origin);",
104
- "if(p.host===self.location.host&&!p.pathname.startsWith('/api/')){",
105
- "var s=self.location.protocol==='https:'?'wss:':'ws:';",
106
- "url=s+'//'+self.location.host+P+p.pathname+p.search;",
107
- "}}catch(_e){}",
108
- "return protocols!==undefined?new _WS(url,protocols):new _WS(url);",
109
- "};",
110
- "self.WebSocket.prototype=_WS.prototype;",
111
- "self.WebSocket.CONNECTING=_WS.CONNECTING;",
112
- "self.WebSocket.OPEN=_WS.OPEN;",
113
- "self.WebSocket.CLOSING=_WS.CLOSING;",
114
- "self.WebSocket.CLOSED=_WS.CLOSED;",
115
- "})();",
116
- ].join(""));
117
- // 1) Set baseURL in localStorage so the debugger's HTTP API calls go through
118
- // the capability proxy.
119
- // 2) Monkey-patch WebSocket in the page and any same-origin workers so that
120
- // Browserless connections targeting the panel origin (e.g.
121
- // ws://panel:8090/?launch=...) are rewritten through the capability proxy.
122
- return [
123
- "<script>(function(){",
124
- // --- localStorage apiSettings.baseURL ---
125
- // Browserless reads `state.apiSettings.baseURL` (a NESTED object); writing
126
- // a flat `state.baseURL` is silently ignored, and the SPA falls back to
127
- // `window.location.origin` (no proxy prefix) — producing connect URLs like
128
- // `ws://panel:8090/?launch=...` that bypass the capability proxy.
129
- "try{var key='browserless-debugger:'+window.location.origin+window.location.pathname;",
130
- "var raw=window.localStorage.getItem(key)||'{}';",
131
- "var state={};try{state=JSON.parse(raw)||{}}catch(_e){}",
132
- `var base=new URL(${escapedPath},window.location.origin);`,
133
- "var token=new URL(window.location.href).searchParams.get('token');",
134
- "if(token)base.searchParams.set('token',token);",
135
- "var settings=(state&&typeof state.apiSettings==='object'&&state.apiSettings)?state.apiSettings:{};",
136
- "settings.baseURL=base.href;",
137
- "state.apiSettings=settings;",
138
- "window.localStorage.setItem(key,JSON.stringify(state));",
139
- "}catch(_e){}",
140
- // --- WebSocket monkey-patch ---
141
- "var _WS=window.WebSocket;",
142
- `var _base=${escapedProxyBase};`,
143
- "window.WebSocket=function(url,protocols){",
144
- "try{var p=new URL(url,window.location.origin);",
145
- "if(p.host===window.location.host&&!p.pathname.startsWith('/api/')){",
146
- "var s=window.location.protocol==='https:'?'wss:':'ws:';",
147
- "url=s+'//'+window.location.host+_base+p.pathname+p.search;",
148
- "}}catch(_e){}",
149
- "return protocols!==undefined?new _WS(url,protocols):new _WS(url);",
150
- "};",
151
- "window.WebSocket.prototype=_WS.prototype;",
152
- "window.WebSocket.CONNECTING=_WS.CONNECTING;",
153
- "window.WebSocket.OPEN=_WS.OPEN;",
154
- "window.WebSocket.CLOSING=_WS.CLOSING;",
155
- "window.WebSocket.CLOSED=_WS.CLOSED;",
156
- // --- Worker monkey-patch ---
157
- "var _Worker=window.Worker;",
158
- `var _workerPrelude=${escapedWorkerPrelude};`,
159
- "function shouldWrapWorker(url){",
160
- "try{var p=new URL(String(url),window.location.href);",
161
- "return p.protocol==='blob:'||p.protocol==='data:'||p.origin===window.location.origin;",
162
- "}catch(_e){return false;}",
163
- "}",
164
- "function wrapWorker(url,options){",
165
- "if(typeof _Worker!=='function'||!shouldWrapWorker(url))return url;",
166
- "try{var resolved=new URL(String(url),window.location.href).href;",
167
- "var isModule=!!(options&&options.type==='module');",
168
- "var source=isModule?_workerPrelude+'\\nimport '+JSON.stringify(resolved)+';':_workerPrelude+'\\nimportScripts('+JSON.stringify(resolved)+');';",
169
- "return URL.createObjectURL(new Blob([source],{type:'text/javascript'}));",
170
- "}catch(_e){return url;}",
171
- "}",
172
- "if(typeof _Worker==='function'){",
173
- "window.Worker=function(url,options){",
174
- "var wrapped=wrapWorker(url,options);",
175
- "return options!==undefined?new _Worker(wrapped,options):new _Worker(wrapped);",
176
- "};",
177
- "window.Worker.prototype=_Worker.prototype;",
178
- "}",
179
- "})();</script>",
180
- ].join("");
181
- }
182
- const JISHU_KB_PRELOAD_SESSION_LIMIT = 50;
183
- const JISHU_KB_PRELOAD_MESSAGE_LIMIT = 20;
184
- const JISHU_KB_PRELOAD_TIMEOUT_MS = 5_000;
185
- const JISHU_KB_PRELOAD_GLOBAL = "__JISHU_KB_PRELOADED_SESSIONS__";
186
- function trimString(value) {
187
- return typeof value === "string" ? value.trim() : "";
188
- }
189
- function parseJishuKbConversationId(value) {
190
- if (typeof value === "number") {
191
- return Number.isSafeInteger(value) && value > 0 ? value : null;
192
- }
193
- const raw = trimString(value);
194
- if (!/^\d+$/.test(raw))
195
- return null;
196
- const parsed = Number(raw);
197
- return Number.isSafeInteger(parsed) && parsed > 0 ? parsed : null;
198
- }
199
- function parseJishuKbTimestamp(value) {
200
- const numeric = typeof value === "number" ? value : Number(value);
201
- return Number.isFinite(numeric) ? numeric : 0;
202
- }
203
- function parseJishuKbRole(value) {
204
- const normalized = trimString(value);
205
- return normalized === "user" || normalized === "assistant" || normalized === "system"
206
- ? normalized
207
- : null;
208
- }
209
- function parseJishuKbCitations(value) {
210
- if (Array.isArray(value))
211
- return value;
212
- if (typeof value !== "string" || !value.trim())
213
- return undefined;
214
- try {
215
- const parsed = JSON.parse(value);
216
- return Array.isArray(parsed) ? parsed : undefined;
217
- }
218
- catch {
219
- return undefined;
220
- }
221
- }
222
- function relayAbort(parentSignal, controller) {
223
- if (parentSignal.aborted) {
224
- controller.abort(parentSignal.reason);
225
- return () => { };
226
- }
227
- const abort = () => controller.abort(parentSignal.reason);
228
- parentSignal.addEventListener("abort", abort, { once: true });
229
- return () => parentSignal.removeEventListener("abort", abort);
230
- }
231
- async function fetchJsonWithTimeout(upstreamOrigin, relativePath, parentSignal) {
232
- const controller = new AbortController();
233
- const cleanupAbort = relayAbort(parentSignal, controller);
234
- const timer = setTimeout(() => controller.abort(new Error("timeout")), JISHU_KB_PRELOAD_TIMEOUT_MS);
235
- try {
236
- const response = await fetch(new URL(relativePath, `${upstreamOrigin}/`).toString(), {
237
- headers: { accept: "application/json" },
238
- signal: controller.signal,
239
- });
240
- if (!response.ok) {
241
- const detail = (await response.text()).slice(0, 200);
242
- throw new Error(`${relativePath} -> ${response.status}${detail ? `: ${detail}` : ""}`);
243
- }
244
- return await response.json();
245
- }
246
- finally {
247
- clearTimeout(timer);
248
- cleanupAbort();
249
- }
250
- }
251
- async function loadJishuKbPreloadedSessions(upstreamOrigin, parentSignal) {
252
- const kbList = await fetchJsonWithTimeout(upstreamOrigin, "/api/kb", parentSignal);
253
- const kbIds = Array.from(new Set((Array.isArray(kbList) ? kbList : [])
254
- .map((kb) => trimString(kb?.id))
255
- .filter(Boolean)));
256
- if (!kbIds.length)
257
- kbIds.push("default");
258
- const conversationLists = await Promise.all(kbIds.map(async (kbId) => {
259
- const query = new URLSearchParams({ kb_id: kbId }).toString();
260
- const rows = await fetchJsonWithTimeout(upstreamOrigin, `/api/conversations?${query}`, parentSignal);
261
- return Array.isArray(rows)
262
- ? rows.map((row) => ({
263
- ...row,
264
- kb_id: trimString(row?.kb_id) || kbId,
265
- }))
266
- : [];
267
- }));
268
- const selected = conversationLists
269
- .flat()
270
- .sort((left, right) => parseJishuKbTimestamp(right.updated_at) - parseJishuKbTimestamp(left.updated_at))
271
- .slice(0, JISHU_KB_PRELOAD_SESSION_LIMIT);
272
- const hydrated = await Promise.all(selected.map(async (conversation) => {
273
- const conversationId = parseJishuKbConversationId(conversation.id);
274
- const kbId = trimString(conversation.kb_id);
275
- if (!conversationId || !kbId) {
276
- console.warn("[cap-proxy] skipping jishukb conversation preload with unsupported id/kb", {
277
- id: conversation.id,
278
- kbId,
279
- });
280
- return null;
281
- }
282
- const messages = await fetchJsonWithTimeout(upstreamOrigin, `/api/conversations/${encodeURIComponent(String(conversationId))}/messages`, parentSignal);
283
- const normalizedMessages = (Array.isArray(messages) ? messages : [])
284
- .map((message) => {
285
- const role = parseJishuKbRole(message?.role);
286
- const content = typeof message?.content === "string" ? message.content : "";
287
- if (!role || !content)
288
- return null;
289
- const cites = parseJishuKbCitations(message?.citations);
290
- return cites?.length
291
- ? { role, content, cites }
292
- : { role, content };
293
- })
294
- .filter((message) => message !== null)
295
- .slice(-JISHU_KB_PRELOAD_MESSAGE_LIMIT);
296
- return {
297
- id: conversationId,
298
- kb: kbId,
299
- title: trimString(conversation.title) || "Untitled",
300
- msgs: normalizedMessages,
301
- _syncedMsgIdx: normalizedMessages.length,
302
- };
303
- }));
304
- return hydrated
305
- .filter((session) => session !== null)
306
- .sort((left, right) => left.id - right.id);
307
- }
308
- function jishuKbConversationBootstrap(preloadedSessions) {
309
- const serialized = JSON.stringify(preloadedSessions);
310
- const globalName = JSON.stringify(JISHU_KB_PRELOAD_GLOBAL);
311
- return [
312
- "<script>(function(){",
313
- "try{",
314
- `var incoming=${serialized};`,
315
- `window[${globalName}]=incoming;`,
316
- "var current=[];",
317
- "try{var raw=window.localStorage.getItem('jkb_sess');current=raw?JSON.parse(raw):[];}catch(_e){current=[];}",
318
- "if(!Array.isArray(current))current=[];",
319
- "var seen=Object.create(null);",
320
- "var merged=[];",
321
- "function key(entry){return String(entry&&entry.kb||'')+'::'+String(entry&&entry.id||'');}",
322
- "function push(entry){if(!entry||typeof entry!=='object')return;var k=key(entry);if(seen[k])return;seen[k]=1;merged.push(entry);}",
323
- "incoming.forEach(push);",
324
- "current.forEach(push);",
325
- "merged.sort(function(a,b){return Number(a&&a.id||0)-Number(b&&b.id||0);});",
326
- `if(merged.length>${JISHU_KB_PRELOAD_SESSION_LIMIT})merged=merged.slice(-${JISHU_KB_PRELOAD_SESSION_LIMIT});`,
327
- "window.localStorage.setItem('jkb_sess',JSON.stringify(merged));",
328
- "}catch(_e){}",
329
- "})();</script>",
330
- ].join("");
331
- }
332
- /**
333
- * Inject a tiny <script> that monkey-patches `fetch`, `XMLHttpRequest.open`,
334
- * and `Element.prototype.{setAttribute,src,href}` so that same-origin absolute
335
- * paths (e.g. `/api/v1/...`, `/static/...`) are transparently rewritten to go
336
- * through the capability proxy prefix.
337
- *
338
- * The alternative — rewriting every JS bundle byte-for-byte — is fragile and
339
- * expensive; a runtime shim at document load is the standard approach used by
340
- * reverse-proxy front-ends (cf. Cloudflare Access, oauth2-proxy, etc.).
341
- */
342
- function capabilityProxyBootstrap(proxyBasePath) {
343
- const prefix = JSON.stringify(proxyBasePath.replace(/\/+$/, ""));
344
- const workerPrelude = JSON.stringify([
345
- "(function(){",
346
- `var P=${prefix};`,
347
- "function px(path){",
348
- "if(!path||path.charAt(0)!=='/'||path.charAt(1)==='/'||path.indexOf(P)===0||path.indexOf('/api/instances/')===0)return path;",
349
- "return P+path;",
350
- "}",
351
- "function str(u){return typeof u==='string'?u:(u&&typeof u.href==='string'?u.href:null);}",
352
- "function rwWs(u){",
353
- "var s0=str(u);if(!s0)return u;",
354
- "var H=typeof __capProxyHost==='string'?__capProxyHost:self.location.host;",
355
- "var L=typeof __capProxyProtocol==='string'?__capProxyProtocol:self.location.protocol;",
356
- "var B=(L==='https:'?'https:':'http:')+'//'+H+'/';",
357
- "try{var p=new URL(s0,B);",
358
- "if(p.host===H&&(p.protocol==='ws:'||p.protocol==='wss:'||p.protocol===L)){",
359
- "var pp=px(p.pathname);",
360
- "if(pp!==p.pathname){var s=L==='https:'?'wss:':'ws:';return s+'//'+H+pp+p.search+p.hash;}",
361
- "}}catch(_e){}",
362
- "return u;",
363
- "}",
364
- "var _WS=self.WebSocket;",
365
- "if(typeof _WS==='function')self.WebSocket=function(url,protocols){url=rwWs(url);return protocols!==undefined?new _WS(url,protocols):new _WS(url);};",
366
- "if(typeof _WS==='function'){self.WebSocket.prototype=_WS.prototype;self.WebSocket.CONNECTING=_WS.CONNECTING;self.WebSocket.OPEN=_WS.OPEN;self.WebSocket.CLOSING=_WS.CLOSING;self.WebSocket.CLOSED=_WS.CLOSED;}",
367
- "})();",
368
- ].join(""));
369
- return [
370
- "<script>(function(){",
371
- `var P=${prefix};`,
372
- "var O=window.location.origin;",
373
- // --- Service Worker neutralization ---
374
- // Embedded SPAs like OpenWebUI register a service worker that aggressively
375
- // caches HTML and JS chunks at the proxy origin. After we update the proxy
376
- // bootstrap, the SW would keep serving the old (unpatched) HTML, so socket.io
377
- // never gets the WebSocket monkey-patch and the splash screen spins forever.
378
- // Unregister any existing SW, purge its caches, and block future
379
- // registrations for the lifetime of the iframe.
380
- "try{if(navigator.serviceWorker){",
381
- "if(navigator.serviceWorker.getRegistrations){",
382
- "navigator.serviceWorker.getRegistrations().then(function(rs){rs.forEach(function(r){try{r.unregister()}catch(_e){}})}).catch(function(){});",
383
- "}",
384
- "navigator.serviceWorker.register=function(){return Promise.reject(new Error('service worker disabled in capability proxy'))};",
385
- "}}catch(_e){}",
386
- "try{if(window.caches&&caches.keys){caches.keys().then(function(ks){ks.forEach(function(k){try{caches.delete(k)}catch(_e){}})}).catch(function(){});}}catch(_e){}",
387
- // Only rewrite paths that do NOT already start with the proxy prefix and
388
- // that are simple absolute paths (start with `/` but not `//`).
389
- "function px(path){",
390
- "if(!path||path.charAt(0)!=='/'||path.charAt(1)==='/'||path.indexOf(P)===0||path.indexOf('/api/instances/')===0)return path;",
391
- "return P+path;",
392
- "}",
393
- "function str(u){return typeof u==='string'?u:(u&&typeof u.href==='string'?u.href:null);}",
394
- "function rw(u){",
395
- "var s0=str(u);if(!s0)return u;",
396
- "var direct=px(s0);",
397
- "if(direct!==s0)return direct;",
398
- "try{var p=new URL(s0,window.location.href);",
399
- "if(p.origin===O){var pp=px(p.pathname);if(pp!==p.pathname)return pp+p.search+p.hash;}",
400
- "}catch(_e){}",
401
- "return u;",
402
- "}",
403
- "function rwWs(u){",
404
- "var s0=str(u);if(!s0)return u;",
405
- "try{var p=new URL(s0,window.location.href);",
406
- "if(p.host===window.location.host&&(p.protocol==='ws:'||p.protocol==='wss:'||p.protocol===window.location.protocol)){",
407
- "var pp=px(p.pathname);",
408
- "if(pp!==p.pathname){var s=window.location.protocol==='https:'?'wss:':'ws:';return s+'//'+window.location.host+pp+p.search+p.hash;}",
409
- "}}catch(_e){}",
410
- "return u;",
411
- "}",
412
- // --- fetch() ---
413
- "var _f=window.fetch;",
414
- "window.fetch=function(r,o){",
415
- "if(typeof r==='string'||(r&&typeof r.href==='string'))r=rw(r);",
416
- "else if(r instanceof Request){",
417
- "var nr=rw(r.url);if(nr!==r.url)r=new Request(nr,r);}",
418
- "return _f.call(this,r,o);};",
419
- // --- XMLHttpRequest.open() ---
420
- "var _xo=XMLHttpRequest.prototype.open;",
421
- "XMLHttpRequest.prototype.open=function(m,u){",
422
- "arguments[1]=rw(u);",
423
- "return _xo.apply(this,arguments);};",
424
- // --- history.pushState / replaceState ---
425
- // SPA routers (SvelteKit, React Router, etc.) navigate via pushState.
426
- // Without this, pushing "/" lands on the panel's own SPA.
427
- "var _ps=history.pushState;",
428
- "var _rs=history.replaceState;",
429
- "history.pushState=function(s,t,u){",
430
- "if(typeof u==='string')u=rw(u);",
431
- "return _ps.call(this,s,t,u);};",
432
- "history.replaceState=function(s,t,u){",
433
- "if(typeof u==='string')u=rw(u);",
434
- "return _rs.call(this,s,t,u);};",
435
- // --- location.assign / location.replace ---
436
- "var _la=location.assign.bind(location);",
437
- "var _lr=location.replace.bind(location);",
438
- "location.assign=function(u){return _la(rw(u));};",
439
- "location.replace=function(u){return _lr(rw(u));};",
440
- // --- frame-busting defense ---
441
- // Embedded SPAs (e.g. WeKnora) frequently do
442
- // window.top.location.href = '/login'
443
- // when they see a 401, intending to log the user out. Inside our
444
- // capability proxy iframe `top` is the panel's main window — that
445
- // tears the user away from the instance detail page entirely.
446
- // Redirect `top`/`parent` to the iframe's own window so the
447
- // navigation stays inside the embed. Safe because the iframe IS
448
- // same-origin as the panel (our reverse proxy serves it from the
449
- // panel's host); cross-origin access would throw and fail closed.
450
- "try{",
451
- "Object.defineProperty(window,'top',{configurable:true,get:function(){return window;}});",
452
- "Object.defineProperty(window,'parent',{configurable:true,get:function(){return window;}});",
453
- "}catch(_e){}",
454
- // --- dynamic property assignment: img.src = '/static/...' ---
455
- "function patchProp(tag,prop){",
456
- "var d=Object.getOwnPropertyDescriptor(tag.prototype,prop);",
457
- "if(!d||!d.set)return;",
458
- "var orig=d.set;",
459
- "Object.defineProperty(tag.prototype,prop,{",
460
- "set:function(v){return orig.call(this,rw(v));},",
461
- "get:d.get,configurable:true,enumerable:true});",
462
- "}",
463
- "patchProp(HTMLImageElement,'src');",
464
- "patchProp(HTMLScriptElement,'src');",
465
- "patchProp(HTMLLinkElement,'href');",
466
- "patchProp(HTMLSourceElement,'src');",
467
- // --- Worker monkey-patch ---
468
- // Some SPA clients create socket.io/WebSocket connections from workers.
469
- // Patch same-origin workers so the same proxy-prefixing rule applies there.
470
- "var _Worker=window.Worker;",
471
- `var _workerPrelude=${workerPrelude};`,
472
- "function shouldWrapWorker(url){",
473
- "try{var p=new URL(String(url),window.location.href);return p.protocol==='blob:'||p.protocol==='data:'||p.origin===O;}catch(_e){return false;}",
474
- "}",
475
- "function wrapWorker(url,options){",
476
- "if(typeof _Worker!=='function'||!shouldWrapWorker(url))return url;",
477
- "try{var resolved=new URL(String(url),window.location.href).href;",
478
- "var isModule=!!(options&&options.type==='module');",
479
- "var workerEnv='var __capProxyHost='+JSON.stringify(window.location.host)+';var __capProxyProtocol='+JSON.stringify(window.location.protocol)+';';",
480
- "var source=isModule?workerEnv+_workerPrelude+'\\nimport '+JSON.stringify(resolved)+';':workerEnv+_workerPrelude+'\\nimportScripts('+JSON.stringify(resolved)+');';",
481
- "return URL.createObjectURL(new Blob([source],{type:'text/javascript'}));",
482
- "}catch(_e){return url;}",
483
- "}",
484
- "if(typeof _Worker==='function'){",
485
- "window.Worker=function(url,options){var wrapped=wrapWorker(url,options);return options!==undefined?new _Worker(wrapped,options):new _Worker(wrapped);};",
486
- "window.Worker.prototype=_Worker.prototype;",
487
- "}",
488
- // --- WebSocket ---
489
- // SPAs like OpenWebUI use socket.io over WebSocket. The socket.io client
490
- // builds ws:// URLs from window.location and the configured path; the URL
491
- // ends up pointing at the panel root (e.g. ws://panel:8090/ws/socket.io)
492
- // instead of the capability proxy. Without this patch the WS upgrade
493
- // request either gets destroyed (no route) or hits the wrong backend.
494
- "var _WS=window.WebSocket;",
495
- "if(typeof _WS==='function'){",
496
- "window.WebSocket=function(url,protocols){",
497
- "url=rwWs(url);",
498
- "return protocols!==undefined?new _WS(url,protocols):new _WS(url);",
499
- "};",
500
- "window.WebSocket.prototype=_WS.prototype;",
501
- "window.WebSocket.CONNECTING=_WS.CONNECTING;",
502
- "window.WebSocket.OPEN=_WS.OPEN;",
503
- "window.WebSocket.CLOSING=_WS.CLOSING;",
504
- "window.WebSocket.CLOSED=_WS.CLOSED;",
505
- "}",
506
- // --- EventSource ---
507
- // Some frameworks use SSE (Server-Sent Events) for real-time updates.
508
- "var _ES=window.EventSource;",
509
- "if(typeof _ES==='function'){",
510
- "window.EventSource=function(url,opts){",
511
- "if(typeof url==='string')url=rw(url);",
512
- "return new _ES(url,opts);",
513
- "};",
514
- "window.EventSource.prototype=_ES.prototype;",
515
- "window.EventSource.CONNECTING=_ES.CONNECTING;",
516
- "window.EventSource.OPEN=_ES.OPEN;",
517
- "window.EventSource.CLOSED=_ES.CLOSED;",
518
- "}",
519
- "})();</script>",
520
- ].join("");
521
- }
522
- function rewriteProxyTextBody(body, contentType, proxyBasePath, extraHeadHtml = "") {
523
- const value = (contentType ?? "").toLowerCase();
524
- const proxyBaseWithSlash = `${proxyBasePath.replace(/\/+$/, "")}/`;
525
- let rewritten = body;
526
- if (value.includes("text/html")) {
527
- // Rewrite asset URLs FIRST, then optionally inject a <base> tag.
528
- // Reversing the order would let the regex below match (and double-
529
- // prefix) the leading slash of the just-inserted `<base href="/api/...">`,
530
- // producing
531
- // <base href="/api/instances/X/provides/Y/api/instances/X/provides/Y/">
532
- // which then resolves every relative asset to a 404.
533
- rewritten = rewritten.replace(/((?:href|src|action|poster)=['"])\/(?!\/)/gi, `$1${proxyBaseWithSlash}`);
534
- // Rewrite dynamic import() paths inside inline <script> blocks so that
535
- // SvelteKit (and similar frameworks) resolve JS modules through the proxy.
536
- // Matches import("/_app/...") and import('/_app/...').
537
- rewritten = rewritten.replace(/\bimport\(\s*(['"])\/(?!\/)/g, `import($1${proxyBaseWithSlash}`);
538
- // Rewrite SvelteKit's client-side base path so that client-side routing
539
- // and subsequent chunk fetches go through the capability proxy path.
540
- // Older SvelteKit SSR output: __sveltekit_XXXXX = { base: "" };
541
- rewritten = rewritten.replace(/(__sveltekit_\w+\s*=\s*\{\s*base\s*:\s*)(["'])["']/, `$1$2${proxyBasePath.replace(/\/+$/, "")}$2`);
542
- // SvelteKit 2.x start() config: paths: { base: "", assets: "..." }
543
- rewritten = rewritten.replace(/(paths\s*:\s*\{\s*base\s*:\s*)(["'])["'](\s*,\s*assets\s*:)/, `$1$2${proxyBasePath.replace(/\/+$/, "")}$2$3`);
544
- if (!/<base\b/i.test(rewritten)) {
545
- if (/<head[^>]*>/i.test(rewritten)) {
546
- rewritten = rewritten.replace(/<head([^>]*)>/i, `<head$1><base href="${proxyBaseWithSlash}">`);
547
- }
548
- else {
549
- rewritten = `<base href="${proxyBaseWithSlash}">${rewritten}`;
550
- }
551
- }
552
- if (extraHeadHtml) {
553
- if (/<base\b/i.test(rewritten)) {
554
- rewritten = rewritten.replace(/<base\b[^>]*>/i, (match) => `${match}${extraHeadHtml}`);
555
- }
556
- else if (/<head[^>]*>/i.test(rewritten)) {
557
- rewritten = rewritten.replace(/<head([^>]*)>/i, `<head$1>${extraHeadHtml}`);
558
- }
559
- else {
560
- rewritten = `${extraHeadHtml}${rewritten}`;
561
- }
562
- }
563
- }
564
- if (value.includes("text/css")) {
565
- rewritten = rewritten.replace(/url\((['"]?)\/(?!\/)/gi, `url($1${proxyBaseWithSlash}`);
566
- }
567
- else if (value.includes("text/html")) {
568
- // HTML can contain inline scripts like new URL("/..."); only rewrite lowercase CSS url(...).
569
- rewritten = rewritten.replace(/url\((['"]?)\/(?!\/)/g, `url($1${proxyBaseWithSlash}`);
570
- }
571
- return rewritten;
572
- }
573
- function isReadableBody(value) {
574
- if (value instanceof Readable)
575
- return true;
576
- if (!value || typeof value !== "object")
577
- return false;
578
- const candidate = value;
579
- return (typeof candidate.pipe === "function" &&
580
- typeof candidate.on === "function" &&
581
- typeof candidate[Symbol.asyncIterator] === "function");
582
- }
583
- async function readProxyBodyStream(stream) {
584
- const chunks = [];
585
- for await (const chunk of stream) {
586
- if (typeof chunk === "string") {
587
- chunks.push(Buffer.from(chunk));
588
- }
589
- else if (chunk instanceof Uint8Array) {
590
- chunks.push(Buffer.from(chunk));
591
- }
592
- else {
593
- chunks.push(Buffer.from(String(chunk)));
594
- }
595
- }
596
- return Buffer.concat(chunks);
597
- }
598
- function bytesToArrayBuffer(bytes) {
599
- const out = new ArrayBuffer(bytes.byteLength);
600
- new Uint8Array(out).set(bytes);
601
- return out;
602
- }
603
- function isPlainRecord(value) {
604
- if (!value || typeof value !== "object")
605
- return false;
606
- const proto = Object.getPrototypeOf(value);
607
- return proto === Object.prototype || proto === null;
608
- }
609
- function encodeFormRecord(body) {
610
- const params = new URLSearchParams();
611
- for (const [key, value] of Object.entries(body)) {
612
- if (Array.isArray(value)) {
613
- for (const item of value)
614
- params.append(key, String(item));
615
- }
616
- else {
617
- params.append(key, String(value));
618
- }
619
- }
620
- return params.toString();
621
- }
622
- async function buildProxyRequestBody(req) {
623
- if (req.method === "GET" || req.method === "HEAD")
624
- return undefined;
625
- const body = req.body;
626
- if (body == null)
627
- return undefined;
628
- if (typeof body === "string") {
629
- return body;
630
- }
631
- if (body instanceof Uint8Array || Buffer.isBuffer(body))
632
- return bytesToArrayBuffer(body);
633
- if (isReadableBody(body)) {
634
- return bytesToArrayBuffer(await readProxyBodyStream(body));
635
- }
636
- const contentType = String(req.headers["content-type"] ?? "").toLowerCase();
637
- if (contentType.includes("application/x-www-form-urlencoded") && isPlainRecord(body)) {
638
- return encodeFormRecord(body);
639
- }
640
- if (contentType.includes("application/json") && isPlainRecord(body)) {
641
- return JSON.stringify(body);
642
- }
643
- if (isPlainRecord(body)) {
644
- return JSON.stringify(body);
645
- }
646
- return undefined;
647
- }
648
- function parseCommandLine(input) {
649
- const trimmed = input.trim();
650
- if (!trimmed)
651
- return [];
652
- const args = [];
653
- let current = "";
654
- let quote = null;
655
- let escaping = false;
656
- for (const char of trimmed) {
657
- if (escaping) {
658
- current += char;
659
- escaping = false;
660
- continue;
661
- }
662
- if (char === "\\") {
663
- escaping = true;
664
- continue;
665
- }
666
- if (quote) {
667
- if (char === quote) {
668
- quote = null;
669
- }
670
- else {
671
- current += char;
672
- }
673
- continue;
674
- }
675
- if (char === '"' || char === "'") {
676
- quote = char;
677
- continue;
678
- }
679
- if (/\s/.test(char)) {
680
- if (current) {
681
- args.push(current);
682
- current = "";
683
- }
684
- continue;
685
- }
686
- current += char;
687
- }
688
- if (escaping)
689
- current += "\\";
690
- if (quote)
691
- throw new Error("Command contains an unterminated quote");
692
- if (current)
693
- args.push(current);
694
- return args;
695
- }
696
- function isTerminalProvide(provide) {
697
- return !!provide && String(provide.protocol).toLowerCase() === "terminal" && !!provide.terminal;
698
- }
699
- function resolveTerminalProvide(instanceId, capability) {
700
- const provide = instanceManager
701
- .getProvidedCapabilitiesForApp(instanceId)
702
- .find((entry) => entry.capability === capability);
703
- if (!provide)
704
- throw new Error(`Capability '${capability}' not found`);
705
- if (!isTerminalProvide(provide)) {
706
- throw new Error(`Capability '${capability}' is not a terminal provide`);
707
- }
708
- return provide;
709
- }
710
- function buildTerminalCommand(baseCommand, input) {
711
- if (!Array.isArray(baseCommand) || baseCommand.length === 0 || baseCommand.some((part) => typeof part !== "string" || !part.trim())) {
712
- throw new Error("Terminal provide is missing a valid base command");
713
- }
714
- const parsed = parseCommandLine(input);
715
- if (!parsed.length)
716
- throw new Error("Command cannot be empty");
717
- const baseName = baseCommand[0].split("/").pop() || baseCommand[0];
718
- const matchesBase = parsed.length >= baseCommand.length && baseCommand.every((part, index) => parsed[index] === part);
719
- const matchesBaseName = parsed[0] === baseName;
720
- if (matchesBase)
721
- return parsed;
722
- if (matchesBaseName)
723
- return [baseCommand[0], ...parsed.slice(1)];
724
- return [...baseCommand, ...parsed];
725
- }
726
- async function proxyProvidedCapability(req, reply) {
727
- const idErr = validateId(req.params.id);
728
- if (idErr)
729
- return reply.status(400).send({ detail: idErr });
730
- const rawInst = instanceManager.getInstance(req.params.id);
731
- if (!rawInst)
732
- return reply.status(404).send({ detail: "Instance not found" });
733
- if (!instanceManager.getApp(req.params.id))
734
- return reply.status(404).send({ detail: "App not found" });
735
- const capabilities = instanceManager.getProvidedCapabilitiesForApp(req.params.id);
736
- const capability = capabilities.find((entry) => entry.capability === req.params.capability);
737
- if (!capability) {
738
- return reply.status(404).send({ detail: `Capability '${req.params.capability}' not found` });
739
- }
740
- if (capability.visibility === "internal") {
741
- return reply.status(403).send({ detail: `Capability '${req.params.capability}' is not externally accessible` });
742
- }
743
- if (capability.protocol !== "http" && capability.protocol !== "https") {
744
- return reply.status(400).send({ detail: `Capability '${req.params.capability}' does not use HTTP(S)` });
745
- }
746
- // Resolve the runtime port (handles port reallocation) instead of using
747
- // the declared AppSpec port which may be stale.
748
- const runtimePort = instanceManager.resolveRuntimeCapabilityPort(req.params.id, req.params.capability)
749
- ?? capability.port;
750
- if (typeof runtimePort !== "number" || runtimePort < 1) {
751
- return reply.status(500).send({ detail: `Capability '${req.params.capability}' has no resolved port` });
752
- }
753
- const upstreamHost = await instanceManager.getHostForAppPort(req.params.id, runtimePort);
754
- const upstreamOrigin = `${capability.protocol}://${instanceManager.urlHost(upstreamHost)}:${runtimePort}`;
755
- const wildcardSuffix = typeof req.params["*"] === "string" ? req.params["*"] : "";
756
- const proxyBasePath = capabilityProxyPath(req.params.id, req.params.capability);
757
- const querySuffix = req.raw.url?.includes("?") ? req.raw.url.slice(req.raw.url.indexOf("?")) : "";
758
- const requestPath = req.raw.url?.split("?")[0] ?? "";
759
- const canonicalProxyBase = canonicalCapabilityProxyBase(proxyBasePath, capability.path);
760
- if (!wildcardSuffix && canonicalProxyBase !== proxyBasePath && !requestPath.endsWith("/")) {
761
- reply.code(308).header("location", `${canonicalProxyBase}${querySuffix}`);
762
- return reply.send();
763
- }
764
- const upstreamPath = joinUpstreamPath(capability.path, wildcardSuffix);
765
- const targetUrl = `${upstreamOrigin}${upstreamPath}${querySuffix}`;
766
- const headers = new Headers();
767
- for (const [key, value] of Object.entries(req.headers)) {
768
- if (value == null)
769
- continue;
770
- const normalizedKey = key.toLowerCase();
771
- if (HOP_BY_HOP.has(normalizedKey) || normalizedKey === "host" || normalizedKey === "content-length" || normalizedKey === "accept-encoding") {
772
- continue;
773
- }
774
- // Strip panel session credentials to avoid leaking them upstream
775
- // (consistent with the WebSocket capability proxy in server.ts)
776
- if (normalizedKey === "authorization")
777
- continue;
778
- if (normalizedKey === "cookie") {
779
- const stripped = stripPanelSessionCookie(value);
780
- if (stripped)
781
- headers.set(key, stripped);
782
- continue;
783
- }
784
- if (Array.isArray(value)) {
785
- for (const item of value)
786
- headers.append(key, item);
787
- }
788
- else {
789
- headers.set(key, String(value));
790
- }
791
- }
792
- headers.set("accept-encoding", "identity");
793
- if (headers.has("origin"))
794
- headers.set("origin", upstreamOrigin);
795
- // `x-forwarded-prefix` is not a standard reverse-proxy header and some
796
- // upstream frameworks (notably SvelteKit apps like Hollama) treat it as a
797
- // deployment base path, which breaks `/_app/*` asset resolution under this
798
- // generic proxy. The HTML/base rewrite below already handles path prefixing.
799
- if (req.headers.host)
800
- headers.set("x-forwarded-host", String(req.headers.host));
801
- headers.set("x-forwarded-proto", req.protocol);
802
- const clientIp = typeof req.ip === "string" && req.ip
803
- ? req.ip
804
- : typeof req.raw?.socket?.remoteAddress === "string"
805
- ? req.raw.socket.remoteAddress
806
- : "";
807
- if (clientIp) {
808
- const forwardedFor = headers.get("x-forwarded-for");
809
- headers.set("x-forwarded-for", forwardedFor ? `${forwardedFor}, ${clientIp}` : clientIp);
810
- headers.set("x-real-ip", clientIp);
811
- }
812
- // Intercept service worker scripts BEFORE talking to upstream. SPAs like
813
- // OpenWebUI register a SvelteKit service worker that aggressively caches
814
- // HTML/JS at the proxy origin; once installed, the SW serves stale bodies
815
- // and the page never receives our latest bootstrap (WebSocket / fetch
816
- // monkey-patch). We replace the SW body with a self-unregistration stub so
817
- // the next browser update cycle removes the offending worker and restores
818
- // network-backed loading.
819
- if (/(?:^|\/)(?:service-worker|sw)\.js$/i.test(requestPath)) {
820
- reply
821
- .code(200)
822
- .header("content-type", "application/javascript; charset=utf-8")
823
- .header("cache-control", "no-store, no-cache, must-revalidate, max-age=0")
824
- .header("pragma", "no-cache")
825
- .header("service-worker-allowed", "/");
826
- return reply.send("// Capability proxy: service worker intentionally disabled.\n" +
827
- "self.addEventListener('install',function(e){self.skipWaiting()});\n" +
828
- "self.addEventListener('activate',function(e){\n" +
829
- " e.waitUntil((async function(){\n" +
830
- " try{var cs=await caches.keys();for(var i=0;i<cs.length;i++){try{await caches.delete(cs[i])}catch(_e){}}}catch(_e){}\n" +
831
- " try{var clients=await self.clients.matchAll({includeUncontrolled:true});clients.forEach(function(c){try{c.navigate(c.url)}catch(_e){}})}catch(_e){}\n" +
832
- " try{await self.registration.unregister()}catch(_e){}\n" +
833
- " })());\n" +
834
- "});\n");
835
- }
836
- // Single AbortController so we can cancel the upstream when the client
837
- // disconnects. AbortSignal.timeout() only limits connection establishment;
838
- // long-poll/SSE bodies (e.g. socket.io) would otherwise pin the fetch
839
- // promise indefinitely and starve the event loop.
840
- const upstreamAbort = new AbortController();
841
- const connectTimer = setTimeout(() => upstreamAbort.abort(new Error("upstream connect timeout")), 30_000);
842
- const onClientClose = () => {
843
- if (!reply.raw.writableEnded)
844
- upstreamAbort.abort(new Error("client disconnected"));
845
- };
846
- reply.raw.once("close", onClientClose);
847
- try {
848
- console.error("[cap-proxy] PRE buildBody method=", req.method, "bodyType=", typeof req.body, req.body?.constructor?.name, "signalAborted=", upstreamAbort.signal.aborted);
849
- const requestBody = await buildProxyRequestBody(req);
850
- console.error("[cap-proxy] POST buildBody size=", requestBody instanceof ArrayBuffer ? requestBody.byteLength : typeof requestBody === "string" ? requestBody.length : "undef", "signalAborted=", upstreamAbort.signal.aborted, "reason=", upstreamAbort.signal.reason?.message);
851
- const upstream = await fetch(targetUrl, {
852
- method: req.method,
853
- headers,
854
- body: requestBody,
855
- redirect: "manual",
856
- signal: upstreamAbort.signal,
857
- }).finally(() => clearTimeout(connectTimer));
858
- console.error("[cap-proxy] POST fetch status=", upstream.status);
859
- const upstreamContentType = upstream.headers.get("content-type");
860
- const willRewriteBody = shouldRewriteProxyResponse(upstreamContentType);
861
- const willInjectHtml = (upstreamContentType ?? "").toLowerCase().includes("text/html");
862
- reply.code(upstream.status);
863
- upstream.headers.forEach((value, key) => {
864
- const normalizedKey = key.toLowerCase();
865
- if (HOP_BY_HOP.has(normalizedKey) || normalizedKey === "content-length" || normalizedKey === "content-encoding") {
866
- return;
867
- }
868
- // When we rewrite the response body (HTML/CSS/JS), the upstream ETag /
869
- // Cache-Control values describe the *original* upstream bytes — but the
870
- // body the browser receives is post-rewrite (proxy-prefixed paths, JS
871
- // hard-coded redirect targets, etc.). Honoring the upstream cache hints
872
- // lets the browser pin a stale rewrite indefinitely: e.g. an early
873
- // visit that pre-dated the JS rewrite gets cached and survives across
874
- // app restarts, breaking the auth redirect logic until a hard refresh.
875
- // Strip cache validators and force revalidation on every load.
876
- if (willRewriteBody && (normalizedKey === "cache-control" ||
877
- normalizedKey === "etag" ||
878
- normalizedKey === "last-modified" ||
879
- normalizedKey === "expires" ||
880
- normalizedKey === "pragma")) {
881
- return;
882
- }
883
- if (willInjectHtml && (normalizedKey === "content-security-policy" ||
884
- normalizedKey === "content-security-policy-report-only" ||
885
- normalizedKey === "x-frame-options")) {
886
- return;
887
- }
888
- if (normalizedKey === "location") {
889
- if (value.startsWith("/")) {
890
- reply.header(key, rewriteCapabilityLocation(proxyBasePath, canonicalProxyBase, value));
891
- return;
892
- }
893
- try {
894
- const parsed = new URL(value);
895
- const upstreamBase = new URL(upstreamOrigin);
896
- if (parsed.origin === upstreamBase.origin) {
897
- reply.header(key, rewriteCapabilityLocation(proxyBasePath, canonicalProxyBase, parsed.pathname, parsed.search, parsed.hash));
898
- return;
899
- }
900
- }
901
- catch {
902
- // fall through to raw location header
903
- }
904
- }
905
- reply.header(key, value);
906
- });
907
- if (req.method === "HEAD") {
908
- reply.raw.off("close", onClientClose);
909
- return reply.send();
910
- }
911
- if (willRewriteBody) {
912
- // Pair with the cache-validator strip above.
913
- reply.header("cache-control", "no-cache, no-store, must-revalidate");
914
- reply.header("pragma", "no-cache");
915
- reply.header("expires", "0");
916
- let extraHeadHtml = "";
917
- if (req.params.capability === "browserless-debugger") {
918
- extraHeadHtml = browserlessDebuggerBootstrap(req.params.id);
919
- }
920
- if (willInjectHtml && req.params.capability === "web-jishukb") {
921
- try {
922
- const preloadedSessions = await loadJishuKbPreloadedSessions(upstreamOrigin, upstreamAbort.signal);
923
- extraHeadHtml += jishuKbConversationBootstrap(preloadedSessions);
924
- }
925
- catch (error) {
926
- console.warn("[cap-proxy] jishukb conversation preload skipped:", error);
927
- }
928
- }
929
- // Inject a generic fetch/XHR monkey-patch for all capability-proxied
930
- // HTML pages. SPA frameworks like SvelteKit compile absolute API paths
931
- // (e.g. `/api/v1/...`, `/ollama/...`) into JS bundles at build time.
932
- // When the page is served under the proxy path those requests bypass
933
- // the proxy and hit the panel's own `/api/` routes instead. The patch
934
- // intercepts fetch() and XMLHttpRequest.open() and rewrites same-origin
935
- // absolute paths that do NOT already start with the proxy prefix.
936
- extraHeadHtml += capabilityProxyBootstrap(proxyBasePath);
937
- // First-visit cleanup: if the browser still has a stale ServiceWorker
938
- // registered from an earlier panel build (which would intercept this
939
- // navigation and serve cached HTML *without* the bootstrap patches),
940
- // emit Clear-Site-Data so the browser drops the SW + its cache and
941
- // reloads through the proxy. We mark the success with a long-lived
942
- // cookie scoped to the proxy path to avoid a reload loop.
943
- // Gate to HTML only — JS/CSS sub-resources also flow through this branch
944
- // now that we rewrite JS bundles, and emitting Clear-Site-Data on a JS
945
- // response would clear storage mid-page-load.
946
- if (willInjectHtml) {
947
- const cookieHeader = (req.headers.cookie || "").toString();
948
- const swCleaned = /(?:^|;\s*)cap_proxy_sw_clean=1(?:;|$)/.test(cookieHeader);
949
- if (!swCleaned) {
950
- reply.header("Clear-Site-Data", '"cache", "storage"');
951
- reply.header("Set-Cookie", `cap_proxy_sw_clean=1; Path=${proxyBasePath}; Max-Age=2592000; SameSite=Lax`);
952
- }
953
- }
954
- const rawBody = await upstream.text();
955
- reply.raw.off("close", onClientClose);
956
- const rewritten = rewriteProxyTextBody(rawBody, upstreamContentType, proxyBasePath, extraHeadHtml);
957
- return reply.send(rewritten);
958
- }
959
- if (!upstream.body) {
960
- reply.raw.off("close", onClientClose);
961
- return reply.send();
962
- }
963
- const readable = Readable.fromWeb(upstream.body);
964
- readable.once("close", () => reply.raw.off("close", onClientClose));
965
- return reply.send(readable);
966
- }
967
- catch (error) {
968
- console.error("[cap-proxy] CATCH", error?.constructor?.name, error?.name, error?.message, "signalAborted=", upstreamAbort.signal.aborted, "reason=", upstreamAbort.signal.reason?.message, "stack=", error?.stack?.split("\n").slice(0, 4).join(" | "));
969
- reply.raw.off("close", onClientClose);
970
- return reply.status(502).send({ detail: error?.message || `Failed to proxy capability '${req.params.capability}'` });
971
- }
972
- }
973
- export async function ensureControlUiAllowedOrigin(instanceId, origin) {
974
- const normalizedOrigin = origin.trim();
975
- if (!normalizedOrigin)
976
- return false;
977
- const config = instanceManager.getStoredConfig(instanceId);
978
- if (!config)
979
- return false;
980
- const gateway = config.gateway ??= {};
981
- const controlUi = gateway.controlUi ??= {};
982
- const existing = Array.isArray(controlUi.allowedOrigins)
983
- ? controlUi.allowedOrigins.map((value) => String(value))
984
- : [];
985
- const normalized = new Set(existing.map((value) => value.trim().toLowerCase()).filter(Boolean));
986
- if (normalized.has("*") || normalized.has(normalizedOrigin.toLowerCase()))
987
- return false;
988
- controlUi.allowedOrigins = [...existing.filter((value) => value.trim()), normalizedOrigin];
989
- await instanceManager.saveConfig(instanceId, config);
990
- return true;
991
- }
992
- // Resolve service manager once at route registration, re-resolve on config change
993
- let _svc = null;
994
- let _svcType = "";
995
- export async function getSvc() {
996
- const currentType = getServiceManagerType();
997
- if (_svc && _svcType === currentType)
998
- return _svc;
999
- _svc = currentType === "nomad"
1000
- ? await import("../services/nomad-manager.js")
1001
- : await import("../services/process-manager.js");
1002
- _svcType = currentType;
1003
- return _svc;
1004
- }
1005
- function getInstanceBackedInstalledApp(instanceId) {
1006
- return instanceManager.getApp(instanceId);
1007
- }
1008
- function shouldUseAppManager(identity) {
1009
- if (!identity)
1010
- return false;
1011
- if (identity.driver === "app-job")
1012
- return true;
1013
- return identity.driver === "local-model" && !!getInstanceBackedInstalledApp(identity.id);
1014
- }
1015
- function shouldUseAppManagerForId(instanceId, identity) {
1016
- return shouldUseAppManager(identity) || (!identity && !!getInstanceBackedInstalledApp(instanceId));
1017
- }
1018
- function hasRuntimeIdentity(instanceId) {
1019
- return resolveRuntimeIdentity(instanceId) != null
1020
- || !!instanceManager.getInstance(instanceId)
1021
- || !!getInstanceBackedInstalledApp(instanceId);
1022
- }
1023
- // TTL 15s: outlives the frontend 10s polling interval so most requests hit cache
1024
- const statusCache = new TtlMap(15_000);
1025
- const controlUiRestartInFlight = new Map();
1026
- function getCachedStatus(svc, instanceId) {
1027
- const cached = statusCache.get(instanceId);
1028
- if (cached !== undefined)
1029
- return Promise.resolve(cached);
1030
- const identity = resolveRuntimeIdentity(instanceId);
1031
- const statusPromise = shouldUseAppManagerForId(instanceId, identity)
1032
- ? instanceManager.getAppStatus(instanceId).then((data) => ({
1033
- status: data.status,
1034
- pid: data.pid,
1035
- uptime: data.uptime,
1036
- memory_mb: data.memory_mb,
1037
- cpu_percent: data.cpu_percent,
1038
- }))
1039
- : Promise.resolve(svc.getStatus(instanceId));
1040
- return statusPromise.then((data) => {
1041
- statusCache.set(instanceId, data);
1042
- return data;
1043
- });
1044
- }
1045
- export async function restartRunningInstanceForControlUiOrigin(instanceId, origin) {
1046
- const inFlight = controlUiRestartInFlight.get(instanceId);
1047
- if (inFlight)
1048
- return inFlight;
1049
- const task = (async () => {
1050
- const svc = await getSvc();
1051
- const status = await svc.getStatus(instanceId);
1052
- if (status.status !== "running")
1053
- return;
1054
- const result = await svc.restartInstance(instanceId);
1055
- statusCache.delete(instanceId);
1056
- if (!result.ok) {
1057
- console.warn(`[gateway-launch] failed to auto-restart ${instanceId} after allowing origin ${origin}:`, result.error || "unknown error");
1058
- return;
1059
- }
1060
- console.log(`[gateway-launch] auto-restarted ${instanceId} after allowing origin ${origin}`);
1061
- })().finally(() => {
1062
- controlUiRestartInFlight.delete(instanceId);
1063
- });
1064
- controlUiRestartInFlight.set(instanceId, task);
1065
- return task;
1
+ import { assertNotLocked } from "../services/backup/backup-manager.js";
2
+ import * as appService from "../services/app-common/service.js";
3
+ import * as appLifecycle from "../services/app-common/lifecycle-service.js";
4
+ import { cleanupInstance as cleanupProxyInstance, getLastProxyError, } from "../services/llm-proxy/instance-proxy.js";
5
+ import { createInstance, isInstanceAdminError, validateId, } from "../services/instances/admin.js";
6
+ import { cloneInstance, isInstanceCloneError } from "../services/instances/clone.js";
7
+ import { getConnectionStatus, getConnectionSummary, isConnectionAdminError, replaceConnections, } from "../services/connections/admin.js";
8
+ import { getAppConfigMeta, isAppConfigAdminError, readAppConfig, writeAppConfig, } from "../services/instances/config-admin.js";
9
+ import { augmentInstanceMetadata, resolvePrimaryIntegrationKind, } from "../services/runtime/instance.js";
10
+ import { getIntegration } from "../services/integrations/index.js";
11
+ import { invalidateExecutionOwner } from "../services/app-common/execution-owner.js";
12
+ import { markRuntimeRepairRestartApplied } from "../services/repair/runtime-repair.js";
13
+ import { proxyProvidedCapability } from "../services/capability-proxy/http.js";
14
+ import { sendTerminalCapabilityInput, startTerminalCapabilitySession, stopTerminalCapabilitySession, streamTerminalCapabilitySession, } from "../services/capability-proxy/terminal.js";
15
+ import { inferRequestOrigin } from "../services/http/request-utils.js";
16
+ import { getCachedStatus } from "../services/instances/status.js";
17
+ import { approvePairingRequest, isInstancePairingError, listPairingRequests, } from "../services/instances/pairing.js";
18
+ // Generic instance API only. Product-specific HTTP behavior belongs in
19
+ // integrations/<kind> or app-modules/<app>, reached through explicit hooks.
20
+ function getLifecycleActionSource(req) {
21
+ const raw = req.headers["x-jishushell-action-source"];
22
+ const value = Array.isArray(raw) ? raw[0] : raw;
23
+ const source = typeof value === "string" ? value.trim() : "";
24
+ return /^[a-z0-9._:-]{1,80}$/i.test(source) ? source : "unknown";
1066
25
  }
1067
26
  export async function instanceRoutes(app) {
1068
27
  // List
1069
28
  app.get("/api/instances", async () => {
1070
- const svc = await getSvc();
1071
- const instances = instanceManager.listInstances();
1072
- const statuses = await Promise.all(instances.map(inst => getCachedStatus(svc, inst.id).catch(() => ({ status: "unknown" }))));
29
+ const instances = appService.listInstances();
30
+ const statuses = await Promise.all(instances.map(inst => getCachedStatus(inst.id, "api-list").catch(() => ({ status: "unknown", pid: null, uptime: null, memory_mb: null, cpu_percent: null }))));
1073
31
  return Promise.all(instances.map(async (inst, i) => ({
1074
32
  ...(await augmentInstanceMetadata(inst.id, inst)),
1075
33
  service: statuses[i],
@@ -1081,7 +39,7 @@ export async function instanceRoutes(app) {
1081
39
  return await createInstance(req.body);
1082
40
  }
1083
41
  catch (e) {
1084
- // Structured rejection from createHermesInstance — return 409 with code
42
+ // Structured rejection from integration create policy — return 409 with code
1085
43
  if (e && e.name === "InstanceCreationRejected") {
1086
44
  return reply.status(409).send({
1087
45
  detail: e.hint,
@@ -1097,16 +55,50 @@ export async function instanceRoutes(app) {
1097
55
  return reply.status(409).send({ detail: e.message });
1098
56
  }
1099
57
  });
58
+ app.post("/api/instances/:id/clone", async (req, reply) => {
59
+ const sourceIdError = validateId(req.params.id);
60
+ if (sourceIdError)
61
+ return reply.status(400).send({ detail: sourceIdError });
62
+ const targetId = typeof req.body?.id === "string" ? req.body.id : "";
63
+ const targetIdError = validateId(targetId);
64
+ if (targetIdError)
65
+ return reply.status(400).send({ detail: targetIdError });
66
+ const name = typeof req.body?.name === "string" ? req.body.name.trim() : "";
67
+ if (!name || name.length > 256) {
68
+ return reply.status(400).send({ detail: "Name must be 1-256 characters" });
69
+ }
70
+ if (typeof req.body?.description === "string" && req.body.description.length > 2048) {
71
+ return reply.status(400).send({ detail: "Description must be at most 2048 characters" });
72
+ }
73
+ try {
74
+ const result = await cloneInstance({
75
+ sourceInstanceId: req.params.id,
76
+ targetId,
77
+ name,
78
+ description: req.body?.description,
79
+ cloneOptions: req.body?.clone_options,
80
+ });
81
+ return reply.status(201).send(result);
82
+ }
83
+ catch (error) {
84
+ if (isInstanceCloneError(error)) {
85
+ return reply.status(error.statusCode).send({
86
+ detail: error.message,
87
+ ...(error.code ? { code: error.code } : {}),
88
+ });
89
+ }
90
+ throw error;
91
+ }
92
+ });
1100
93
  // Get
1101
94
  app.get("/api/instances/:id", async (req, reply) => {
1102
95
  const idErr = validateId(req.params.id);
1103
96
  if (idErr)
1104
97
  return reply.status(400).send({ detail: idErr });
1105
- const svc = await getSvc();
1106
- const inst = instanceManager.getInstance(req.params.id);
98
+ const inst = appService.getInstance(req.params.id);
1107
99
  if (!inst)
1108
100
  return reply.status(404).send({ detail: "Instance not found" });
1109
- const status = await getCachedStatus(svc, req.params.id);
101
+ const status = await getCachedStatus(req.params.id, "api-detail");
1110
102
  return {
1111
103
  ...(await augmentInstanceMetadata(req.params.id, inst)),
1112
104
  service: status,
@@ -1130,11 +122,11 @@ export async function instanceRoutes(app) {
1130
122
  catch (e) {
1131
123
  return reply.status(e.statusCode || 409).send({ detail: e.message });
1132
124
  }
1133
- const inst = instanceManager.updateInstance(req.params.id, req.body.name, req.body.description);
125
+ const inst = appService.updateInstance(req.params.id, req.body.name, req.body.description);
1134
126
  if (!inst)
1135
127
  return reply.status(404).send({ detail: "Instance not found" });
1136
- invalidateRuntimeIdentity(req.params.id);
1137
- return inst;
128
+ invalidateExecutionOwner(req.params.id);
129
+ return augmentInstanceMetadata(req.params.id, inst);
1138
130
  });
1139
131
  // Delete
1140
132
  app.delete("/api/instances/:id", async (req, reply) => {
@@ -1147,61 +139,35 @@ export async function instanceRoutes(app) {
1147
139
  catch (e) {
1148
140
  return reply.status(e.statusCode || 409).send({ detail: e.message });
1149
141
  }
1150
- if (getInstanceBackedInstalledApp(req.params.id)) {
1151
- const sudoPassword = typeof req.body?.sudoPassword === "string" && req.body.sudoPassword.trim()
1152
- ? req.body.sudoPassword
1153
- : undefined;
1154
- const result = instanceManager.uninstallAppTask(req.params.id, sudoPassword ? { sudoPassword } : undefined);
1155
- if (!result.ok) {
1156
- const code = result.code;
1157
- const status = code === "TASK_BUSY" ? 409 : code === "APP_NOT_FOUND" ? 404 : 400;
1158
- return reply.status(status).send({ detail: result.error, code });
1159
- }
1160
- statusCache.delete(req.params.id);
1161
- invalidateRuntimeIdentity(req.params.id);
1162
- cleanupProxyInstance(req.params.id);
142
+ const purgeBackups = req.query.purge_backups === "true";
143
+ const sudoPassword = typeof req.body?.sudoPassword === "string" && req.body.sudoPassword.trim()
144
+ ? req.body.sudoPassword
145
+ : undefined;
146
+ const result = await appLifecycle.deleteManagedInstance(req.params.id, {
147
+ purgeBackups,
148
+ ...(sudoPassword ? { exec: { sudoPassword } } : {}),
149
+ });
150
+ if (!result.ok) {
151
+ const status = result.code === "TASK_BUSY"
152
+ ? 409
153
+ : result.code === "APP_NOT_FOUND" || result.code === "INSTANCE_NOT_FOUND"
154
+ ? 404
155
+ : 400;
156
+ return reply.status(status).send({
157
+ detail: result.error,
158
+ ...(result.code ? { code: result.code } : {}),
159
+ });
160
+ }
161
+ invalidateExecutionOwner(req.params.id);
162
+ cleanupProxyInstance(req.params.id);
163
+ if (result.taskId) {
1163
164
  return reply.status(202).send({
1164
165
  ok: true,
1165
166
  taskId: result.taskId,
1166
- ...result.reused ? { reused: true } : {},
167
+ ...(result.reused ? { reused: true } : {}),
1167
168
  });
1168
169
  }
1169
- const svc = await getSvc();
1170
- let stopFailed = false;
1171
- try {
1172
- await svc.stopInstance(req.params.id, true);
1173
- }
1174
- catch {
1175
- try {
1176
- await svc.stopInstance(req.params.id);
1177
- }
1178
- catch {
1179
- stopFailed = true;
1180
- }
1181
- }
1182
- // Also stop any legacy process-manager process that might be lingering
1183
- try {
1184
- const { getLegacyStatus, stopInstance: stopLegacy } = await import("../services/process-manager.js");
1185
- if ((await getLegacyStatus(req.params.id)).status === "running") {
1186
- await stopLegacy(req.params.id);
1187
- stopFailed = false;
1188
- }
1189
- }
1190
- catch { /* ignore */ }
1191
- statusCache.delete(req.params.id);
1192
- invalidateRuntimeIdentity(req.params.id);
1193
- cleanupProxyInstance(req.params.id);
1194
- const purgeBackups = req.query.purge_backups === "true";
1195
- const result = await instanceManager.deleteInstance(req.params.id, purgeBackups);
1196
- if (!result.ok && result.warnings?.some(w => w.includes("not found"))) {
1197
- return reply.status(404).send({ detail: "Instance not found" });
1198
- }
1199
- const warnings = result.warnings ? [...result.warnings] : [];
1200
- if (stopFailed) {
1201
- console.warn(`[instances] Delete ${req.params.id}: service stop failed, orphaned processes may remain`);
1202
- warnings.push("Service stop did not complete; verify no orphaned processes remain.");
1203
- }
1204
- return { ok: result.ok, warnings: warnings.length ? warnings : undefined };
170
+ return { ok: true, warnings: result.warnings?.length ? result.warnings : undefined };
1205
171
  });
1206
172
  // Config
1207
173
  app.get("/api/instances/:id/config-meta", async (req, reply) => {
@@ -1245,15 +211,20 @@ export async function instanceRoutes(app) {
1245
211
  const idErr = validateId(req.params.id);
1246
212
  if (idErr)
1247
213
  return reply.status(400).send({ detail: idErr });
1248
- const svc = await getSvc();
1249
- const identity = resolveRuntimeIdentity(req.params.id);
1250
- if (!identity && !hasRuntimeIdentity(req.params.id)) {
1251
- return reply.status(404).send({ detail: "Instance not found" });
214
+ let status;
215
+ try {
216
+ status = await appLifecycle.getManagedStatus(req.params.id);
1252
217
  }
1253
- if (shouldUseAppManagerForId(req.params.id, identity)) {
1254
- return instanceManager.getAppStatus(req.params.id);
218
+ catch (error) {
219
+ if (appService.isCanonicalRuntimePortRequiredError(error)) {
220
+ return reply.status(error.statusCode || 409).send({ detail: error.message, code: error.code });
221
+ }
222
+ throw error;
1255
223
  }
1256
- return svc.getStatus(req.params.id);
224
+ if (!status) {
225
+ return reply.status(404).send({ detail: "Instance not found" });
226
+ }
227
+ return status;
1257
228
  });
1258
229
  app.post("/api/instances/:id/service/start", async (req, reply) => {
1259
230
  const idErr = validateId(req.params.id);
@@ -1265,21 +236,18 @@ export async function instanceRoutes(app) {
1265
236
  catch (e) {
1266
237
  return reply.status(e.statusCode || 409).send({ detail: e.message });
1267
238
  }
1268
- const svc = await getSvc();
1269
- const identity = resolveRuntimeIdentity(req.params.id);
1270
- if (!identity && !hasRuntimeIdentity(req.params.id)) {
1271
- return reply.status(404).send({ detail: "Instance not found" });
1272
- }
1273
- const result = shouldUseAppManagerForId(req.params.id, identity)
1274
- ? await instanceManager.startApp(req.params.id)
1275
- : await svc.startInstance(req.params.id);
1276
- statusCache.delete(req.params.id);
1277
- invalidateRuntimeIdentity(req.params.id);
239
+ const actionSource = getLifecycleActionSource(req);
240
+ console.log(`[lifecycle] start requested for ${req.params.id} source=${actionSource}`);
241
+ const controlUiOrigin = inferRequestOrigin(req);
242
+ const result = controlUiOrigin
243
+ ? await appLifecycle.startInstance(req.params.id, { controlUiOrigin })
244
+ : await appLifecycle.startInstance(req.params.id);
245
+ invalidateExecutionOwner(req.params.id);
1278
246
  if (!result.ok) {
1279
247
  const resultRecord = result;
1280
248
  // Surface the phase tag so the UI can highlight where the start
1281
249
  // pipeline failed (running_check / home_conflict / port_alloc /
1282
- // pre_start_hook / submit). Legacy clients that only read `detail`
250
+ // port allocation / submit). Legacy clients that only read `detail`
1283
251
  // keep working.
1284
252
  const payload = { detail: result.error };
1285
253
  if (resultRecord.phase)
@@ -1290,6 +258,9 @@ export async function instanceRoutes(app) {
1290
258
  payload.taskId = resultRecord.taskId;
1291
259
  if (resultRecord.code)
1292
260
  payload.code = resultRecord.code;
261
+ if (resultRecord.code === "INSTANCE_NOT_FOUND") {
262
+ return reply.status(404).send(payload);
263
+ }
1293
264
  // Honor the structured ConnectionError statusCode (412 / 409 / 400)
1294
265
  // when present so the UI can distinguish missing-required from
1295
266
  // ambiguous-prefix from invalid-binding without parsing the message.
@@ -1298,7 +269,7 @@ export async function instanceRoutes(app) {
1298
269
  : 400;
1299
270
  return reply.status(statusCode).send(payload);
1300
271
  }
1301
- await acknowledgeRuntimeRestartAdvisory(req.params.id);
272
+ markRuntimeRepairRestartApplied(req.params.id);
1302
273
  return result;
1303
274
  });
1304
275
  app.post("/api/instances/:id/service/stop", async (req, reply) => {
@@ -1311,18 +282,14 @@ export async function instanceRoutes(app) {
1311
282
  catch (e) {
1312
283
  return reply.status(e.statusCode || 409).send({ detail: e.message });
1313
284
  }
1314
- const svc = await getSvc();
1315
- const identity = resolveRuntimeIdentity(req.params.id);
1316
- if (!identity && !hasRuntimeIdentity(req.params.id)) {
1317
- return reply.status(404).send({ detail: "Instance not found" });
285
+ const actionSource = getLifecycleActionSource(req);
286
+ console.log(`[lifecycle] stop requested for ${req.params.id} source=${actionSource}`);
287
+ const result = await appLifecycle.stopInstance(req.params.id);
288
+ invalidateExecutionOwner(req.params.id);
289
+ if (!result.ok) {
290
+ const statusCode = result.code === "INSTANCE_NOT_FOUND" ? 404 : 400;
291
+ return reply.status(statusCode).send({ detail: result.error, ...(result.code ? { code: result.code } : {}) });
1318
292
  }
1319
- const result = shouldUseAppManagerForId(req.params.id, identity)
1320
- ? await instanceManager.stopApp(req.params.id)
1321
- : await svc.stopInstance(req.params.id);
1322
- statusCache.delete(req.params.id);
1323
- invalidateRuntimeIdentity(req.params.id);
1324
- if (!result.ok)
1325
- return reply.status(400).send({ detail: result.error });
1326
293
  return result;
1327
294
  });
1328
295
  app.post("/api/instances/:id/service/restart", async (req, reply) => {
@@ -1335,19 +302,21 @@ export async function instanceRoutes(app) {
1335
302
  catch (e) {
1336
303
  return reply.status(e.statusCode || 409).send({ detail: e.message });
1337
304
  }
1338
- const svc = await getSvc();
1339
- const identity = resolveRuntimeIdentity(req.params.id);
1340
- if (!identity && !hasRuntimeIdentity(req.params.id)) {
1341
- return reply.status(404).send({ detail: "Instance not found" });
305
+ const actionSource = getLifecycleActionSource(req);
306
+ console.log(`[lifecycle] restart requested for ${req.params.id} source=${actionSource}`);
307
+ const controlUiOrigin = inferRequestOrigin(req);
308
+ const result = controlUiOrigin
309
+ ? await appLifecycle.restartInstance(req.params.id, { controlUiOrigin })
310
+ : await appLifecycle.restartInstance(req.params.id);
311
+ invalidateExecutionOwner(req.params.id);
312
+ if (!result.ok) {
313
+ const statusCode = result.code === "INSTANCE_NOT_FOUND" ? 404 : 400;
314
+ return reply.status(statusCode).send({
315
+ detail: result.error || "Unknown error",
316
+ ...(result.code ? { code: result.code } : {}),
317
+ });
1342
318
  }
1343
- const result = shouldUseAppManagerForId(req.params.id, identity)
1344
- ? await instanceManager.restartApp(req.params.id)
1345
- : await svc.restartInstance(req.params.id);
1346
- statusCache.delete(req.params.id);
1347
- invalidateRuntimeIdentity(req.params.id);
1348
- if (!result.ok)
1349
- return reply.status(400).send({ detail: result.error || "Unknown error" });
1350
- await acknowledgeRuntimeRestartAdvisory(req.params.id);
319
+ markRuntimeRepairRestartApplied(req.params.id);
1351
320
  return result;
1352
321
  });
1353
322
  // ── Pairing ──────────────────────────────────────────────────────────────
@@ -1359,33 +328,19 @@ export async function instanceRoutes(app) {
1359
328
  const idErr = validateId(req.params.id);
1360
329
  if (idErr)
1361
330
  return reply.status(400).send({ detail: idErr });
1362
- const inst = instanceManager.getInstance(req.params.id);
1363
- if (!inst) {
1364
- return reply.status(404).send({ detail: "Instance not found" });
331
+ try {
332
+ return await listPairingRequests(req.params.id);
1365
333
  }
1366
- const capabilities = await getInstanceCapabilities(req.params.id, inst);
1367
- if (!capabilities.pairing.list) {
1368
- return reply.status(501).send({ detail: "Pairing list is not supported for this runtime" });
334
+ catch (error) {
335
+ if (isInstancePairingError(error))
336
+ return reply.status(error.statusCode).send({ detail: error.message });
337
+ throw error;
1369
338
  }
1370
- const agentType = resolveAgentType(inst);
1371
- const svc = await getSvc();
1372
- // Pure adapter dispatch — no hardcoded kind fallback.
1373
- const cmd = await getAdapter(agentType).buildPairingListCommand(req.params.id);
1374
- const result = await svc.exec(req.params.id, cmd, 15_000);
1375
- return { output: result.stdout + result.stderr, exitCode: result.exitCode };
1376
339
  });
1377
340
  app.post("/api/instances/:id/pairing/approve", async (req, reply) => {
1378
341
  const idErr = validateId(req.params.id);
1379
342
  if (idErr)
1380
343
  return reply.status(400).send({ detail: idErr });
1381
- const inst = instanceManager.getInstance(req.params.id);
1382
- if (!inst) {
1383
- return reply.status(404).send({ detail: "Instance not found" });
1384
- }
1385
- const capabilities = await getInstanceCapabilities(req.params.id, inst);
1386
- if (!capabilities.pairing.approve) {
1387
- return reply.status(501).send({ detail: "Pairing approve is not supported for this runtime" });
1388
- }
1389
344
  const { channel, code, notify } = req.body ?? {};
1390
345
  if (!channel || !PAIRING_CHANNEL_RE.test(channel)) {
1391
346
  return reply.status(400).send({ detail: "Invalid channel: must be lowercase alphanumeric/hyphen/underscore" });
@@ -1393,26 +348,23 @@ export async function instanceRoutes(app) {
1393
348
  if (!code || !PAIRING_CODE_RE.test(code)) {
1394
349
  return reply.status(400).send({ detail: "Invalid pairing code: must be 4-16 uppercase alphanumeric characters" });
1395
350
  }
1396
- const agentType = resolveAgentType(inst);
1397
- const cmd = await getAdapter(agentType).buildPairingApproveCommand(req.params.id, {
1398
- channel,
1399
- code,
1400
- notify,
1401
- });
1402
- const svc = await getSvc();
1403
- const result = await svc.exec(req.params.id, cmd, 15_000);
1404
- if (result.exitCode !== 0) {
1405
- return reply.status(400).send({ detail: (result.stderr || result.stdout || "Approval failed").trim() });
351
+ try {
352
+ return await approvePairingRequest(req.params.id, { channel, code, notify });
353
+ }
354
+ catch (error) {
355
+ if (isInstancePairingError(error))
356
+ return reply.status(error.statusCode).send({ detail: error.message });
357
+ throw error;
1406
358
  }
1407
- return { ok: true, output: (result.stdout + result.stderr).trim() };
1408
359
  });
1409
- // Agent chat (inline chat panel for runtimes that expose an OpenAI-compat
1410
- // HTTP chat completion endpoint and declare chatPanel="inline" in their
1411
- // capability profile currently only Hermes).
360
+ // Inline Chat surface for runtimes that choose the JishuShell-rendered Chat
361
+ // tab instead of an iframe-backed app UI. The runtime declares how Core can
362
+ // reach its chat endpoint via `inlineChatDescriptor`; this route owns only
363
+ // the shared forwarding/SSE wrapper.
1412
364
  //
1413
- // Flow: panel JWT auth read per-instance API_SERVER_KEY from agent-home/.env →
1414
- // read allocated host port from runtime.ports → POST forward to
1415
- // http://127.0.0.1:<port>/v1/chat/completions.
365
+ // Flow: panel JWT auth -> read the declared per-instance secret from
366
+ // integration-home/.env -> read allocated host port from runtime.ports ->
367
+ // POST forward to the declared runtime chat endpoint.
1416
368
  //
1417
369
  // The response is framed as Server-Sent Events with periodic `: ping`
1418
370
  // heartbeats while we wait for the agent to finish. Long-running agent
@@ -1424,53 +376,62 @@ export async function instanceRoutes(app) {
1424
376
  // Errors before headers are sent fall back to HTTP 5xx JSON; errors
1425
377
  // after hijack go out as an `event: error` SSE payload.
1426
378
  //
1427
- // This is a thin server-side forwarder, NOT a new LLM proxy. The actual
1428
- // LLM call still goes through Hermes jsproxy JishuShell /proxy/v1
1429
- // upstream provider.
379
+ // This is a thin server-side forwarder, NOT a new LLM proxy. Managed model
380
+ // traffic still goes through the runtime's configured Core proxy binding.
1430
381
  app.post("/api/instances/:id/agent/chat", async (req, reply) => {
1431
382
  const idErr = validateId(req.params.id);
1432
383
  if (idErr)
1433
384
  return reply.status(400).send({ detail: idErr });
1434
- const rawInst = instanceManager.getInstance(req.params.id);
385
+ const rawInst = appService.getInstance(req.params.id);
1435
386
  if (!rawInst)
1436
387
  return reply.status(404).send({ detail: "Instance not found" });
1437
- // getInstance returns raw instance.json without `capabilities` (that's
1438
- // runtime-synthesized per §32.4). Use augmentInstanceMetadata so we
1439
- // read the adapter's live defaultCapabilities.
388
+ // getInstance returns raw instance.json without `capabilities` (those are
389
+ // synthesized by the integration layer). Use augmentInstanceMetadata so we
390
+ // read the integration's live defaultCapabilities.
1440
391
  const inst = await augmentInstanceMetadata(req.params.id, rawInst);
392
+ const integrationKind = resolvePrimaryIntegrationKind(inst);
1441
393
  // Only runtimes declaring chatPanel="inline" are supported here
1442
- const chatPanel = inst?.capabilities?.gateway?.chatPanel;
394
+ const chatPanel = inst?.capabilities?.ui?.chatPanel;
1443
395
  if (chatPanel !== "inline") {
1444
396
  return reply.status(400).send({
1445
- detail: `Runtime "${inst.agentType}" does not support inline chat (chatPanel=${chatPanel})`,
397
+ detail: `Runtime "${integrationKind ?? "generic"}" does not support inline chat (chatPanel=${chatPanel})`,
398
+ });
399
+ }
400
+ // Integration-owned dispatch: any integration that declares chatPanel
401
+ // "inline" MUST also supply `inlineChatDescriptor` (secret env var plus
402
+ // optional path/header/timeout) so this forwarder can reach its runtime.
403
+ if (!integrationKind) {
404
+ return reply.status(500).send({
405
+ detail: `Instance "${req.params.id}" has no integration identity but declared chatPanel=inline`,
1446
406
  });
1447
407
  }
1448
- // Adapter-owned dispatch: the route no longer hardcodes Hermes's env
1449
- // var name or endpoint path. Any adapter that declares chatPanel
1450
- // "inline" MUST also supply `inlineChatDescriptor` (api key env var +
1451
- // optional path/header/timeout) so this forwarder can reach its agent.
1452
- const agentType = resolveAgentType(inst);
1453
- const adapter = getAdapter(agentType);
1454
- const desc = adapter.inlineChatDescriptor;
408
+ const integration = getIntegration(integrationKind);
409
+ const desc = integration.inlineChatDescriptor;
1455
410
  if (!desc) {
1456
411
  return reply.status(500).send({
1457
- detail: `Runtime "${agentType}" declares chatPanel=inline but no inlineChatDescriptor`,
412
+ detail: `Runtime "${integrationKind}" declares chatPanel=inline but no inlineChatDescriptor`,
1458
413
  });
1459
414
  }
1460
415
  // Resolve host port from the persisted RuntimeSpec.ports[] allocation.
1461
- const ports = Array.isArray(inst?.runtime?.ports) ? inst.runtime.ports : [];
1462
- const gw = ports.find((p) => p?.name === "gateway") || ports[0];
1463
- const hostPort = Number(gw?.hostPort) || 0;
1464
- if (!hostPort) {
1465
- return reply.status(500).send({ detail: "Gateway host port not allocated" });
416
+ let hostPort = 0;
417
+ let gwHost = "127.0.0.1";
418
+ try {
419
+ hostPort = appService.getPrimaryHostPort(req.params.id);
420
+ gwHost = await appService.getPrimaryHostForInstance(req.params.id);
421
+ }
422
+ catch (error) {
423
+ if (appService.isCanonicalRuntimePortRequiredError(error)) {
424
+ return reply.status(error.statusCode || 409).send({ detail: error.message, code: error.code });
425
+ }
426
+ throw error;
1466
427
  }
1467
- // Agent API key lives in the adapter-managed secretEnv file. Adapter
1468
- // declares which env var holds it (Hermes → API_SERVER_KEY).
428
+ // The runtime API key lives in the integration-managed secretEnv file.
429
+ // Integration declares which env var holds it.
1469
430
  const secretEnv = inst?.paths?.secretEnv;
1470
431
  if (!secretEnv) {
1471
432
  return reply.status(500).send({ detail: "Instance has no secretEnv path" });
1472
433
  }
1473
- const envVars = instanceManager.parseEnvFile(secretEnv);
434
+ const envVars = appService.parseEnvFile(secretEnv);
1474
435
  const apiKey = envVars[desc.apiKeyEnvVar] || "";
1475
436
  if (!apiKey) {
1476
437
  return reply.status(500).send({
@@ -1480,8 +441,8 @@ export async function instanceRoutes(app) {
1480
441
  const endpointPath = desc.endpointPath ?? "/v1/chat/completions";
1481
442
  const authHeader = desc.authHeader ?? "Authorization";
1482
443
  const authScheme = desc.authScheme ?? "Bearer ";
1483
- // Upstream budget: the Hermes call itself still gets a hard ceiling so
1484
- // a wedged container can't hold the connection forever. Adapter can
444
+ // Upstream budget: the runtime call still gets a hard ceiling so
445
+ // a wedged container can't hold the connection forever. Integration can
1485
446
  // extend this via inlineChatDescriptor.timeoutMs; default is 30 min
1486
447
  // which comfortably covers multi-step tool loops.
1487
448
  const upstreamTimeoutMs = desc.timeoutMs ?? 30 * 60_000;
@@ -1490,8 +451,7 @@ export async function instanceRoutes(app) {
1490
451
  // on modern Linux (Debian 12, Ubuntu 22.04+) that's frequently `::1`
1491
452
  // rather than `127.0.0.1` — so a hardcoded IPv4 fetch() returns
1492
453
  // ECONNREFUSED and the user sees "Failed to reach agent".
1493
- const gwHost = await instanceManager.getGatewayHost(req.params.id);
1494
- const target = `http://${instanceManager.urlHost(gwHost)}:${hostPort}${endpointPath}`;
454
+ const target = `http://${appService.urlHost(gwHost)}:${hostPort}${endpointPath}`;
1495
455
  // Hijack the response so we own the raw socket — lets us flush SSE
1496
456
  // headers + heartbeats before the upstream fetch resolves.
1497
457
  reply.hijack();
@@ -1554,101 +514,16 @@ export async function instanceRoutes(app) {
1554
514
  }
1555
515
  });
1556
516
  app.post("/api/instances/:id/provides/:capability/terminal/session", async (req, reply) => {
1557
- const idErr = validateId(req.params.id);
1558
- if (idErr)
1559
- return reply.status(400).send({ detail: idErr });
1560
- if (!instanceManager.getInstance(req.params.id) && !getInstanceBackedInstalledApp(req.params.id)) {
1561
- return reply.status(404).send({ detail: "Instance not found" });
1562
- }
1563
- try {
1564
- const provide = resolveTerminalProvide(req.params.id, req.params.capability);
1565
- const terminal = provide.terminal;
1566
- const input = typeof req.body?.input === "string" ? req.body.input : "";
1567
- const command = buildTerminalCommand(terminal.command, input);
1568
- const session = startTerminalSession({
1569
- instanceId: req.params.id,
1570
- capability: req.params.capability,
1571
- terminal,
1572
- command,
1573
- });
1574
- return reply.send(session);
1575
- }
1576
- catch (error) {
1577
- return reply.status(400).send({ detail: error?.message || "Failed to start terminal session" });
1578
- }
517
+ return startTerminalCapabilitySession(req, reply);
1579
518
  });
1580
519
  app.get("/api/instances/:id/provides/:capability/terminal/session/:sessionId/stream", async (req, reply) => {
1581
- const idErr = validateId(req.params.id);
1582
- if (idErr)
1583
- return reply.status(400).send({ detail: idErr });
1584
- if (!assertTerminalSessionOwner(req.params.sessionId, req.params.id, req.params.capability)) {
1585
- return reply.status(404).send({ detail: "Terminal session not found" });
1586
- }
1587
- const session = getTerminalSession(req.params.sessionId);
1588
- if (!session)
1589
- return reply.status(404).send({ detail: "Terminal session not found" });
1590
- const since = Math.max(parseInt(req.query.since || "0", 10) || 0, 0);
1591
- reply.hijack();
1592
- const raw = reply.raw;
1593
- raw.writeHead(200, {
1594
- "Content-Type": "text/event-stream; charset=utf-8",
1595
- "Cache-Control": "no-cache, no-transform",
1596
- "Connection": "keep-alive",
1597
- "X-Accel-Buffering": "no",
1598
- });
1599
- const writeEvent = (event, data) => {
1600
- raw.write(`event: ${event}\ndata: ${JSON.stringify(data)}\n\n`);
1601
- };
1602
- for (const event of getTerminalSessionEvents(req.params.sessionId, since)) {
1603
- writeEvent(event.type, event);
1604
- }
1605
- if (!session.running) {
1606
- writeEvent("done", { sessionId: req.params.sessionId });
1607
- raw.end();
1608
- return;
1609
- }
1610
- const unsubscribe = subscribeTerminalSession(req.params.sessionId, (event) => {
1611
- writeEvent(event.type, event);
1612
- if (event.type === "exit" || event.type === "error") {
1613
- writeEvent("done", { sessionId: req.params.sessionId });
1614
- unsubscribe?.();
1615
- raw.end();
1616
- }
1617
- });
1618
- req.raw.on("close", () => {
1619
- unsubscribe?.();
1620
- });
1621
- raw.write(": ping\n\n");
520
+ return streamTerminalCapabilitySession(req, reply);
1622
521
  });
1623
522
  app.post("/api/instances/:id/provides/:capability/terminal/session/:sessionId/input", async (req, reply) => {
1624
- const idErr = validateId(req.params.id);
1625
- if (idErr)
1626
- return reply.status(400).send({ detail: idErr });
1627
- if (!assertTerminalSessionOwner(req.params.sessionId, req.params.id, req.params.capability)) {
1628
- return reply.status(404).send({ detail: "Terminal session not found" });
1629
- }
1630
- try {
1631
- sendTerminalSessionInput(req.params.sessionId, typeof req.body?.input === "string" ? req.body.input : "");
1632
- return reply.send({ ok: true });
1633
- }
1634
- catch (error) {
1635
- return reply.status(400).send({ detail: error?.message || "Failed to send terminal input" });
1636
- }
523
+ return sendTerminalCapabilityInput(req, reply);
1637
524
  });
1638
525
  app.post("/api/instances/:id/provides/:capability/terminal/session/:sessionId/stop", async (req, reply) => {
1639
- const idErr = validateId(req.params.id);
1640
- if (idErr)
1641
- return reply.status(400).send({ detail: idErr });
1642
- if (!assertTerminalSessionOwner(req.params.sessionId, req.params.id, req.params.capability)) {
1643
- return reply.status(404).send({ detail: "Terminal session not found" });
1644
- }
1645
- try {
1646
- stopTerminalSession(req.params.sessionId);
1647
- return reply.send({ ok: true });
1648
- }
1649
- catch (error) {
1650
- return reply.status(400).send({ detail: error?.message || "Failed to stop terminal session" });
1651
- }
526
+ return stopTerminalCapabilitySession(req, reply);
1652
527
  });
1653
528
  app.all("/api/instances/:id/provides/:capability", async (req, reply) => proxyProvidedCapability(req, reply));
1654
529
  app.all("/api/instances/:id/provides/:capability/*", async (req, reply) => proxyProvidedCapability(req, reply));
@@ -1657,145 +532,19 @@ export async function instanceRoutes(app) {
1657
532
  const idErr = validateId(req.params.id);
1658
533
  if (idErr)
1659
534
  return reply.status(400).send({ detail: idErr });
1660
- const svc = await getSvc();
1661
- const identity = resolveRuntimeIdentity(req.params.id);
1662
- if (!identity && !hasRuntimeIdentity(req.params.id)) {
1663
- return reply.status(404).send({ detail: "Instance not found" });
1664
- }
1665
535
  const logType = req.query.log_type || "stderr";
1666
536
  if (logType !== "stdout" && logType !== "stderr") {
1667
537
  return reply.status(400).send({ detail: "log_type must be stdout or stderr" });
1668
538
  }
1669
539
  const MAX_LOG_LINES = 5000;
1670
540
  const lines = Math.min(parseInt(req.query.lines || "100", 10) || 100, MAX_LOG_LINES);
1671
- const logLines = shouldUseAppManagerForId(req.params.id, identity)
1672
- ? await instanceManager.getAppLogs(req.params.id, "", lines, logType)
1673
- : await svc.getLogs(req.params.id, lines, logType);
1674
- return { lines: logLines };
1675
- });
1676
- // Admin: re-encrypt all instance secrets with current AES key
1677
- app.post("/api/admin/migrate-secrets", async (_req, _reply) => {
1678
- const { getAesKey, getJwtSecret } = await import("../config.js");
1679
- const { scryptSync, createDecipheriv, createCipheriv, randomBytes } = await import("crypto");
1680
- const { readFileSync, existsSync: fsExistsSync } = await import("fs");
1681
- const instances = instanceManager.listInstances();
1682
- const results = [];
1683
- const currentKey = getAesKey();
1684
- const legacyKey = scryptSync(getJwtSecret(), "jishushell-apikey-v1", 32);
1685
- for (const inst of instances) {
1686
- const envFiles = instanceManager.getRuntimeEnvFiles(inst.id);
1687
- const providerEnvFile = envFiles[0]?.replace(/model\.env$/, "provider.env");
1688
- if (!providerEnvFile || !fsExistsSync(providerEnvFile)) {
1689
- results.push({ id: inst.id, status: "skipped", error: "no provider.env" });
1690
- continue;
1691
- }
1692
- const envContent = readFileSync(providerEnvFile, "utf-8");
1693
- const match = envContent.match(/UPSTREAM_API_KEY=(.+)/);
1694
- if (!match || !match[1]?.startsWith("enc:")) {
1695
- results.push({ id: inst.id, status: "skipped", error: "no encrypted key" });
1696
- continue;
1697
- }
1698
- const encrypted = match[1];
1699
- const raw = Buffer.from(encrypted.slice(4), "base64");
1700
- if (raw.length < 29) {
1701
- results.push({ id: inst.id, status: "error", error: "encrypted data too short" });
1702
- continue;
1703
- }
1704
- const iv = raw.subarray(0, 12);
1705
- const tag = raw.subarray(12, 28);
1706
- const ciphertext = raw.subarray(28);
1707
- // Try decrypt with current key first
1708
- let plaintext = null;
1709
- let needsReEncrypt = false;
1710
- try {
1711
- const d = createDecipheriv("aes-256-gcm", currentKey, iv);
1712
- d.setAuthTag(tag);
1713
- plaintext = d.update(ciphertext, undefined, "utf-8") + d.final("utf-8");
1714
- // Already encrypted with current key — no migration needed
1715
- results.push({ id: inst.id, status: "ok" });
1716
- continue;
1717
- }
1718
- catch {
1719
- // Current key failed — try legacy
1720
- needsReEncrypt = true;
1721
- }
1722
- if (needsReEncrypt) {
1723
- try {
1724
- const d = createDecipheriv("aes-256-gcm", legacyKey, iv);
1725
- d.setAuthTag(tag);
1726
- plaintext = d.update(ciphertext, undefined, "utf-8") + d.final("utf-8");
1727
- }
1728
- catch {
1729
- results.push({ id: inst.id, status: "error", error: "decrypt failed with both keys" });
1730
- continue;
1731
- }
1732
- // Re-encrypt with current key
1733
- const newIv = randomBytes(12);
1734
- const c = createCipheriv("aes-256-gcm", currentKey, newIv);
1735
- const enc = Buffer.concat([c.update(plaintext, "utf-8"), c.final()]);
1736
- const newTag = c.getAuthTag();
1737
- const newEncrypted = "enc:" + Buffer.concat([newIv, newTag, enc]).toString("base64");
1738
- // Write back
1739
- const newContent = envContent.replace(/UPSTREAM_API_KEY=.+/, `UPSTREAM_API_KEY=${newEncrypted}`);
1740
- writeSecretFile(providerEnvFile, newContent);
1741
- results.push({ id: inst.id, status: "migrated" });
1742
- }
1743
- }
1744
- // Invalidate proxy config cache for migrated instances
1745
- for (const r of results) {
1746
- if (r.status === "migrated")
1747
- invalidateConfigCache(r.id);
1748
- }
1749
- return { ok: true, results };
1750
- });
1751
- // ── Docker image check & pull ───────────────────────────────────────────
1752
- // Generic Docker operations used by NewInstance UI to verify / pull runtime
1753
- // images before creating an instance. Framework-level (not adapter-scoped)
1754
- // because every container runtime shares the same docker CLI here.
1755
- app.get("/api/docker/image-check", async (req, reply) => {
1756
- const image = req.query.image;
1757
- if (!image || typeof image !== "string") {
1758
- return reply.status(400).send({ detail: "Missing 'image' query parameter" });
1759
- }
1760
- // Validate image name to prevent command injection
1761
- if (!/^[a-zA-Z0-9][a-zA-Z0-9\-_.:/@]*$/.test(image) || image.length > 256) {
1762
- return reply.status(400).send({ detail: "Invalid Docker image name" });
1763
- }
1764
- const { inspectDockerImage, toDockerInspectUserError } = await import("../utils/docker-inspect.js");
1765
- const result = inspectDockerImage(image, { timeout: 10000 });
1766
- if (result.ok) {
1767
- return { exists: true, image };
1768
- }
1769
- if (result.reason === "not_found")
1770
- return { exists: false, image };
1771
- const inspectError = toDockerInspectUserError(image, result);
1772
- return reply.status(inspectError.statusCode).send({
1773
- detail: inspectError.message,
1774
- code: inspectError.code,
1775
- exists: false,
1776
- image,
1777
- });
1778
- });
1779
- app.post("/api/docker/image-pull", async (req, reply) => {
1780
- const image = req.body?.image;
1781
- if (!image || typeof image !== "string") {
1782
- return reply.status(400).send({ detail: "Missing 'image' in request body" });
1783
- }
1784
- if (!/^[a-zA-Z0-9][a-zA-Z0-9\-_.:/@]*$/.test(image) || image.length > 256) {
1785
- return reply.status(400).send({ detail: "Invalid Docker image name" });
1786
- }
1787
- try {
1788
- const { execFile } = await import("child_process");
1789
- const { promisify } = await import("util");
1790
- const execFileAsync = promisify(execFile);
1791
- await execFileAsync("docker", ["pull", image], { timeout: 600_000 });
1792
- return { ok: true, image };
1793
- }
1794
- catch (e) {
1795
- return reply.status(500).send({ detail: `Failed to pull image: ${e.message}` });
541
+ const logLines = await appLifecycle.getManagedLogs(req.params.id, lines, logType);
542
+ if (!logLines) {
543
+ return reply.status(404).send({ detail: "Instance not found" });
1796
544
  }
545
+ return { lines: logLines };
1797
546
  });
1798
- // ── Connections REST API (PR 4 of app-interconnect-design) ──────────────
547
+ // ── Connections REST API ────────────────────────────────────────────────
1799
548
  /** GET /api/instances/:id/connections — view spec.requires + bindings. */
1800
549
  app.get("/api/instances/:id/connections", async (req, reply) => {
1801
550
  try {
@@ -1844,112 +593,5 @@ export async function instanceRoutes(app) {
1844
593
  return { state: "error", unboundRequired: [], unboundOptional: [], bindable: 0, error: e.message };
1845
594
  }
1846
595
  });
1847
- // ── Suggestions API (PR 6) ─────────────────────────────────────────────
1848
- app.get("/api/suggestions", async () => {
1849
- const { computeSuggestions } = await import("../services/suggestions.js");
1850
- return { suggestions: computeSuggestions() };
1851
- });
1852
- app.post("/api/suggestions/:id/apply", async (req, reply) => {
1853
- const { computeSuggestions } = await import("../services/suggestions.js");
1854
- const all = computeSuggestions();
1855
- const target = all.find((s) => s.id === req.params.id);
1856
- if (!target) {
1857
- return reply.status(404).send({ detail: "Suggestion no longer applies" });
1858
- }
1859
- // Apply by issuing the equivalent PUT /connections — read current
1860
- // bindings, splice in the new one for `slot`, persist via the
1861
- // transactor.
1862
- const meta = instanceManager.getInstance(target.consumerInstanceId);
1863
- if (!meta)
1864
- return reply.status(404).send({ detail: "Consumer instance not found" });
1865
- // Resolve consumer spec — app-installed instances have it in the app
1866
- // registry; legacy instances (no app_id) fall back to the
1867
- // yaml-template synthesizer used everywhere else for legacy
1868
- // capability work.
1869
- let consumerSpec = null;
1870
- if (target.appId) {
1871
- const appData = instanceManager.getApp(target.appId);
1872
- if (!appData)
1873
- return reply.status(404).send({ detail: "App spec not found" });
1874
- consumerSpec = appData.spec;
1875
- }
1876
- else {
1877
- const { loadCapabilitySpecForLegacyInstance } = await import("../services/runtime/migrations.js");
1878
- consumerSpec = loadCapabilitySpecForLegacyInstance(meta);
1879
- if (!consumerSpec) {
1880
- return reply.status(404).send({ detail: "No capability spec for legacy instance" });
1881
- }
1882
- }
1883
- const newConnections = {
1884
- ...(meta.connections ?? {}),
1885
- [target.slot]: {
1886
- kind: "single",
1887
- providerId: target.candidate.providerId,
1888
- capability: target.candidate.capability,
1889
- },
1890
- };
1891
- const { applyConnections } = await import("../services/connection-transactor.js");
1892
- const safeJson = await import("../utils/safe-json.js");
1893
- const fs = await import("fs");
1894
- const path = await import("path");
1895
- const instancePath = instanceManager.instanceMetaPath(target.consumerInstanceId);
1896
- const readInstanceJson = async () => (safeJson.safeReadJson(instancePath, `instance:${target.consumerInstanceId}`) ?? {});
1897
- const saveInstanceJson = async (_id, mutator) => {
1898
- const cur = (safeJson.safeReadJson(instancePath, `instance:${target.consumerInstanceId}`) ?? {});
1899
- try {
1900
- fs.mkdirSync(path.dirname(instancePath), { recursive: true });
1901
- }
1902
- catch {
1903
- /* noop */
1904
- }
1905
- safeJson.safeWriteJson(instancePath, mutator(cur));
1906
- };
1907
- let adapter = null;
1908
- try {
1909
- const agentType = resolveAgentType(meta);
1910
- if (hasAdapter(agentType)) {
1911
- adapter = getAdapter(agentType);
1912
- if (typeof adapter.applyConnectionEnv !== "function")
1913
- adapter = null;
1914
- }
1915
- }
1916
- catch {
1917
- adapter = null;
1918
- }
1919
- try {
1920
- const result = await applyConnections({
1921
- instance: meta,
1922
- spec: consumerSpec,
1923
- newConnections,
1924
- saveInstanceJson,
1925
- readInstanceJson,
1926
- adapter,
1927
- });
1928
- return { ok: true, applied: target.id, resolved: result.resolved.length };
1929
- }
1930
- catch (e) {
1931
- return reply.status(e?.statusCode ?? 500).send({
1932
- detail: e?.message ?? "Suggestion apply failed",
1933
- code: e?.code,
1934
- });
1935
- }
1936
- });
1937
- app.post("/api/suggestions/:id/dismiss", async (req, reply) => {
1938
- const { dismissSuggestion } = await import("../services/suggestions.js");
1939
- try {
1940
- await dismissSuggestion(req.params.id);
1941
- return { ok: true };
1942
- }
1943
- catch (e) {
1944
- return reply.status(400).send({ detail: e?.message ?? "Invalid suggestion id" });
1945
- }
1946
- });
1947
- try {
1948
- const { registerOpenclawRoutes } = await import("./openclaw-routes.js");
1949
- registerOpenclawRoutes(app);
1950
- }
1951
- catch (err) {
1952
- console.error("[instances] openclaw route registration failed:", err);
1953
- }
1954
596
  }
1955
597
  //# sourceMappingURL=instances.js.map