@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,201 @@
1
+ import { createHash } from "node:crypto";
2
+ import { chmodSync, readFileSync, renameSync, statSync, writeFileSync } from "node:fs";
3
+ import { dirname } from "node:path";
4
+ import { gondolinInventory } from "./gondolin-inventory.js";
5
+ import { shellEscape } from "./utils.js";
6
+ function sha256(data) {
7
+ return createHash("sha256").update(data).digest("hex");
8
+ }
9
+ function warn(message) {
10
+ process.stderr.write(`[gondolin-worker] ${message}\n`);
11
+ }
12
+ function heartbeatFresh(path, since, staleMs) {
13
+ let mtimeMs = 0;
14
+ try {
15
+ mtimeMs = statSync(path).mtimeMs;
16
+ }
17
+ catch {
18
+ // no heartbeat yet — fall back to worker start time
19
+ }
20
+ return Date.now() - Math.max(mtimeMs, since) <= staleMs;
21
+ }
22
+ function restrictSocketAccess(socketPath) {
23
+ // The session socket grants arbitrary exec inside the VM (and through its
24
+ // mounts, the workspace) — keep it to this user even under a lax umask.
25
+ try {
26
+ chmodSync(dirname(socketPath), 0o700);
27
+ chmodSync(socketPath, 0o600);
28
+ }
29
+ catch {
30
+ // best-effort hardening
31
+ }
32
+ }
33
+ function partitionMounts(mounts) {
34
+ const directories = [];
35
+ const files = [];
36
+ for (const mount of mounts) {
37
+ let isDirectory;
38
+ try {
39
+ isDirectory = statSync(mount.source).isDirectory();
40
+ }
41
+ catch {
42
+ warn(`skipping missing mount source ${mount.source}`);
43
+ continue;
44
+ }
45
+ if (isDirectory) {
46
+ directories.push(mount);
47
+ }
48
+ else {
49
+ files.push({
50
+ ...mount,
51
+ syncBack: mount.target.startsWith("/workspace/"),
52
+ lastHash: "",
53
+ });
54
+ }
55
+ }
56
+ return { directories, files };
57
+ }
58
+ /**
59
+ * Host one Gondolin VM for its whole life: boot it, persist the inventory
60
+ * record other processes adopt it through, announce readiness on stdout, then
61
+ * watch the VM runner and shut down when it dies, when a SIGTERM arrives, or
62
+ * when every mikan that could adopt the runtime is gone (stale heartbeat).
63
+ */
64
+ export async function runGondolinWorker(config, deps = {}) {
65
+ const announce = deps.announce ?? ((line) => process.stdout.write(line + "\n"));
66
+ const exit = deps.exit ?? ((code) => process.exit(code));
67
+ const pollIntervalMs = deps.pollIntervalMs ?? 2000;
68
+ const loadGondolin = deps.loadGondolin ?? (() => import("@earendil-works/gondolin"));
69
+ gondolinInventory.configure(config.inventoryDir);
70
+ const { VM, RealFSProvider, findSession, ensureImageSelector } = await loadGondolin();
71
+ let imagePath = config.image;
72
+ if (!imagePath) {
73
+ if (!config.imageSelector)
74
+ throw new Error("worker config needs image or imageSelector");
75
+ imagePath = (await ensureImageSelector(config.imageSelector)).assetDir;
76
+ }
77
+ const { directories, files } = partitionMounts(config.mounts);
78
+ const vm = await VM.create({
79
+ sandbox: { imagePath },
80
+ env: { TZ: "Asia/Taipei" },
81
+ sessionLabel: `mikan:${config.instanceId}`,
82
+ cpus: config.cpus,
83
+ memory: config.memory,
84
+ vfs: {
85
+ mounts: Object.fromEntries(directories.map(({ source, target }) => [target, new RealFSProvider(source)])),
86
+ },
87
+ });
88
+ let session;
89
+ try {
90
+ await vm.start();
91
+ await projectFiles(vm, files);
92
+ session = await findSession(vm.id);
93
+ if (!session)
94
+ throw new Error(`Gondolin session '${vm.id}' did not register`);
95
+ }
96
+ catch (error) {
97
+ // never leave a half-booted runner (and its overlay disk) behind
98
+ await vm.close().catch(() => { });
99
+ throw error;
100
+ }
101
+ restrictSocketAccess(session.socketPath);
102
+ gondolinInventory.record({
103
+ sessionId: vm.id,
104
+ instanceId: config.instanceId,
105
+ runnerPid: vm.getHostPid(),
106
+ socketPath: session.socketPath,
107
+ fingerprint: config.fingerprint,
108
+ });
109
+ const startedAt = Date.now();
110
+ let closing = false;
111
+ let syncing = false;
112
+ const syncProjections = async () => {
113
+ if (syncing)
114
+ return;
115
+ syncing = true;
116
+ try {
117
+ for (const projection of files) {
118
+ if (!projection.syncBack)
119
+ continue;
120
+ try {
121
+ const data = await vm.fs.readFile(projection.target);
122
+ const content = Buffer.isBuffer(data) ? data : Buffer.from(String(data));
123
+ const hash = sha256(content);
124
+ if (hash === projection.lastHash)
125
+ continue;
126
+ // atomic host write: a crash mid-sync must not truncate the file
127
+ const staged = `${projection.source}.mikan-sync`;
128
+ writeFileSync(staged, content);
129
+ renameSync(staged, projection.source);
130
+ projection.lastHash = hash;
131
+ }
132
+ catch {
133
+ // guest file missing or read raced a writer; next tick retries
134
+ }
135
+ }
136
+ }
137
+ finally {
138
+ syncing = false;
139
+ }
140
+ };
141
+ const shutdown = async (code) => {
142
+ if (closing)
143
+ return;
144
+ closing = true;
145
+ clearInterval(watchdog);
146
+ try {
147
+ await syncProjections();
148
+ }
149
+ catch {
150
+ // best effort; the periodic sync already captured earlier edits
151
+ }
152
+ try {
153
+ await vm.close();
154
+ }
155
+ catch {
156
+ // the runner may already be gone
157
+ }
158
+ gondolinInventory.release(vm.id);
159
+ exit(code);
160
+ };
161
+ const watchdog = setInterval(() => {
162
+ const runnerPid = vm.getHostPid();
163
+ if (runnerPid === null) {
164
+ // The VM runner died under us; exit so mikan sees the socket close and
165
+ // recreates the runtime instead of hanging on a silent session.
166
+ void shutdown(1);
167
+ return;
168
+ }
169
+ gondolinInventory.refresh(vm.id, runnerPid);
170
+ void syncProjections();
171
+ const heartbeat = gondolinInventory.heartbeatPath();
172
+ if (config.heartbeatStaleMs > 0 &&
173
+ heartbeat &&
174
+ !heartbeatFresh(heartbeat, startedAt, config.heartbeatStaleMs)) {
175
+ void shutdown(0);
176
+ }
177
+ }, pollIntervalMs);
178
+ process.on("SIGTERM", () => void shutdown(0));
179
+ process.on("SIGINT", () => void shutdown(0));
180
+ announce(JSON.stringify({
181
+ ready: true,
182
+ sessionId: vm.id,
183
+ socketPath: session.socketPath,
184
+ workerPid: process.pid,
185
+ runnerPid: vm.getHostPid(),
186
+ }));
187
+ }
188
+ /** Copy file mounts into the guest; credentials get user-only permissions. */
189
+ async function projectFiles(vm, files) {
190
+ for (const projection of files) {
191
+ const content = readFileSync(projection.source);
192
+ await vm.fs.mkdir(dirname(projection.target), { recursive: true });
193
+ await vm.fs.writeFile(projection.target, content);
194
+ if (!projection.syncBack) {
195
+ // credential projection: no write-back, keep it owner-only
196
+ await vm.exec(`chmod 600 ${shellEscape(projection.target)}`);
197
+ }
198
+ projection.lastHash = sha256(content);
199
+ }
200
+ }
201
+ //# sourceMappingURL=gondolin-worker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gondolin-worker.js","sourceRoot":"","sources":["../../src/sandbox/gondolin-worker.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash } from \"node:crypto\";\nimport { chmodSync, readFileSync, renameSync, statSync, writeFileSync } from \"node:fs\";\nimport { dirname } from \"node:path\";\nimport { gondolinInventory } from \"./gondolin-inventory.js\";\nimport { shellEscape } from \"./utils.js\";\n\ntype GondolinModule = typeof import(\"@earendil-works/gondolin\");\n\n/**\n * Everything a worker process needs to host one Gondolin VM. Serialized as a\n * single JSON argv entry — it must stay free of secrets (vault env travels\n * per-exec over the session IPC socket, never through the worker command\n * line).\n */\nexport interface GondolinWorkerConfig {\n /** mikan session key the runtime belongs to. */\n instanceId: string;\n /** Resolved guest image asset directory. */\n image?: string;\n /** Image selector resolved inside the worker (remote workers, where the\n * spawning host has no image store). Ignored when `image` is set. */\n imageSelector?: string;\n mounts: Array<{ source: string; target: string }>;\n cpus?: number;\n memory?: string;\n /** Desired-runtime fingerprint recorded for adoption checks. */\n fingerprint: string;\n /** Runtime inventory directory (shared with the spawning mikan). */\n inventoryDir: string;\n /**\n * Self-stop when the mikan heartbeat file is older than this — no mikan is\n * left to adopt the runtime. 0 disables the check.\n */\n heartbeatStaleMs: number;\n}\n\n/** First stdout line of a worker, consumed by the spawning mikan. */\nexport interface GondolinWorkerHandshake {\n ready: boolean;\n error?: string;\n sessionId?: string;\n socketPath?: string;\n workerPid?: number;\n runnerPid?: number | null;\n}\n\ninterface GondolinWorkerDeps {\n loadGondolin?: () => Promise<GondolinModule>;\n announce?: (line: string) => void;\n exit?: (code: number) => void;\n pollIntervalMs?: number;\n}\n\n/**\n * A single-file mount handled outside the VFS: Gondolin's guest prepares every\n * VFS mount point with `mkdir -p`, so a file target can never bind (the guest\n * ends up bind-mounting a file onto a directory and the VM refuses to start).\n * Files are copied in after boot instead; the ones under /workspace sync guest\n * edits back to the host so agent-maintained files like MEMORY.md persist.\n */\ninterface FileProjection {\n source: string;\n target: string;\n syncBack: boolean;\n lastHash: string;\n}\n\nfunction sha256(data: Buffer): string {\n return createHash(\"sha256\").update(data).digest(\"hex\");\n}\n\nfunction warn(message: string): void {\n process.stderr.write(`[gondolin-worker] ${message}\\n`);\n}\n\nfunction heartbeatFresh(path: string, since: number, staleMs: number): boolean {\n let mtimeMs = 0;\n try {\n mtimeMs = statSync(path).mtimeMs;\n } catch {\n // no heartbeat yet — fall back to worker start time\n }\n return Date.now() - Math.max(mtimeMs, since) <= staleMs;\n}\n\nfunction restrictSocketAccess(socketPath: string): void {\n // The session socket grants arbitrary exec inside the VM (and through its\n // mounts, the workspace) — keep it to this user even under a lax umask.\n try {\n chmodSync(dirname(socketPath), 0o700);\n chmodSync(socketPath, 0o600);\n } catch {\n // best-effort hardening\n }\n}\n\nfunction partitionMounts(mounts: GondolinWorkerConfig[\"mounts\"]): {\n directories: GondolinWorkerConfig[\"mounts\"];\n files: FileProjection[];\n} {\n const directories: GondolinWorkerConfig[\"mounts\"] = [];\n const files: FileProjection[] = [];\n for (const mount of mounts) {\n let isDirectory: boolean;\n try {\n isDirectory = statSync(mount.source).isDirectory();\n } catch {\n warn(`skipping missing mount source ${mount.source}`);\n continue;\n }\n if (isDirectory) {\n directories.push(mount);\n } else {\n files.push({\n ...mount,\n syncBack: mount.target.startsWith(\"/workspace/\"),\n lastHash: \"\",\n });\n }\n }\n return { directories, files };\n}\n\n/**\n * Host one Gondolin VM for its whole life: boot it, persist the inventory\n * record other processes adopt it through, announce readiness on stdout, then\n * watch the VM runner and shut down when it dies, when a SIGTERM arrives, or\n * when every mikan that could adopt the runtime is gone (stale heartbeat).\n */\nexport async function runGondolinWorker(\n config: GondolinWorkerConfig,\n deps: GondolinWorkerDeps = {},\n): Promise<void> {\n const announce = deps.announce ?? ((line: string) => process.stdout.write(line + \"\\n\"));\n const exit = deps.exit ?? ((code: number) => process.exit(code));\n const pollIntervalMs = deps.pollIntervalMs ?? 2000;\n const loadGondolin =\n deps.loadGondolin ?? (() => import(\"@earendil-works/gondolin\") as Promise<GondolinModule>);\n\n gondolinInventory.configure(config.inventoryDir);\n const { VM, RealFSProvider, findSession, ensureImageSelector } = await loadGondolin();\n let imagePath = config.image;\n if (!imagePath) {\n if (!config.imageSelector) throw new Error(\"worker config needs image or imageSelector\");\n imagePath = (await ensureImageSelector(config.imageSelector)).assetDir;\n }\n const { directories, files } = partitionMounts(config.mounts);\n const vm = await VM.create({\n sandbox: { imagePath },\n env: { TZ: \"Asia/Taipei\" },\n sessionLabel: `mikan:${config.instanceId}`,\n cpus: config.cpus,\n memory: config.memory,\n vfs: {\n mounts: Object.fromEntries(\n directories.map(({ source, target }) => [target, new RealFSProvider(source)]),\n ),\n },\n });\n\n let session: Awaited<ReturnType<typeof findSession>>;\n try {\n await vm.start();\n await projectFiles(vm, files);\n session = await findSession(vm.id);\n if (!session) throw new Error(`Gondolin session '${vm.id}' did not register`);\n } catch (error) {\n // never leave a half-booted runner (and its overlay disk) behind\n await vm.close().catch(() => {});\n throw error;\n }\n restrictSocketAccess(session.socketPath);\n gondolinInventory.record({\n sessionId: vm.id,\n instanceId: config.instanceId,\n runnerPid: vm.getHostPid(),\n socketPath: session.socketPath,\n fingerprint: config.fingerprint,\n });\n\n const startedAt = Date.now();\n let closing = false;\n let syncing = false;\n const syncProjections = async (): Promise<void> => {\n if (syncing) return;\n syncing = true;\n try {\n for (const projection of files) {\n if (!projection.syncBack) continue;\n try {\n const data = await vm.fs.readFile(projection.target);\n const content = Buffer.isBuffer(data) ? data : Buffer.from(String(data));\n const hash = sha256(content);\n if (hash === projection.lastHash) continue;\n // atomic host write: a crash mid-sync must not truncate the file\n const staged = `${projection.source}.mikan-sync`;\n writeFileSync(staged, content);\n renameSync(staged, projection.source);\n projection.lastHash = hash;\n } catch {\n // guest file missing or read raced a writer; next tick retries\n }\n }\n } finally {\n syncing = false;\n }\n };\n\n const shutdown = async (code: number): Promise<void> => {\n if (closing) return;\n closing = true;\n clearInterval(watchdog);\n try {\n await syncProjections();\n } catch {\n // best effort; the periodic sync already captured earlier edits\n }\n try {\n await vm.close();\n } catch {\n // the runner may already be gone\n }\n gondolinInventory.release(vm.id);\n exit(code);\n };\n\n const watchdog = setInterval(() => {\n const runnerPid = vm.getHostPid();\n if (runnerPid === null) {\n // The VM runner died under us; exit so mikan sees the socket close and\n // recreates the runtime instead of hanging on a silent session.\n void shutdown(1);\n return;\n }\n gondolinInventory.refresh(vm.id, runnerPid);\n void syncProjections();\n const heartbeat = gondolinInventory.heartbeatPath();\n if (\n config.heartbeatStaleMs > 0 &&\n heartbeat &&\n !heartbeatFresh(heartbeat, startedAt, config.heartbeatStaleMs)\n ) {\n void shutdown(0);\n }\n }, pollIntervalMs);\n\n process.on(\"SIGTERM\", () => void shutdown(0));\n process.on(\"SIGINT\", () => void shutdown(0));\n\n announce(\n JSON.stringify({\n ready: true,\n sessionId: vm.id,\n socketPath: session.socketPath,\n workerPid: process.pid,\n runnerPid: vm.getHostPid(),\n } satisfies GondolinWorkerHandshake),\n );\n}\n\n/** Copy file mounts into the guest; credentials get user-only permissions. */\nasync function projectFiles(\n vm: {\n fs: {\n mkdir: (path: string, options?: { recursive?: boolean }) => Promise<void>;\n writeFile: (path: string, data: Buffer) => Promise<void>;\n };\n exec: (command: string) => PromiseLike<unknown>;\n },\n files: FileProjection[],\n): Promise<void> {\n for (const projection of files) {\n const content = readFileSync(projection.source);\n await vm.fs.mkdir(dirname(projection.target), { recursive: true });\n await vm.fs.writeFile(projection.target, content);\n if (!projection.syncBack) {\n // credential projection: no write-back, keep it owner-only\n await vm.exec(`chmod 600 ${shellEscape(projection.target)}`);\n }\n projection.lastHash = sha256(content);\n }\n}\n"]}
@@ -0,0 +1,52 @@
1
+ import type { ResourceLimits, SandboxLimitStatus, SandboxResourceController } from "../types.js";
2
+ import type { ExecOptions, ExecResult, Executor, GondolinSandboxConfig, RuntimePathContext, SandboxAdapter } from "./types.js";
3
+ declare class GondolinResourceManager implements SandboxResourceController {
4
+ private defaultLimits?;
5
+ private boostLimits?;
6
+ private readonly boostedKeys;
7
+ private readonly overrideLimits;
8
+ configure(defaultLimits?: ResourceLimits, boostLimits?: ResourceLimits): void;
9
+ boost(key: string): Promise<SandboxLimitStatus>;
10
+ setLimits(key: string, limits: ResourceLimits): Promise<SandboxLimitStatus>;
11
+ getLimitStatus(key: string): SandboxLimitStatus;
12
+ getDefaultLimits(): ResourceLimits | undefined;
13
+ getBoostLimits(): ResourceLimits | undefined;
14
+ clear(key: string): void;
15
+ private effectiveLimits;
16
+ }
17
+ export declare const gondolinResources: GondolinResourceManager;
18
+ /**
19
+ * Fail fast when `gondolin:remote` is selected but no worker source is
20
+ * configured. Call after the fleet and gateway have been configured.
21
+ */
22
+ export declare function assertRemoteConfigured(): void;
23
+ export declare function stopIdleGondolinVms(maxIdleMs: number, now?: number): Promise<void>;
24
+ /**
25
+ * Stop workers surviving from a previous mikan that no conversation has
26
+ * adopted — without this, a runtime whose conversation went quiet before the
27
+ * restart would idle forever (its worker only self-stops when every mikan is
28
+ * gone, and the in-memory idle sweep only tracks acquired sessions).
29
+ */
30
+ export declare function sweepUnadoptedGondolinWorkers(): Promise<void>;
31
+ /**
32
+ * Forget every session without stopping the workers: runtimes deliberately
33
+ * outlive the mikan process so the next one adopts them instead of paying a
34
+ * VM boot per conversation on every deploy.
35
+ */
36
+ export declare function disconnectAllGondolinRuntimes(): Promise<void>;
37
+ export declare class GondolinExecutor implements Executor {
38
+ private readonly config;
39
+ private readonly env?;
40
+ private readonly workspacePath;
41
+ private readonly instanceId;
42
+ constructor(config: GondolinSandboxConfig, env?: Record<string, string> | undefined);
43
+ exec(command: string, options?: ExecOptions): Promise<ExecResult>;
44
+ readFile(path: string): Promise<string>;
45
+ writeFile(path: string, content: string): Promise<void>;
46
+ getWorkspacePath(): string;
47
+ getPathContext(hostWorkspaceRoot: string): RuntimePathContext;
48
+ getSandboxConfig(): GondolinSandboxConfig;
49
+ }
50
+ export declare const gondolinSandboxAdapter: SandboxAdapter<GondolinSandboxConfig>;
51
+ export {};
52
+ //# sourceMappingURL=gondolin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gondolin.d.ts","sourceRoot":"","sources":["../../src/sandbox/gondolin.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,kBAAkB,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;AAejG,OAAO,KAAK,EACV,WAAW,EACX,UAAU,EACV,QAAQ,EACR,qBAAqB,EACrB,kBAAkB,EAClB,cAAc,EACf,MAAM,YAAY,CAAC;AA8BpB,cAAM,uBAAwB,YAAW,yBAAyB;IAChE,OAAO,CAAC,aAAa,CAAC,CAAiB;IACvC,OAAO,CAAC,WAAW,CAAC,CAAiB;IACrC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAqB;IACjD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAqC;IAEpE,SAAS,CAAC,aAAa,CAAC,EAAE,cAAc,EAAE,WAAW,CAAC,EAAE,cAAc,GAAG,IAAI,CAK5E;IAEK,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAMpD;IAEK,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAIhF;IAED,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,kBAAkB,CAE9C;IAED,gBAAgB,IAAI,cAAc,GAAG,SAAS,CAE7C;IAED,cAAc,IAAI,cAAc,GAAG,SAAS,CAE3C;IAED,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAGvB;IAED,OAAO,CAAC,eAAe;CAMxB;AAED,eAAO,MAAM,iBAAiB,yBAAgC,CAAC;AAsC/D;;;GAGG;AACH,wBAAgB,sBAAsB,IAAI,IAAI,CAe7C;AAwQD,wBAAsB,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,SAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAkB5F;AAED;;;;;GAKG;AACH,wBAAsB,6BAA6B,IAAI,OAAO,CAAC,IAAI,CAAC,CAQnE;AAED;;;;GAIG;AACH,wBAAsB,6BAA6B,IAAI,OAAO,CAAC,IAAI,CAAC,CAcnE;AAWD,qBAAa,gBAAiB,YAAW,QAAQ;IAK7C,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC;IALvB,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IAEpC,YACmB,MAAM,EAAE,qBAAqB,EAC7B,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,YAAA,EAO9C;IAEK,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,CAOtE;IAEK,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAE5C;IAEK,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE5D;IAED,gBAAgB,IAAI,MAAM,CAEzB;IAED,cAAc,CAAC,iBAAiB,EAAE,MAAM,GAAG,kBAAkB,CAE5D;IAED,gBAAgB,IAAI,qBAAqB,CAExC;CACF;AAED,eAAO,MAAM,sBAAsB,EAAE,cAAc,CAAC,qBAAqB,CAKxE,CAAC"}