@geminixiang/mikan 1.0.0-beta.4 → 1.0.0-beta.40

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 (639) hide show
  1. package/CHANGELOG.md +688 -0
  2. package/README.md +99 -36
  3. package/dist/adapter.d.ts +11 -1
  4. package/dist/adapter.d.ts.map +1 -1
  5. package/dist/adapter.js +18 -1
  6. package/dist/adapter.js.map +1 -1
  7. package/dist/adapters/discord/bot.d.ts +6 -7
  8. package/dist/adapters/discord/bot.d.ts.map +1 -1
  9. package/dist/adapters/discord/bot.js +82 -117
  10. package/dist/adapters/discord/bot.js.map +1 -1
  11. package/dist/adapters/discord/context.d.ts +3 -1
  12. package/dist/adapters/discord/context.d.ts.map +1 -1
  13. package/dist/adapters/discord/context.js +54 -215
  14. package/dist/adapters/discord/context.js.map +1 -1
  15. package/dist/adapters/github/bot.d.ts +89 -0
  16. package/dist/adapters/github/bot.d.ts.map +1 -0
  17. package/dist/adapters/github/bot.js +653 -0
  18. package/dist/adapters/github/bot.js.map +1 -0
  19. package/dist/adapters/github/client.d.ts +122 -0
  20. package/dist/adapters/github/client.d.ts.map +1 -0
  21. package/dist/adapters/github/client.js +314 -0
  22. package/dist/adapters/github/client.js.map +1 -0
  23. package/dist/adapters/github/cloudbuild.d.ts +19 -0
  24. package/dist/adapters/github/cloudbuild.d.ts.map +1 -0
  25. package/dist/adapters/github/cloudbuild.js +71 -0
  26. package/dist/adapters/github/cloudbuild.js.map +1 -0
  27. package/dist/adapters/github/context.d.ts +12 -0
  28. package/dist/adapters/github/context.d.ts.map +1 -0
  29. package/dist/adapters/github/context.js +101 -0
  30. package/dist/adapters/github/context.js.map +1 -0
  31. package/dist/adapters/github/gcp-auth.d.ts +28 -0
  32. package/dist/adapters/github/gcp-auth.d.ts.map +1 -0
  33. package/dist/adapters/github/gcp-auth.js +196 -0
  34. package/dist/adapters/github/gcp-auth.js.map +1 -0
  35. package/dist/adapters/github/github-ops.d.ts +91 -0
  36. package/dist/adapters/github/github-ops.d.ts.map +1 -0
  37. package/dist/adapters/github/github-ops.js +406 -0
  38. package/dist/adapters/github/github-ops.js.map +1 -0
  39. package/dist/adapters/github/ids.d.ts +34 -0
  40. package/dist/adapters/github/ids.d.ts.map +1 -0
  41. package/dist/adapters/github/ids.js +57 -0
  42. package/dist/adapters/github/ids.js.map +1 -0
  43. package/dist/adapters/github/repo.d.ts +33 -0
  44. package/dist/adapters/github/repo.d.ts.map +1 -0
  45. package/dist/adapters/github/repo.js +141 -0
  46. package/dist/adapters/github/repo.js.map +1 -0
  47. package/dist/adapters/github/tool-pack.d.ts +14 -0
  48. package/dist/adapters/github/tool-pack.d.ts.map +1 -0
  49. package/dist/adapters/github/tool-pack.js +56 -0
  50. package/dist/adapters/github/tool-pack.js.map +1 -0
  51. package/dist/adapters/github/tools/checks.d.ts +19 -0
  52. package/dist/adapters/github/tools/checks.d.ts.map +1 -0
  53. package/dist/adapters/github/tools/checks.js +105 -0
  54. package/dist/adapters/github/tools/checks.js.map +1 -0
  55. package/dist/adapters/github/tools/issue.d.ts +21 -0
  56. package/dist/adapters/github/tools/issue.d.ts.map +1 -0
  57. package/dist/adapters/github/tools/issue.js +48 -0
  58. package/dist/adapters/github/tools/issue.js.map +1 -0
  59. package/dist/adapters/github/tools/pr.d.ts +22 -0
  60. package/dist/adapters/github/tools/pr.d.ts.map +1 -0
  61. package/dist/adapters/github/tools/pr.js +48 -0
  62. package/dist/adapters/github/tools/pr.js.map +1 -0
  63. package/dist/adapters/github/tools/read.d.ts +21 -0
  64. package/dist/adapters/github/tools/read.d.ts.map +1 -0
  65. package/dist/adapters/github/tools/read.js +141 -0
  66. package/dist/adapters/github/tools/read.js.map +1 -0
  67. package/dist/adapters/github/tools/review-reply.d.ts +17 -0
  68. package/dist/adapters/github/tools/review-reply.d.ts.map +1 -0
  69. package/dist/adapters/github/tools/review-reply.js +38 -0
  70. package/dist/adapters/github/tools/review-reply.js.map +1 -0
  71. package/dist/adapters/github/tools/sync.d.ts +17 -0
  72. package/dist/adapters/github/tools/sync.d.ts.map +1 -0
  73. package/dist/adapters/github/tools/sync.js +34 -0
  74. package/dist/adapters/github/tools/sync.js.map +1 -0
  75. package/dist/adapters/github/types.d.ts +373 -0
  76. package/dist/adapters/github/types.d.ts.map +1 -0
  77. package/dist/adapters/github/types.js +2 -0
  78. package/dist/adapters/github/types.js.map +1 -0
  79. package/dist/adapters/intake.d.ts +16 -5
  80. package/dist/adapters/intake.d.ts.map +1 -1
  81. package/dist/adapters/intake.js +86 -23
  82. package/dist/adapters/intake.js.map +1 -1
  83. package/dist/adapters/progressive-renderer.d.ts +7 -0
  84. package/dist/adapters/progressive-renderer.d.ts.map +1 -0
  85. package/dist/adapters/progressive-renderer.js +383 -0
  86. package/dist/adapters/progressive-renderer.js.map +1 -0
  87. package/dist/adapters/shared.d.ts +23 -10
  88. package/dist/adapters/shared.d.ts.map +1 -1
  89. package/dist/adapters/shared.js +60 -22
  90. package/dist/adapters/shared.js.map +1 -1
  91. package/dist/adapters/slack/blocks.d.ts +14 -0
  92. package/dist/adapters/slack/blocks.d.ts.map +1 -1
  93. package/dist/adapters/slack/blocks.js +147 -111
  94. package/dist/adapters/slack/blocks.js.map +1 -1
  95. package/dist/adapters/slack/bot.d.ts +43 -13
  96. package/dist/adapters/slack/bot.d.ts.map +1 -1
  97. package/dist/adapters/slack/bot.js +385 -207
  98. package/dist/adapters/slack/bot.js.map +1 -1
  99. package/dist/adapters/slack/context.d.ts +3 -1
  100. package/dist/adapters/slack/context.d.ts.map +1 -1
  101. package/dist/adapters/slack/context.js +11 -17
  102. package/dist/adapters/slack/context.js.map +1 -1
  103. package/dist/adapters/slack/response-lifecycle.d.ts.map +1 -1
  104. package/dist/adapters/slack/response-lifecycle.js +126 -323
  105. package/dist/adapters/slack/response-lifecycle.js.map +1 -1
  106. package/dist/adapters/slack/session.d.ts.map +1 -1
  107. package/dist/adapters/slack/session.js +7 -11
  108. package/dist/adapters/slack/session.js.map +1 -1
  109. package/dist/adapters/slack/tool-pack.d.ts +11 -0
  110. package/dist/adapters/slack/tool-pack.d.ts.map +1 -0
  111. package/dist/adapters/slack/tool-pack.js +45 -0
  112. package/dist/adapters/slack/tool-pack.js.map +1 -0
  113. package/dist/adapters/slack/tools/attach.js +1 -1
  114. package/dist/adapters/slack/tools/attach.js.map +1 -1
  115. package/dist/adapters/slack/tools/blockkit.d.ts +14 -0
  116. package/dist/adapters/slack/tools/blockkit.d.ts.map +1 -0
  117. package/dist/adapters/slack/tools/blockkit.js +106 -0
  118. package/dist/adapters/slack/tools/blockkit.js.map +1 -0
  119. package/dist/adapters/slack/types.d.ts +40 -2
  120. package/dist/adapters/slack/types.d.ts.map +1 -1
  121. package/dist/adapters/slack/types.js.map +1 -1
  122. package/dist/adapters/telegram/bot.d.ts +8 -9
  123. package/dist/adapters/telegram/bot.d.ts.map +1 -1
  124. package/dist/adapters/telegram/bot.js +90 -117
  125. package/dist/adapters/telegram/bot.js.map +1 -1
  126. package/dist/adapters/telegram/context.d.ts +2 -0
  127. package/dist/adapters/telegram/context.d.ts.map +1 -1
  128. package/dist/adapters/telegram/context.js +61 -184
  129. package/dist/adapters/telegram/context.js.map +1 -1
  130. package/dist/adapters/telegram/html.d.ts.map +1 -1
  131. package/dist/adapters/telegram/html.js +10 -7
  132. package/dist/adapters/telegram/html.js.map +1 -1
  133. package/dist/adapters/types.d.ts +109 -12
  134. package/dist/adapters/types.d.ts.map +1 -1
  135. package/dist/adapters/types.js.map +1 -1
  136. package/dist/agent-events.d.ts +3 -2
  137. package/dist/agent-events.d.ts.map +1 -1
  138. package/dist/agent-events.js +19 -1
  139. package/dist/agent-events.js.map +1 -1
  140. package/dist/agent.d.ts +14 -19
  141. package/dist/agent.d.ts.map +1 -1
  142. package/dist/agent.js +840 -298
  143. package/dist/agent.js.map +1 -1
  144. package/dist/cli/arg-grammar.d.ts +25 -0
  145. package/dist/cli/arg-grammar.d.ts.map +1 -0
  146. package/dist/cli/arg-grammar.js +61 -0
  147. package/dist/cli/arg-grammar.js.map +1 -0
  148. package/dist/cli/boot.d.ts +5 -0
  149. package/dist/cli/boot.d.ts.map +1 -0
  150. package/dist/cli/boot.js +117 -0
  151. package/dist/cli/boot.js.map +1 -0
  152. package/dist/cli/download.d.ts.map +1 -0
  153. package/dist/{download.js → cli/download.js} +2 -0
  154. package/dist/cli/download.js.map +1 -0
  155. package/dist/cli/ext-dev.d.ts +2 -0
  156. package/dist/cli/ext-dev.d.ts.map +1 -0
  157. package/dist/cli/ext-dev.js +188 -0
  158. package/dist/cli/ext-dev.js.map +1 -0
  159. package/dist/cli/ext.d.ts +2 -0
  160. package/dist/cli/ext.d.ts.map +1 -0
  161. package/dist/cli/ext.js +324 -0
  162. package/dist/cli/ext.js.map +1 -0
  163. package/dist/cli/office.d.ts +2 -0
  164. package/dist/cli/office.d.ts.map +1 -0
  165. package/dist/cli/office.js +91 -0
  166. package/dist/cli/office.js.map +1 -0
  167. package/dist/cli/types.d.ts +16 -0
  168. package/dist/cli/types.d.ts.map +1 -0
  169. package/dist/cli/types.js +2 -0
  170. package/dist/cli/types.js.map +1 -0
  171. package/dist/commands/admin.d.ts.map +1 -1
  172. package/dist/commands/admin.js +3 -2
  173. package/dist/commands/admin.js.map +1 -1
  174. package/dist/commands/auto-reply.d.ts.map +1 -1
  175. package/dist/commands/auto-reply.js +5 -9
  176. package/dist/commands/auto-reply.js.map +1 -1
  177. package/dist/commands/extensions.d.ts.map +1 -1
  178. package/dist/commands/extensions.js +9 -6
  179. package/dist/commands/extensions.js.map +1 -1
  180. package/dist/commands/login.d.ts +2 -1
  181. package/dist/commands/login.d.ts.map +1 -1
  182. package/dist/commands/login.js +40 -5
  183. package/dist/commands/login.js.map +1 -1
  184. package/dist/commands/manifest.d.ts +37 -0
  185. package/dist/commands/manifest.d.ts.map +1 -0
  186. package/dist/commands/manifest.js +151 -0
  187. package/dist/commands/manifest.js.map +1 -0
  188. package/dist/commands/model.d.ts +2 -3
  189. package/dist/commands/model.d.ts.map +1 -1
  190. package/dist/commands/model.js +63 -24
  191. package/dist/commands/model.js.map +1 -1
  192. package/dist/commands/new.d.ts.map +1 -1
  193. package/dist/commands/new.js +15 -3
  194. package/dist/commands/new.js.map +1 -1
  195. package/dist/commands/registry.d.ts +2 -2
  196. package/dist/commands/registry.d.ts.map +1 -1
  197. package/dist/commands/registry.js +1 -2
  198. package/dist/commands/registry.js.map +1 -1
  199. package/dist/commands/sandbox.d.ts.map +1 -1
  200. package/dist/commands/sandbox.js +83 -33
  201. package/dist/commands/sandbox.js.map +1 -1
  202. package/dist/commands/session-view.d.ts.map +1 -1
  203. package/dist/commands/session-view.js +6 -3
  204. package/dist/commands/session-view.js.map +1 -1
  205. package/dist/commands/types.d.ts +79 -7
  206. package/dist/commands/types.d.ts.map +1 -1
  207. package/dist/commands/types.js.map +1 -1
  208. package/dist/config.d.ts +23 -8
  209. package/dist/config.d.ts.map +1 -1
  210. package/dist/config.js +222 -135
  211. package/dist/config.js.map +1 -1
  212. package/dist/env-manifest.d.ts +30 -0
  213. package/dist/env-manifest.d.ts.map +1 -0
  214. package/dist/env-manifest.js +229 -0
  215. package/dist/env-manifest.js.map +1 -0
  216. package/dist/events.d.ts.map +1 -1
  217. package/dist/events.js +20 -81
  218. package/dist/events.js.map +1 -1
  219. package/dist/execution-resolver.d.ts +7 -8
  220. package/dist/execution-resolver.d.ts.map +1 -1
  221. package/dist/execution-resolver.js +106 -110
  222. package/dist/execution-resolver.js.map +1 -1
  223. package/dist/extension-schedules.d.ts +31 -0
  224. package/dist/extension-schedules.d.ts.map +1 -0
  225. package/dist/extension-schedules.js +229 -0
  226. package/dist/extension-schedules.js.map +1 -0
  227. package/dist/harness/auth.d.ts +2 -1
  228. package/dist/harness/auth.d.ts.map +1 -1
  229. package/dist/harness/auth.js +11 -5
  230. package/dist/harness/auth.js.map +1 -1
  231. package/dist/harness/event-format.d.ts +27 -0
  232. package/dist/harness/event-format.d.ts.map +1 -0
  233. package/dist/harness/event-format.js +160 -0
  234. package/dist/harness/event-format.js.map +1 -0
  235. package/dist/harness/extensions/loader.d.ts +27 -49
  236. package/dist/harness/extensions/loader.d.ts.map +1 -1
  237. package/dist/harness/extensions/loader.js +486 -130
  238. package/dist/harness/extensions/loader.js.map +1 -1
  239. package/dist/harness/extensions/registry.d.ts +107 -2
  240. package/dist/harness/extensions/registry.d.ts.map +1 -1
  241. package/dist/harness/extensions/registry.js +316 -0
  242. package/dist/harness/extensions/registry.js.map +1 -1
  243. package/dist/harness/extensions/types.d.ts +482 -42
  244. package/dist/harness/extensions/types.d.ts.map +1 -1
  245. package/dist/harness/extensions/types.js.map +1 -1
  246. package/dist/harness/index.d.ts +18 -8
  247. package/dist/harness/index.d.ts.map +1 -1
  248. package/dist/harness/index.js +7 -4
  249. package/dist/harness/index.js.map +1 -1
  250. package/dist/harness/models.d.ts +7 -4
  251. package/dist/harness/models.d.ts.map +1 -1
  252. package/dist/harness/models.js +46 -24
  253. package/dist/harness/models.js.map +1 -1
  254. package/dist/harness/runner.d.ts +50 -54
  255. package/dist/harness/runner.d.ts.map +1 -1
  256. package/dist/harness/runner.js +232 -46
  257. package/dist/harness/runner.js.map +1 -1
  258. package/dist/harness/session-store.d.ts +11 -5
  259. package/dist/harness/session-store.d.ts.map +1 -1
  260. package/dist/harness/session-store.js +141 -36
  261. package/dist/harness/session-store.js.map +1 -1
  262. package/dist/harness/settings.d.ts +2 -20
  263. package/dist/harness/settings.d.ts.map +1 -1
  264. package/dist/harness/settings.js +12 -1
  265. package/dist/harness/settings.js.map +1 -1
  266. package/dist/harness/skills.d.ts +10 -29
  267. package/dist/harness/skills.d.ts.map +1 -1
  268. package/dist/harness/skills.js +48 -6
  269. package/dist/harness/skills.js.map +1 -1
  270. package/dist/harness/subagent-profiles.d.ts +8 -0
  271. package/dist/harness/subagent-profiles.d.ts.map +1 -0
  272. package/dist/harness/subagent-profiles.js +299 -0
  273. package/dist/harness/subagent-profiles.js.map +1 -0
  274. package/dist/harness/subagent-runner.d.ts +39 -0
  275. package/dist/harness/subagent-runner.d.ts.map +1 -0
  276. package/dist/harness/subagent-runner.js +617 -0
  277. package/dist/harness/subagent-runner.js.map +1 -0
  278. package/dist/harness/types.d.ts +267 -1
  279. package/dist/harness/types.d.ts.map +1 -1
  280. package/dist/harness/types.js.map +1 -1
  281. package/dist/harness/usage.d.ts +6 -0
  282. package/dist/harness/usage.d.ts.map +1 -0
  283. package/dist/harness/usage.js +32 -0
  284. package/dist/harness/usage.js.map +1 -0
  285. package/dist/index.d.ts +36 -8
  286. package/dist/index.d.ts.map +1 -1
  287. package/dist/index.js +22 -6
  288. package/dist/index.js.map +1 -1
  289. package/dist/main.js +391 -127
  290. package/dist/main.js.map +1 -1
  291. package/dist/observability/instrument.js +7 -5
  292. package/dist/observability/instrument.js.map +1 -1
  293. package/dist/observability/sentry.d.ts +2 -0
  294. package/dist/observability/sentry.d.ts.map +1 -1
  295. package/dist/observability/sentry.js +10 -2
  296. package/dist/observability/sentry.js.map +1 -1
  297. package/dist/office/address.d.ts +31 -0
  298. package/dist/office/address.d.ts.map +1 -0
  299. package/dist/office/address.js +113 -0
  300. package/dist/office/address.js.map +1 -0
  301. package/dist/office/index.d.ts +11 -0
  302. package/dist/office/index.d.ts.map +1 -0
  303. package/dist/office/index.js +11 -0
  304. package/dist/office/index.js.map +1 -0
  305. package/dist/office/layout.d.ts +27 -0
  306. package/dist/office/layout.d.ts.map +1 -0
  307. package/dist/office/layout.js +97 -0
  308. package/dist/office/layout.js.map +1 -0
  309. package/dist/office/migration.d.ts +44 -0
  310. package/dist/office/migration.d.ts.map +1 -0
  311. package/dist/office/migration.js +255 -0
  312. package/dist/office/migration.js.map +1 -0
  313. package/dist/office/registry.d.ts +75 -0
  314. package/dist/office/registry.d.ts.map +1 -0
  315. package/dist/office/registry.js +646 -0
  316. package/dist/office/registry.js.map +1 -0
  317. package/dist/office/types.d.ts +71 -0
  318. package/dist/office/types.d.ts.map +1 -0
  319. package/dist/office/types.js +2 -0
  320. package/dist/office/types.js.map +1 -0
  321. package/dist/packages/admin.d.ts +17 -0
  322. package/dist/packages/admin.d.ts.map +1 -0
  323. package/dist/packages/admin.js +98 -0
  324. package/dist/packages/admin.js.map +1 -0
  325. package/dist/packages/index.d.ts +6 -0
  326. package/dist/packages/index.d.ts.map +1 -0
  327. package/dist/packages/index.js +6 -0
  328. package/dist/packages/index.js.map +1 -0
  329. package/dist/packages/inspect.d.ts +11 -0
  330. package/dist/packages/inspect.d.ts.map +1 -0
  331. package/dist/packages/inspect.js +98 -0
  332. package/dist/packages/inspect.js.map +1 -0
  333. package/dist/packages/materialize.d.ts +40 -0
  334. package/dist/packages/materialize.d.ts.map +1 -0
  335. package/dist/packages/materialize.js +297 -0
  336. package/dist/packages/materialize.js.map +1 -0
  337. package/dist/packages/resolve.d.ts +25 -0
  338. package/dist/packages/resolve.d.ts.map +1 -0
  339. package/dist/packages/resolve.js +208 -0
  340. package/dist/packages/resolve.js.map +1 -0
  341. package/dist/packages/source.d.ts +39 -0
  342. package/dist/packages/source.d.ts.map +1 -0
  343. package/dist/packages/source.js +189 -0
  344. package/dist/packages/source.js.map +1 -0
  345. package/dist/packages/types.d.ts +104 -0
  346. package/dist/packages/types.d.ts.map +1 -0
  347. package/dist/packages/types.js +2 -0
  348. package/dist/packages/types.js.map +1 -0
  349. package/dist/provisioner.d.ts +66 -0
  350. package/dist/provisioner.d.ts.map +1 -1
  351. package/dist/provisioner.js +335 -13
  352. package/dist/provisioner.js.map +1 -1
  353. package/dist/runtime/conversation-runtime.d.ts +1 -1
  354. package/dist/runtime/conversation-runtime.d.ts.map +1 -1
  355. package/dist/runtime/conversation-runtime.js +562 -118
  356. package/dist/runtime/conversation-runtime.js.map +1 -1
  357. package/dist/runtime/session-lifecycle.d.ts +38 -0
  358. package/dist/runtime/session-lifecycle.d.ts.map +1 -0
  359. package/dist/runtime/session-lifecycle.js +193 -0
  360. package/dist/runtime/session-lifecycle.js.map +1 -0
  361. package/dist/runtime/types.d.ts +66 -7
  362. package/dist/runtime/types.d.ts.map +1 -1
  363. package/dist/runtime/types.js.map +1 -1
  364. package/dist/sandbox/cloudflare.d.ts +3 -0
  365. package/dist/sandbox/cloudflare.d.ts.map +1 -1
  366. package/dist/sandbox/cloudflare.js +13 -1
  367. package/dist/sandbox/cloudflare.js.map +1 -1
  368. package/dist/sandbox/container.d.ts +4 -0
  369. package/dist/sandbox/container.d.ts.map +1 -1
  370. package/dist/sandbox/container.js +13 -3
  371. package/dist/sandbox/container.js.map +1 -1
  372. package/dist/sandbox/firecracker.d.ts +3 -0
  373. package/dist/sandbox/firecracker.d.ts.map +1 -1
  374. package/dist/sandbox/firecracker.js +13 -2
  375. package/dist/sandbox/firecracker.js.map +1 -1
  376. package/dist/sandbox/gondolin.d.ts +57 -0
  377. package/dist/sandbox/gondolin.d.ts.map +1 -0
  378. package/dist/sandbox/gondolin.js +764 -0
  379. package/dist/sandbox/gondolin.js.map +1 -0
  380. package/dist/sandbox/host.d.ts +3 -0
  381. package/dist/sandbox/host.d.ts.map +1 -1
  382. package/dist/sandbox/host.js +18 -3
  383. package/dist/sandbox/host.js.map +1 -1
  384. package/dist/sandbox/identity.d.ts +44 -0
  385. package/dist/sandbox/identity.d.ts.map +1 -0
  386. package/dist/sandbox/identity.js +68 -0
  387. package/dist/sandbox/identity.js.map +1 -0
  388. package/dist/sandbox/image.d.ts.map +1 -1
  389. package/dist/sandbox/image.js +2 -0
  390. package/dist/sandbox/image.js.map +1 -1
  391. package/dist/sandbox/index.d.ts +17 -4
  392. package/dist/sandbox/index.d.ts.map +1 -1
  393. package/dist/sandbox/index.js +37 -3
  394. package/dist/sandbox/index.js.map +1 -1
  395. package/dist/sandbox/types.d.ts +65 -1
  396. package/dist/sandbox/types.d.ts.map +1 -1
  397. package/dist/sandbox/types.js.map +1 -1
  398. package/dist/sandbox/utils.d.ts +14 -0
  399. package/dist/sandbox/utils.d.ts.map +1 -1
  400. package/dist/sandbox/utils.js +68 -1
  401. package/dist/sandbox/utils.js.map +1 -1
  402. package/dist/sessions/chat-history-sync.d.ts +25 -0
  403. package/dist/sessions/chat-history-sync.d.ts.map +1 -0
  404. package/dist/sessions/{agent-memory-file-manager.js → chat-history-sync.js} +135 -131
  405. package/dist/sessions/chat-history-sync.js.map +1 -0
  406. package/dist/sessions/conversation-log.d.ts +9 -0
  407. package/dist/sessions/conversation-log.d.ts.map +1 -0
  408. package/dist/sessions/conversation-log.js +50 -0
  409. package/dist/sessions/conversation-log.js.map +1 -0
  410. package/dist/sessions/history-line.d.ts +29 -0
  411. package/dist/sessions/history-line.d.ts.map +1 -0
  412. package/dist/sessions/history-line.js +45 -0
  413. package/dist/sessions/history-line.js.map +1 -0
  414. package/dist/sessions/rotation.d.ts +2 -0
  415. package/dist/sessions/rotation.d.ts.map +1 -0
  416. package/dist/sessions/rotation.js +39 -0
  417. package/dist/sessions/rotation.js.map +1 -0
  418. package/dist/sessions/session-key.d.ts +33 -0
  419. package/dist/sessions/session-key.d.ts.map +1 -0
  420. package/dist/sessions/session-key.js +115 -0
  421. package/dist/sessions/session-key.js.map +1 -0
  422. package/dist/sessions/store.d.ts +15 -7
  423. package/dist/sessions/store.d.ts.map +1 -1
  424. package/dist/sessions/store.js +127 -36
  425. package/dist/sessions/store.js.map +1 -1
  426. package/dist/sessions/types.d.ts +19 -5
  427. package/dist/sessions/types.d.ts.map +1 -1
  428. package/dist/sessions/types.js.map +1 -1
  429. package/dist/settings-mutation.d.ts +40 -0
  430. package/dist/settings-mutation.d.ts.map +1 -0
  431. package/dist/settings-mutation.js +61 -0
  432. package/dist/settings-mutation.js.map +1 -0
  433. package/dist/subagent-progress.d.ts +43 -0
  434. package/dist/subagent-progress.d.ts.map +1 -0
  435. package/dist/subagent-progress.js +220 -0
  436. package/dist/subagent-progress.js.map +1 -0
  437. package/dist/tools/bash.d.ts +3 -1
  438. package/dist/tools/bash.d.ts.map +1 -1
  439. package/dist/tools/bash.js +26 -18
  440. package/dist/tools/bash.js.map +1 -1
  441. package/dist/tools/edit.d.ts.map +1 -1
  442. package/dist/tools/edit.js +14 -13
  443. package/dist/tools/edit.js.map +1 -1
  444. package/dist/tools/event.d.ts +1 -1
  445. package/dist/tools/event.d.ts.map +1 -1
  446. package/dist/tools/event.js +58 -45
  447. package/dist/tools/event.js.map +1 -1
  448. package/dist/tools/generate-image.d.ts +23 -0
  449. package/dist/tools/generate-image.d.ts.map +1 -0
  450. package/dist/tools/generate-image.js +65 -0
  451. package/dist/tools/generate-image.js.map +1 -0
  452. package/dist/tools/host-fn-tool.d.ts +21 -0
  453. package/dist/tools/host-fn-tool.d.ts.map +1 -0
  454. package/dist/tools/host-fn-tool.js +32 -0
  455. package/dist/tools/host-fn-tool.js.map +1 -0
  456. package/dist/tools/index.d.ts +19 -2
  457. package/dist/tools/index.d.ts.map +1 -1
  458. package/dist/tools/index.js +25 -2
  459. package/dist/tools/index.js.map +1 -1
  460. package/dist/tools/react.d.ts +15 -0
  461. package/dist/tools/react.d.ts.map +1 -0
  462. package/dist/tools/react.js +29 -0
  463. package/dist/tools/react.js.map +1 -0
  464. package/dist/tools/read.d.ts +1 -0
  465. package/dist/tools/read.d.ts.map +1 -1
  466. package/dist/tools/read.js +39 -33
  467. package/dist/tools/read.js.map +1 -1
  468. package/dist/tools/sandbox.d.ts +2 -2
  469. package/dist/tools/sandbox.d.ts.map +1 -1
  470. package/dist/tools/sandbox.js +14 -9
  471. package/dist/tools/sandbox.js.map +1 -1
  472. package/dist/tools/subagent-slots.d.ts +28 -0
  473. package/dist/tools/subagent-slots.d.ts.map +1 -0
  474. package/dist/tools/subagent-slots.js +72 -0
  475. package/dist/tools/subagent-slots.js.map +1 -0
  476. package/dist/tools/subagent.d.ts +54 -0
  477. package/dist/tools/subagent.d.ts.map +1 -0
  478. package/dist/tools/subagent.js +411 -0
  479. package/dist/tools/subagent.js.map +1 -0
  480. package/dist/tools/types.d.ts +40 -32
  481. package/dist/tools/types.d.ts.map +1 -1
  482. package/dist/tools/types.js.map +1 -1
  483. package/dist/tools/write.d.ts.map +1 -1
  484. package/dist/tools/write.js +2 -8
  485. package/dist/tools/write.js.map +1 -1
  486. package/dist/trigger.d.ts +2 -1
  487. package/dist/trigger.d.ts.map +1 -1
  488. package/dist/trigger.js +6 -9
  489. package/dist/trigger.js.map +1 -1
  490. package/dist/types.d.ts +403 -59
  491. package/dist/types.d.ts.map +1 -1
  492. package/dist/types.js +2 -2
  493. package/dist/types.js.map +1 -1
  494. package/dist/utils/file-guards.d.ts +9 -0
  495. package/dist/utils/file-guards.d.ts.map +1 -1
  496. package/dist/utils/file-guards.js +44 -1
  497. package/dist/utils/file-guards.js.map +1 -1
  498. package/dist/vault/disabled.d.ts +9 -0
  499. package/dist/vault/disabled.d.ts.map +1 -0
  500. package/dist/vault/disabled.js +25 -0
  501. package/dist/vault/disabled.js.map +1 -0
  502. package/dist/vault/index.d.ts +45 -2
  503. package/dist/vault/index.d.ts.map +1 -1
  504. package/dist/vault/index.js +127 -36
  505. package/dist/vault/index.js.map +1 -1
  506. package/dist/vault/types.d.ts +6 -2
  507. package/dist/vault/types.d.ts.map +1 -1
  508. package/dist/vault/types.js.map +1 -1
  509. package/dist/web/admin/portal.d.ts +31 -3
  510. package/dist/web/admin/portal.d.ts.map +1 -1
  511. package/dist/web/admin/portal.js +846 -345
  512. package/dist/web/admin/portal.js.map +1 -1
  513. package/dist/web/admin/provider-models.js +1 -1
  514. package/dist/web/admin/provider-models.js.map +1 -1
  515. package/dist/web/admin/types.d.ts +23 -3
  516. package/dist/web/admin/types.d.ts.map +1 -1
  517. package/dist/web/admin/types.js.map +1 -1
  518. package/dist/web/login/oauth.d.ts +2 -3
  519. package/dist/web/login/oauth.d.ts.map +1 -1
  520. package/dist/web/login/oauth.js +1 -32
  521. package/dist/web/login/oauth.js.map +1 -1
  522. package/dist/web/login/portal.d.ts +1 -1
  523. package/dist/web/login/portal.d.ts.map +1 -1
  524. package/dist/web/login/portal.js +13 -36
  525. package/dist/web/login/portal.js.map +1 -1
  526. package/dist/web/login/types.d.ts +0 -11
  527. package/dist/web/login/types.d.ts.map +1 -1
  528. package/dist/web/login/types.js.map +1 -1
  529. package/dist/web/portal-shell.d.ts +21 -0
  530. package/dist/web/portal-shell.d.ts.map +1 -0
  531. package/dist/{portal-shell.js → web/portal-shell.js} +67 -2
  532. package/dist/web/portal-shell.js.map +1 -0
  533. package/dist/web/server.d.ts +3 -2
  534. package/dist/web/server.d.ts.map +1 -1
  535. package/dist/web/server.js +11 -4
  536. package/dist/web/server.js.map +1 -1
  537. package/dist/web/session-view/portal.d.ts +1 -1
  538. package/dist/web/session-view/portal.d.ts.map +1 -1
  539. package/dist/web/session-view/portal.js +37 -28
  540. package/dist/web/session-view/portal.js.map +1 -1
  541. package/dist/web/session-view/service.d.ts +1 -1
  542. package/dist/web/session-view/service.d.ts.map +1 -1
  543. package/dist/web/session-view/service.js +61 -18
  544. package/dist/web/session-view/service.js.map +1 -1
  545. package/dist/web/session-view/types.d.ts +0 -3
  546. package/dist/web/session-view/types.d.ts.map +1 -1
  547. package/dist/web/session-view/types.js.map +1 -1
  548. package/dist/web/token-store.js +1 -1
  549. package/dist/web/token-store.js.map +1 -1
  550. package/dist/workspace-projection/index.d.ts +10 -0
  551. package/dist/workspace-projection/index.d.ts.map +1 -0
  552. package/dist/workspace-projection/index.js +120 -0
  553. package/dist/workspace-projection/index.js.map +1 -0
  554. package/dist/workspace-projection/types.d.ts +16 -0
  555. package/dist/workspace-projection/types.d.ts.map +1 -0
  556. package/dist/workspace-projection/types.js +2 -0
  557. package/dist/workspace-projection/types.js.map +1 -0
  558. package/package.json +67 -37
  559. package/dist/adapters/streaming.d.ts +0 -18
  560. package/dist/adapters/streaming.d.ts.map +0 -1
  561. package/dist/adapters/streaming.js +0 -44
  562. package/dist/adapters/streaming.js.map +0 -1
  563. package/dist/commands/parse.d.ts +0 -7
  564. package/dist/commands/parse.d.ts.map +0 -1
  565. package/dist/commands/parse.js +0 -14
  566. package/dist/commands/parse.js.map +0 -1
  567. package/dist/download.d.ts.map +0 -1
  568. package/dist/download.js.map +0 -1
  569. package/dist/model-registry.d.ts +0 -4
  570. package/dist/model-registry.d.ts.map +0 -1
  571. package/dist/model-registry.js +0 -7
  572. package/dist/model-registry.js.map +0 -1
  573. package/dist/portal-shell.d.ts +0 -4
  574. package/dist/portal-shell.d.ts.map +0 -1
  575. package/dist/portal-shell.js.map +0 -1
  576. package/dist/runtime/agent-run-controller.d.ts +0 -31
  577. package/dist/runtime/agent-run-controller.d.ts.map +0 -1
  578. package/dist/runtime/agent-run-controller.js +0 -195
  579. package/dist/runtime/agent-run-controller.js.map +0 -1
  580. package/dist/sandbox/path-context.d.ts +0 -3
  581. package/dist/sandbox/path-context.d.ts.map +0 -1
  582. package/dist/sandbox/path-context.js +0 -20
  583. package/dist/sandbox/path-context.js.map +0 -1
  584. package/dist/sessions/agent-memory-file-manager.d.ts +0 -19
  585. package/dist/sessions/agent-memory-file-manager.d.ts.map +0 -1
  586. package/dist/sessions/agent-memory-file-manager.js.map +0 -1
  587. package/dist/sessions/metadata.d.ts +0 -3
  588. package/dist/sessions/metadata.d.ts.map +0 -1
  589. package/dist/sessions/metadata.js +0 -11
  590. package/dist/sessions/metadata.js.map +0 -1
  591. package/dist/sessions/policy.d.ts +0 -6
  592. package/dist/sessions/policy.d.ts.map +0 -1
  593. package/dist/sessions/policy.js +0 -23
  594. package/dist/sessions/policy.js.map +0 -1
  595. package/dist/store.d.ts +0 -46
  596. package/dist/store.d.ts.map +0 -1
  597. package/dist/store.js +0 -177
  598. package/dist/store.js.map +0 -1
  599. package/dist/tools/truncate.d.ts +0 -33
  600. package/dist/tools/truncate.d.ts.map +0 -1
  601. package/dist/tools/truncate.js +0 -184
  602. package/dist/tools/truncate.js.map +0 -1
  603. package/dist/utils/date.d.ts +0 -10
  604. package/dist/utils/date.d.ts.map +0 -1
  605. package/dist/utils/date.js +0 -23
  606. package/dist/utils/date.js.map +0 -1
  607. package/dist/utils/env.d.ts +0 -3
  608. package/dist/utils/env.d.ts.map +0 -1
  609. package/dist/utils/env.js +0 -12
  610. package/dist/utils/env.js.map +0 -1
  611. package/dist/utils/fs-atomic.d.ts +0 -10
  612. package/dist/utils/fs-atomic.d.ts.map +0 -1
  613. package/dist/utils/fs-atomic.js +0 -45
  614. package/dist/utils/fs-atomic.js.map +0 -1
  615. package/dist/utils/html.d.ts +0 -2
  616. package/dist/utils/html.d.ts.map +0 -1
  617. package/dist/utils/html.js +0 -4
  618. package/dist/utils/html.js.map +0 -1
  619. package/dist/utils/http-body.d.ts +0 -10
  620. package/dist/utils/http-body.d.ts.map +0 -1
  621. package/dist/utils/http-body.js +0 -34
  622. package/dist/utils/http-body.js.map +0 -1
  623. package/dist/vault/routing.d.ts +0 -3
  624. package/dist/vault/routing.d.ts.map +0 -1
  625. package/dist/vault/routing.js +0 -13
  626. package/dist/vault/routing.js.map +0 -1
  627. package/dist/web/agent-events/portal.d.ts +0 -3
  628. package/dist/web/agent-events/portal.d.ts.map +0 -1
  629. package/dist/web/agent-events/portal.js +0 -18
  630. package/dist/web/agent-events/portal.js.map +0 -1
  631. package/dist/web/request.d.ts +0 -3
  632. package/dist/web/request.d.ts.map +0 -1
  633. package/dist/web/request.js +0 -13
  634. package/dist/web/request.js.map +0 -1
  635. package/dist/web/session-view/command.d.ts +0 -4
  636. package/dist/web/session-view/command.d.ts.map +0 -1
  637. package/dist/web/session-view/command.js +0 -7
  638. package/dist/web/session-view/command.js.map +0 -1
  639. /package/dist/{download.d.ts → cli/download.d.ts} +0 -0
package/dist/main.js CHANGED
@@ -1,30 +1,39 @@
1
1
  #!/usr/bin/env node
2
2
  import "./observability/instrument.js";
3
- import { join, resolve } from "path";
4
- import { mkdirSync, statSync, writeFileSync } from "fs";
5
- import { homedir } from "os";
6
- import { fileURLToPath } from "url";
7
- import { dirname, join as pathJoin } from "path";
3
+ import { join } from "node:path";
4
+ import { mkdirSync, statSync, writeFileSync } from "node:fs";
5
+ import { fileURLToPath } from "node:url";
6
+ import { dirname, join as pathJoin } from "node:path";
8
7
  import { DiscordMessagingBot } from "./adapters/discord/bot.js";
8
+ import { GithubMessagingBot } from "./adapters/github/bot.js";
9
+ import { createGithubToolPack } from "./adapters/github/tool-pack.js";
10
+ import { GcpTokenProvider } from "./adapters/github/gcp-auth.js";
9
11
  import { TelegramMessagingBot } from "./adapters/telegram/bot.js";
10
12
  import { SlackMessagingBot as SlackMessagingBotClass } from "./adapters/slack/bot.js";
11
- import { downloadChannel } from "./download.js";
13
+ import { createSlackToolPack } from "./adapters/slack/tool-pack.js";
14
+ import { downloadChannel } from "./cli/download.js";
12
15
  import { EventsWatcher } from "./events.js";
16
+ import { ExtensionCallbackScheduler } from "./extension-schedules.js";
13
17
  import * as log from "./log.js";
14
18
  import { startWebServer } from "./web/server.js";
15
19
  import { InMemoryAdminTokenStore } from "./web/admin/store.js";
16
20
  import { InMemoryLinkTokenStore } from "./web/login/store.js";
17
21
  import { InMemorySessionViewTokenStore } from "./web/session-view/store.js";
18
22
  import { DockerContainerManager } from "./provisioner.js";
19
- import { assertStateDirOutsideWorkspace, createGlobalSettingsFile, loadGlobalSettings, MissingGlobalSettingsError, } from "./config.js";
23
+ import { assertStateDirOutsideWorkspace, createGlobalSettingsFile, loadGlobalSettings, MissingGlobalSettingsError, resolveLinkBaseUrl, } from "./config.js";
20
24
  import { configureHttpDispatcher, defaultAuthPath, defaultModelsJsonPath, parseHttpIdleTimeoutMs, } from "./harness/index.js";
21
- import { existsSync, readFileSync } from "fs";
22
- import { readEnv, setEnvAliases } from "./utils/env.js";
25
+ import { existsSync, readFileSync } from "node:fs";
26
+ import { readEnv, setEnvAliases } from "./env-manifest.js";
23
27
  import { ensureDirExists, isRecord, readJsonFileIfExists } from "./utils/file-guards.js";
24
- import { SandboxError, parseSandboxArg, validateSandbox, } from "./sandbox/index.js";
28
+ import { SandboxError, validateSandbox } from "./sandbox/index.js";
29
+ import { helpText, resolveBoot } from "./cli/boot.js";
30
+ import { envReport, noPlatformsMessage, platformIsActive } from "./env-manifest.js";
31
+ import { configureGondolinRuntime, gondolinResources, reconcileGondolinRuntimes, stopAllGondolinRuntimes, stopIdleGondolinVms, } from "./sandbox/gondolin.js";
25
32
  import { FileVaultManager } from "./vault/index.js";
33
+ import { runExtCommand } from "./cli/ext.js";
34
+ import { runOfficeCommand } from "./cli/office.js";
35
+ import { buildContainerBindTranslator, createWorkspace, formatUnmigratedOfficesError, migrateLegacyOffices, OfficeRegistry, } from "./office/index.js";
26
36
  import { createConversationRuntime } from "./runtime/conversation-runtime.js";
27
- import { ChannelStore } from "./store.js";
28
37
  import * as Sentry from "@sentry/node";
29
38
  function getVersion() {
30
39
  // Try to find package.json in the dist directory or parent
@@ -44,56 +53,19 @@ const SLACK_APP_TOKEN = readEnv("SLACK_APP_TOKEN");
44
53
  const SLACK_BOT_TOKEN = readEnv("SLACK_BOT_TOKEN");
45
54
  const TELEGRAM_BOT_TOKEN = readEnv("TELEGRAM_BOT_TOKEN");
46
55
  const DISCORD_BOT_TOKEN = readEnv("DISCORD_BOT_TOKEN");
47
- const LINK_URL = readEnv("LINK_URL");
56
+ const GITHUB_APP_ID = readEnv("GITHUB_APP_ID");
57
+ const GITHUB_APP_PRIVATE_KEY = readEnv("GITHUB_APP_PRIVATE_KEY");
58
+ const GITHUB_APP_PRIVATE_KEY_PATH = readEnv("GITHUB_APP_PRIVATE_KEY_PATH");
59
+ const GITHUB_INSTALLATION_ID = readEnv("GITHUB_INSTALLATION_ID");
60
+ const GITHUB_REPOS = readEnv("GITHUB_REPOS");
61
+ const GITHUB_POLL_INTERVAL = readEnv("GITHUB_POLL_INTERVAL");
62
+ const GOOGLE_APPLICATION_CREDENTIALS = readEnv("GOOGLE_APPLICATION_CREDENTIALS");
63
+ const GOOGLE_CLOUD_PROJECT = readEnv("GOOGLE_CLOUD_PROJECT");
64
+ // Externally-visible base URL of the link/OAuth server; the env read and
65
+ // trailing-slash normalization live in config.resolveLinkBaseUrl.
66
+ const LINK_BASE_URL = resolveLinkBaseUrl();
48
67
  const LINK_PORT_RAW = readEnv("LINK_PORT");
49
- const LINK_PORT = LINK_PORT_RAW ? parseInt(LINK_PORT_RAW, 10) : LINK_URL ? 8181 : undefined;
50
- function parseArgs() {
51
- const args = process.argv.slice(2);
52
- let sandbox = { type: "host" };
53
- let workingDir;
54
- let stateDirArg;
55
- let downloadChannelId;
56
- let showOnboard = false;
57
- let showVersion = false;
58
- for (let i = 0; i < args.length; i++) {
59
- const arg = args[i];
60
- if (arg === "--version" || arg === "-v" || arg === "-V") {
61
- showVersion = true;
62
- }
63
- else if (arg === "--onboard") {
64
- showOnboard = true;
65
- }
66
- else if (arg.startsWith("--sandbox=")) {
67
- sandbox = parseSandboxArg(arg.slice("--sandbox=".length));
68
- }
69
- else if (arg === "--sandbox") {
70
- sandbox = parseSandboxArg(args[++i] || "");
71
- }
72
- else if (arg.startsWith("--state-dir=")) {
73
- stateDirArg = arg.slice("--state-dir=".length);
74
- }
75
- else if (arg === "--state-dir") {
76
- stateDirArg = args[++i];
77
- }
78
- else if (arg.startsWith("--download=")) {
79
- downloadChannelId = arg.slice("--download=".length);
80
- }
81
- else if (arg === "--download") {
82
- downloadChannelId = args[++i];
83
- }
84
- else if (!arg.startsWith("-")) {
85
- workingDir = arg;
86
- }
87
- }
88
- return {
89
- workingDir: workingDir ? resolve(workingDir) : undefined,
90
- stateDir: stateDirArg ? resolve(stateDirArg) : undefined,
91
- sandbox,
92
- downloadChannel: downloadChannelId,
93
- showOnboard,
94
- showVersion,
95
- };
96
- }
68
+ const LINK_PORT = LINK_PORT_RAW ? parseInt(LINK_PORT_RAW, 10) : LINK_BASE_URL ? 8181 : undefined;
97
69
  const WORLD_WRITABLE_MODE = 0o002;
98
70
  function ensureSecureStateDir(path) {
99
71
  let stat;
@@ -149,31 +121,48 @@ function handleStartupError(error) {
149
121
  console.error(String(error));
150
122
  process.exit(1);
151
123
  }
152
- let parsedArgs;
124
+ let plan;
153
125
  try {
154
- parsedArgs = parseArgs();
126
+ plan = resolveBoot();
155
127
  }
156
128
  catch (error) {
157
129
  handleStartupError(error);
158
130
  }
131
+ // `mikan ext …` manages extensions and exits; handle it before the normal
132
+ // bot-mode startup (which requires platform tokens).
133
+ if (plan.mode === "ext") {
134
+ const code = await runExtCommand(plan.extArgs ?? []);
135
+ process.exit(code);
136
+ }
137
+ // `mikan office …` inspects/claims conversation offices and exits.
138
+ if (plan.mode === "office") {
139
+ process.exit(runOfficeCommand(plan.officeArgs ?? []));
140
+ }
159
141
  // Global fetch: proxy support (HTTP_PROXY/HTTPS_PROXY/NO_PROXY) and idle
160
142
  // timeouts so a stalled LLM stream errors out instead of hanging a session.
161
143
  const httpIdleTimeoutMs = parseHttpIdleTimeoutMs(readEnv("HTTP_IDLE_TIMEOUT"));
162
144
  configureHttpDispatcher(httpIdleTimeoutMs);
163
- // Handle --version
164
- if (parsedArgs.showVersion) {
145
+ if (plan.mode === "help") {
146
+ console.log(helpText());
147
+ process.exit(0);
148
+ }
149
+ if (plan.mode === "env") {
150
+ console.log(envReport());
151
+ process.exit(0);
152
+ }
153
+ if (plan.mode === "version") {
165
154
  console.log(getVersion());
166
155
  process.exit(0);
167
156
  }
168
157
  // Handle --onboard mode
169
- if (parsedArgs.showOnboard) {
170
- const stateDir = parsedArgs.stateDir ?? join(homedir(), ".mikan");
158
+ if (plan.mode === "onboard") {
159
+ const stateDir = plan.stateDir;
171
160
  setEnvAliases("STATE_DIR", stateDir);
172
161
  ensureSecureStateDir(stateDir);
173
162
  try {
174
163
  const settingsPath = createGlobalSettingsFile(stateDir);
175
164
  console.log(`Created global settings at ${settingsPath}`);
176
- console.log("Review the file, then start mikan with your working directory.");
165
+ console.log(`Review the file, then start mikan (workspace defaults to ${join(stateDir, "workspace")}).`);
177
166
  process.exit(0);
178
167
  }
179
168
  catch (err) {
@@ -182,53 +171,92 @@ if (parsedArgs.showOnboard) {
182
171
  }
183
172
  }
184
173
  // Handle --download mode (Slack only)
185
- if (parsedArgs.downloadChannel) {
174
+ if (plan.mode === "download" && plan.downloadChannel) {
186
175
  if (!SLACK_BOT_TOKEN) {
187
176
  console.error("Missing env: SLACK_BOT_TOKEN");
188
177
  process.exit(1);
189
178
  }
190
- await downloadChannel(parsedArgs.downloadChannel, SLACK_BOT_TOKEN);
179
+ await downloadChannel(plan.downloadChannel, SLACK_BOT_TOKEN);
191
180
  process.exit(0);
192
181
  }
193
- // Normal bot mode - require working dir
194
- if (!parsedArgs.workingDir) {
195
- console.error("Usage: mikan [--state-dir=<dir>] [--sandbox=host|container:<name>|image:<image>|firecracker:<vm-id>:<host-path>|cloudflare:<sandbox-id>] <working-directory>");
196
- console.error(" mikan --onboard [--state-dir=<dir>]");
197
- console.error(" mikan --download <channel-id>");
198
- process.exit(1);
199
- }
200
- const { workingDir, sandbox } = { workingDir: parsedArgs.workingDir, sandbox: parsedArgs.sandbox };
201
- const stateDir = parsedArgs.stateDir ?? join(homedir(), ".mikan");
182
+ // Normal bot mode - working dir is optional and defaults under the state dir
183
+ const sandbox = plan.sandbox;
184
+ const stateDir = plan.stateDir;
185
+ const workingDir = plan.workingDir;
202
186
  setEnvAliases("STATE_DIR", stateDir);
203
187
  ensureSecureStateDir(stateDir);
188
+ if (!plan.workingDirExplicit) {
189
+ ensureDirExists(workingDir);
190
+ }
204
191
  try {
205
192
  assertStateDirOutsideWorkspace(stateDir, workingDir, sandbox.type);
206
193
  }
207
194
  catch (error) {
208
195
  handleStartupError(error);
209
196
  }
210
- // Validate platform tokens
211
- const hasSlack = !!(SLACK_APP_TOKEN && SLACK_BOT_TOKEN);
212
- const hasTelegram = !!TELEGRAM_BOT_TOKEN;
213
- const hasDiscord = !!DISCORD_BOT_TOKEN;
214
- if (!hasSlack && !hasTelegram && !hasDiscord) {
215
- console.error("No platform tokens found. Set one of:\n" +
216
- " Slack: SLACK_APP_TOKEN + SLACK_BOT_TOKEN\n" +
217
- " Telegram: TELEGRAM_BOT_TOKEN\n" +
218
- " Discord: DISCORD_BOT_TOKEN");
197
+ // Validate platform tokens — activation rules live in the env manifest.
198
+ const hasSlack = platformIsActive("slack");
199
+ const hasTelegram = platformIsActive("telegram");
200
+ const hasDiscord = platformIsActive("discord");
201
+ const hasGithub = platformIsActive("github");
202
+ if (!hasSlack && !hasTelegram && !hasDiscord && !hasGithub) {
203
+ console.error(noPlatformsMessage());
219
204
  process.exit(1);
220
205
  }
206
+ // Move legacy raw-id conversation directories to the office-key layout before
207
+ // anything touches the workspace. Runs every boot; a completed migration is a
208
+ // no-op. Unowned or failed offices are fatal: after the layout flip a legacy
209
+ // directory is invisible to the runtime, and booting anyway would present
210
+ // those conversations as silently empty.
211
+ const enabledPlatforms = [
212
+ ...(hasSlack ? ["slack"] : []),
213
+ ...(hasTelegram ? ["telegram"] : []),
214
+ ...(hasDiscord ? ["discord"] : []),
215
+ ...(hasGithub ? ["github"] : []),
216
+ ];
217
+ const officeMigration = (() => {
218
+ try {
219
+ return migrateLegacyOffices({ workspaceRoot: workingDir, stateDir, enabledPlatforms });
220
+ }
221
+ catch (error) {
222
+ handleStartupError(error);
223
+ }
224
+ })();
225
+ if (officeMigration.unowned.length > 0 ||
226
+ officeMigration.failed.length > 0 ||
227
+ officeMigration.vaultConflicts.length > 0 ||
228
+ officeMigration.stateDirConflicts.length > 0) {
229
+ console.error(formatUnmigratedOfficesError(officeMigration));
230
+ process.exit(1);
231
+ }
232
+ if (officeMigration.migrated.length > 0 || officeMigration.recovered.length > 0) {
233
+ console.log(` Office layout migration: ${officeMigration.migrated.length} moved, ` +
234
+ `${officeMigration.recovered.length} recovered.`);
235
+ }
236
+ if (officeMigration.vaultKeysMigrated.length > 0) {
237
+ console.log(` Vault keys migrated to office keys: ${officeMigration.vaultKeysMigrated.length}.`);
238
+ }
239
+ if (officeMigration.stateDirsMigrated.length > 0) {
240
+ console.log(` Host state dirs migrated to office keys: ${officeMigration.stateDirsMigrated.length}.`);
241
+ }
221
242
  try {
222
243
  await validateSandbox(sandbox);
223
244
  }
224
245
  catch (error) {
225
246
  handleStartupError(error);
226
247
  }
248
+ // The one Workspace value for this process: workspace-global paths plus the
249
+ // per-conversation Office factory. Constructed after the office migration so
250
+ // every office it materializes lands in the office-key layout.
251
+ const workspace = createWorkspace({ root: workingDir, stateDir });
227
252
  const vaultManager = new FileVaultManager(stateDir);
228
253
  if (vaultManager.isEnabled()) {
229
254
  console.log(sandbox.type === "container"
230
255
  ? " Vault system enabled. Container vault active."
231
- : sandbox.type === "image" || sandbox.type === "firecracker" || sandbox.type === "cloudflare"
256
+ : sandbox.type === "image" ||
257
+ sandbox.type === "gondolin" ||
258
+ sandbox.type === "firecracker" ||
259
+ sandbox.type === "cloudflare"
232
260
  ? " Vault system enabled. Conversation-scoped credential routing active."
233
261
  : " Vault system enabled. Host mode will not inject vault env.");
234
262
  }
@@ -240,11 +268,12 @@ const startupConfig = (() => {
240
268
  handleStartupError(error);
241
269
  }
242
270
  })();
243
- const sandboxLimits = startupConfig.sandboxCpus || startupConfig.sandboxMemory
244
- ? { cpus: startupConfig.sandboxCpus, memory: startupConfig.sandboxMemory }
271
+ const sandboxSettings = startupConfig.sandbox;
272
+ const sandboxLimits = sandboxSettings?.cpus || sandboxSettings?.memory
273
+ ? { cpus: sandboxSettings?.cpus, memory: sandboxSettings?.memory }
245
274
  : undefined;
246
- const sandboxBoostLimits = startupConfig.sandboxBoostCpus || startupConfig.sandboxBoostMemory
247
- ? { cpus: startupConfig.sandboxBoostCpus, memory: startupConfig.sandboxBoostMemory }
275
+ const sandboxBoostLimits = sandboxSettings?.boost?.cpus || sandboxSettings?.boost?.memory
276
+ ? { cpus: sandboxSettings?.boost?.cpus, memory: sandboxSettings?.boost?.memory }
248
277
  : undefined;
249
278
  const provisioner = sandbox.type === "image"
250
279
  ? new DockerContainerManager(sandbox.image, {
@@ -252,11 +281,49 @@ const provisioner = sandbox.type === "image"
252
281
  boostLimits: sandboxBoostLimits,
253
282
  })
254
283
  : undefined;
255
- if (sandbox.type === "image") {
256
- ensureDirExists(join(workingDir, "skills"));
257
- ensureDirExists(join(workingDir, "events"));
284
+ // Containers provisioned before the office migration mount the renamed
285
+ // legacy paths. Their writable layers (everything installed inside) are
286
+ // preserved: each container is committed and recreated with translated
287
+ // mounts — on demand before its next message, and via a background sweep
288
+ // after the bots start. MIKAN_SKIP_CONTAINER_PRESERVATION=1 falls back to
289
+ // plain removal (containers rebuild from the base image on next use).
290
+ const registryOffices = new OfficeRegistry(stateDir).getOffices();
291
+ if (provisioner && registryOffices.length > 0) {
292
+ if (readEnv("SKIP_CONTAINER_PRESERVATION") === "1") {
293
+ if (officeMigration.migrated.length > 0 || officeMigration.recovered.length > 0) {
294
+ await provisioner.removeContainersForConversations(new Set([...officeMigration.migrated, ...officeMigration.recovered]));
295
+ }
296
+ }
297
+ else {
298
+ provisioner.armContainerLayoutMigration(buildContainerBindTranslator({
299
+ offices: registryOffices,
300
+ workspaceRoot: workingDir,
301
+ stateDir,
302
+ }));
303
+ }
304
+ }
305
+ if (sandbox.type === "gondolin") {
258
306
  try {
259
- writeFileSync(join(workingDir, "MEMORY.md"), "", { flag: "wx" });
307
+ configureGondolinRuntime({
308
+ limits: sandboxLimits,
309
+ boostLimits: sandboxBoostLimits,
310
+ });
311
+ }
312
+ catch (error) {
313
+ handleStartupError(error);
314
+ }
315
+ }
316
+ const resourceController = sandbox.type === "image"
317
+ ? provisioner
318
+ : sandbox.type === "gondolin"
319
+ ? gondolinResources
320
+ : undefined;
321
+ if (sandbox.type === "image" || sandbox.type === "gondolin") {
322
+ ensureDirExists(workspace.skillsDir);
323
+ ensureDirExists(workspace.eventsDir);
324
+ ensureDirExists(workspace.agentsDir);
325
+ try {
326
+ writeFileSync(workspace.memoryPath, "", { flag: "wx" });
260
327
  }
261
328
  catch (err) {
262
329
  if (err.code !== "EEXIST")
@@ -270,50 +337,200 @@ setInterval(() => linkTokenStore.purge(), 5 * 60 * 1000).unref();
270
337
  setInterval(() => sessionViewTokenStore.purge(), 5 * 60 * 1000).unref();
271
338
  setInterval(() => adminTokenStore.purge(), 5 * 60 * 1000).unref();
272
339
  function portalBaseUrl() {
273
- if (LINK_URL)
274
- return LINK_URL.replace(/\/+$/, "");
340
+ if (LINK_BASE_URL)
341
+ return LINK_BASE_URL;
275
342
  if (LINK_PORT)
276
343
  return `http://localhost:${LINK_PORT}`;
277
344
  return undefined;
278
345
  }
279
- /** Idle timeout for managed image containers (10 minutes) */
280
- const IMAGE_IDLE_TIMEOUT_MS = 10 * 60 * 1000;
346
+ /** Idle timeout for managed sandboxes (10 minutes) */
347
+ const MANAGED_SANDBOX_IDLE_TIMEOUT_MS = 10 * 60 * 1000;
281
348
  if (provisioner) {
282
349
  await provisioner.reconcile();
283
- await provisioner.stopIdle(IMAGE_IDLE_TIMEOUT_MS);
284
- setInterval(() => provisioner.stopIdle(IMAGE_IDLE_TIMEOUT_MS), IMAGE_IDLE_TIMEOUT_MS).unref();
350
+ await provisioner.stopIdle(MANAGED_SANDBOX_IDLE_TIMEOUT_MS);
351
+ setInterval(() => provisioner.stopIdle(MANAGED_SANDBOX_IDLE_TIMEOUT_MS), MANAGED_SANDBOX_IDLE_TIMEOUT_MS).unref();
352
+ }
353
+ if (sandbox.type === "gondolin") {
354
+ await reconcileGondolinRuntimes();
355
+ setInterval(() => void stopIdleGondolinVms(MANAGED_SANDBOX_IDLE_TIMEOUT_MS), MANAGED_SANDBOX_IDLE_TIMEOUT_MS).unref();
285
356
  }
286
- // Declared before the runtime so the notifier closure can capture them;
287
- // bots register below once their platforms initialize.
288
- const bots = [];
289
357
  const botsByPlatform = {};
290
358
  /**
291
- * Extension `api.notify` backend: post into a conversation without an agent
292
- * run. Platform resolution mirrors event files — explicit platform, or the
293
- * sole running platform.
359
+ * Resolve which platform bot to use: an explicit platform, or the sole
360
+ * running one. Mirrors event-file platform resolution.
294
361
  */
295
- const platformNotifier = async (conversationId, text, platform) => {
362
+ function resolvePlatformBot(op, platform) {
296
363
  const available = Object.keys(botsByPlatform);
297
364
  const key = platform?.trim().toLowerCase() || (available.length === 1 ? available[0] : undefined);
298
365
  const bot = key ? botsByPlatform[key] : undefined;
299
366
  if (!bot) {
300
367
  throw new Error(platform
301
- ? `notify: unknown platform '${platform}' (available: ${available.join(", ") || "none"})`
302
- : `notify: multiple platforms active (${available.join(", ")}); specify platform`);
368
+ ? `${op}: unknown platform '${platform}' (available: ${available.join(", ") || "none"})`
369
+ : `${op}: multiple platforms active (${available.join(", ")}); specify platform`);
370
+ }
371
+ return [key, bot];
372
+ }
373
+ /** Extension `api.notify` backend: post into a conversation without a run. */
374
+ const platformNotifier = async (conversationId, text, options) => {
375
+ const [key, bot] = resolvePlatformBot("notify", options?.platform);
376
+ let messageTs;
377
+ if (options?.threadTs) {
378
+ if (!bot.postInThread) {
379
+ throw new Error(`notify: platform '${key}' does not support threaded posts`);
380
+ }
381
+ messageTs = await bot.postInThread(conversationId, options.threadTs, text);
382
+ }
383
+ else {
384
+ messageTs = await bot.postMessage(conversationId, text);
303
385
  }
304
- await bot.postMessage(conversationId, text);
305
386
  log.logInfo(`[notify] posted to ${key}/${conversationId} (${text.length} chars)`);
387
+ return messageTs;
388
+ };
389
+ /** Extension `api.openDm` backend: resolve a user's DM conversation id. */
390
+ const platformDmOpener = async (userId, platform) => {
391
+ const [key, bot] = resolvePlatformBot("openDm", platform);
392
+ if (!bot.openDirectConversation) {
393
+ throw new Error(`openDm: platform '${key}' does not support opening direct messages`);
394
+ }
395
+ return bot.openDirectConversation(userId);
396
+ };
397
+ /** Extension `api.fetchHistory` backend: read recent conversation messages. */
398
+ const platformHistoryFetcher = async (conversationId, options) => {
399
+ const [key, bot] = resolvePlatformBot("fetchHistory", options?.platform);
400
+ if (!bot.fetchHistory) {
401
+ throw new Error(`fetchHistory: platform '${key}' does not support history reads`);
402
+ }
403
+ const { platform: _platform, ...historyOptions } = options ?? {};
404
+ return bot.fetchHistory(conversationId, historyOptions);
405
+ };
406
+ /** Extension `api.listUsers` backend: list the workspace's active users. */
407
+ const platformUserLister = async (platform) => {
408
+ const [key, bot] = resolvePlatformBot("listUsers", platform);
409
+ if (!bot.listUsers) {
410
+ throw new Error(`listUsers: platform '${key}' does not support user listings`);
411
+ }
412
+ return bot.listUsers();
413
+ };
414
+ /** Extension `api.react` backend: add a reaction to a message. */
415
+ const platformReactor = async (conversationId, messageTs, emoji, platform) => {
416
+ const [key, bot] = resolvePlatformBot("react", platform);
417
+ if (!bot.addReaction) {
418
+ throw new Error(`react: platform '${key}' does not support reactions`);
419
+ }
420
+ await bot.addReaction(conversationId, messageTs, emoji);
421
+ log.logInfo(`[react] :${emoji}: on ${key}/${conversationId}`);
422
+ };
423
+ /** Extension `api.uploadFile` backend: send a host file into a conversation. */
424
+ const platformUploader = async (conversationId, filePath, title, platform) => {
425
+ const [key, bot] = resolvePlatformBot("upload", platform);
426
+ if (!bot.uploadFile) {
427
+ throw new Error(`upload: platform '${key}' does not support file uploads`);
428
+ }
429
+ await bot.uploadFile(conversationId, filePath, title);
430
+ log.logInfo(`[upload] ${filePath} to ${key}/${conversationId}`);
431
+ };
432
+ /** github_* tool backends: PR push/create and CI checks, host-side. */
433
+ function requireGithubBot(op) {
434
+ const bot = botsByPlatform.github;
435
+ if (!bot) {
436
+ throw new Error(`${op}: the GitHub platform is not running`);
437
+ }
438
+ return bot;
439
+ }
440
+ /** slack_* tool backends: Block Kit posting/updating, host-side. */
441
+ function requireSlackBot(op) {
442
+ const bot = botsByPlatform.slack;
443
+ if (!bot) {
444
+ throw new Error(`${op}: the Slack platform is not running`);
445
+ }
446
+ return bot;
447
+ }
448
+ /** Extension `api.blockkit` backend: interactive Block Kit, Slack-only today. */
449
+ const platformBlockKit = {
450
+ postBlocks: async (conversationId, message, platform) => {
451
+ if (platform && platform !== "slack") {
452
+ throw new Error(`blockkit: platform '${platform}' does not support Block Kit`);
453
+ }
454
+ const bot = requireSlackBot("blockkit");
455
+ const ts = message.threadTs
456
+ ? await bot.postInThreadBlocks(conversationId, message.threadTs, message.text, message.blocks)
457
+ : await bot.postMessageBlocks(conversationId, message.text, message.blocks);
458
+ return { ts };
459
+ },
460
+ updateBlocks: async (conversationId, messageTs, message, platform) => {
461
+ if (platform && platform !== "slack") {
462
+ throw new Error(`blockkit: platform '${platform}' does not support Block Kit`);
463
+ }
464
+ await requireSlackBot("blockkit").updateMessageBlocks(conversationId, messageTs, message.text, message.blocks);
465
+ },
306
466
  };
467
+ /**
468
+ * Platform capability pack factories — only when the corresponding bot is
469
+ * configured. Factories, not instances: each runner materializes its own
470
+ * pack so per-run bind state never crosses conversations.
471
+ */
472
+ function buildPlatformToolPackFactories() {
473
+ const factories = [];
474
+ if (hasSlack) {
475
+ const platformSlackOps = {
476
+ postBlocks: async (conversationId, { text, blocks, threadTs }) => {
477
+ const bot = requireSlackBot("slack_blockkit");
478
+ const ts = threadTs
479
+ ? await bot.postInThreadBlocks(conversationId, threadTs, text, blocks)
480
+ : await bot.postMessageBlocks(conversationId, text, blocks);
481
+ bot.logBotResponse(conversationId, text, ts, threadTs, blocks);
482
+ return { ts };
483
+ },
484
+ updateBlocks: async (conversationId, { ts, text, blocks, threadTs }) => {
485
+ const bot = requireSlackBot("slack_blockkit");
486
+ await bot.updateMessageBlocks(conversationId, ts, text, blocks);
487
+ bot.logBotResponse(conversationId, text, ts, threadTs, blocks);
488
+ },
489
+ ownsBlockKitMessage: (conversationId, ts, threadTs) => requireSlackBot("slack_blockkit").ownsBlockKitMessage(conversationId, ts, threadTs),
490
+ };
491
+ factories.push(() => createSlackToolPack(platformSlackOps));
492
+ }
493
+ if (!hasGithub)
494
+ return factories;
495
+ const platformGithubOps = {
496
+ pushAndCreatePr: (conversationId, request) => requireGithubBot("github_pr").ops.pushAndCreatePr(conversationId, request),
497
+ getChecks: (conversationId, branch) => requireGithubBot("github_checks").ops.getChecks(conversationId, branch),
498
+ getJobLog: (conversationId, jobId) => requireGithubBot("github_checks").ops.getJobLog(conversationId, jobId),
499
+ getBuildLog: (conversationId, buildId) => requireGithubBot("github_checks").ops.getBuildLog(conversationId, buildId),
500
+ replyToReviewThread: (conversationId, commentId, body) => requireGithubBot("github_review_reply").ops.replyToReviewThread(conversationId, commentId, body),
501
+ syncRepo: (conversationId, branch) => requireGithubBot("github_sync").ops.syncRepo(conversationId, branch),
502
+ readGithub: (conversationId, request) => requireGithubBot("github_read").ops.readGithub(conversationId, request),
503
+ manageIssue: (conversationId, request) => requireGithubBot("github_issue").ops.manageIssue(conversationId, request),
504
+ };
505
+ factories.push(() => createGithubToolPack(platformGithubOps));
506
+ return factories;
507
+ }
508
+ // Host-authoritative engine for extension callback schedules. Dispatch routes
509
+ // through the runtime so fires run against the conversation's activated
510
+ // extensions; created before the runtime, wired after (mutual reference).
511
+ const extensionScheduleEngine = new ExtensionCallbackScheduler({
512
+ stateDir,
513
+ dispatch: (fire) => handler.handleExtensionScheduleCallback(fire),
514
+ });
307
515
  const handler = createConversationRuntime({
308
- workingDir,
516
+ workspace,
309
517
  sandbox,
310
518
  vaultManager,
311
519
  provisioner,
520
+ resourceController,
312
521
  linkTokenStore,
313
522
  sessionViewTokenStore,
314
523
  adminTokenStore,
315
524
  portalBaseUrl: portalBaseUrl(),
316
525
  platformNotifier,
526
+ platformReactor,
527
+ platformUploader,
528
+ platformBlockKit,
529
+ platformDmOpener,
530
+ platformHistoryFetcher,
531
+ platformUserLister,
532
+ extensionScheduleEngine,
533
+ platformToolPackFactories: buildPlatformToolPackFactories(),
317
534
  });
318
535
  const sandboxDesc = sandbox.type === "host"
319
536
  ? "host"
@@ -321,9 +538,11 @@ const sandboxDesc = sandbox.type === "host"
321
538
  ? `container:${sandbox.container}`
322
539
  : sandbox.type === "image"
323
540
  ? `image:${sandbox.image}`
324
- : sandbox.type === "firecracker"
325
- ? `firecracker:${sandbox.vmId}`
326
- : `cloudflare:${sandbox.sandboxId}`;
541
+ : sandbox.type === "gondolin"
542
+ ? `gondolin:${sandbox.profile}`
543
+ : sandbox.type === "firecracker"
544
+ ? `firecracker:${sandbox.vmId}`
545
+ : `cloudflare:${sandbox.sandboxId}`;
327
546
  log.logStartup(workingDir, sandboxDesc);
328
547
  logHarnessStartupSummary();
329
548
  /**
@@ -361,14 +580,11 @@ if (hasSlack) {
361
580
  if (!slackMessagingBotToken || !slackAppToken) {
362
581
  throw new Error("Slack startup requires both SLACK_APP_TOKEN and SLACK_BOT_TOKEN");
363
582
  }
364
- const sharedStore = new ChannelStore({ workingDir, botToken: slackMessagingBotToken });
365
583
  const slackMessagingBot = new SlackMessagingBotClass(handler, {
366
584
  appToken: slackAppToken,
367
585
  botToken: slackMessagingBotToken,
368
- workingDir,
369
- store: sharedStore,
586
+ workspace,
370
587
  });
371
- bots.push(slackMessagingBot);
372
588
  botsByPlatform.slack = slackMessagingBot;
373
589
  log.logInfo("Platform: Slack");
374
590
  }
@@ -379,9 +595,8 @@ if (hasTelegram) {
379
595
  }
380
596
  const telegramMessagingBot = new TelegramMessagingBot(handler, {
381
597
  token: telegramToken,
382
- workingDir,
598
+ workspace,
383
599
  });
384
- bots.push(telegramMessagingBot);
385
600
  botsByPlatform.telegram = telegramMessagingBot;
386
601
  log.logInfo("Platform: Telegram");
387
602
  }
@@ -392,12 +607,51 @@ if (hasDiscord) {
392
607
  }
393
608
  const discordMessagingBot = new DiscordMessagingBot(handler, {
394
609
  token: discordToken,
395
- workingDir,
610
+ workspace,
396
611
  });
397
- bots.push(discordMessagingBot);
398
612
  botsByPlatform.discord = discordMessagingBot;
399
613
  log.logInfo("Platform: Discord");
400
614
  }
615
+ if (hasGithub) {
616
+ if (!GITHUB_APP_ID || !GITHUB_INSTALLATION_ID) {
617
+ throw new Error("GitHub startup requires GITHUB_APP_ID and GITHUB_INSTALLATION_ID");
618
+ }
619
+ // Env vars flatten PEM newlines to literal `\n`; a key file avoids that.
620
+ const githubPrivateKey = GITHUB_APP_PRIVATE_KEY_PATH
621
+ ? readFileSync(GITHUB_APP_PRIVATE_KEY_PATH, "utf-8")
622
+ : GITHUB_APP_PRIVATE_KEY?.replace(/\\n/g, "\n");
623
+ if (!githubPrivateKey) {
624
+ throw new Error("GitHub startup requires GITHUB_APP_PRIVATE_KEY or GITHUB_APP_PRIVATE_KEY_PATH");
625
+ }
626
+ const pollIntervalSeconds = GITHUB_POLL_INTERVAL ? parseInt(GITHUB_POLL_INTERVAL, 10) : NaN;
627
+ const githubMessagingBot = new GithubMessagingBot(handler, {
628
+ appId: GITHUB_APP_ID,
629
+ privateKey: githubPrivateKey,
630
+ installationId: GITHUB_INSTALLATION_ID,
631
+ repos: GITHUB_REPOS
632
+ ? GITHUB_REPOS.split(",")
633
+ .map((repo) => repo.trim())
634
+ .filter(Boolean)
635
+ : [],
636
+ pollIntervalMs: (Number.isFinite(pollIntervalSeconds) && pollIntervalSeconds > 0 ? pollIntervalSeconds : 60) *
637
+ 1000,
638
+ workspace,
639
+ syncStatePath: join(stateDir, "github-sync.json"),
640
+ // Host-side GCP creds (e.g. a WIF external_account file) unlock Cloud
641
+ // Build logs in github_checks; without them external CI degrades to
642
+ // guidance text. Credentials never enter the sandbox.
643
+ cloudBuild: GOOGLE_APPLICATION_CREDENTIALS
644
+ ? {
645
+ tokenProvider: new GcpTokenProvider({
646
+ credentialsPath: GOOGLE_APPLICATION_CREDENTIALS,
647
+ }),
648
+ projectFallback: GOOGLE_CLOUD_PROJECT,
649
+ }
650
+ : undefined,
651
+ });
652
+ botsByPlatform.github = githubMessagingBot;
653
+ log.logInfo(`Platform: GitHub${GOOGLE_APPLICATION_CREDENTIALS ? " (Cloud Build logs enabled)" : ""}`);
654
+ }
401
655
  if (LINK_PORT) {
402
656
  startWebServer({
403
657
  port: LINK_PORT,
@@ -410,28 +664,38 @@ if (LINK_PORT) {
410
664
  },
411
665
  sessionViewTokenStore,
412
666
  sessionViewInteractive: { handler, botsByPlatform },
413
- adminOptions: { adminTokenStore, workingDir, runtime: handler, sandbox, botsByPlatform },
667
+ adminOptions: { adminTokenStore, workspace, runtime: handler, sandbox, botsByPlatform },
414
668
  });
415
669
  }
416
670
  // Start events watcher with explicit platform routing
417
- const eventsWatcher = new EventsWatcher(join(workingDir, "events"), botsByPlatform);
671
+ const eventsWatcher = new EventsWatcher(workspace.eventsDir, botsByPlatform);
418
672
  const slackMessagingBot = botsByPlatform.slack;
419
673
  if (slackMessagingBot) {
420
674
  slackMessagingBot.setEventsWatcher(eventsWatcher);
421
675
  }
422
676
  eventsWatcher.start();
677
+ extensionScheduleEngine.start();
423
678
  // Handle shutdown
424
679
  async function shutdown() {
425
680
  await handler.shutdown();
426
681
  eventsWatcher.stop();
682
+ extensionScheduleEngine.stop();
683
+ await stopAllGondolinRuntimes();
427
684
  await Sentry.close(5000);
428
685
  process.exit(0);
429
686
  }
430
687
  process.on("SIGINT", shutdown);
431
688
  process.on("SIGTERM", shutdown);
432
689
  // Start all bots
433
- await Promise.all(bots.map((bot) => bot.start().catch((err) => {
690
+ await Promise.all(Object.values(botsByPlatform).map((bot) => bot.start().catch((err) => {
434
691
  log.logWarning("Failed to start bot", err instanceof Error ? err.message : String(err));
435
692
  process.exit(1);
436
693
  })));
694
+ // Drain the container layout migration off the hot path; every unit is
695
+ // idempotent, so an interrupted sweep simply resumes on the next boot.
696
+ if (provisioner) {
697
+ void provisioner.sweepContainerLayoutMigration().catch((err) => {
698
+ log.logWarning("Container layout sweep failed", err instanceof Error ? err.message : String(err));
699
+ });
700
+ }
437
701
  //# sourceMappingURL=main.js.map