@geminixiang/mikan 1.0.0-beta.2 → 1.0.0-beta.20

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 (412) hide show
  1. package/CHANGELOG.md +354 -0
  2. package/README.md +42 -16
  3. package/dist/adapter.d.ts +1 -1
  4. package/dist/adapter.d.ts.map +1 -1
  5. package/dist/adapter.js.map +1 -1
  6. package/dist/adapters/discord/bot.d.ts +1 -0
  7. package/dist/adapters/discord/bot.d.ts.map +1 -1
  8. package/dist/adapters/discord/bot.js +36 -67
  9. package/dist/adapters/discord/bot.js.map +1 -1
  10. package/dist/adapters/discord/context.d.ts.map +1 -1
  11. package/dist/adapters/discord/context.js +17 -42
  12. package/dist/adapters/discord/context.js.map +1 -1
  13. package/dist/adapters/github/bot.d.ts +148 -0
  14. package/dist/adapters/github/bot.d.ts.map +1 -0
  15. package/dist/adapters/github/bot.js +1031 -0
  16. package/dist/adapters/github/bot.js.map +1 -0
  17. package/dist/adapters/github/client.d.ts +118 -0
  18. package/dist/adapters/github/client.d.ts.map +1 -0
  19. package/dist/adapters/github/client.js +309 -0
  20. package/dist/adapters/github/client.js.map +1 -0
  21. package/dist/adapters/github/cloudbuild.d.ts +24 -0
  22. package/dist/adapters/github/cloudbuild.d.ts.map +1 -0
  23. package/dist/adapters/github/cloudbuild.js +71 -0
  24. package/dist/adapters/github/cloudbuild.js.map +1 -0
  25. package/dist/adapters/github/context.d.ts +9 -0
  26. package/dist/adapters/github/context.d.ts.map +1 -0
  27. package/dist/adapters/github/context.js +175 -0
  28. package/dist/adapters/github/context.js.map +1 -0
  29. package/dist/adapters/github/gcp-auth.d.ts +31 -0
  30. package/dist/adapters/github/gcp-auth.d.ts.map +1 -0
  31. package/dist/adapters/github/gcp-auth.js +196 -0
  32. package/dist/adapters/github/gcp-auth.js.map +1 -0
  33. package/dist/adapters/github/ids.d.ts +34 -0
  34. package/dist/adapters/github/ids.d.ts.map +1 -0
  35. package/dist/adapters/github/ids.js +53 -0
  36. package/dist/adapters/github/ids.js.map +1 -0
  37. package/dist/adapters/github/repo.d.ts +30 -0
  38. package/dist/adapters/github/repo.d.ts.map +1 -0
  39. package/dist/adapters/github/repo.js +136 -0
  40. package/dist/adapters/github/repo.js.map +1 -0
  41. package/dist/adapters/github/tool-pack.d.ts +14 -0
  42. package/dist/adapters/github/tool-pack.d.ts.map +1 -0
  43. package/dist/adapters/github/tool-pack.js +56 -0
  44. package/dist/adapters/github/tool-pack.js.map +1 -0
  45. package/dist/adapters/github/tools/checks.d.ts +24 -0
  46. package/dist/adapters/github/tools/checks.d.ts.map +1 -0
  47. package/dist/adapters/github/tools/checks.js +116 -0
  48. package/dist/adapters/github/tools/checks.js.map +1 -0
  49. package/dist/adapters/github/tools/issue.d.ts +22 -0
  50. package/dist/adapters/github/tools/issue.d.ts.map +1 -0
  51. package/dist/adapters/github/tools/issue.js +59 -0
  52. package/dist/adapters/github/tools/issue.js.map +1 -0
  53. package/dist/adapters/github/tools/pr.d.ts +22 -0
  54. package/dist/adapters/github/tools/pr.d.ts.map +1 -0
  55. package/dist/adapters/github/tools/pr.js +59 -0
  56. package/dist/adapters/github/tools/pr.js.map +1 -0
  57. package/dist/adapters/github/tools/read.d.ts +22 -0
  58. package/dist/adapters/github/tools/read.d.ts.map +1 -0
  59. package/dist/adapters/github/tools/read.js +152 -0
  60. package/dist/adapters/github/tools/read.js.map +1 -0
  61. package/dist/adapters/github/tools/review-reply.d.ts +19 -0
  62. package/dist/adapters/github/tools/review-reply.d.ts.map +1 -0
  63. package/dist/adapters/github/tools/review-reply.js +49 -0
  64. package/dist/adapters/github/tools/review-reply.js.map +1 -0
  65. package/dist/adapters/github/tools/sync.d.ts +17 -0
  66. package/dist/adapters/github/tools/sync.d.ts.map +1 -0
  67. package/dist/adapters/github/tools/sync.js +45 -0
  68. package/dist/adapters/github/tools/sync.js.map +1 -0
  69. package/dist/adapters/github/types.d.ts +350 -0
  70. package/dist/adapters/github/types.d.ts.map +1 -0
  71. package/dist/adapters/github/types.js +2 -0
  72. package/dist/adapters/github/types.js.map +1 -0
  73. package/dist/adapters/intake.d.ts +16 -5
  74. package/dist/adapters/intake.d.ts.map +1 -1
  75. package/dist/adapters/intake.js +79 -22
  76. package/dist/adapters/intake.js.map +1 -1
  77. package/dist/adapters/slack/bot.d.ts +8 -6
  78. package/dist/adapters/slack/bot.d.ts.map +1 -1
  79. package/dist/adapters/slack/bot.js +81 -133
  80. package/dist/adapters/slack/bot.js.map +1 -1
  81. package/dist/adapters/slack/context.d.ts.map +1 -1
  82. package/dist/adapters/slack/context.js +3 -14
  83. package/dist/adapters/slack/context.js.map +1 -1
  84. package/dist/adapters/slack/response-lifecycle.d.ts.map +1 -1
  85. package/dist/adapters/slack/response-lifecycle.js +14 -17
  86. package/dist/adapters/slack/response-lifecycle.js.map +1 -1
  87. package/dist/adapters/slack/session.d.ts.map +1 -1
  88. package/dist/adapters/slack/session.js +5 -8
  89. package/dist/adapters/slack/session.js.map +1 -1
  90. package/dist/adapters/streaming.d.ts +4 -0
  91. package/dist/adapters/streaming.d.ts.map +1 -1
  92. package/dist/adapters/streaming.js +11 -0
  93. package/dist/adapters/streaming.js.map +1 -1
  94. package/dist/adapters/telegram/bot.d.ts +1 -2
  95. package/dist/adapters/telegram/bot.d.ts.map +1 -1
  96. package/dist/adapters/telegram/bot.js +27 -62
  97. package/dist/adapters/telegram/bot.js.map +1 -1
  98. package/dist/adapters/telegram/context.d.ts.map +1 -1
  99. package/dist/adapters/telegram/context.js +8 -27
  100. package/dist/adapters/telegram/context.js.map +1 -1
  101. package/dist/adapters/types.d.ts +28 -2
  102. package/dist/adapters/types.d.ts.map +1 -1
  103. package/dist/adapters/types.js.map +1 -1
  104. package/dist/agent.d.ts +38 -14
  105. package/dist/agent.d.ts.map +1 -1
  106. package/dist/agent.js +358 -224
  107. package/dist/agent.js.map +1 -1
  108. package/dist/cli/download.d.ts.map +1 -0
  109. package/dist/cli/download.js.map +1 -0
  110. package/dist/cli/ext-git.d.ts +22 -0
  111. package/dist/cli/ext-git.d.ts.map +1 -0
  112. package/dist/cli/ext-git.js +76 -0
  113. package/dist/cli/ext-git.js.map +1 -0
  114. package/dist/cli/ext.d.ts +2 -0
  115. package/dist/cli/ext.d.ts.map +1 -0
  116. package/dist/cli/ext.js +217 -0
  117. package/dist/cli/ext.js.map +1 -0
  118. package/dist/commands/admin.d.ts.map +1 -1
  119. package/dist/commands/admin.js +2 -1
  120. package/dist/commands/admin.js.map +1 -1
  121. package/dist/commands/auto-reply.d.ts.map +1 -1
  122. package/dist/commands/auto-reply.js +2 -6
  123. package/dist/commands/auto-reply.js.map +1 -1
  124. package/dist/commands/extensions.d.ts.map +1 -1
  125. package/dist/commands/extensions.js +16 -6
  126. package/dist/commands/extensions.js.map +1 -1
  127. package/dist/commands/login.d.ts +2 -1
  128. package/dist/commands/login.d.ts.map +1 -1
  129. package/dist/commands/login.js +30 -1
  130. package/dist/commands/login.js.map +1 -1
  131. package/dist/commands/manifest.d.ts +72 -0
  132. package/dist/commands/manifest.d.ts.map +1 -0
  133. package/dist/commands/manifest.js +121 -0
  134. package/dist/commands/manifest.js.map +1 -0
  135. package/dist/commands/model.d.ts.map +1 -1
  136. package/dist/commands/model.js +3 -1
  137. package/dist/commands/model.js.map +1 -1
  138. package/dist/commands/new.d.ts.map +1 -1
  139. package/dist/commands/new.js +2 -1
  140. package/dist/commands/new.js.map +1 -1
  141. package/dist/commands/sandbox.d.ts.map +1 -1
  142. package/dist/commands/sandbox.js +16 -12
  143. package/dist/commands/sandbox.js.map +1 -1
  144. package/dist/commands/text.d.ts +2 -0
  145. package/dist/commands/text.d.ts.map +1 -0
  146. package/dist/commands/text.js +16 -0
  147. package/dist/commands/text.js.map +1 -0
  148. package/dist/commands/types.d.ts +14 -1
  149. package/dist/commands/types.d.ts.map +1 -1
  150. package/dist/commands/types.js.map +1 -1
  151. package/dist/config.d.ts +1 -1
  152. package/dist/config.d.ts.map +1 -1
  153. package/dist/config.js +90 -54
  154. package/dist/config.js.map +1 -1
  155. package/dist/events.d.ts +10 -0
  156. package/dist/events.d.ts.map +1 -1
  157. package/dist/events.js +14 -5
  158. package/dist/events.js.map +1 -1
  159. package/dist/execution-resolver.d.ts +3 -2
  160. package/dist/execution-resolver.d.ts.map +1 -1
  161. package/dist/execution-resolver.js +28 -12
  162. package/dist/execution-resolver.js.map +1 -1
  163. package/dist/harness/extensions/loader.d.ts +39 -9
  164. package/dist/harness/extensions/loader.d.ts.map +1 -1
  165. package/dist/harness/extensions/loader.js +258 -54
  166. package/dist/harness/extensions/loader.js.map +1 -1
  167. package/dist/harness/extensions/registry.d.ts +48 -1
  168. package/dist/harness/extensions/registry.d.ts.map +1 -1
  169. package/dist/harness/extensions/registry.js +146 -0
  170. package/dist/harness/extensions/registry.js.map +1 -1
  171. package/dist/harness/extensions/types.d.ts +161 -14
  172. package/dist/harness/extensions/types.d.ts.map +1 -1
  173. package/dist/harness/extensions/types.js.map +1 -1
  174. package/dist/harness/index.d.ts +5 -5
  175. package/dist/harness/index.d.ts.map +1 -1
  176. package/dist/harness/index.js +2 -2
  177. package/dist/harness/index.js.map +1 -1
  178. package/dist/harness/models.d.ts +5 -0
  179. package/dist/harness/models.d.ts.map +1 -1
  180. package/dist/harness/models.js +10 -0
  181. package/dist/harness/models.js.map +1 -1
  182. package/dist/harness/runner.d.ts +21 -2
  183. package/dist/harness/runner.d.ts.map +1 -1
  184. package/dist/harness/runner.js +80 -22
  185. package/dist/harness/runner.js.map +1 -1
  186. package/dist/harness/session-store.d.ts +4 -1
  187. package/dist/harness/session-store.d.ts.map +1 -1
  188. package/dist/harness/session-store.js +11 -2
  189. package/dist/harness/session-store.js.map +1 -1
  190. package/dist/harness/subagent-runner.d.ts +17 -0
  191. package/dist/harness/subagent-runner.d.ts.map +1 -0
  192. package/dist/harness/subagent-runner.js +307 -0
  193. package/dist/harness/subagent-runner.js.map +1 -0
  194. package/dist/harness/types.d.ts +53 -0
  195. package/dist/harness/types.d.ts.map +1 -1
  196. package/dist/harness/types.js.map +1 -1
  197. package/dist/index.d.ts +1 -1
  198. package/dist/index.d.ts.map +1 -1
  199. package/dist/index.js.map +1 -1
  200. package/dist/main.js +232 -29
  201. package/dist/main.js.map +1 -1
  202. package/dist/provisioner.d.ts.map +1 -1
  203. package/dist/provisioner.js +2 -5
  204. package/dist/provisioner.js.map +1 -1
  205. package/dist/runtime/conversation-runtime.d.ts +1 -1
  206. package/dist/runtime/conversation-runtime.d.ts.map +1 -1
  207. package/dist/runtime/conversation-runtime.js +264 -41
  208. package/dist/runtime/conversation-runtime.js.map +1 -1
  209. package/dist/runtime/types.d.ts +32 -5
  210. package/dist/runtime/types.d.ts.map +1 -1
  211. package/dist/runtime/types.js.map +1 -1
  212. package/dist/sandbox/cloudflare.d.ts +2 -0
  213. package/dist/sandbox/cloudflare.d.ts.map +1 -1
  214. package/dist/sandbox/cloudflare.js +7 -0
  215. package/dist/sandbox/cloudflare.js.map +1 -1
  216. package/dist/sandbox/container.d.ts +3 -0
  217. package/dist/sandbox/container.d.ts.map +1 -1
  218. package/dist/sandbox/container.js +8 -2
  219. package/dist/sandbox/container.js.map +1 -1
  220. package/dist/sandbox/firecracker.d.ts +2 -0
  221. package/dist/sandbox/firecracker.d.ts.map +1 -1
  222. package/dist/sandbox/firecracker.js +7 -1
  223. package/dist/sandbox/firecracker.js.map +1 -1
  224. package/dist/sandbox/gondolin-fleet.d.ts +104 -0
  225. package/dist/sandbox/gondolin-fleet.d.ts.map +1 -0
  226. package/dist/sandbox/gondolin-fleet.js +330 -0
  227. package/dist/sandbox/gondolin-fleet.js.map +1 -0
  228. package/dist/sandbox/gondolin-gateway.d.ts +85 -0
  229. package/dist/sandbox/gondolin-gateway.d.ts.map +1 -0
  230. package/dist/sandbox/gondolin-gateway.js +400 -0
  231. package/dist/sandbox/gondolin-gateway.js.map +1 -0
  232. package/dist/sandbox/gondolin-inventory.d.ts +89 -0
  233. package/dist/sandbox/gondolin-inventory.d.ts.map +1 -0
  234. package/dist/sandbox/gondolin-inventory.js +267 -0
  235. package/dist/sandbox/gondolin-inventory.js.map +1 -0
  236. package/dist/sandbox/gondolin-join.d.ts +62 -0
  237. package/dist/sandbox/gondolin-join.d.ts.map +1 -0
  238. package/dist/sandbox/gondolin-join.js +261 -0
  239. package/dist/sandbox/gondolin-join.js.map +1 -0
  240. package/dist/sandbox/gondolin-nfs-advisory.d.ts +15 -0
  241. package/dist/sandbox/gondolin-nfs-advisory.d.ts.map +1 -0
  242. package/dist/sandbox/gondolin-nfs-advisory.js +60 -0
  243. package/dist/sandbox/gondolin-nfs-advisory.js.map +1 -0
  244. package/dist/sandbox/gondolin-placement.d.ts +32 -0
  245. package/dist/sandbox/gondolin-placement.d.ts.map +1 -0
  246. package/dist/sandbox/gondolin-placement.js +83 -0
  247. package/dist/sandbox/gondolin-placement.js.map +1 -0
  248. package/dist/sandbox/gondolin-remote.d.ts +73 -0
  249. package/dist/sandbox/gondolin-remote.d.ts.map +1 -0
  250. package/dist/sandbox/gondolin-remote.js +352 -0
  251. package/dist/sandbox/gondolin-remote.js.map +1 -0
  252. package/dist/sandbox/gondolin-worker-client.d.ts +139 -0
  253. package/dist/sandbox/gondolin-worker-client.d.ts.map +1 -0
  254. package/dist/sandbox/gondolin-worker-client.js +325 -0
  255. package/dist/sandbox/gondolin-worker-client.js.map +1 -0
  256. package/dist/sandbox/gondolin-worker-main.d.ts +2 -0
  257. package/dist/sandbox/gondolin-worker-main.d.ts.map +1 -0
  258. package/dist/sandbox/gondolin-worker-main.js +22 -0
  259. package/dist/sandbox/gondolin-worker-main.js.map +1 -0
  260. package/dist/sandbox/gondolin-worker.d.ts +55 -0
  261. package/dist/sandbox/gondolin-worker.d.ts.map +1 -0
  262. package/dist/sandbox/gondolin-worker.js +201 -0
  263. package/dist/sandbox/gondolin-worker.js.map +1 -0
  264. package/dist/sandbox/gondolin.d.ts +52 -0
  265. package/dist/sandbox/gondolin.d.ts.map +1 -0
  266. package/dist/sandbox/gondolin.js +425 -0
  267. package/dist/sandbox/gondolin.js.map +1 -0
  268. package/dist/sandbox/host.d.ts +2 -0
  269. package/dist/sandbox/host.d.ts.map +1 -1
  270. package/dist/sandbox/host.js +11 -0
  271. package/dist/sandbox/host.js.map +1 -1
  272. package/dist/sandbox/identity.d.ts +21 -0
  273. package/dist/sandbox/identity.d.ts.map +1 -0
  274. package/dist/sandbox/identity.js +36 -0
  275. package/dist/sandbox/identity.js.map +1 -0
  276. package/dist/sandbox/index.d.ts +4 -3
  277. package/dist/sandbox/index.d.ts.map +1 -1
  278. package/dist/sandbox/index.js +5 -3
  279. package/dist/sandbox/index.js.map +1 -1
  280. package/dist/sandbox/types.d.ts +26 -1
  281. package/dist/sandbox/types.d.ts.map +1 -1
  282. package/dist/sandbox/types.js.map +1 -1
  283. package/dist/sandbox/utils.d.ts +11 -0
  284. package/dist/sandbox/utils.d.ts.map +1 -1
  285. package/dist/sandbox/utils.js +35 -0
  286. package/dist/sandbox/utils.js.map +1 -1
  287. package/dist/sessions/agent-memory-file-manager.d.ts.map +1 -1
  288. package/dist/sessions/agent-memory-file-manager.js +16 -30
  289. package/dist/sessions/agent-memory-file-manager.js.map +1 -1
  290. package/dist/sessions/history-line.d.ts +20 -0
  291. package/dist/sessions/history-line.d.ts.map +1 -0
  292. package/dist/sessions/history-line.js +24 -0
  293. package/dist/sessions/history-line.js.map +1 -0
  294. package/dist/sessions/policy.d.ts.map +1 -1
  295. package/dist/sessions/policy.js +5 -3
  296. package/dist/sessions/policy.js.map +1 -1
  297. package/dist/sessions/session-key.d.ts +31 -0
  298. package/dist/sessions/session-key.d.ts.map +1 -0
  299. package/dist/sessions/session-key.js +44 -0
  300. package/dist/sessions/session-key.js.map +1 -0
  301. package/dist/sessions/store.d.ts.map +1 -1
  302. package/dist/sessions/store.js +2 -2
  303. package/dist/sessions/store.js.map +1 -1
  304. package/dist/tools/bash.d.ts +3 -1
  305. package/dist/tools/bash.d.ts.map +1 -1
  306. package/dist/tools/bash.js +24 -17
  307. package/dist/tools/bash.js.map +1 -1
  308. package/dist/tools/edit.d.ts.map +1 -1
  309. package/dist/tools/edit.js +9 -12
  310. package/dist/tools/edit.js.map +1 -1
  311. package/dist/tools/event.d.ts +1 -1
  312. package/dist/tools/event.d.ts.map +1 -1
  313. package/dist/tools/event.js +33 -4
  314. package/dist/tools/event.js.map +1 -1
  315. package/dist/tools/generate-image.d.ts +17 -0
  316. package/dist/tools/generate-image.d.ts.map +1 -0
  317. package/dist/tools/generate-image.js +63 -0
  318. package/dist/tools/generate-image.js.map +1 -0
  319. package/dist/tools/index.d.ts +16 -2
  320. package/dist/tools/index.d.ts.map +1 -1
  321. package/dist/tools/index.js +27 -3
  322. package/dist/tools/index.js.map +1 -1
  323. package/dist/tools/react.d.ts +15 -0
  324. package/dist/tools/react.d.ts.map +1 -0
  325. package/dist/tools/react.js +40 -0
  326. package/dist/tools/react.js.map +1 -0
  327. package/dist/tools/sandbox.d.ts +2 -2
  328. package/dist/tools/sandbox.d.ts.map +1 -1
  329. package/dist/tools/sandbox.js +8 -7
  330. package/dist/tools/sandbox.js.map +1 -1
  331. package/dist/tools/subagent.d.ts +69 -0
  332. package/dist/tools/subagent.d.ts.map +1 -0
  333. package/dist/tools/subagent.js +286 -0
  334. package/dist/tools/subagent.js.map +1 -0
  335. package/dist/tools/types.d.ts +34 -1
  336. package/dist/tools/types.d.ts.map +1 -1
  337. package/dist/tools/types.js.map +1 -1
  338. package/dist/tools/write.d.ts.map +1 -1
  339. package/dist/tools/write.js +1 -8
  340. package/dist/tools/write.js.map +1 -1
  341. package/dist/trigger.d.ts.map +1 -1
  342. package/dist/trigger.js +1 -2
  343. package/dist/trigger.js.map +1 -1
  344. package/dist/types.d.ts +139 -7
  345. package/dist/types.d.ts.map +1 -1
  346. package/dist/types.js.map +1 -1
  347. package/dist/vault/disabled.d.ts +9 -0
  348. package/dist/vault/disabled.d.ts.map +1 -0
  349. package/dist/vault/disabled.js +23 -0
  350. package/dist/vault/disabled.js.map +1 -0
  351. package/dist/vault/index.d.ts.map +1 -1
  352. package/dist/vault/index.js +3 -24
  353. package/dist/vault/index.js.map +1 -1
  354. package/dist/vault/policy.d.ts +20 -0
  355. package/dist/vault/policy.d.ts.map +1 -0
  356. package/dist/vault/policy.js +20 -0
  357. package/dist/vault/policy.js.map +1 -0
  358. package/dist/vault/routing.d.ts +1 -0
  359. package/dist/vault/routing.d.ts.map +1 -1
  360. package/dist/vault/routing.js +3 -10
  361. package/dist/vault/routing.js.map +1 -1
  362. package/dist/web/admin/portal.d.ts +27 -0
  363. package/dist/web/admin/portal.d.ts.map +1 -1
  364. package/dist/web/admin/portal.js +91 -130
  365. package/dist/web/admin/portal.js.map +1 -1
  366. package/dist/web/admin/types.d.ts +3 -0
  367. package/dist/web/admin/types.d.ts.map +1 -1
  368. package/dist/web/admin/types.js.map +1 -1
  369. package/dist/web/login/oauth.d.ts +2 -3
  370. package/dist/web/login/oauth.d.ts.map +1 -1
  371. package/dist/web/login/oauth.js +0 -31
  372. package/dist/web/login/oauth.js.map +1 -1
  373. package/dist/web/login/portal.js +1 -1
  374. package/dist/web/login/portal.js.map +1 -1
  375. package/dist/web/login/types.d.ts +0 -11
  376. package/dist/web/login/types.d.ts.map +1 -1
  377. package/dist/web/login/types.js.map +1 -1
  378. package/dist/web/portal-shell.d.ts +4 -0
  379. package/dist/web/portal-shell.d.ts.map +1 -0
  380. package/dist/{portal-shell.js → web/portal-shell.js} +2 -2
  381. package/dist/web/portal-shell.js.map +1 -0
  382. package/dist/web/server.d.ts.map +1 -1
  383. package/dist/web/server.js +7 -0
  384. package/dist/web/server.js.map +1 -1
  385. package/dist/web/session-view/command.d.ts.map +1 -1
  386. package/dist/web/session-view/command.js +4 -1
  387. package/dist/web/session-view/command.js.map +1 -1
  388. package/dist/web/session-view/portal.d.ts.map +1 -1
  389. package/dist/web/session-view/portal.js +4 -3
  390. package/dist/web/session-view/portal.js.map +1 -1
  391. package/dist/web/session-view/service.d.ts.map +1 -1
  392. package/dist/web/session-view/service.js +2 -1
  393. package/dist/web/session-view/service.js.map +1 -1
  394. package/dist/web/session-view/types.d.ts +2 -1
  395. package/dist/web/session-view/types.d.ts.map +1 -1
  396. package/dist/web/session-view/types.js.map +1 -1
  397. package/package.json +7 -4
  398. package/dist/download.d.ts.map +0 -1
  399. package/dist/download.js.map +0 -1
  400. package/dist/model-registry.d.ts +0 -4
  401. package/dist/model-registry.d.ts.map +0 -1
  402. package/dist/model-registry.js +0 -7
  403. package/dist/model-registry.js.map +0 -1
  404. package/dist/portal-shell.d.ts +0 -4
  405. package/dist/portal-shell.d.ts.map +0 -1
  406. package/dist/portal-shell.js.map +0 -1
  407. package/dist/runtime/agent-run-controller.d.ts +0 -31
  408. package/dist/runtime/agent-run-controller.d.ts.map +0 -1
  409. package/dist/runtime/agent-run-controller.js +0 -195
  410. package/dist/runtime/agent-run-controller.js.map +0 -1
  411. /package/dist/{download.d.ts → cli/download.d.ts} +0 -0
  412. /package/dist/{download.js → cli/download.js} +0 -0
@@ -0,0 +1,352 @@
1
+ import { readFileSync, statSync } from "node:fs";
2
+ import { request as httpsRequest } from "node:https";
3
+ import { relative, isAbsolute, join } from "node:path";
4
+ import * as log from "../log.js";
5
+ import { SandboxError } from "./errors.js";
6
+ import { GondolinRuntimeGoneError, execOverSessionConnect, } from "./gondolin-worker-client.js";
7
+ const LEASE_TTL_SECONDS = 300;
8
+ const REQUEST_TIMEOUT_MS = 15_000;
9
+ /** VM boot happens inside this request; the daemon's own handshake cap is 2 min. */
10
+ const ENSURE_TIMEOUT_MS = 150_000;
11
+ /** A request that never reached the daemon (network/TLS/timeout failure). */
12
+ export class GondolinWorkerUnreachableError extends Error {
13
+ }
14
+ /** Parses the daemon-to-client session framing: u8 type + u32be length + payload. */
15
+ export function createSessionFrameParser(callbacks) {
16
+ let buffer = Buffer.alloc(0);
17
+ return (chunk) => {
18
+ buffer = Buffer.concat([buffer, chunk]);
19
+ while (buffer.length >= 5) {
20
+ const type = buffer.readUInt8(0);
21
+ const length = buffer.readUInt32BE(1);
22
+ if (buffer.length < 5 + length)
23
+ return;
24
+ const payload = buffer.subarray(5, 5 + length);
25
+ buffer = buffer.subarray(5 + length);
26
+ if (type === 1) {
27
+ callbacks.onBinary(Buffer.from(payload));
28
+ continue;
29
+ }
30
+ try {
31
+ callbacks.onJson(JSON.parse(payload.toString("utf8")));
32
+ }
33
+ catch {
34
+ // ignore malformed frames
35
+ }
36
+ }
37
+ };
38
+ }
39
+ /** Encodes a client-to-daemon session message: u32be length + JSON. */
40
+ export function encodeSessionMessage(message) {
41
+ const payload = Buffer.from(JSON.stringify(message));
42
+ const header = Buffer.alloc(4);
43
+ header.writeUInt32BE(payload.length, 0);
44
+ return Buffer.concat([header, payload]);
45
+ }
46
+ /**
47
+ * One mikan-worker daemon as seen from mikan: mTLS requests, per-instance
48
+ * fenced leases with heartbeat renewal, and per-command upgraded tunnels.
49
+ * Commands travel through one tunnel each, so abort semantics match the local
50
+ * transport exactly.
51
+ */
52
+ export class GondolinRemoteConnection {
53
+ constructor(settings, overrides = {}) {
54
+ this.settings = settings;
55
+ this.overrides = overrides;
56
+ this.leases = new Map();
57
+ this.leaseTtlSeconds = overrides.leaseTtlSeconds ?? LEASE_TTL_SECONDS;
58
+ this.requestTimeoutMs = overrides.requestTimeoutMs ?? REQUEST_TIMEOUT_MS;
59
+ }
60
+ /** Drop lease timers and caches (does not touch the daemon). */
61
+ dispose() {
62
+ for (const lease of this.leases.values())
63
+ clearInterval(lease.renewTimer);
64
+ this.leases.clear();
65
+ }
66
+ async health() {
67
+ const response = await this.request("GET", "/v1/health");
68
+ if (response.status !== 200) {
69
+ throw new SandboxError(`Error: gondolin remote worker health check failed (${response.status})`);
70
+ }
71
+ return response.json;
72
+ }
73
+ async ensure(instanceId, spec) {
74
+ const { mounts, credentialFiles } = this.translateMounts(spec);
75
+ const body = {
76
+ instanceId,
77
+ imageSelector: spec.image,
78
+ mounts,
79
+ credentialFiles,
80
+ cpus: spec.cpus ?? "",
81
+ memory: spec.memory ?? "",
82
+ fingerprint: spec.fingerprint,
83
+ };
84
+ const idempotencyKey = `${instanceId}:${spec.fingerprint}:${Date.now()}`;
85
+ for (let attempt = 0;; attempt += 1) {
86
+ const lease = await this.leaseFor(instanceId);
87
+ const response = await this.request("POST", "/v1/runtimes", body, { ...this.leaseHeaders(lease), "Idempotency-Key": idempotencyKey }, ENSURE_TIMEOUT_MS);
88
+ if (response.status === 200) {
89
+ return {
90
+ sessionId: response.json.sessionId,
91
+ instanceId,
92
+ socketPath: "",
93
+ workerPid: response.json.workerPid ?? 0,
94
+ fingerprint: spec.fingerprint,
95
+ };
96
+ }
97
+ if ((response.status === 409 || response.status === 410) && attempt === 0) {
98
+ this.dropLease(instanceId);
99
+ continue;
100
+ }
101
+ throw new SandboxError(`Error: remote worker refused runtime (${response.status}): ${String(response.json.message ?? "")}`);
102
+ }
103
+ }
104
+ async stop(handle) {
105
+ const lease = await this.leaseFor(handle.instanceId);
106
+ const response = await this.request("DELETE", `/v1/runtimes/${handle.sessionId}`, undefined, this.leaseHeaders(lease));
107
+ if (response.status === 409 || response.status === 410) {
108
+ this.dropLease(handle.instanceId);
109
+ }
110
+ this.releaseLease(handle.instanceId);
111
+ }
112
+ async isRuntimeAlive(handle) {
113
+ try {
114
+ const response = await this.request("GET", `/v1/runtimes/${handle.sessionId}`);
115
+ return response.status === 200;
116
+ }
117
+ catch {
118
+ return false;
119
+ }
120
+ }
121
+ /** Live runtimes hosted by this worker (fleet reconciliation). */
122
+ async listRuntimes() {
123
+ const response = await this.request("GET", "/v1/runtimes");
124
+ if (response.status !== 200)
125
+ return [];
126
+ const runtimes = response.json.runtimes;
127
+ return Array.isArray(runtimes)
128
+ ? runtimes
129
+ : [];
130
+ }
131
+ async exec(handle, command, options = {}) {
132
+ const lease = this.leases.get(handle.instanceId);
133
+ if (!lease) {
134
+ // the lease lapsed (e.g. mikan slept); recreate the session cleanly
135
+ throw new GondolinRuntimeGoneError("no live lease for this runtime");
136
+ }
137
+ return execOverSessionConnect((callbacks) => this.openTunnel(handle.instanceId, `/v1/runtimes/${handle.sessionId}/session`, this.leaseHeaders(lease), callbacks), command, options);
138
+ }
139
+ /**
140
+ * Split mounts for the remote worker:
141
+ * - sources under the mikan-host workspace are translated to the worker's
142
+ * shared `workspaceRoot` (shared POSIX storage), and
143
+ * - sources outside it that are files (vault credentials, which live in the
144
+ * host state dir, not the shared workspace) are read and shipped as
145
+ * content payloads for the worker to project into the guest.
146
+ * A non-file source outside the workspace has nowhere to go and is dropped.
147
+ */
148
+ translateMounts(spec) {
149
+ const root = this.settings.workspaceRoot;
150
+ if (!root || !spec.workspacePath) {
151
+ return { mounts: spec.mounts, credentialFiles: [] };
152
+ }
153
+ const mounts = [];
154
+ const credentialFiles = [];
155
+ for (const mount of spec.mounts) {
156
+ const suffix = relative(spec.workspacePath, mount.source);
157
+ if (!suffix.startsWith("..") && !isAbsolute(suffix)) {
158
+ mounts.push({ source: join(root, suffix), target: mount.target });
159
+ continue;
160
+ }
161
+ try {
162
+ if (!statSync(mount.source).isFile()) {
163
+ log.logWarning(`Skipping directory mount outside the shared workspace for remote runtime: ${mount.source}`);
164
+ continue;
165
+ }
166
+ credentialFiles.push({
167
+ target: mount.target,
168
+ contentBase64: readFileSync(mount.source).toString("base64"),
169
+ });
170
+ }
171
+ catch {
172
+ // missing source: skip, matching the local worker's behavior
173
+ }
174
+ }
175
+ return { mounts, credentialFiles };
176
+ }
177
+ async leaseFor(instanceId) {
178
+ const cached = this.leases.get(instanceId);
179
+ if (cached)
180
+ return cached;
181
+ const response = await this.request("POST", "/v1/leases", {
182
+ instanceId,
183
+ ttlSeconds: this.leaseTtlSeconds,
184
+ });
185
+ if (response.status !== 200) {
186
+ throw new SandboxError(`Error: remote worker refused lease (${response.status}): ${String(response.json.message ?? "")}`);
187
+ }
188
+ const lease = {
189
+ leaseId: response.json.id,
190
+ epoch: response.json.epoch,
191
+ renewTimer: setInterval(() => void this.renew(instanceId), (this.leaseTtlSeconds * 1000) / 3),
192
+ };
193
+ lease.renewTimer.unref?.();
194
+ this.leases.set(instanceId, lease);
195
+ this.reportLeaseActivity(instanceId);
196
+ return lease;
197
+ }
198
+ async renew(instanceId) {
199
+ const lease = this.leases.get(instanceId);
200
+ if (!lease)
201
+ return;
202
+ try {
203
+ const response = await this.request("POST", `/v1/leases/${lease.leaseId}/renew`, {
204
+ ttlSeconds: this.leaseTtlSeconds,
205
+ });
206
+ if (response.status === 200)
207
+ this.reportLeaseActivity(instanceId);
208
+ else
209
+ this.dropLease(instanceId);
210
+ }
211
+ catch (err) {
212
+ log.logWarning(`Failed to renew remote worker lease for '${instanceId}'`, err instanceof Error ? err.message : String(err));
213
+ }
214
+ }
215
+ reportLeaseActivity(instanceId) {
216
+ // fencing watermark by mikan's own clock: the worker-side lease cannot
217
+ // outlive this moment plus its ttl, no matter whose clock is skewed
218
+ this.overrides.onLeaseActivity?.(instanceId, Date.now() + this.leaseTtlSeconds * 1000);
219
+ }
220
+ releaseLease(instanceId) {
221
+ const lease = this.leases.get(instanceId);
222
+ if (!lease)
223
+ return;
224
+ this.dropLease(instanceId);
225
+ void this.request("DELETE", `/v1/leases/${lease.leaseId}`).catch(() => { });
226
+ }
227
+ dropLease(instanceId) {
228
+ const lease = this.leases.get(instanceId);
229
+ if (!lease)
230
+ return;
231
+ clearInterval(lease.renewTimer);
232
+ this.leases.delete(instanceId);
233
+ }
234
+ leaseHeaders(lease) {
235
+ return { "X-Mikan-Lease": lease.leaseId, "X-Mikan-Epoch": String(lease.epoch) };
236
+ }
237
+ request(method, path, body, headers, timeoutMs = this.requestTimeoutMs) {
238
+ if (this.overrides.request)
239
+ return this.overrides.request(method, path, body, headers);
240
+ const url = new URL(path, this.settings.url);
241
+ const payload = body === undefined ? undefined : Buffer.from(JSON.stringify(body));
242
+ return new Promise((resolve, reject) => {
243
+ const request = httpsRequest({
244
+ method,
245
+ host: url.hostname,
246
+ port: url.port,
247
+ path: url.pathname + url.search,
248
+ signal: AbortSignal.timeout(timeoutMs),
249
+ headers: {
250
+ ...(payload
251
+ ? { "Content-Type": "application/json", "Content-Length": payload.length }
252
+ : {}),
253
+ ...headers,
254
+ },
255
+ ...this.tlsOptions(),
256
+ }, (response) => {
257
+ let raw = "";
258
+ response.setEncoding("utf8");
259
+ response.on("data", (chunk) => {
260
+ raw += chunk;
261
+ });
262
+ response.on("end", () => {
263
+ let json = {};
264
+ try {
265
+ json = raw ? JSON.parse(raw) : {};
266
+ }
267
+ catch {
268
+ // non-JSON body; status carries the outcome
269
+ }
270
+ resolve({ status: response.statusCode ?? 0, json });
271
+ });
272
+ });
273
+ request.on("error", (error) => reject(new GondolinWorkerUnreachableError(error.message)));
274
+ if (payload)
275
+ request.write(payload);
276
+ request.end();
277
+ });
278
+ }
279
+ openTunnel(instanceId, path, headers, callbacks) {
280
+ if (this.overrides.tunnel)
281
+ return this.overrides.tunnel(path, headers, callbacks);
282
+ const url = new URL(path, this.settings.url);
283
+ return new Promise((resolve, reject) => {
284
+ const request = httpsRequest({
285
+ method: "GET",
286
+ host: url.hostname,
287
+ port: url.port,
288
+ path: url.pathname,
289
+ signal: AbortSignal.timeout(this.requestTimeoutMs),
290
+ headers: { ...headers, Connection: "Upgrade", Upgrade: "gondolin-session" },
291
+ ...this.tlsOptions(),
292
+ });
293
+ request.on("upgrade", (_response, socket) => {
294
+ socket.setNoDelay(true);
295
+ let closed = false;
296
+ const parse = createSessionFrameParser(callbacks);
297
+ socket.on("data", parse);
298
+ socket.on("error", (error) => {
299
+ if (closed)
300
+ return;
301
+ closed = true;
302
+ callbacks.onClose(error);
303
+ });
304
+ socket.on("close", () => {
305
+ if (closed)
306
+ return;
307
+ closed = true;
308
+ callbacks.onClose();
309
+ });
310
+ resolve({
311
+ send: (message) => {
312
+ if (!closed)
313
+ socket.write(encodeSessionMessage(message));
314
+ },
315
+ close: () => {
316
+ if (closed)
317
+ return;
318
+ closed = true;
319
+ socket.destroy();
320
+ },
321
+ });
322
+ });
323
+ request.on("response", (response) => {
324
+ if (response.statusCode === 409 || response.statusCode === 410) {
325
+ this.dropLease(instanceId);
326
+ }
327
+ const error = new Error(`tunnel refused: HTTP ${response.statusCode}`);
328
+ error.code = "ECONNREFUSED"; // nothing executed — safe to recreate and retry
329
+ reject(error);
330
+ });
331
+ request.on("error", (error) => {
332
+ error.code ??= "ECONNREFUSED";
333
+ reject(error);
334
+ });
335
+ request.end();
336
+ });
337
+ }
338
+ tlsOptions() {
339
+ if (this.tls)
340
+ return this.tls;
341
+ if (!this.settings.certFile || !this.settings.keyFile) {
342
+ throw new SandboxError(`Error: gondolin remote worker '${this.settings.name ?? this.settings.url}' needs certFile and keyFile`);
343
+ }
344
+ this.tls = {
345
+ ...(this.settings.caFile ? { ca: readFileSync(this.settings.caFile) } : {}),
346
+ cert: readFileSync(this.settings.certFile),
347
+ key: readFileSync(this.settings.keyFile),
348
+ };
349
+ return this.tls;
350
+ }
351
+ }
352
+ //# sourceMappingURL=gondolin-remote.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gondolin-remote.js","sourceRoot":"","sources":["../../src/sandbox/gondolin-remote.ts"],"names":[],"mappings":"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","sourcesContent":["import { readFileSync, statSync } from \"node:fs\";\nimport { request as httpsRequest } from \"node:https\";\nimport { relative, isAbsolute, join } from \"node:path\";\nimport * as log from \"../log.js\";\nimport type { GondolinRemoteWorkerSettings } from \"../types.js\";\nimport { SandboxError } from \"./errors.js\";\nimport {\n GondolinRuntimeGoneError,\n execOverSessionConnect,\n type GondolinRuntimeHandle,\n type GondolinRuntimeSpec,\n type SessionClient,\n type SessionClientCallbacks,\n} from \"./gondolin-worker-client.js\";\nimport type { ExecResult } from \"./types.js\";\n\nconst LEASE_TTL_SECONDS = 300;\nconst REQUEST_TIMEOUT_MS = 15_000;\n/** VM boot happens inside this request; the daemon's own handshake cap is 2 min. */\nconst ENSURE_TIMEOUT_MS = 150_000;\n\ninterface RemoteLease {\n leaseId: string;\n epoch: number;\n renewTimer: NodeJS.Timeout;\n}\n\ninterface RemoteResponse {\n status: number;\n json: Record<string, unknown>;\n}\n\n/** A request that never reached the daemon (network/TLS/timeout failure). */\nexport class GondolinWorkerUnreachableError extends Error {}\n\nexport interface GondolinRemoteOverrides {\n request?: (\n method: string,\n path: string,\n body?: object,\n headers?: Record<string, string>,\n ) => Promise<RemoteResponse>;\n tunnel?: (\n path: string,\n headers: Record<string, string>,\n callbacks: SessionClientCallbacks,\n ) => SessionClient | Promise<SessionClient>;\n leaseTtlSeconds?: number;\n requestTimeoutMs?: number;\n /** Reports lease grants/renewals so the fleet can persist fencing watermarks. */\n onLeaseActivity?: (instanceId: string, expiresAtMs: number) => void;\n}\n\n/** Parses the daemon-to-client session framing: u8 type + u32be length + payload. */\nexport function createSessionFrameParser(\n callbacks: SessionClientCallbacks,\n): (chunk: Buffer) => void {\n let buffer = Buffer.alloc(0);\n return (chunk: Buffer) => {\n buffer = Buffer.concat([buffer, chunk]);\n while (buffer.length >= 5) {\n const type = buffer.readUInt8(0);\n const length = buffer.readUInt32BE(1);\n if (buffer.length < 5 + length) return;\n const payload = buffer.subarray(5, 5 + length);\n buffer = buffer.subarray(5 + length);\n if (type === 1) {\n callbacks.onBinary(Buffer.from(payload));\n continue;\n }\n try {\n callbacks.onJson(JSON.parse(payload.toString(\"utf8\")));\n } catch {\n // ignore malformed frames\n }\n }\n };\n}\n\n/** Encodes a client-to-daemon session message: u32be length + JSON. */\nexport function encodeSessionMessage(message: object): Buffer {\n const payload = Buffer.from(JSON.stringify(message));\n const header = Buffer.alloc(4);\n header.writeUInt32BE(payload.length, 0);\n return Buffer.concat([header, payload]);\n}\n\n/**\n * One mikan-worker daemon as seen from mikan: mTLS requests, per-instance\n * fenced leases with heartbeat renewal, and per-command upgraded tunnels.\n * Commands travel through one tunnel each, so abort semantics match the local\n * transport exactly.\n */\nexport class GondolinRemoteConnection {\n private readonly leases = new Map<string, RemoteLease>();\n private readonly leaseTtlSeconds: number;\n private readonly requestTimeoutMs: number;\n private tls?: { ca?: Buffer; cert: Buffer; key: Buffer };\n\n constructor(\n private readonly settings: GondolinRemoteWorkerSettings,\n private readonly overrides: GondolinRemoteOverrides = {},\n ) {\n this.leaseTtlSeconds = overrides.leaseTtlSeconds ?? LEASE_TTL_SECONDS;\n this.requestTimeoutMs = overrides.requestTimeoutMs ?? REQUEST_TIMEOUT_MS;\n }\n\n /** Drop lease timers and caches (does not touch the daemon). */\n dispose(): void {\n for (const lease of this.leases.values()) clearInterval(lease.renewTimer);\n this.leases.clear();\n }\n\n async health(): Promise<Record<string, unknown>> {\n const response = await this.request(\"GET\", \"/v1/health\");\n if (response.status !== 200) {\n throw new SandboxError(\n `Error: gondolin remote worker health check failed (${response.status})`,\n );\n }\n return response.json;\n }\n\n async ensure(instanceId: string, spec: GondolinRuntimeSpec): Promise<GondolinRuntimeHandle> {\n const { mounts, credentialFiles } = this.translateMounts(spec);\n const body = {\n instanceId,\n imageSelector: spec.image,\n mounts,\n credentialFiles,\n cpus: spec.cpus ?? \"\",\n memory: spec.memory ?? \"\",\n fingerprint: spec.fingerprint,\n };\n const idempotencyKey = `${instanceId}:${spec.fingerprint}:${Date.now()}`;\n for (let attempt = 0; ; attempt += 1) {\n const lease = await this.leaseFor(instanceId);\n const response = await this.request(\n \"POST\",\n \"/v1/runtimes\",\n body,\n { ...this.leaseHeaders(lease), \"Idempotency-Key\": idempotencyKey },\n ENSURE_TIMEOUT_MS,\n );\n if (response.status === 200) {\n return {\n sessionId: response.json.sessionId as string,\n instanceId,\n socketPath: \"\",\n workerPid: (response.json.workerPid as number) ?? 0,\n fingerprint: spec.fingerprint,\n };\n }\n if ((response.status === 409 || response.status === 410) && attempt === 0) {\n this.dropLease(instanceId);\n continue;\n }\n throw new SandboxError(\n `Error: remote worker refused runtime (${response.status}): ${String(response.json.message ?? \"\")}`,\n );\n }\n }\n\n async stop(\n handle: Pick<GondolinRuntimeHandle, \"workerPid\" | \"sessionId\" | \"instanceId\">,\n ): Promise<void> {\n const lease = await this.leaseFor(handle.instanceId);\n const response = await this.request(\n \"DELETE\",\n `/v1/runtimes/${handle.sessionId}`,\n undefined,\n this.leaseHeaders(lease),\n );\n if (response.status === 409 || response.status === 410) {\n this.dropLease(handle.instanceId);\n }\n this.releaseLease(handle.instanceId);\n }\n\n async isRuntimeAlive(handle: GondolinRuntimeHandle): Promise<boolean> {\n try {\n const response = await this.request(\"GET\", `/v1/runtimes/${handle.sessionId}`);\n return response.status === 200;\n } catch {\n return false;\n }\n }\n\n /** Live runtimes hosted by this worker (fleet reconciliation). */\n async listRuntimes(): Promise<Array<{ sessionId: string; instanceId: string }>> {\n const response = await this.request(\"GET\", \"/v1/runtimes\");\n if (response.status !== 200) return [];\n const runtimes = response.json.runtimes;\n return Array.isArray(runtimes)\n ? (runtimes as Array<{ sessionId: string; instanceId: string }>)\n : [];\n }\n\n async exec(\n handle: GondolinRuntimeHandle,\n command: string,\n options: { env?: Record<string, string>; signal?: AbortSignal } = {},\n ): Promise<ExecResult> {\n const lease = this.leases.get(handle.instanceId);\n if (!lease) {\n // the lease lapsed (e.g. mikan slept); recreate the session cleanly\n throw new GondolinRuntimeGoneError(\"no live lease for this runtime\");\n }\n return execOverSessionConnect(\n (callbacks) =>\n this.openTunnel(\n handle.instanceId,\n `/v1/runtimes/${handle.sessionId}/session`,\n this.leaseHeaders(lease),\n callbacks,\n ),\n command,\n options,\n );\n }\n\n /**\n * Split mounts for the remote worker:\n * - sources under the mikan-host workspace are translated to the worker's\n * shared `workspaceRoot` (shared POSIX storage), and\n * - sources outside it that are files (vault credentials, which live in the\n * host state dir, not the shared workspace) are read and shipped as\n * content payloads for the worker to project into the guest.\n * A non-file source outside the workspace has nowhere to go and is dropped.\n */\n private translateMounts(spec: GondolinRuntimeSpec): {\n mounts: Array<{ source: string; target: string }>;\n credentialFiles: Array<{ target: string; contentBase64: string }>;\n } {\n const root = this.settings.workspaceRoot;\n if (!root || !spec.workspacePath) {\n return { mounts: spec.mounts, credentialFiles: [] };\n }\n const mounts: Array<{ source: string; target: string }> = [];\n const credentialFiles: Array<{ target: string; contentBase64: string }> = [];\n for (const mount of spec.mounts) {\n const suffix = relative(spec.workspacePath, mount.source);\n if (!suffix.startsWith(\"..\") && !isAbsolute(suffix)) {\n mounts.push({ source: join(root, suffix), target: mount.target });\n continue;\n }\n try {\n if (!statSync(mount.source).isFile()) {\n log.logWarning(\n `Skipping directory mount outside the shared workspace for remote runtime: ${mount.source}`,\n );\n continue;\n }\n credentialFiles.push({\n target: mount.target,\n contentBase64: readFileSync(mount.source).toString(\"base64\"),\n });\n } catch {\n // missing source: skip, matching the local worker's behavior\n }\n }\n return { mounts, credentialFiles };\n }\n\n private async leaseFor(instanceId: string): Promise<RemoteLease> {\n const cached = this.leases.get(instanceId);\n if (cached) return cached;\n const response = await this.request(\"POST\", \"/v1/leases\", {\n instanceId,\n ttlSeconds: this.leaseTtlSeconds,\n });\n if (response.status !== 200) {\n throw new SandboxError(\n `Error: remote worker refused lease (${response.status}): ${String(response.json.message ?? \"\")}`,\n );\n }\n const lease: RemoteLease = {\n leaseId: response.json.id as string,\n epoch: response.json.epoch as number,\n renewTimer: setInterval(() => void this.renew(instanceId), (this.leaseTtlSeconds * 1000) / 3),\n };\n lease.renewTimer.unref?.();\n this.leases.set(instanceId, lease);\n this.reportLeaseActivity(instanceId);\n return lease;\n }\n\n private async renew(instanceId: string): Promise<void> {\n const lease = this.leases.get(instanceId);\n if (!lease) return;\n try {\n const response = await this.request(\"POST\", `/v1/leases/${lease.leaseId}/renew`, {\n ttlSeconds: this.leaseTtlSeconds,\n });\n if (response.status === 200) this.reportLeaseActivity(instanceId);\n else this.dropLease(instanceId);\n } catch (err) {\n log.logWarning(\n `Failed to renew remote worker lease for '${instanceId}'`,\n err instanceof Error ? err.message : String(err),\n );\n }\n }\n\n private reportLeaseActivity(instanceId: string): void {\n // fencing watermark by mikan's own clock: the worker-side lease cannot\n // outlive this moment plus its ttl, no matter whose clock is skewed\n this.overrides.onLeaseActivity?.(instanceId, Date.now() + this.leaseTtlSeconds * 1000);\n }\n\n private releaseLease(instanceId: string): void {\n const lease = this.leases.get(instanceId);\n if (!lease) return;\n this.dropLease(instanceId);\n void this.request(\"DELETE\", `/v1/leases/${lease.leaseId}`).catch(() => {});\n }\n\n private dropLease(instanceId: string): void {\n const lease = this.leases.get(instanceId);\n if (!lease) return;\n clearInterval(lease.renewTimer);\n this.leases.delete(instanceId);\n }\n\n private leaseHeaders(lease: RemoteLease): Record<string, string> {\n return { \"X-Mikan-Lease\": lease.leaseId, \"X-Mikan-Epoch\": String(lease.epoch) };\n }\n\n private request(\n method: string,\n path: string,\n body?: object,\n headers?: Record<string, string>,\n timeoutMs = this.requestTimeoutMs,\n ): Promise<RemoteResponse> {\n if (this.overrides.request) return this.overrides.request(method, path, body, headers);\n const url = new URL(path, this.settings.url);\n const payload = body === undefined ? undefined : Buffer.from(JSON.stringify(body));\n return new Promise((resolve, reject) => {\n const request = httpsRequest(\n {\n method,\n host: url.hostname,\n port: url.port,\n path: url.pathname + url.search,\n signal: AbortSignal.timeout(timeoutMs),\n headers: {\n ...(payload\n ? { \"Content-Type\": \"application/json\", \"Content-Length\": payload.length }\n : {}),\n ...headers,\n },\n ...this.tlsOptions(),\n },\n (response) => {\n let raw = \"\";\n response.setEncoding(\"utf8\");\n response.on(\"data\", (chunk: string) => {\n raw += chunk;\n });\n response.on(\"end\", () => {\n let json: Record<string, unknown> = {};\n try {\n json = raw ? (JSON.parse(raw) as Record<string, unknown>) : {};\n } catch {\n // non-JSON body; status carries the outcome\n }\n resolve({ status: response.statusCode ?? 0, json });\n });\n },\n );\n request.on(\"error\", (error: Error) =>\n reject(new GondolinWorkerUnreachableError(error.message)),\n );\n if (payload) request.write(payload);\n request.end();\n });\n }\n\n private openTunnel(\n instanceId: string,\n path: string,\n headers: Record<string, string>,\n callbacks: SessionClientCallbacks,\n ): SessionClient | Promise<SessionClient> {\n if (this.overrides.tunnel) return this.overrides.tunnel(path, headers, callbacks);\n const url = new URL(path, this.settings.url);\n return new Promise((resolve, reject) => {\n const request = httpsRequest({\n method: \"GET\",\n host: url.hostname,\n port: url.port,\n path: url.pathname,\n signal: AbortSignal.timeout(this.requestTimeoutMs),\n headers: { ...headers, Connection: \"Upgrade\", Upgrade: \"gondolin-session\" },\n ...this.tlsOptions(),\n });\n request.on(\"upgrade\", (_response, socket) => {\n socket.setNoDelay(true);\n let closed = false;\n const parse = createSessionFrameParser(callbacks);\n socket.on(\"data\", parse);\n socket.on(\"error\", (error: Error) => {\n if (closed) return;\n closed = true;\n callbacks.onClose(error);\n });\n socket.on(\"close\", () => {\n if (closed) return;\n closed = true;\n callbacks.onClose();\n });\n resolve({\n send: (message) => {\n if (!closed) socket.write(encodeSessionMessage(message));\n },\n close: () => {\n if (closed) return;\n closed = true;\n socket.destroy();\n },\n });\n });\n request.on(\"response\", (response) => {\n if (response.statusCode === 409 || response.statusCode === 410) {\n this.dropLease(instanceId);\n }\n const error = new Error(\n `tunnel refused: HTTP ${response.statusCode}`,\n ) as NodeJS.ErrnoException;\n error.code = \"ECONNREFUSED\"; // nothing executed — safe to recreate and retry\n reject(error);\n });\n request.on(\"error\", (error: NodeJS.ErrnoException) => {\n error.code ??= \"ECONNREFUSED\";\n reject(error);\n });\n request.end();\n });\n }\n\n private tlsOptions(): { ca?: Buffer; cert: Buffer; key: Buffer } {\n if (this.tls) return this.tls;\n if (!this.settings.certFile || !this.settings.keyFile) {\n throw new SandboxError(\n `Error: gondolin remote worker '${this.settings.name ?? this.settings.url}' needs certFile and keyFile`,\n );\n }\n this.tls = {\n ...(this.settings.caFile ? { ca: readFileSync(this.settings.caFile) } : {}),\n cert: readFileSync(this.settings.certFile),\n key: readFileSync(this.settings.keyFile),\n };\n return this.tls;\n }\n}\n"]}
@@ -0,0 +1,139 @@
1
+ import type { Readable } from "node:stream";
2
+ import type { GondolinWorkerConfig } from "./gondolin-worker.js";
3
+ import type { ExecResult } from "./types.js";
4
+ /** A live worker-hosted runtime as seen from mikan. */
5
+ export interface GondolinRuntimeHandle {
6
+ sessionId: string;
7
+ instanceId: string;
8
+ socketPath: string;
9
+ workerPid: number;
10
+ fingerprint: string;
11
+ /** Fleet identity of the worker hosting the runtime (remote transport). */
12
+ workerName?: string;
13
+ }
14
+ /**
15
+ * What a runtime should look like, resolved by the executor layer. `image` is
16
+ * a local asset directory for the local transport and an image selector for
17
+ * the remote one (resolved on the worker host).
18
+ */
19
+ export interface GondolinRuntimeSpec {
20
+ image: string;
21
+ mounts: Array<{
22
+ source: string;
23
+ target: string;
24
+ }>;
25
+ /** Raw fractional CPU limit (cgroup enforcement on remote Linux workers). */
26
+ cpus?: string;
27
+ /** Whole vCPUs given to the VM. */
28
+ vmCpus?: number;
29
+ memory?: string;
30
+ fingerprint: string;
31
+ /** mikan-host workspace root, for remote mount prefix translation. */
32
+ workspacePath?: string;
33
+ }
34
+ /** One way of running Gondolin runtimes: in local workers or on a remote fleet. */
35
+ export interface GondolinRuntimeTransport {
36
+ ensure(instanceId: string, spec: GondolinRuntimeSpec): Promise<GondolinRuntimeHandle>;
37
+ stop(handle: Pick<GondolinRuntimeHandle, "workerPid" | "sessionId" | "instanceId" | "workerName">): Promise<void>;
38
+ exec(handle: GondolinRuntimeHandle, command: string, options?: {
39
+ env?: Record<string, string>;
40
+ signal?: AbortSignal;
41
+ }): Promise<ExecResult>;
42
+ isRuntimeAlive(handle: GondolinRuntimeHandle): Promise<boolean>;
43
+ }
44
+ /**
45
+ * The runtime is gone and the command never reached it (the session socket
46
+ * refused the connection) — safe to recreate the runtime and retry.
47
+ */
48
+ export declare class GondolinRuntimeGoneError extends Error {
49
+ }
50
+ /** The runtime died with the command in flight — not safe to retry blindly. */
51
+ export declare class GondolinRuntimeInterruptedError extends Error {
52
+ }
53
+ interface WorkerProcessLike {
54
+ pid?: number;
55
+ stdout: Readable | null;
56
+ stderr: Readable | null;
57
+ once(event: "close", listener: (code: number | null) => void): unknown;
58
+ once(event: "error", listener: (error: Error) => void): unknown;
59
+ kill(signal?: NodeJS.Signals): boolean;
60
+ unref(): void;
61
+ }
62
+ export interface SessionClientCallbacks {
63
+ onJson: (message: {
64
+ type: string;
65
+ id?: number;
66
+ exit_code?: number | null;
67
+ code?: string;
68
+ message?: string;
69
+ }) => void;
70
+ onBinary: (frame: Buffer) => void;
71
+ onClose: (error?: Error) => void;
72
+ }
73
+ export interface SessionClient {
74
+ send(message: object): void;
75
+ close(): void;
76
+ }
77
+ interface GondolinWorkerClientOverrides {
78
+ spawnProcess?: (command: string, args: string[]) => WorkerProcessLike;
79
+ connect?: (socketPath: string, callbacks: SessionClientCallbacks) => SessionClient;
80
+ kill?: (pid: number, signal: NodeJS.Signals | 0) => void;
81
+ handshakeTimeoutMs?: number;
82
+ stopWaitMs?: number;
83
+ stopPollIntervalMs?: number;
84
+ }
85
+ /**
86
+ * Run one command through a fresh session connection — the shared state
87
+ * machine for both transports. Closing the connection (abort, timeout, or the
88
+ * far side dying) kills the in-flight guest process.
89
+ */
90
+ export declare function execOverSessionConnect(connect: (callbacks: SessionClientCallbacks) => SessionClient | Promise<SessionClient>, command: string, options?: {
91
+ env?: Record<string, string>;
92
+ signal?: AbortSignal;
93
+ idleTimeoutMs?: number;
94
+ }): Promise<ExecResult>;
95
+ declare class GondolinWorkerClient implements GondolinRuntimeTransport {
96
+ private spawnProcess;
97
+ private connectImpl;
98
+ private killImpl;
99
+ private handshakeTimeoutMs;
100
+ private stopWaitMs;
101
+ private stopPollIntervalMs;
102
+ configure(overrides?: GondolinWorkerClientOverrides): void;
103
+ /** Adopt a surviving local worker or spawn a fresh one for the spec. */
104
+ ensure(instanceId: string, spec: GondolinRuntimeSpec): Promise<GondolinRuntimeHandle>;
105
+ /** Whether the runtime's worker process is still alive. */
106
+ isRuntimeAlive(handle: GondolinRuntimeHandle): Promise<boolean>;
107
+ /** Spawn a detached worker for the config and wait for its ready handshake. */
108
+ spawn(config: GondolinWorkerConfig): Promise<GondolinRuntimeHandle>;
109
+ /**
110
+ * Adopt a runtime a previous mikan left running: newest live record for the
111
+ * key whose fingerprint still matches and whose session answers a probe.
112
+ * Anything stale — drifted fingerprint, unresponsive session — is stopped so
113
+ * the caller can spawn fresh.
114
+ */
115
+ adopt(instanceId: string, fingerprint: string): Promise<GondolinRuntimeHandle | undefined>;
116
+ /**
117
+ * Stop a worker and wait for it to clean up after itself; escalate to
118
+ * SIGKILL and reap its leftovers if it will not die.
119
+ */
120
+ stop(handle: Pick<GondolinRuntimeHandle, "workerPid" | "sessionId">): Promise<void>;
121
+ /** Whether the worker process behind a handle is still alive. */
122
+ isWorkerAlive(handle: Pick<GondolinRuntimeHandle, "workerPid">): boolean;
123
+ /**
124
+ * Run one command over a dedicated session IPC connection. Aborting (or the
125
+ * caller's timeout signal firing) destroys the connection, which kills the
126
+ * in-flight guest process.
127
+ */
128
+ exec(handle: GondolinRuntimeHandle, command: string, options?: {
129
+ env?: Record<string, string>;
130
+ signal?: AbortSignal;
131
+ }): Promise<ExecResult>;
132
+ private signal;
133
+ private isPidAlive;
134
+ private waitForExit;
135
+ private readHandshake;
136
+ }
137
+ export declare const gondolinWorkers: GondolinWorkerClient;
138
+ export {};
139
+ //# sourceMappingURL=gondolin-worker-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gondolin-worker-client.d.ts","sourceRoot":"","sources":["../../src/sandbox/gondolin-worker-client.ts"],"names":[],"mappings":"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"}