@geminixiang/mikan 1.0.0-beta.7 → 1.0.0-beta.71

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 (856) hide show
  1. package/CHANGELOG.md +1052 -0
  2. package/README.md +98 -38
  3. package/dist/adapters/commands/admin.d.ts.map +1 -0
  4. package/dist/{commands → adapters/commands}/admin.js +11 -8
  5. package/dist/adapters/commands/admin.js.map +1 -0
  6. package/dist/{commands → adapters/commands}/auto-reply.d.ts +0 -3
  7. package/dist/adapters/commands/auto-reply.d.ts.map +1 -0
  8. package/dist/adapters/commands/auto-reply.js +47 -0
  9. package/dist/adapters/commands/auto-reply.js.map +1 -0
  10. package/dist/adapters/commands/login.d.ts +6 -0
  11. package/dist/adapters/commands/login.d.ts.map +1 -0
  12. package/dist/adapters/commands/login.js +166 -0
  13. package/dist/adapters/commands/login.js.map +1 -0
  14. package/dist/adapters/commands/manifest.d.ts +37 -0
  15. package/dist/adapters/commands/manifest.d.ts.map +1 -0
  16. package/dist/adapters/commands/manifest.js +155 -0
  17. package/dist/adapters/commands/manifest.js.map +1 -0
  18. package/dist/adapters/commands/model.d.ts +15 -0
  19. package/dist/adapters/commands/model.d.ts.map +1 -0
  20. package/dist/adapters/commands/model.js +153 -0
  21. package/dist/adapters/commands/model.js.map +1 -0
  22. package/dist/adapters/commands/new.d.ts.map +1 -0
  23. package/dist/adapters/commands/new.js +41 -0
  24. package/dist/adapters/commands/new.js.map +1 -0
  25. package/dist/adapters/commands/registry.d.ts +5 -0
  26. package/dist/adapters/commands/registry.d.ts.map +1 -0
  27. package/dist/adapters/commands/registry.js +43 -0
  28. package/dist/adapters/commands/registry.js.map +1 -0
  29. package/dist/adapters/commands/sandbox.d.ts.map +1 -0
  30. package/dist/adapters/commands/sandbox.js +125 -0
  31. package/dist/adapters/commands/sandbox.js.map +1 -0
  32. package/dist/adapters/commands/session-view.d.ts.map +1 -0
  33. package/dist/{commands → adapters/commands}/session-view.js +23 -16
  34. package/dist/adapters/commands/session-view.js.map +1 -0
  35. package/dist/adapters/commands/types.d.ts +145 -0
  36. package/dist/adapters/commands/types.d.ts.map +1 -0
  37. package/dist/adapters/commands/types.js.map +1 -0
  38. package/dist/adapters/commands/utils.d.ts +14 -0
  39. package/dist/adapters/commands/utils.d.ts.map +1 -0
  40. package/dist/{commands → adapters/commands}/utils.js +18 -1
  41. package/dist/adapters/commands/utils.js.map +1 -0
  42. package/dist/adapters/discord/bot.d.ts +11 -8
  43. package/dist/adapters/discord/bot.d.ts.map +1 -1
  44. package/dist/adapters/discord/bot.js +223 -256
  45. package/dist/adapters/discord/bot.js.map +1 -1
  46. package/dist/adapters/discord/components.d.ts +28 -0
  47. package/dist/adapters/discord/components.d.ts.map +1 -0
  48. package/dist/adapters/discord/components.js +32 -0
  49. package/dist/adapters/discord/components.js.map +1 -0
  50. package/dist/adapters/discord/context.d.ts +2 -6
  51. package/dist/adapters/discord/context.d.ts.map +1 -1
  52. package/dist/adapters/discord/context.js +64 -218
  53. package/dist/adapters/discord/context.js.map +1 -1
  54. package/dist/adapters/discord/format.d.ts +3 -0
  55. package/dist/adapters/discord/format.d.ts.map +1 -0
  56. package/dist/adapters/discord/format.js +84 -0
  57. package/dist/adapters/discord/format.js.map +1 -0
  58. package/dist/adapters/discord/types.d.ts +8 -1
  59. package/dist/adapters/discord/types.d.ts.map +1 -1
  60. package/dist/adapters/discord/types.js.map +1 -1
  61. package/dist/adapters/github/bot.d.ts +102 -0
  62. package/dist/adapters/github/bot.d.ts.map +1 -0
  63. package/dist/adapters/github/bot.js +720 -0
  64. package/dist/adapters/github/bot.js.map +1 -0
  65. package/dist/adapters/github/client.d.ts +122 -0
  66. package/dist/adapters/github/client.d.ts.map +1 -0
  67. package/dist/adapters/github/client.js +301 -0
  68. package/dist/adapters/github/client.js.map +1 -0
  69. package/dist/adapters/github/context.d.ts +5 -0
  70. package/dist/adapters/github/context.d.ts.map +1 -0
  71. package/dist/adapters/github/context.js +101 -0
  72. package/dist/adapters/github/context.js.map +1 -0
  73. package/dist/adapters/github/github-ops.d.ts +78 -0
  74. package/dist/adapters/github/github-ops.d.ts.map +1 -0
  75. package/dist/adapters/github/github-ops.js +337 -0
  76. package/dist/adapters/github/github-ops.js.map +1 -0
  77. package/dist/adapters/github/ids.d.ts +34 -0
  78. package/dist/adapters/github/ids.d.ts.map +1 -0
  79. package/dist/adapters/github/ids.js +57 -0
  80. package/dist/adapters/github/ids.js.map +1 -0
  81. package/dist/adapters/github/repo.d.ts +33 -0
  82. package/dist/adapters/github/repo.d.ts.map +1 -0
  83. package/dist/adapters/github/repo.js +141 -0
  84. package/dist/adapters/github/repo.js.map +1 -0
  85. package/dist/adapters/github/tool-pack.d.ts +14 -0
  86. package/dist/adapters/github/tool-pack.d.ts.map +1 -0
  87. package/dist/adapters/github/tool-pack.js +55 -0
  88. package/dist/adapters/github/tool-pack.js.map +1 -0
  89. package/dist/adapters/github/tools/checks.d.ts +18 -0
  90. package/dist/adapters/github/tools/checks.d.ts.map +1 -0
  91. package/dist/adapters/github/tools/checks.js +86 -0
  92. package/dist/adapters/github/tools/checks.js.map +1 -0
  93. package/dist/adapters/github/tools/issue.d.ts +21 -0
  94. package/dist/adapters/github/tools/issue.d.ts.map +1 -0
  95. package/dist/adapters/github/tools/issue.js +48 -0
  96. package/dist/adapters/github/tools/issue.js.map +1 -0
  97. package/dist/adapters/github/tools/pr.d.ts +22 -0
  98. package/dist/adapters/github/tools/pr.d.ts.map +1 -0
  99. package/dist/adapters/github/tools/pr.js +48 -0
  100. package/dist/adapters/github/tools/pr.js.map +1 -0
  101. package/dist/adapters/github/tools/read.d.ts +21 -0
  102. package/dist/adapters/github/tools/read.d.ts.map +1 -0
  103. package/dist/adapters/github/tools/read.js +141 -0
  104. package/dist/adapters/github/tools/read.js.map +1 -0
  105. package/dist/adapters/github/tools/review-reply.d.ts +17 -0
  106. package/dist/adapters/github/tools/review-reply.d.ts.map +1 -0
  107. package/dist/adapters/github/tools/review-reply.js +38 -0
  108. package/dist/adapters/github/tools/review-reply.js.map +1 -0
  109. package/dist/adapters/github/tools/sync.d.ts +17 -0
  110. package/dist/adapters/github/tools/sync.d.ts.map +1 -0
  111. package/dist/adapters/github/tools/sync.js +34 -0
  112. package/dist/adapters/github/tools/sync.js.map +1 -0
  113. package/dist/adapters/github/types.d.ts +345 -0
  114. package/dist/adapters/github/types.d.ts.map +1 -0
  115. package/dist/adapters/github/types.js.map +1 -0
  116. package/dist/adapters/github/webhook.d.ts +20 -0
  117. package/dist/adapters/github/webhook.d.ts.map +1 -0
  118. package/dist/adapters/github/webhook.js +78 -0
  119. package/dist/adapters/github/webhook.js.map +1 -0
  120. package/dist/adapters/index.d.ts +12 -0
  121. package/dist/adapters/index.d.ts.map +1 -0
  122. package/dist/adapters/index.js +19 -0
  123. package/dist/adapters/index.js.map +1 -0
  124. package/dist/adapters/intake.d.ts +17 -6
  125. package/dist/adapters/intake.d.ts.map +1 -1
  126. package/dist/adapters/intake.js +96 -27
  127. package/dist/adapters/intake.js.map +1 -1
  128. package/dist/adapters/markdown-tables.d.ts +19 -0
  129. package/dist/adapters/markdown-tables.d.ts.map +1 -0
  130. package/dist/adapters/markdown-tables.js +152 -0
  131. package/dist/adapters/markdown-tables.js.map +1 -0
  132. package/dist/{platform-messages.d.ts → adapters/messages.d.ts} +3 -2
  133. package/dist/adapters/messages.d.ts.map +1 -0
  134. package/dist/{platform-messages.js → adapters/messages.js} +4 -1
  135. package/dist/adapters/messages.js.map +1 -0
  136. package/dist/adapters/progressive-renderer.d.ts +7 -0
  137. package/dist/adapters/progressive-renderer.d.ts.map +1 -0
  138. package/dist/adapters/progressive-renderer.js +443 -0
  139. package/dist/adapters/progressive-renderer.js.map +1 -0
  140. package/dist/adapters/shared.d.ts +37 -11
  141. package/dist/adapters/shared.d.ts.map +1 -1
  142. package/dist/adapters/shared.js +130 -24
  143. package/dist/adapters/shared.js.map +1 -1
  144. package/dist/adapters/slack/assistant.d.ts +73 -0
  145. package/dist/adapters/slack/assistant.d.ts.map +1 -0
  146. package/dist/adapters/slack/assistant.js +205 -0
  147. package/dist/adapters/slack/assistant.js.map +1 -0
  148. package/dist/adapters/slack/auto-reply-context.d.ts +21 -0
  149. package/dist/adapters/slack/auto-reply-context.d.ts.map +1 -0
  150. package/dist/adapters/slack/auto-reply-context.js +28 -0
  151. package/dist/adapters/slack/auto-reply-context.js.map +1 -0
  152. package/dist/adapters/slack/blocks.d.ts +14 -0
  153. package/dist/adapters/slack/blocks.d.ts.map +1 -1
  154. package/dist/adapters/slack/blocks.js +104 -148
  155. package/dist/adapters/slack/blocks.js.map +1 -1
  156. package/dist/adapters/slack/bot.d.ts +154 -21
  157. package/dist/adapters/slack/bot.d.ts.map +1 -1
  158. package/dist/adapters/slack/bot.js +1037 -484
  159. package/dist/adapters/slack/bot.js.map +1 -1
  160. package/dist/adapters/slack/context.d.ts +2 -6
  161. package/dist/adapters/slack/context.d.ts.map +1 -1
  162. package/dist/adapters/slack/context.js +11 -17
  163. package/dist/adapters/slack/context.js.map +1 -1
  164. package/dist/adapters/slack/jev-context.d.ts +30 -0
  165. package/dist/adapters/slack/jev-context.d.ts.map +1 -0
  166. package/dist/adapters/slack/jev-context.js +67 -0
  167. package/dist/adapters/slack/jev-context.js.map +1 -0
  168. package/dist/adapters/slack/markdown.d.ts +3 -0
  169. package/dist/adapters/slack/markdown.d.ts.map +1 -0
  170. package/dist/adapters/slack/markdown.js +48 -0
  171. package/dist/adapters/slack/markdown.js.map +1 -0
  172. package/dist/adapters/slack/persona.d.ts +15 -0
  173. package/dist/adapters/slack/persona.d.ts.map +1 -0
  174. package/dist/adapters/slack/persona.js +22 -0
  175. package/dist/adapters/slack/persona.js.map +1 -0
  176. package/dist/adapters/slack/response-lifecycle.d.ts +1 -1
  177. package/dist/adapters/slack/response-lifecycle.d.ts.map +1 -1
  178. package/dist/adapters/slack/response-lifecycle.js +261 -345
  179. package/dist/adapters/slack/response-lifecycle.js.map +1 -1
  180. package/dist/adapters/slack/session.d.ts.map +1 -1
  181. package/dist/adapters/slack/session.js +7 -11
  182. package/dist/adapters/slack/session.js.map +1 -1
  183. package/dist/adapters/slack/stream-limits.d.ts +35 -0
  184. package/dist/adapters/slack/stream-limits.d.ts.map +1 -0
  185. package/dist/adapters/slack/stream-limits.js +56 -0
  186. package/dist/adapters/slack/stream-limits.js.map +1 -0
  187. package/dist/adapters/slack/task-intent.d.ts +32 -0
  188. package/dist/adapters/slack/task-intent.d.ts.map +1 -0
  189. package/dist/adapters/slack/task-intent.js +72 -0
  190. package/dist/adapters/slack/task-intent.js.map +1 -0
  191. package/dist/adapters/slack/task-status.d.ts +7 -0
  192. package/dist/adapters/slack/task-status.d.ts.map +1 -0
  193. package/dist/adapters/slack/task-status.js +107 -0
  194. package/dist/adapters/slack/task-status.js.map +1 -0
  195. package/dist/adapters/slack/tool-pack.d.ts +11 -0
  196. package/dist/adapters/slack/tool-pack.d.ts.map +1 -0
  197. package/dist/adapters/slack/tool-pack.js +45 -0
  198. package/dist/adapters/slack/tool-pack.js.map +1 -0
  199. package/dist/adapters/slack/tools/blockkit.d.ts +14 -0
  200. package/dist/adapters/slack/tools/blockkit.d.ts.map +1 -0
  201. package/dist/adapters/slack/tools/blockkit.js +106 -0
  202. package/dist/adapters/slack/tools/blockkit.js.map +1 -0
  203. package/dist/adapters/slack/types.d.ts +73 -2
  204. package/dist/adapters/slack/types.d.ts.map +1 -1
  205. package/dist/adapters/slack/types.js.map +1 -1
  206. package/dist/adapters/slack/update-diagnostics.d.ts +14 -0
  207. package/dist/adapters/slack/update-diagnostics.d.ts.map +1 -0
  208. package/dist/adapters/slack/update-diagnostics.js +134 -0
  209. package/dist/adapters/slack/update-diagnostics.js.map +1 -0
  210. package/dist/adapters/telegram/bot.d.ts +10 -9
  211. package/dist/adapters/telegram/bot.d.ts.map +1 -1
  212. package/dist/adapters/telegram/bot.js +133 -202
  213. package/dist/adapters/telegram/bot.js.map +1 -1
  214. package/dist/adapters/telegram/context.d.ts +2 -6
  215. package/dist/adapters/telegram/context.d.ts.map +1 -1
  216. package/dist/adapters/telegram/context.js +53 -190
  217. package/dist/adapters/telegram/context.js.map +1 -1
  218. package/dist/adapters/telegram/types.d.ts +1 -1
  219. package/dist/adapters/telegram/types.d.ts.map +1 -1
  220. package/dist/adapters/telegram/types.js.map +1 -1
  221. package/dist/adapters/types.d.ts +144 -13
  222. package/dist/adapters/types.d.ts.map +1 -1
  223. package/dist/adapters/types.js.map +1 -1
  224. package/dist/adapters/web/admin/portal.d.ts +44 -0
  225. package/dist/adapters/web/admin/portal.d.ts.map +1 -0
  226. package/dist/adapters/web/admin/portal.js +3207 -0
  227. package/dist/adapters/web/admin/portal.js.map +1 -0
  228. package/dist/{web → adapters/web}/admin/provider-models.d.ts +1 -1
  229. package/dist/adapters/web/admin/provider-models.d.ts.map +1 -0
  230. package/dist/{web → adapters/web}/admin/provider-models.js +1 -1
  231. package/dist/adapters/web/admin/provider-models.js.map +1 -0
  232. package/dist/adapters/web/admin/types.d.ts +53 -0
  233. package/dist/adapters/web/admin/types.d.ts.map +1 -0
  234. package/dist/adapters/web/admin/types.js.map +1 -0
  235. package/dist/adapters/web/login/oauth.d.ts +5 -0
  236. package/dist/adapters/web/login/oauth.d.ts.map +1 -0
  237. package/dist/{web → adapters/web}/login/oauth.js +50 -85
  238. package/dist/adapters/web/login/oauth.js.map +1 -0
  239. package/dist/{web → adapters/web}/login/portal.d.ts +9 -3
  240. package/dist/adapters/web/login/portal.d.ts.map +1 -0
  241. package/dist/{web → adapters/web}/login/portal.js +161 -119
  242. package/dist/adapters/web/login/portal.js.map +1 -0
  243. package/dist/{web → adapters/web}/login/types.d.ts +1 -12
  244. package/dist/adapters/web/login/types.d.ts.map +1 -0
  245. package/dist/adapters/web/login/types.js.map +1 -0
  246. package/dist/adapters/web/portal-shell.d.ts +22 -0
  247. package/dist/adapters/web/portal-shell.d.ts.map +1 -0
  248. package/dist/{portal-shell.js → adapters/web/portal-shell.js} +78 -2
  249. package/dist/adapters/web/portal-shell.js.map +1 -0
  250. package/dist/{web → adapters/web}/server.d.ts +14 -8
  251. package/dist/adapters/web/server.d.ts.map +1 -0
  252. package/dist/{web → adapters/web}/server.js +14 -7
  253. package/dist/adapters/web/server.js.map +1 -0
  254. package/dist/adapters/web/session-view/portal.d.ts +20 -0
  255. package/dist/adapters/web/session-view/portal.d.ts.map +1 -0
  256. package/dist/{web → adapters/web}/session-view/portal.js +633 -162
  257. package/dist/adapters/web/session-view/portal.js.map +1 -0
  258. package/dist/{web → adapters/web}/session-view/types.d.ts +11 -6
  259. package/dist/adapters/web/session-view/types.d.ts.map +1 -0
  260. package/dist/adapters/web/session-view/types.js.map +1 -0
  261. package/dist/adapters/web/token-store.d.ts.map +1 -0
  262. package/dist/{web → adapters/web}/token-store.js +1 -1
  263. package/dist/adapters/web/token-store.js.map +1 -0
  264. package/dist/adapters/web/types.d.ts.map +1 -0
  265. package/dist/adapters/web/types.js.map +1 -0
  266. package/dist/cli/arg-grammar.d.ts +11 -0
  267. package/dist/cli/arg-grammar.d.ts.map +1 -0
  268. package/dist/cli/arg-grammar.js +50 -0
  269. package/dist/cli/arg-grammar.js.map +1 -0
  270. package/dist/cli/boot.d.ts +5 -0
  271. package/dist/cli/boot.d.ts.map +1 -0
  272. package/dist/cli/boot.js +90 -0
  273. package/dist/cli/boot.js.map +1 -0
  274. package/dist/cli/download.d.ts.map +1 -0
  275. package/dist/cli/download.js +88 -0
  276. package/dist/cli/download.js.map +1 -0
  277. package/dist/cli/office.d.ts +2 -0
  278. package/dist/cli/office.d.ts.map +1 -0
  279. package/dist/cli/office.js +181 -0
  280. package/dist/cli/office.js.map +1 -0
  281. package/dist/cli/onboard.d.ts +10 -0
  282. package/dist/cli/onboard.d.ts.map +1 -0
  283. package/dist/cli/onboard.js +225 -0
  284. package/dist/cli/onboard.js.map +1 -0
  285. package/dist/cli/process-lifecycle.d.ts +19 -0
  286. package/dist/cli/process-lifecycle.d.ts.map +1 -0
  287. package/dist/cli/process-lifecycle.js +67 -0
  288. package/dist/cli/process-lifecycle.js.map +1 -0
  289. package/dist/cli/sessions.d.ts +2 -0
  290. package/dist/cli/sessions.d.ts.map +1 -0
  291. package/dist/cli/sessions.js +88 -0
  292. package/dist/cli/sessions.js.map +1 -0
  293. package/dist/cli/types.d.ts +25 -0
  294. package/dist/cli/types.d.ts.map +1 -0
  295. package/dist/cli/types.js.map +1 -0
  296. package/dist/dream/index.d.ts +20 -0
  297. package/dist/dream/index.d.ts.map +1 -0
  298. package/dist/dream/index.js +264 -0
  299. package/dist/dream/index.js.map +1 -0
  300. package/dist/dream/types.d.ts +30 -0
  301. package/dist/dream/types.d.ts.map +1 -0
  302. package/dist/dream/types.js +2 -0
  303. package/dist/dream/types.js.map +1 -0
  304. package/dist/env-manifest.d.ts +38 -0
  305. package/dist/env-manifest.d.ts.map +1 -0
  306. package/dist/env-manifest.js +260 -0
  307. package/dist/env-manifest.js.map +1 -0
  308. package/dist/events/index.d.ts +172 -0
  309. package/dist/events/index.d.ts.map +1 -0
  310. package/dist/events/index.js +340 -0
  311. package/dist/events/index.js.map +1 -0
  312. package/dist/events/scheduler.d.ts +34 -0
  313. package/dist/events/scheduler.d.ts.map +1 -0
  314. package/dist/events/scheduler.js +231 -0
  315. package/dist/events/scheduler.js.map +1 -0
  316. package/dist/file-guards.d.ts +26 -0
  317. package/dist/file-guards.d.ts.map +1 -0
  318. package/dist/file-guards.js +133 -0
  319. package/dist/file-guards.js.map +1 -0
  320. package/dist/harness/execution-env.d.ts +19 -0
  321. package/dist/harness/execution-env.d.ts.map +1 -0
  322. package/dist/harness/execution-env.js +262 -0
  323. package/dist/harness/execution-env.js.map +1 -0
  324. package/dist/harness/execution-resolver.d.ts +25 -0
  325. package/dist/harness/execution-resolver.d.ts.map +1 -0
  326. package/dist/harness/execution-resolver.js +156 -0
  327. package/dist/harness/execution-resolver.js.map +1 -0
  328. package/dist/harness/index.d.ts +18 -13
  329. package/dist/harness/index.d.ts.map +1 -1
  330. package/dist/harness/index.js +11 -11
  331. package/dist/harness/index.js.map +1 -1
  332. package/dist/harness/jev.d.ts +86 -0
  333. package/dist/harness/jev.d.ts.map +1 -0
  334. package/dist/harness/jev.js +167 -0
  335. package/dist/harness/jev.js.map +1 -0
  336. package/dist/harness/mcp.d.ts +38 -0
  337. package/dist/harness/mcp.d.ts.map +1 -0
  338. package/dist/harness/mcp.js +304 -0
  339. package/dist/harness/mcp.js.map +1 -0
  340. package/dist/harness/models.d.ts +7 -4
  341. package/dist/harness/models.d.ts.map +1 -1
  342. package/dist/harness/models.js +54 -55
  343. package/dist/harness/models.js.map +1 -1
  344. package/dist/harness/open-connector.d.ts +25 -0
  345. package/dist/harness/open-connector.d.ts.map +1 -0
  346. package/dist/harness/open-connector.js +178 -0
  347. package/dist/harness/open-connector.js.map +1 -0
  348. package/dist/harness/presenter.d.ts +31 -0
  349. package/dist/harness/presenter.d.ts.map +1 -0
  350. package/dist/harness/presenter.js +859 -0
  351. package/dist/harness/presenter.js.map +1 -0
  352. package/dist/harness/prompt.d.ts +30 -0
  353. package/dist/harness/prompt.d.ts.map +1 -0
  354. package/dist/harness/prompt.js +420 -0
  355. package/dist/harness/prompt.js.map +1 -0
  356. package/dist/harness/runner.d.ts +2 -123
  357. package/dist/harness/runner.d.ts.map +1 -1
  358. package/dist/harness/runner.js +551 -416
  359. package/dist/harness/runner.js.map +1 -1
  360. package/dist/harness/session.d.ts +122 -0
  361. package/dist/harness/session.d.ts.map +1 -0
  362. package/dist/harness/session.js +581 -0
  363. package/dist/harness/session.js.map +1 -0
  364. package/dist/harness/skills.d.ts +17 -28
  365. package/dist/harness/skills.d.ts.map +1 -1
  366. package/dist/harness/skills.js +104 -39
  367. package/dist/harness/skills.js.map +1 -1
  368. package/dist/harness/subagent-profiles.d.ts +8 -0
  369. package/dist/harness/subagent-profiles.d.ts.map +1 -0
  370. package/dist/harness/subagent-profiles.js +293 -0
  371. package/dist/harness/subagent-profiles.js.map +1 -0
  372. package/dist/harness/subagent.d.ts +64 -0
  373. package/dist/harness/subagent.d.ts.map +1 -0
  374. package/dist/harness/subagent.js +687 -0
  375. package/dist/harness/subagent.js.map +1 -0
  376. package/dist/harness/tools/attach.d.ts.map +1 -0
  377. package/dist/{adapters/slack → harness}/tools/attach.js +1 -1
  378. package/dist/harness/tools/attach.js.map +1 -0
  379. package/dist/{tools → harness/tools}/event.d.ts +4 -33
  380. package/dist/harness/tools/event.d.ts.map +1 -0
  381. package/dist/harness/tools/event.js +175 -0
  382. package/dist/harness/tools/event.js.map +1 -0
  383. package/dist/harness/tools/generate-image.d.ts +23 -0
  384. package/dist/harness/tools/generate-image.d.ts.map +1 -0
  385. package/dist/harness/tools/generate-image.js +65 -0
  386. package/dist/harness/tools/generate-image.js.map +1 -0
  387. package/dist/harness/tools/host-fn-tool.d.ts +21 -0
  388. package/dist/harness/tools/host-fn-tool.d.ts.map +1 -0
  389. package/dist/harness/tools/host-fn-tool.js +32 -0
  390. package/dist/harness/tools/host-fn-tool.js.map +1 -0
  391. package/dist/harness/tools/index.d.ts +41 -0
  392. package/dist/harness/tools/index.d.ts.map +1 -0
  393. package/dist/harness/tools/index.js +51 -0
  394. package/dist/harness/tools/index.js.map +1 -0
  395. package/dist/harness/tools/jev.d.ts +21 -0
  396. package/dist/harness/tools/jev.d.ts.map +1 -0
  397. package/dist/harness/tools/jev.js +109 -0
  398. package/dist/harness/tools/jev.js.map +1 -0
  399. package/dist/harness/tools/pi-tools.d.ts +18 -0
  400. package/dist/harness/tools/pi-tools.d.ts.map +1 -0
  401. package/dist/harness/tools/pi-tools.js +84 -0
  402. package/dist/harness/tools/pi-tools.js.map +1 -0
  403. package/dist/harness/tools/react.d.ts.map +1 -0
  404. package/dist/{tools → harness/tools}/react.js +6 -17
  405. package/dist/harness/tools/react.js.map +1 -0
  406. package/dist/{tools → harness/tools}/sandbox.d.ts +4 -4
  407. package/dist/harness/tools/sandbox.d.ts.map +1 -0
  408. package/dist/{tools → harness/tools}/sandbox.js +12 -8
  409. package/dist/harness/tools/sandbox.js.map +1 -0
  410. package/dist/harness/tools/subagent.d.ts +85 -0
  411. package/dist/harness/tools/subagent.d.ts.map +1 -0
  412. package/dist/harness/tools/subagent.js +677 -0
  413. package/dist/harness/tools/subagent.js.map +1 -0
  414. package/dist/harness/tools/task.d.ts +20 -0
  415. package/dist/harness/tools/task.d.ts.map +1 -0
  416. package/dist/harness/tools/task.js +79 -0
  417. package/dist/harness/tools/task.js.map +1 -0
  418. package/dist/harness/tools/types.d.ts +29 -0
  419. package/dist/harness/tools/types.d.ts.map +1 -0
  420. package/dist/harness/tools/types.js +2 -0
  421. package/dist/harness/tools/types.js.map +1 -0
  422. package/dist/harness/types.d.ts +384 -25
  423. package/dist/harness/types.d.ts.map +1 -1
  424. package/dist/harness/types.js +1 -1
  425. package/dist/harness/types.js.map +1 -1
  426. package/dist/index.d.ts +33 -9
  427. package/dist/index.d.ts.map +1 -1
  428. package/dist/index.js +19 -6
  429. package/dist/index.js.map +1 -1
  430. package/dist/log.d.ts.map +1 -1
  431. package/dist/log.js +4 -1
  432. package/dist/log.js.map +1 -1
  433. package/dist/main.js +357 -198
  434. package/dist/main.js.map +1 -1
  435. package/dist/observability/index.d.ts +33 -0
  436. package/dist/observability/index.d.ts.map +1 -0
  437. package/dist/observability/index.js +257 -0
  438. package/dist/observability/index.js.map +1 -0
  439. package/dist/observability/instrument.js +14 -6
  440. package/dist/observability/instrument.js.map +1 -1
  441. package/dist/observability/otel.d.ts +10 -0
  442. package/dist/observability/otel.d.ts.map +1 -0
  443. package/dist/observability/otel.js +183 -0
  444. package/dist/observability/otel.js.map +1 -0
  445. package/dist/observability/sentry.d.ts +40 -7
  446. package/dist/observability/sentry.d.ts.map +1 -1
  447. package/dist/observability/sentry.js +176 -32
  448. package/dist/observability/sentry.js.map +1 -1
  449. package/dist/observability/types.d.ts +24 -3
  450. package/dist/observability/types.d.ts.map +1 -1
  451. package/dist/observability/types.js.map +1 -1
  452. package/dist/office/index.d.ts +139 -0
  453. package/dist/office/index.d.ts.map +1 -0
  454. package/dist/office/index.js +1084 -0
  455. package/dist/office/index.js.map +1 -0
  456. package/dist/office/projection.d.ts +42 -0
  457. package/dist/office/projection.d.ts.map +1 -0
  458. package/dist/office/projection.js +182 -0
  459. package/dist/office/projection.js.map +1 -0
  460. package/dist/office/types.d.ts +116 -0
  461. package/dist/office/types.d.ts.map +1 -0
  462. package/dist/office/types.js +2 -0
  463. package/dist/office/types.js.map +1 -0
  464. package/dist/runtime/conversation-runtime.d.ts +1 -1
  465. package/dist/runtime/conversation-runtime.d.ts.map +1 -1
  466. package/dist/runtime/conversation-runtime.js +423 -152
  467. package/dist/runtime/conversation-runtime.js.map +1 -1
  468. package/dist/runtime/session-lifecycle.d.ts +76 -0
  469. package/dist/runtime/session-lifecycle.d.ts.map +1 -0
  470. package/dist/runtime/session-lifecycle.js +404 -0
  471. package/dist/runtime/session-lifecycle.js.map +1 -0
  472. package/dist/runtime/types.d.ts +63 -15
  473. package/dist/runtime/types.d.ts.map +1 -1
  474. package/dist/runtime/types.js.map +1 -1
  475. package/dist/sandbox/cloudflare.d.ts +4 -0
  476. package/dist/sandbox/cloudflare.d.ts.map +1 -1
  477. package/dist/sandbox/cloudflare.js +54 -52
  478. package/dist/sandbox/cloudflare.js.map +1 -1
  479. package/dist/sandbox/container.d.ts +3 -0
  480. package/dist/sandbox/container.d.ts.map +1 -1
  481. package/dist/sandbox/container.js +19 -7
  482. package/dist/sandbox/container.js.map +1 -1
  483. package/dist/sandbox/host.d.ts +3 -0
  484. package/dist/sandbox/host.d.ts.map +1 -1
  485. package/dist/sandbox/host.js +44 -35
  486. package/dist/sandbox/host.js.map +1 -1
  487. package/dist/sandbox/identity.d.ts +42 -0
  488. package/dist/sandbox/identity.d.ts.map +1 -0
  489. package/dist/sandbox/identity.js +77 -0
  490. package/dist/sandbox/identity.js.map +1 -0
  491. package/dist/sandbox/index.d.ts +24 -6
  492. package/dist/sandbox/index.d.ts.map +1 -1
  493. package/dist/sandbox/index.js +77 -17
  494. package/dist/sandbox/index.js.map +1 -1
  495. package/dist/sandbox/provisioner.d.ts +139 -0
  496. package/dist/sandbox/provisioner.d.ts.map +1 -0
  497. package/dist/{provisioner.js → sandbox/provisioner.js} +378 -24
  498. package/dist/sandbox/provisioner.js.map +1 -0
  499. package/dist/sandbox/types.d.ts +43 -9
  500. package/dist/sandbox/types.d.ts.map +1 -1
  501. package/dist/sandbox/types.js.map +1 -1
  502. package/dist/sandbox/utils.d.ts +24 -0
  503. package/dist/sandbox/utils.d.ts.map +1 -1
  504. package/dist/sandbox/utils.js +92 -1
  505. package/dist/sandbox/utils.js.map +1 -1
  506. package/dist/sessions/chat-history-sync.d.ts +23 -0
  507. package/dist/sessions/chat-history-sync.d.ts.map +1 -0
  508. package/dist/sessions/{agent-memory-file-manager.js → chat-history-sync.js} +239 -175
  509. package/dist/sessions/chat-history-sync.js.map +1 -0
  510. package/dist/sessions/history-line.d.ts +29 -0
  511. package/dist/sessions/history-line.d.ts.map +1 -0
  512. package/dist/sessions/history-line.js +45 -0
  513. package/dist/sessions/history-line.js.map +1 -0
  514. package/dist/sessions/migrate-common.d.ts +43 -0
  515. package/dist/sessions/migrate-common.d.ts.map +1 -0
  516. package/dist/sessions/migrate-common.js +99 -0
  517. package/dist/sessions/migrate-common.js.map +1 -0
  518. package/dist/sessions/migrate-pi-084.d.ts +8 -0
  519. package/dist/sessions/migrate-pi-084.d.ts.map +1 -0
  520. package/dist/sessions/migrate-pi-084.js +302 -0
  521. package/dist/sessions/migrate-pi-084.js.map +1 -0
  522. package/dist/sessions/migrate-v3.d.ts +15 -0
  523. package/dist/sessions/migrate-v3.d.ts.map +1 -0
  524. package/dist/sessions/migrate-v3.js +419 -0
  525. package/dist/sessions/migrate-v3.js.map +1 -0
  526. package/dist/sessions/session-key.d.ts +33 -0
  527. package/dist/sessions/session-key.d.ts.map +1 -0
  528. package/dist/sessions/session-key.js +115 -0
  529. package/dist/sessions/session-key.js.map +1 -0
  530. package/dist/sessions/session-store.d.ts +61 -0
  531. package/dist/sessions/session-store.d.ts.map +1 -0
  532. package/dist/sessions/session-store.js +684 -0
  533. package/dist/sessions/session-store.js.map +1 -0
  534. package/dist/sessions/store.d.ts +17 -10
  535. package/dist/sessions/store.d.ts.map +1 -1
  536. package/dist/sessions/store.js +182 -47
  537. package/dist/sessions/store.js.map +1 -1
  538. package/dist/sessions/types.d.ts +74 -8
  539. package/dist/sessions/types.d.ts.map +1 -1
  540. package/dist/sessions/types.js +1 -1
  541. package/dist/sessions/types.js.map +1 -1
  542. package/dist/settings/apply.d.ts +16 -0
  543. package/dist/settings/apply.d.ts.map +1 -0
  544. package/dist/settings/apply.js +60 -0
  545. package/dist/settings/apply.js.map +1 -0
  546. package/dist/settings/index.d.ts +126 -0
  547. package/dist/settings/index.d.ts.map +1 -0
  548. package/dist/settings/index.js +422 -0
  549. package/dist/settings/index.js.map +1 -0
  550. package/dist/settings/migrate.d.ts +21 -0
  551. package/dist/settings/migrate.d.ts.map +1 -0
  552. package/dist/settings/migrate.js +86 -0
  553. package/dist/settings/migrate.js.map +1 -0
  554. package/dist/types.d.ts +330 -141
  555. package/dist/types.d.ts.map +1 -1
  556. package/dist/types.js +2 -2
  557. package/dist/types.js.map +1 -1
  558. package/dist/vault/index.d.ts +52 -2
  559. package/dist/vault/index.d.ts.map +1 -1
  560. package/dist/vault/index.js +218 -86
  561. package/dist/vault/index.js.map +1 -1
  562. package/dist/vault/types.d.ts +6 -2
  563. package/dist/vault/types.d.ts.map +1 -1
  564. package/dist/vault/types.js.map +1 -1
  565. package/package.json +79 -40
  566. package/dist/adapter.d.ts +0 -2
  567. package/dist/adapter.d.ts.map +0 -1
  568. package/dist/adapter.js +0 -2
  569. package/dist/adapter.js.map +0 -1
  570. package/dist/adapters/slack/tools/attach.d.ts.map +0 -1
  571. package/dist/adapters/slack/tools/attach.js.map +0 -1
  572. package/dist/adapters/streaming.d.ts +0 -18
  573. package/dist/adapters/streaming.d.ts.map +0 -1
  574. package/dist/adapters/streaming.js +0 -44
  575. package/dist/adapters/streaming.js.map +0 -1
  576. package/dist/adapters/telegram/html.d.ts +0 -3
  577. package/dist/adapters/telegram/html.d.ts.map +0 -1
  578. package/dist/adapters/telegram/html.js +0 -98
  579. package/dist/adapters/telegram/html.js.map +0 -1
  580. package/dist/agent-events.d.ts +0 -5
  581. package/dist/agent-events.d.ts.map +0 -1
  582. package/dist/agent-events.js +0 -26
  583. package/dist/agent-events.js.map +0 -1
  584. package/dist/agent.d.ts +0 -39
  585. package/dist/agent.d.ts.map +0 -1
  586. package/dist/agent.js +0 -1291
  587. package/dist/agent.js.map +0 -1
  588. package/dist/cli/ext-git.d.ts +0 -22
  589. package/dist/cli/ext-git.d.ts.map +0 -1
  590. package/dist/cli/ext-git.js +0 -76
  591. package/dist/cli/ext-git.js.map +0 -1
  592. package/dist/cli/ext.d.ts +0 -2
  593. package/dist/cli/ext.d.ts.map +0 -1
  594. package/dist/cli/ext.js +0 -217
  595. package/dist/cli/ext.js.map +0 -1
  596. package/dist/commands/admin.d.ts.map +0 -1
  597. package/dist/commands/admin.js.map +0 -1
  598. package/dist/commands/auto-reply.d.ts.map +0 -1
  599. package/dist/commands/auto-reply.js +0 -76
  600. package/dist/commands/auto-reply.js.map +0 -1
  601. package/dist/commands/extensions.d.ts +0 -14
  602. package/dist/commands/extensions.d.ts.map +0 -1
  603. package/dist/commands/extensions.js +0 -55
  604. package/dist/commands/extensions.js.map +0 -1
  605. package/dist/commands/login.d.ts +0 -5
  606. package/dist/commands/login.d.ts.map +0 -1
  607. package/dist/commands/login.js +0 -115
  608. package/dist/commands/login.js.map +0 -1
  609. package/dist/commands/model.d.ts +0 -10
  610. package/dist/commands/model.d.ts.map +0 -1
  611. package/dist/commands/model.js +0 -102
  612. package/dist/commands/model.js.map +0 -1
  613. package/dist/commands/new.d.ts.map +0 -1
  614. package/dist/commands/new.js +0 -25
  615. package/dist/commands/new.js.map +0 -1
  616. package/dist/commands/parse.d.ts +0 -7
  617. package/dist/commands/parse.d.ts.map +0 -1
  618. package/dist/commands/parse.js +0 -14
  619. package/dist/commands/parse.js.map +0 -1
  620. package/dist/commands/registry.d.ts +0 -5
  621. package/dist/commands/registry.d.ts.map +0 -1
  622. package/dist/commands/registry.js +0 -31
  623. package/dist/commands/registry.js.map +0 -1
  624. package/dist/commands/sandbox.d.ts.map +0 -1
  625. package/dist/commands/sandbox.js +0 -78
  626. package/dist/commands/sandbox.js.map +0 -1
  627. package/dist/commands/session-view.d.ts.map +0 -1
  628. package/dist/commands/session-view.js.map +0 -1
  629. package/dist/commands/types.d.ts +0 -66
  630. package/dist/commands/types.d.ts.map +0 -1
  631. package/dist/commands/types.js.map +0 -1
  632. package/dist/commands/utils.d.ts +0 -11
  633. package/dist/commands/utils.d.ts.map +0 -1
  634. package/dist/commands/utils.js.map +0 -1
  635. package/dist/config.d.ts +0 -78
  636. package/dist/config.d.ts.map +0 -1
  637. package/dist/config.js +0 -450
  638. package/dist/config.js.map +0 -1
  639. package/dist/download.d.ts.map +0 -1
  640. package/dist/download.js +0 -89
  641. package/dist/download.js.map +0 -1
  642. package/dist/events.d.ts +0 -43
  643. package/dist/events.d.ts.map +0 -1
  644. package/dist/events.js +0 -456
  645. package/dist/events.js.map +0 -1
  646. package/dist/execution-resolver.d.ts +0 -21
  647. package/dist/execution-resolver.d.ts.map +0 -1
  648. package/dist/execution-resolver.js +0 -170
  649. package/dist/execution-resolver.js.map +0 -1
  650. package/dist/harness/auth.d.ts +0 -16
  651. package/dist/harness/auth.d.ts.map +0 -1
  652. package/dist/harness/auth.js +0 -86
  653. package/dist/harness/auth.js.map +0 -1
  654. package/dist/harness/extensions/loader.d.ts +0 -86
  655. package/dist/harness/extensions/loader.d.ts.map +0 -1
  656. package/dist/harness/extensions/loader.js +0 -525
  657. package/dist/harness/extensions/loader.js.map +0 -1
  658. package/dist/harness/extensions/registry.d.ts +0 -23
  659. package/dist/harness/extensions/registry.d.ts.map +0 -1
  660. package/dist/harness/extensions/registry.js +0 -45
  661. package/dist/harness/extensions/registry.js.map +0 -1
  662. package/dist/harness/extensions/types.d.ts +0 -248
  663. package/dist/harness/extensions/types.d.ts.map +0 -1
  664. package/dist/harness/extensions/types.js.map +0 -1
  665. package/dist/harness/session-store.d.ts +0 -77
  666. package/dist/harness/session-store.d.ts.map +0 -1
  667. package/dist/harness/session-store.js +0 -248
  668. package/dist/harness/session-store.js.map +0 -1
  669. package/dist/harness/settings.d.ts +0 -47
  670. package/dist/harness/settings.d.ts.map +0 -1
  671. package/dist/harness/settings.js +0 -29
  672. package/dist/harness/settings.js.map +0 -1
  673. package/dist/model-registry.d.ts +0 -4
  674. package/dist/model-registry.d.ts.map +0 -1
  675. package/dist/model-registry.js +0 -7
  676. package/dist/model-registry.js.map +0 -1
  677. package/dist/platform-messages.d.ts.map +0 -1
  678. package/dist/platform-messages.js.map +0 -1
  679. package/dist/portal-shell.d.ts +0 -4
  680. package/dist/portal-shell.d.ts.map +0 -1
  681. package/dist/portal-shell.js.map +0 -1
  682. package/dist/provisioner.d.ts +0 -61
  683. package/dist/provisioner.d.ts.map +0 -1
  684. package/dist/provisioner.js.map +0 -1
  685. package/dist/runtime/agent-run-controller.d.ts +0 -31
  686. package/dist/runtime/agent-run-controller.d.ts.map +0 -1
  687. package/dist/runtime/agent-run-controller.js +0 -195
  688. package/dist/runtime/agent-run-controller.js.map +0 -1
  689. package/dist/sandbox/errors.d.ts +0 -6
  690. package/dist/sandbox/errors.d.ts.map +0 -1
  691. package/dist/sandbox/errors.js +0 -11
  692. package/dist/sandbox/errors.js.map +0 -1
  693. package/dist/sandbox/firecracker.d.ts +0 -15
  694. package/dist/sandbox/firecracker.d.ts.map +0 -1
  695. package/dist/sandbox/firecracker.js +0 -212
  696. package/dist/sandbox/firecracker.js.map +0 -1
  697. package/dist/sandbox/image.d.ts +0 -3
  698. package/dist/sandbox/image.d.ts.map +0 -1
  699. package/dist/sandbox/image.js +0 -27
  700. package/dist/sandbox/image.js.map +0 -1
  701. package/dist/sandbox/path-context.d.ts +0 -3
  702. package/dist/sandbox/path-context.d.ts.map +0 -1
  703. package/dist/sandbox/path-context.js +0 -20
  704. package/dist/sandbox/path-context.js.map +0 -1
  705. package/dist/sessions/agent-memory-file-manager.d.ts +0 -19
  706. package/dist/sessions/agent-memory-file-manager.d.ts.map +0 -1
  707. package/dist/sessions/agent-memory-file-manager.js.map +0 -1
  708. package/dist/sessions/metadata.d.ts +0 -3
  709. package/dist/sessions/metadata.d.ts.map +0 -1
  710. package/dist/sessions/metadata.js +0 -11
  711. package/dist/sessions/metadata.js.map +0 -1
  712. package/dist/sessions/policy.d.ts +0 -6
  713. package/dist/sessions/policy.d.ts.map +0 -1
  714. package/dist/sessions/policy.js +0 -23
  715. package/dist/sessions/policy.js.map +0 -1
  716. package/dist/store.d.ts +0 -46
  717. package/dist/store.d.ts.map +0 -1
  718. package/dist/store.js +0 -177
  719. package/dist/store.js.map +0 -1
  720. package/dist/tools/bash.d.ts +0 -10
  721. package/dist/tools/bash.d.ts.map +0 -1
  722. package/dist/tools/bash.js +0 -80
  723. package/dist/tools/bash.js.map +0 -1
  724. package/dist/tools/edit.d.ts +0 -11
  725. package/dist/tools/edit.d.ts.map +0 -1
  726. package/dist/tools/edit.js +0 -131
  727. package/dist/tools/edit.js.map +0 -1
  728. package/dist/tools/event.d.ts.map +0 -1
  729. package/dist/tools/event.js +0 -252
  730. package/dist/tools/event.js.map +0 -1
  731. package/dist/tools/index.d.ts +0 -24
  732. package/dist/tools/index.d.ts.map +0 -1
  733. package/dist/tools/index.js +0 -31
  734. package/dist/tools/index.js.map +0 -1
  735. package/dist/tools/react.d.ts.map +0 -1
  736. package/dist/tools/react.js.map +0 -1
  737. package/dist/tools/read.d.ts +0 -11
  738. package/dist/tools/read.d.ts.map +0 -1
  739. package/dist/tools/read.js +0 -134
  740. package/dist/tools/read.js.map +0 -1
  741. package/dist/tools/sandbox.d.ts.map +0 -1
  742. package/dist/tools/sandbox.js.map +0 -1
  743. package/dist/tools/truncate.d.ts +0 -33
  744. package/dist/tools/truncate.d.ts.map +0 -1
  745. package/dist/tools/truncate.js +0 -184
  746. package/dist/tools/truncate.js.map +0 -1
  747. package/dist/tools/types.d.ts +0 -54
  748. package/dist/tools/types.d.ts.map +0 -1
  749. package/dist/tools/types.js.map +0 -1
  750. package/dist/tools/write.d.ts +0 -10
  751. package/dist/tools/write.d.ts.map +0 -1
  752. package/dist/tools/write.js +0 -29
  753. package/dist/tools/write.js.map +0 -1
  754. package/dist/trigger.d.ts +0 -22
  755. package/dist/trigger.d.ts.map +0 -1
  756. package/dist/trigger.js +0 -100
  757. package/dist/trigger.js.map +0 -1
  758. package/dist/utils/date.d.ts +0 -10
  759. package/dist/utils/date.d.ts.map +0 -1
  760. package/dist/utils/date.js +0 -23
  761. package/dist/utils/date.js.map +0 -1
  762. package/dist/utils/env.d.ts +0 -3
  763. package/dist/utils/env.d.ts.map +0 -1
  764. package/dist/utils/env.js +0 -12
  765. package/dist/utils/env.js.map +0 -1
  766. package/dist/utils/file-guards.d.ts +0 -9
  767. package/dist/utils/file-guards.d.ts.map +0 -1
  768. package/dist/utils/file-guards.js +0 -59
  769. package/dist/utils/file-guards.js.map +0 -1
  770. package/dist/utils/fs-atomic.d.ts +0 -10
  771. package/dist/utils/fs-atomic.d.ts.map +0 -1
  772. package/dist/utils/fs-atomic.js +0 -45
  773. package/dist/utils/fs-atomic.js.map +0 -1
  774. package/dist/utils/html.d.ts +0 -2
  775. package/dist/utils/html.d.ts.map +0 -1
  776. package/dist/utils/html.js +0 -4
  777. package/dist/utils/html.js.map +0 -1
  778. package/dist/utils/http-body.d.ts +0 -10
  779. package/dist/utils/http-body.d.ts.map +0 -1
  780. package/dist/utils/http-body.js +0 -34
  781. package/dist/utils/http-body.js.map +0 -1
  782. package/dist/vault/routing.d.ts +0 -3
  783. package/dist/vault/routing.d.ts.map +0 -1
  784. package/dist/vault/routing.js +0 -13
  785. package/dist/vault/routing.js.map +0 -1
  786. package/dist/web/admin/portal.d.ts +0 -5
  787. package/dist/web/admin/portal.d.ts.map +0 -1
  788. package/dist/web/admin/portal.js +0 -2572
  789. package/dist/web/admin/portal.js.map +0 -1
  790. package/dist/web/admin/provider-models.d.ts.map +0 -1
  791. package/dist/web/admin/provider-models.js.map +0 -1
  792. package/dist/web/admin/store.d.ts +0 -13
  793. package/dist/web/admin/store.d.ts.map +0 -1
  794. package/dist/web/admin/store.js +0 -14
  795. package/dist/web/admin/store.js.map +0 -1
  796. package/dist/web/admin/types.d.ts +0 -30
  797. package/dist/web/admin/types.d.ts.map +0 -1
  798. package/dist/web/admin/types.js.map +0 -1
  799. package/dist/web/agent-events/portal.d.ts +0 -3
  800. package/dist/web/agent-events/portal.d.ts.map +0 -1
  801. package/dist/web/agent-events/portal.js +0 -18
  802. package/dist/web/agent-events/portal.js.map +0 -1
  803. package/dist/web/login/oauth.d.ts +0 -6
  804. package/dist/web/login/oauth.d.ts.map +0 -1
  805. package/dist/web/login/oauth.js.map +0 -1
  806. package/dist/web/login/portal.d.ts.map +0 -1
  807. package/dist/web/login/portal.js.map +0 -1
  808. package/dist/web/login/store.d.ts +0 -8
  809. package/dist/web/login/store.d.ts.map +0 -1
  810. package/dist/web/login/store.js +0 -15
  811. package/dist/web/login/store.js.map +0 -1
  812. package/dist/web/login/types.d.ts.map +0 -1
  813. package/dist/web/login/types.js.map +0 -1
  814. package/dist/web/request.d.ts +0 -3
  815. package/dist/web/request.d.ts.map +0 -1
  816. package/dist/web/request.js +0 -13
  817. package/dist/web/request.js.map +0 -1
  818. package/dist/web/server.d.ts.map +0 -1
  819. package/dist/web/server.js.map +0 -1
  820. package/dist/web/session-view/command.d.ts +0 -4
  821. package/dist/web/session-view/command.d.ts.map +0 -1
  822. package/dist/web/session-view/command.js +0 -7
  823. package/dist/web/session-view/command.js.map +0 -1
  824. package/dist/web/session-view/portal.d.ts +0 -13
  825. package/dist/web/session-view/portal.d.ts.map +0 -1
  826. package/dist/web/session-view/portal.js.map +0 -1
  827. package/dist/web/session-view/service.d.ts +0 -6
  828. package/dist/web/session-view/service.d.ts.map +0 -1
  829. package/dist/web/session-view/service.js +0 -498
  830. package/dist/web/session-view/service.js.map +0 -1
  831. package/dist/web/session-view/store.d.ts +0 -8
  832. package/dist/web/session-view/store.d.ts.map +0 -1
  833. package/dist/web/session-view/store.js +0 -15
  834. package/dist/web/session-view/store.js.map +0 -1
  835. package/dist/web/session-view/types.d.ts.map +0 -1
  836. package/dist/web/session-view/types.js.map +0 -1
  837. package/dist/web/token-store.d.ts.map +0 -1
  838. package/dist/web/token-store.js.map +0 -1
  839. package/dist/web/types.d.ts.map +0 -1
  840. package/dist/web/types.js.map +0 -1
  841. /package/dist/{commands → adapters/commands}/admin.d.ts +0 -0
  842. /package/dist/{commands → adapters/commands}/new.d.ts +0 -0
  843. /package/dist/{commands → adapters/commands}/sandbox.d.ts +0 -0
  844. /package/dist/{commands → adapters/commands}/session-view.d.ts +0 -0
  845. /package/dist/{commands → adapters/commands}/types.js +0 -0
  846. /package/dist/{harness/extensions → adapters/github}/types.js +0 -0
  847. /package/dist/{tools → adapters/web/admin}/types.js +0 -0
  848. /package/dist/{web/admin → adapters/web/login}/types.js +0 -0
  849. /package/dist/{web/login → adapters/web/session-view}/types.js +0 -0
  850. /package/dist/{web → adapters/web}/token-store.d.ts +0 -0
  851. /package/dist/{web → adapters/web}/types.d.ts +0 -0
  852. /package/dist/{web/session-view → adapters/web}/types.js +0 -0
  853. /package/dist/{download.d.ts → cli/download.d.ts} +0 -0
  854. /package/dist/{web → cli}/types.js +0 -0
  855. /package/dist/{adapters/slack → harness}/tools/attach.d.ts +0 -0
  856. /package/dist/{tools → harness/tools}/react.d.ts +0 -0
@@ -0,0 +1,1084 @@
1
+ /**
2
+ * The Conversation office module: canonical identity, the Workspace/Office
3
+ * layout values, the durable registry journal, and the boot-time legacy
4
+ * migration. Everything outside `src/office/` imports from this module;
5
+ * exported types live in `types.ts` per module convention.
6
+ */
7
+ import { createHash, randomBytes } from "node:crypto";
8
+ import { existsSync, lstatSync, mkdirSync, readdirSync, readFileSync, renameSync, rmSync, statSync, writeFileSync, } from "node:fs";
9
+ import { isAbsolute, join, resolve } from "node:path";
10
+ import * as log from "../log.js";
11
+ import { parseGithubConversationId } from "../adapters/github/ids.js";
12
+ import { legacyConversationCredentialKey } from "../sandbox/identity.js";
13
+ import { migrateConversationVaultKeys } from "../vault/index.js";
14
+ import { atomicWritePrivateFile, isRecord, readTextFileIfExists } from "../file-guards.js";
15
+ // ── Office identity (address & keys) ──────────────────────────────────────────
16
+ const OFFICE_KEY_VERSION = "v1";
17
+ const OFFICE_KEY_DOMAIN = "office-address-v1";
18
+ const OFFICE_KEY_DIGEST_LENGTH = 16;
19
+ const READABLE_ID_LENGTH = 32;
20
+ const PLATFORM_NAMES = new Set(["slack", "discord", "telegram", "github"]);
21
+ const OFFICE_KEY_PATTERN = /^v1-(slack|discord|telegram|github)-[a-z0-9]+(?:-[a-z0-9]+)*-[a-f0-9]{16}$/;
22
+ /** Construct the canonical identity used by future office consumers. */
23
+ export function createOfficeAddress(platform, conversationId) {
24
+ assertPlatformName(platform);
25
+ assertConversationId(conversationId);
26
+ return Object.freeze({ platform, conversationId });
27
+ }
28
+ /** Validate an untrusted runtime value as a canonical office address. */
29
+ export function validateOfficeAddress(value) {
30
+ if (!isRecord(value))
31
+ throw new Error("Office address must be an object");
32
+ if (typeof value.platform !== "string") {
33
+ throw new Error("Office address platform must be a string");
34
+ }
35
+ if (typeof value.conversationId !== "string") {
36
+ throw new Error("Office address conversation id must be a string");
37
+ }
38
+ return createOfficeAddress(assertPlatformName(value.platform), value.conversationId);
39
+ }
40
+ /** Return true only for a supported platform name. */
41
+ function isPlatformName(value) {
42
+ return typeof value === "string" && PLATFORM_NAMES.has(value);
43
+ }
44
+ /** Validate a platform name and return it for typed callers. */
45
+ export function assertPlatformName(value) {
46
+ if (!isPlatformName(value))
47
+ throw new Error(`Unsupported platform: ${JSON.stringify(value)}`);
48
+ return value;
49
+ }
50
+ /** Path separators and the C0/C1 control ranges are never allowed in an id. */
51
+ function isUnsafeConversationIdChar(character) {
52
+ const code = character.codePointAt(0) ?? 0;
53
+ return character === "/" || character === "\\" || code <= 0x1f || (code >= 0x7f && code <= 0x9f);
54
+ }
55
+ /** Validate a raw platform conversation identifier before it enters storage. */
56
+ export function assertConversationId(value) {
57
+ if (value.length === 0 || value === "." || value === "..") {
58
+ throw new Error("Conversation id must be non-empty and not a path marker");
59
+ }
60
+ if ([...value].some(isUnsafeConversationIdChar)) {
61
+ throw new Error("Conversation id must not contain path separators or control characters");
62
+ }
63
+ return value;
64
+ }
65
+ /** Derive a readable diagnostic key whose digest remains the identity authority. */
66
+ export function officeKey(address) {
67
+ const normalized = validateOfficeAddress(address);
68
+ const readable = readableConversationId(normalized.conversationId);
69
+ const digest = createHash("sha256")
70
+ .update(`${OFFICE_KEY_DOMAIN}\0${normalized.platform}\0${normalized.conversationId}`)
71
+ .digest("hex")
72
+ .slice(0, OFFICE_KEY_DIGEST_LENGTH);
73
+ return `${OFFICE_KEY_VERSION}-${normalized.platform}-${readable}-${digest}`;
74
+ }
75
+ /**
76
+ * Resolve the persistent workspace directory for an office.
77
+ * Module-internal: registry/migration record target paths with it. Callers
78
+ * outside `src/office/` use the `Office` value's `dir` field instead.
79
+ */
80
+ export function officeDir(workspaceRoot, address) {
81
+ return join(workspaceRoot, officeKey(address));
82
+ }
83
+ /**
84
+ * Resolve the host-only state directory for an office.
85
+ *
86
+ * Settings and migration callers that only hold a `stateDir` string use this
87
+ * when no materialized `Office` value is available.
88
+ */
89
+ export function officeStateDir(stateDir, address) {
90
+ return join(stateDir, "conversations", officeKey(address));
91
+ }
92
+ /** Compare canonical office identities without relying on their readable key. */
93
+ export function sameOffice(left, right) {
94
+ const leftAddress = validateOfficeAddress(left);
95
+ const rightAddress = validateOfficeAddress(right);
96
+ return (leftAddress.platform === rightAddress.platform &&
97
+ leftAddress.conversationId === rightAddress.conversationId);
98
+ }
99
+ /** Validate a persisted or externally supplied office key. */
100
+ export function assertOfficeKey(value) {
101
+ if (!OFFICE_KEY_PATTERN.test(value)) {
102
+ throw new Error(`Invalid office key: ${JSON.stringify(value)}`);
103
+ }
104
+ return value;
105
+ }
106
+ export function isOfficeKey(value) {
107
+ return typeof value === "string" && OFFICE_KEY_PATTERN.test(value);
108
+ }
109
+ function readableConversationId(conversationId) {
110
+ const readable = conversationId
111
+ .toLowerCase()
112
+ .replace(/[^a-z0-9]+/g, "-")
113
+ .replace(/^-+|-+$/g, "")
114
+ .slice(0, READABLE_ID_LENGTH)
115
+ .replace(/-+$/g, "");
116
+ return readable || "conversation";
117
+ }
118
+ // ── Workspace/Office layout ───────────────────────────────────────────────────
119
+ /**
120
+ * Workspace-root entries that are shared infrastructure, never office dirs.
121
+ * The single definition behind boot-time directory setup, the workspace
122
+ * projection, and the migration's legacy-dir scan. `events` stays reserved
123
+ * for the legacy scheduling bus that `mikan office migrate-events` drains.
124
+ */
125
+ export const RESERVED_WORKSPACE_NAMES = Object.freeze(new Set(["skills", "events", "agents", "MEMORY.md"]));
126
+ /**
127
+ * Construct the Workspace value for a deployment. One construction site per
128
+ * process (main.ts for the daemon; CLI subcommands and tests build their
129
+ * own). The value owns the registry instance and the recorded-office cache
130
+ * that office materialization uses on hot paths, so there is no process-wide
131
+ * registry state.
132
+ */
133
+ /**
134
+ * An office's session files live in `<office dir>/sessions` — the one home of
135
+ * that rule. String-based for surfaces that hold a conversation dir rather
136
+ * than an `Office` value (mirrors `officeStateDir`); `Office.sessionsDir` is
137
+ * derived from it. Pointer/thread-file semantics live in `sessions/store`.
138
+ */
139
+ export function officeSessionsDir(dir) {
140
+ return join(dir, "sessions");
141
+ }
142
+ export function createWorkspace(options) {
143
+ // Paths are joined as given (no resolve) so values match what callers
144
+ // passing the same root/stateDir strings computed before this module.
145
+ const { root, stateDir } = options;
146
+ // Lazy: CLI surfaces construct a Workspace for path math without paying
147
+ // for (or being allowed to create) the registry journal.
148
+ let registry;
149
+ const recorded = new Set();
150
+ const offices = new Map();
151
+ const workspace = Object.freeze({
152
+ root,
153
+ stateDir,
154
+ memoryPath: join(root, "MEMORY.md"),
155
+ skillsDir: join(root, "skills"),
156
+ agentsDir: join(root, "agents"),
157
+ reservedNames: RESERVED_WORKSPACE_NAMES,
158
+ office(address) {
159
+ const normalized = validateOfficeAddress(address);
160
+ const key = officeKey(normalized);
161
+ const existing = offices.get(key);
162
+ if (existing)
163
+ return existing;
164
+ const dir = join(root, key);
165
+ const office = Object.freeze({
166
+ address: normalized,
167
+ key,
168
+ dir,
169
+ memoryPath: join(dir, "MEMORY.md"),
170
+ skillsDir: join(dir, "skills"),
171
+ sessionsDir: officeSessionsDir(dir),
172
+ attachmentsDir: join(dir, "attachments"),
173
+ logPath: join(dir, "log.jsonl"),
174
+ stateDir: join(stateDir, "conversations", key),
175
+ workspace,
176
+ ensure() {
177
+ // Record-first ordering: a crash can leave a record without a
178
+ // directory (harmless; recreated on the next message) but never an
179
+ // anonymous office directory the registry cannot enumerate.
180
+ if (!recorded.has(key)) {
181
+ registry ??= new OfficeRegistry(stateDir);
182
+ registry.recordOffice(normalized);
183
+ recorded.add(key);
184
+ }
185
+ ensureRegularOfficeDirectory(dir);
186
+ return dir;
187
+ },
188
+ });
189
+ offices.set(key, office);
190
+ return office;
191
+ },
192
+ });
193
+ return workspace;
194
+ }
195
+ /** mkdir-if-missing with the same fail-closed type guard as projection roots. */
196
+ function ensureRegularOfficeDirectory(dir) {
197
+ let stats;
198
+ try {
199
+ stats = lstatSync(dir);
200
+ }
201
+ catch (err) {
202
+ if (err.code !== "ENOENT")
203
+ throw err;
204
+ mkdirSync(dir, { recursive: true, mode: 0o700 });
205
+ return;
206
+ }
207
+ if (stats.isSymbolicLink() || !stats.isDirectory()) {
208
+ throw new Error(`Office directory must be a regular non-symlink directory: ${dir}`);
209
+ }
210
+ }
211
+ // ── Office registry journal ───────────────────────────────────────────────────
212
+ const REGISTRY_VERSION = 1;
213
+ const REGISTRY_FILENAME = "office-registry.json";
214
+ const MIGRATION_STATUSES = new Set([
215
+ "needs-owner",
216
+ "prepared",
217
+ "moving",
218
+ "committed",
219
+ "failed",
220
+ ]);
221
+ const REGISTRY_LOCK_FILENAME = ".office-registry.lock";
222
+ const REGISTRY_LOCK_RETRY_MS = 25;
223
+ const REGISTRY_LOCK_TIMEOUT_MS = 5_000;
224
+ const REGISTRY_LOCK_STALE_MS = 60_000;
225
+ export class OfficeRegistry {
226
+ constructor(stateDir, options = {}) {
227
+ this.stateDir = resolve(stateDir);
228
+ mkdirSync(this.stateDir, { recursive: true, mode: 0o700 });
229
+ assertRegularDirectory(this.stateDir, "State directory");
230
+ this.registryPath = resolve(this.stateDir, REGISTRY_FILENAME);
231
+ this.lockPath = join(this.stateDir, REGISTRY_LOCK_FILENAME);
232
+ this.writeState = options.writeState ?? atomicWritePrivateFile;
233
+ this.lockTimeoutMs = options.lockTimeoutMs ?? REGISTRY_LOCK_TIMEOUT_MS;
234
+ this.state = this.readState();
235
+ }
236
+ /** Reload the atomic registry file after another host process changed it. */
237
+ reload() {
238
+ this.state = this.readState();
239
+ return this.state;
240
+ }
241
+ getState() {
242
+ return this.state;
243
+ }
244
+ getMigration(rawConversationId) {
245
+ assertConversationId(rawConversationId);
246
+ return this.state.migrations.find((record) => record.rawConversationId === rawConversationId);
247
+ }
248
+ enablePlatform(platform) {
249
+ const validPlatform = assertPlatformName(platform);
250
+ return this.withExclusiveLease(() => {
251
+ if (this.state.enabledPlatforms.includes(validPlatform))
252
+ return this.state;
253
+ const enabledPlatforms = [...this.state.enabledPlatforms, validPlatform].toSorted();
254
+ this.replaceState(enabledPlatforms, this.state.offices, this.state.migrations);
255
+ return this.state;
256
+ });
257
+ }
258
+ /**
259
+ * Record that an office exists. Idempotent: re-recording a known office is
260
+ * a lock-free cache hit for callers that materialize directories per
261
+ * message, so this sits safely on hot write paths.
262
+ */
263
+ recordOffice(address) {
264
+ const normalized = validateOfficeAddress(address);
265
+ const existing = this.findOffice(normalized);
266
+ if (existing)
267
+ return existing;
268
+ return this.withExclusiveLease(() => {
269
+ const found = this.findOffice(normalized);
270
+ if (found)
271
+ return found;
272
+ const record = Object.freeze({
273
+ platform: normalized.platform,
274
+ conversationId: normalized.conversationId,
275
+ recordedAt: new Date().toISOString(),
276
+ });
277
+ this.replaceState(this.state.enabledPlatforms, [...this.state.offices, record], this.state.migrations);
278
+ return record;
279
+ });
280
+ }
281
+ getOffices() {
282
+ return this.state.offices;
283
+ }
284
+ findOffice(address) {
285
+ return this.state.offices.find((record) => record.platform === address.platform && record.conversationId === address.conversationId);
286
+ }
287
+ /**
288
+ * Validate and record a legacy directory. With exactly one enabled platform,
289
+ * ownership is safe to infer. With zero or multiple platforms, the record
290
+ * remains explicit `needs-owner` unless the caller supplies an owner.
291
+ */
292
+ prepareLegacyMigration(options) {
293
+ const rawConversationId = assertConversationId(options.rawConversationId);
294
+ const sourceDir = resolve(options.sourceDir);
295
+ const workspaceRoot = resolve(options.workspaceRoot);
296
+ return this.withExclusiveLease(() => {
297
+ const existing = this.getMigration(rawConversationId);
298
+ assertCanonicalSource(sourceDir, workspaceRoot, rawConversationId);
299
+ if (existing) {
300
+ assertSameMigrationInputs(existing, sourceDir, workspaceRoot);
301
+ if (existing.status !== "needs-owner")
302
+ return existing;
303
+ }
304
+ assertRegularDirectory(sourceDir, "Legacy office source");
305
+ const ownerPlatform = this.resolveOwner(options.ownerPlatform, rawConversationId);
306
+ if (!ownerPlatform) {
307
+ const record = makeRecord({
308
+ rawConversationId,
309
+ sourceDir,
310
+ workspaceRoot,
311
+ status: "needs-owner",
312
+ });
313
+ this.replaceMigration(existing, record);
314
+ return record;
315
+ }
316
+ const targetDir = officeDir(workspaceRoot, {
317
+ platform: ownerPlatform,
318
+ conversationId: rawConversationId,
319
+ });
320
+ if (pathExists(targetDir)) {
321
+ const failed = makeRecord({
322
+ rawConversationId,
323
+ sourceDir,
324
+ workspaceRoot,
325
+ ownerPlatform,
326
+ targetDir,
327
+ status: "failed",
328
+ error: "Target office directory already exists",
329
+ });
330
+ this.replaceMigration(existing, failed);
331
+ throw new Error(`${failed.error}: ${targetDir}`);
332
+ }
333
+ const prepared = makeRecord({
334
+ rawConversationId,
335
+ sourceDir,
336
+ workspaceRoot,
337
+ ownerPlatform,
338
+ targetDir,
339
+ status: "prepared",
340
+ });
341
+ this.replaceMigration(existing, prepared);
342
+ return prepared;
343
+ });
344
+ }
345
+ markMoving(rawConversationId) {
346
+ return this.withExclusiveLease(() => {
347
+ const record = this.requireMigration(rawConversationId);
348
+ if (record.status === "moving" ||
349
+ record.status === "committed" ||
350
+ record.status === "failed") {
351
+ return record;
352
+ }
353
+ if (record.status === "needs-owner") {
354
+ throw new Error(`Legacy office ${JSON.stringify(rawConversationId)} still needs an owner`);
355
+ }
356
+ assertRegularDirectory(record.sourceDir, "Legacy office source");
357
+ const targetDir = migrationTarget(record);
358
+ if (!targetDir)
359
+ throw new Error("Prepared office migration has no target directory");
360
+ if (pathExists(targetDir)) {
361
+ const failed = this.failRecord(record, "Target office directory appeared before moving");
362
+ throw new Error(`${failed.error}: ${targetDir}`);
363
+ }
364
+ const moving = transitionRecord(record, "moving");
365
+ this.replaceMigration(record, moving);
366
+ return moving;
367
+ });
368
+ }
369
+ markCommitted(rawConversationId) {
370
+ return this.withExclusiveLease(() => {
371
+ const record = this.requireMigration(rawConversationId);
372
+ if (record.status === "committed" || record.status === "failed")
373
+ return record;
374
+ if (record.status !== "moving") {
375
+ throw new Error(`Cannot commit office migration from ${record.status}`);
376
+ }
377
+ const targetDir = migrationTarget(record);
378
+ if (!targetDir)
379
+ throw new Error("Moving office migration has no target directory");
380
+ assertRegularDirectory(targetDir, "Migrated office target");
381
+ assertPathAbsent(record.sourceDir, "Legacy office source");
382
+ const committed = transitionRecord(record, "committed");
383
+ this.replaceMigration(record, committed);
384
+ return committed;
385
+ });
386
+ }
387
+ markFailed(rawConversationId, error) {
388
+ return this.withExclusiveLease(() => {
389
+ const record = this.requireMigration(rawConversationId);
390
+ if (record.status === "committed") {
391
+ throw new Error("A committed office migration cannot be marked failed");
392
+ }
393
+ if (record.status === "failed")
394
+ return record;
395
+ return this.failRecord(record, error);
396
+ });
397
+ }
398
+ resolveOwner(ownerPlatform, rawConversationId) {
399
+ if (ownerPlatform !== undefined) {
400
+ const validPlatform = assertPlatformName(ownerPlatform);
401
+ if (!this.state.enabledPlatforms.includes(validPlatform)) {
402
+ throw new Error(`Owner platform ${validPlatform} is not enabled`);
403
+ }
404
+ return validPlatform;
405
+ }
406
+ const candidates = platformsMatchingConversationIdFormat(rawConversationId, this.state.enabledPlatforms);
407
+ return candidates.length === 1 ? candidates[0] : undefined;
408
+ }
409
+ requireMigration(rawConversationId) {
410
+ assertConversationId(rawConversationId);
411
+ const record = this.getMigration(rawConversationId);
412
+ if (!record)
413
+ throw new Error(`No office migration registered for ${rawConversationId}`);
414
+ return record;
415
+ }
416
+ failRecord(record, error) {
417
+ const message = error.trim();
418
+ if (!message)
419
+ throw new Error("Office migration failure reason must not be empty");
420
+ const failed = transitionRecord(record, "failed", message);
421
+ this.replaceMigration(record, failed);
422
+ return failed;
423
+ }
424
+ replaceMigration(previous, next) {
425
+ const migrations = [...this.state.migrations];
426
+ const index = previous
427
+ ? migrations.findIndex((record) => record.rawConversationId === previous.rawConversationId)
428
+ : -1;
429
+ if (index === -1)
430
+ migrations.push(next);
431
+ else
432
+ migrations[index] = next;
433
+ this.replaceState(this.state.enabledPlatforms, this.state.offices, migrations);
434
+ }
435
+ replaceState(enabledPlatforms, offices, migrations) {
436
+ const candidate = freezeState({ enabledPlatforms, offices, migrations });
437
+ this.writeState(this.registryPath, `${JSON.stringify(candidate, null, 2)}\n`);
438
+ this.state = candidate;
439
+ }
440
+ /**
441
+ * Acquire the domain lease, reload while holding it, then perform one
442
+ * read-modify-write. A future move transaction can retain the same lease
443
+ * across its filesystem operation instead of splitting the transition.
444
+ */
445
+ withExclusiveLease(operation) {
446
+ const release = acquireRegistryLease(this.lockPath, this.lockTimeoutMs);
447
+ try {
448
+ this.state = this.readState();
449
+ return operation();
450
+ }
451
+ finally {
452
+ release();
453
+ }
454
+ }
455
+ readState() {
456
+ assertRegistryFileSafe(this.registryPath);
457
+ const raw = readTextFileIfExists(this.registryPath);
458
+ if (raw === undefined) {
459
+ return freezeState({ enabledPlatforms: [], offices: [], migrations: [] });
460
+ }
461
+ let value;
462
+ try {
463
+ value = JSON.parse(raw);
464
+ }
465
+ catch (error) {
466
+ throw new Error(`Invalid office registry JSON at ${this.registryPath}`, { cause: error });
467
+ }
468
+ return parseState(value, this.registryPath);
469
+ }
470
+ }
471
+ function makeRecord(fields) {
472
+ const record = {
473
+ rawConversationId: fields.rawConversationId,
474
+ sourceDir: fields.sourceDir,
475
+ workspaceRoot: fields.workspaceRoot,
476
+ ...(fields.ownerPlatform ? { ownerPlatform: fields.ownerPlatform } : {}),
477
+ ...(fields.targetDir ? { targetDir: fields.targetDir } : {}),
478
+ status: fields.status,
479
+ ...(fields.error ? { error: fields.error } : {}),
480
+ updatedAt: fields.updatedAt ?? new Date().toISOString(),
481
+ };
482
+ return Object.freeze(record);
483
+ }
484
+ function transitionRecord(record, status, error) {
485
+ const targetDir = migrationTarget(record);
486
+ return makeRecord({
487
+ rawConversationId: record.rawConversationId,
488
+ sourceDir: record.sourceDir,
489
+ workspaceRoot: record.workspaceRoot,
490
+ ...(record.ownerPlatform ? { ownerPlatform: record.ownerPlatform } : {}),
491
+ ...(targetDir ? { targetDir } : {}),
492
+ status,
493
+ ...(error ? { error } : {}),
494
+ });
495
+ }
496
+ function migrationTarget(record) {
497
+ return record.ownerPlatform
498
+ ? officeDir(record.workspaceRoot, {
499
+ platform: record.ownerPlatform,
500
+ conversationId: record.rawConversationId,
501
+ })
502
+ : undefined;
503
+ }
504
+ function freezeState(input) {
505
+ return Object.freeze({
506
+ version: REGISTRY_VERSION,
507
+ enabledPlatforms: Object.freeze([...input.enabledPlatforms]),
508
+ offices: Object.freeze(input.offices.map((record) => Object.freeze({ ...record }))),
509
+ migrations: Object.freeze(input.migrations.map((record) => Object.freeze({ ...record }))),
510
+ });
511
+ }
512
+ function parseState(value, path) {
513
+ if (!isRecord(value) || value.version !== REGISTRY_VERSION) {
514
+ throw new Error(`Invalid office registry version at ${path}`);
515
+ }
516
+ if (!Array.isArray(value.enabledPlatforms) || !Array.isArray(value.migrations)) {
517
+ throw new Error(`Invalid office registry shape at ${path}`);
518
+ }
519
+ const enabledPlatforms = value.enabledPlatforms.map((platform) => {
520
+ if (typeof platform !== "string")
521
+ throw new Error(`Invalid enabled platform in ${path}`);
522
+ return assertPlatformName(platform);
523
+ });
524
+ if (new Set(enabledPlatforms).size !== enabledPlatforms.length) {
525
+ throw new Error(`Duplicate enabled platform in ${path}`);
526
+ }
527
+ // Files written before office records existed simply have no offices yet.
528
+ const offices = (Array.isArray(value.offices) ? value.offices : []).map((entry) => parseOfficeRecord(entry, path));
529
+ if (new Set(offices.map((record) => officeKey(record))).size !== offices.length) {
530
+ throw new Error(`Duplicate office record in ${path}`);
531
+ }
532
+ const migrations = value.migrations.map((entry) => parseRecord(entry, path, enabledPlatforms));
533
+ if (new Set(migrations.map((record) => record.rawConversationId)).size !== migrations.length) {
534
+ throw new Error(`Duplicate office migration in ${path}`);
535
+ }
536
+ return freezeState({ enabledPlatforms, offices, migrations });
537
+ }
538
+ function parseOfficeRecord(value, path) {
539
+ if (!isRecord(value))
540
+ throw new Error(`Invalid office record in ${path}`);
541
+ if (typeof value.platform !== "string" ||
542
+ typeof value.conversationId !== "string" ||
543
+ typeof value.recordedAt !== "string") {
544
+ throw new Error(`Invalid office record fields in ${path}`);
545
+ }
546
+ return Object.freeze({
547
+ platform: assertPlatformName(value.platform),
548
+ conversationId: assertConversationId(value.conversationId),
549
+ recordedAt: value.recordedAt,
550
+ });
551
+ }
552
+ function hasMigrationStrings(value) {
553
+ return (typeof value.rawConversationId === "string" &&
554
+ typeof value.sourceDir === "string" &&
555
+ typeof value.workspaceRoot === "string" &&
556
+ typeof value.status === "string" &&
557
+ typeof value.updatedAt === "string");
558
+ }
559
+ /** Validate the fields every stored migration record must carry. */
560
+ function parseMigrationFields(value, path) {
561
+ if (!hasMigrationStrings(value)) {
562
+ throw new Error(`Invalid office migration fields in ${path}`);
563
+ }
564
+ assertConversationId(value.rawConversationId);
565
+ if (!isAbsolute(value.sourceDir) || !isAbsolute(value.workspaceRoot)) {
566
+ throw new Error(`Office migration paths must be absolute in ${path}`);
567
+ }
568
+ assertCanonicalSource(value.sourceDir, value.workspaceRoot, value.rawConversationId);
569
+ if (!MIGRATION_STATUSES.has(value.status)) {
570
+ throw new Error(`Invalid office migration status in ${path}`);
571
+ }
572
+ return {
573
+ rawConversationId: value.rawConversationId,
574
+ sourceDir: value.sourceDir,
575
+ workspaceRoot: value.workspaceRoot,
576
+ status: value.status,
577
+ updatedAt: value.updatedAt,
578
+ };
579
+ }
580
+ /**
581
+ * Ownership rules by status: `needs-owner` must carry neither owner nor
582
+ * target, `failed` may carry either, every other status must carry both.
583
+ */
584
+ function assertOwnershipMatchesStatus(status, ownerPlatform, targetDir, path) {
585
+ const owned = ownerPlatform !== undefined;
586
+ const targeted = targetDir !== undefined;
587
+ if (status === "needs-owner" && (owned || targeted)) {
588
+ throw new Error(`Needs-owner migration cannot have an owner or target in ${path}`);
589
+ }
590
+ if (status !== "needs-owner" && status !== "failed" && !(owned && targeted)) {
591
+ throw new Error(`Prepared office migration is missing ownership in ${path}`);
592
+ }
593
+ if (!owned && targeted) {
594
+ throw new Error(`Office migration target has no owner in ${path}`);
595
+ }
596
+ }
597
+ function parseRecord(value, path, enabledPlatforms) {
598
+ if (!isRecord(value))
599
+ throw new Error(`Invalid office migration record in ${path}`);
600
+ const fields = parseMigrationFields(value, path);
601
+ const ownerPlatform = optionalPlatform(value.ownerPlatform);
602
+ const targetDir = optionalString(value.targetDir);
603
+ const error = optionalString(value.error);
604
+ if (ownerPlatform !== undefined && !enabledPlatforms.includes(ownerPlatform)) {
605
+ throw new Error(`Office migration owner is not enabled in ${path}`);
606
+ }
607
+ assertOwnershipMatchesStatus(fields.status, ownerPlatform, targetDir, path);
608
+ const expectedTargetDir = ownerPlatform
609
+ ? officeDir(fields.workspaceRoot, {
610
+ platform: ownerPlatform,
611
+ conversationId: fields.rawConversationId,
612
+ })
613
+ : undefined;
614
+ if (targetDir !== expectedTargetDir) {
615
+ throw new Error(`Office migration target does not match its office address in ${path}`);
616
+ }
617
+ if (fields.status === "failed" && !error) {
618
+ throw new Error(`Failed office migration is missing an error in ${path}`);
619
+ }
620
+ return buildMigrationRecord(fields, ownerPlatform, expectedTargetDir, error);
621
+ }
622
+ function buildMigrationRecord(fields, ownerPlatform, targetDir, error) {
623
+ return makeRecord({
624
+ rawConversationId: fields.rawConversationId,
625
+ sourceDir: fields.sourceDir,
626
+ workspaceRoot: fields.workspaceRoot,
627
+ ...(ownerPlatform ? { ownerPlatform } : {}),
628
+ ...(targetDir ? { targetDir } : {}),
629
+ status: fields.status,
630
+ ...(error ? { error } : {}),
631
+ updatedAt: fields.updatedAt,
632
+ });
633
+ }
634
+ function optionalPlatform(value) {
635
+ return value === undefined
636
+ ? undefined
637
+ : typeof value === "string"
638
+ ? assertPlatformName(value)
639
+ : failOptional("platform");
640
+ }
641
+ function optionalString(value) {
642
+ return value === undefined
643
+ ? undefined
644
+ : typeof value === "string"
645
+ ? value
646
+ : failOptional("string");
647
+ }
648
+ function failOptional(label) {
649
+ throw new Error(`Invalid optional ${label} in office registry`);
650
+ }
651
+ function assertSameMigrationInputs(existing, sourceDir, workspaceRoot) {
652
+ if (existing.sourceDir !== sourceDir || existing.workspaceRoot !== workspaceRoot) {
653
+ throw new Error(`Legacy office migration inputs changed for ${existing.rawConversationId}`);
654
+ }
655
+ }
656
+ function assertCanonicalSource(sourceDir, workspaceRoot, rawConversationId) {
657
+ const expectedSourceDir = resolve(workspaceRoot, rawConversationId);
658
+ if (sourceDir !== expectedSourceDir) {
659
+ throw new Error(`Legacy office source must be ${expectedSourceDir}`);
660
+ }
661
+ assertRegularDirectory(workspaceRoot, "Workspace root");
662
+ assertPathIfPresent(sourceDir, "Legacy office source");
663
+ }
664
+ function assertRegularDirectory(path, label) {
665
+ let stat;
666
+ try {
667
+ stat = lstatSync(path);
668
+ }
669
+ catch (error) {
670
+ throw new Error(`${label} does not exist: ${path}`, { cause: error });
671
+ }
672
+ if (stat.isSymbolicLink() || !stat.isDirectory()) {
673
+ throw new Error(`${label} must be a regular directory: ${path}`);
674
+ }
675
+ }
676
+ /** `lstat` that reports a missing path as undefined; other errors still throw. */
677
+ function lstatIfExists(path) {
678
+ try {
679
+ return lstatSync(path);
680
+ }
681
+ catch (error) {
682
+ if (isErrno(error, "ENOENT"))
683
+ return undefined;
684
+ throw error;
685
+ }
686
+ }
687
+ function assertRegistryFileSafe(path) {
688
+ const stat = lstatIfExists(path);
689
+ if (stat && (stat.isSymbolicLink() || !stat.isFile())) {
690
+ throw new Error(`Office registry must be a regular file: ${path}`);
691
+ }
692
+ }
693
+ function assertPathIfPresent(path, label) {
694
+ const stat = lstatIfExists(path);
695
+ if (stat && (stat.isSymbolicLink() || !stat.isDirectory())) {
696
+ throw new Error(`${label} must be a regular directory: ${path}`);
697
+ }
698
+ }
699
+ function assertPathAbsent(path, label) {
700
+ if (lstatIfExists(path))
701
+ throw new Error(`${label} must be absent: ${path}`);
702
+ }
703
+ function pathExists(path) {
704
+ return lstatIfExists(path) !== undefined;
705
+ }
706
+ /** Create the lock directory and stamp it with our token, unwinding on failure. */
707
+ function claimRegistryLock(lockPath, token) {
708
+ mkdirSync(lockPath, { mode: 0o700 });
709
+ try {
710
+ writeFileSync(join(lockPath, "owner"), `${token}\n`, { mode: 0o600 });
711
+ }
712
+ catch (error) {
713
+ rmSync(lockPath, { recursive: true, force: true });
714
+ throw error;
715
+ }
716
+ }
717
+ function acquireRegistryLease(lockPath, timeoutMs) {
718
+ const deadline = Date.now() + timeoutMs;
719
+ const token = `${process.pid}:${randomBytes(8).toString("hex")}`;
720
+ for (;;) {
721
+ try {
722
+ claimRegistryLock(lockPath, token);
723
+ return () => releaseRegistryLease(lockPath, token);
724
+ }
725
+ catch (error) {
726
+ awaitFreeRegistryLock(lockPath, deadline, error);
727
+ }
728
+ }
729
+ }
730
+ /**
731
+ * Handle one failed lock attempt: rethrow anything but a held lock, clear a
732
+ * stale lock so the next attempt wins, else wait until the deadline passes.
733
+ */
734
+ function awaitFreeRegistryLock(lockPath, deadline, error) {
735
+ if (!isErrno(error, "EEXIST"))
736
+ throw error;
737
+ if (registryLockIsStale(lockPath)) {
738
+ rmSync(lockPath, { recursive: true, force: true });
739
+ return;
740
+ }
741
+ if (Date.now() >= deadline) {
742
+ throw new Error(`Timed out acquiring office registry lock: ${lockPath}`, { cause: error });
743
+ }
744
+ sleepSync(REGISTRY_LOCK_RETRY_MS);
745
+ }
746
+ function releaseRegistryLease(lockPath, token) {
747
+ try {
748
+ if (readFileSync(join(lockPath, "owner"), "utf8").trim() === token) {
749
+ rmSync(lockPath, { recursive: true, force: true });
750
+ }
751
+ }
752
+ catch (error) {
753
+ if (!isErrno(error, "ENOENT"))
754
+ throw error;
755
+ }
756
+ }
757
+ function registryLockIsStale(lockPath) {
758
+ let ownerKnown = false;
759
+ let ownerAlive = false;
760
+ try {
761
+ const owner = readFileSync(join(lockPath, "owner"), "utf8").trim();
762
+ const pid = Number(owner.split(":", 1)[0]);
763
+ if (Number.isInteger(pid) && pid > 0) {
764
+ ownerKnown = true;
765
+ try {
766
+ process.kill(pid, 0);
767
+ ownerAlive = true;
768
+ }
769
+ catch (error) {
770
+ if (isErrno(error, "EPERM"))
771
+ ownerAlive = true;
772
+ }
773
+ }
774
+ }
775
+ catch {
776
+ // The owner file may not have been written before its process died.
777
+ }
778
+ try {
779
+ const oldEnough = Date.now() - statSync(lockPath).mtimeMs >= REGISTRY_LOCK_STALE_MS;
780
+ return ownerKnown ? !ownerAlive : oldEnough;
781
+ }
782
+ catch {
783
+ return false;
784
+ }
785
+ }
786
+ function sleepSync(milliseconds) {
787
+ Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, milliseconds);
788
+ }
789
+ // ── raw-id lookups (cold paths: CLI, Admin enumeration) ──────────────────────
790
+ /** Current office inventory, read fresh from disk for cross-process freshness. */
791
+ export function listRegisteredOffices(stateDir) {
792
+ return new OfficeRegistry(stateDir).getOffices();
793
+ }
794
+ /**
795
+ * Enabled platforms whose id format could have produced this raw
796
+ * conversation id. Auto-claiming uses this as verification, not guessing:
797
+ * every format below is one mikan itself writes (GitHub ids are mikan-derived
798
+ * slugs; Slack/Telegram/Discord ids are the platforms' own grammars), and a
799
+ * directory is only claimed when exactly one enabled platform's format
800
+ * matches. Bare digits stay ambiguous while both Telegram and Discord are
801
+ * enabled (negative ids are Telegram-only); anything matching no enabled
802
+ * format fails closed to needs-owner.
803
+ */
804
+ function platformsMatchingConversationIdFormat(rawConversationId, enabledPlatforms) {
805
+ return enabledPlatforms.filter((platform) => {
806
+ switch (platform) {
807
+ case "github":
808
+ return isGithubConversationId(rawConversationId);
809
+ case "telegram":
810
+ return /^-?\d+$/.test(rawConversationId);
811
+ case "discord":
812
+ return /^\d+$/.test(rawConversationId);
813
+ case "slack":
814
+ return /^[A-Z][A-Z0-9]*$/.test(rawConversationId);
815
+ }
816
+ });
817
+ }
818
+ function isGithubConversationId(rawConversationId) {
819
+ try {
820
+ parseGithubConversationId(rawConversationId);
821
+ return true;
822
+ }
823
+ catch {
824
+ return false;
825
+ }
826
+ }
827
+ function isErrno(error, code) {
828
+ return error instanceof Error && "code" in error && error.code === code;
829
+ }
830
+ // ── Boot-time legacy migration ────────────────────────────────────────────────
831
+ /**
832
+ * Move every legacy raw-id office directory under the workspace root to the
833
+ * canonical office-key layout, journaling each move through the office
834
+ * registry so an interrupted run resumes instead of losing offices.
835
+ *
836
+ * The engine never guesses: with several enabled platforms an unowned raw
837
+ * directory stays in place and is reported for `mikan office claim`. Callers
838
+ * must treat a non-empty `unowned`/`failed` as fatal for daemon boot — after
839
+ * the layout flip, an unmigrated legacy directory is invisible to the
840
+ * runtime, which would silently present the conversation as empty.
841
+ */
842
+ export function migrateLegacyOffices(options) {
843
+ const registry = new OfficeRegistry(options.stateDir);
844
+ for (const platform of options.enabledPlatforms)
845
+ registry.enablePlatform(platform);
846
+ const summary = {
847
+ migrated: [],
848
+ recovered: [],
849
+ unowned: [],
850
+ failed: [],
851
+ vaultKeysMigrated: [],
852
+ vaultConflicts: [],
853
+ stateDirsMigrated: [],
854
+ stateDirConflicts: [],
855
+ };
856
+ recoverInterruptedMoves(registry, summary);
857
+ claimAndMoveLegacyDirs(registry, options.workspaceRoot, summary);
858
+ // Credential vaults are keyed by office too; the registry inventory (which
859
+ // the directory moves above just extended) drives the same rename.
860
+ const vaults = migrateConversationVaultKeys({
861
+ stateDir: options.stateDir,
862
+ offices: registry.getOffices(),
863
+ });
864
+ summary.vaultKeysMigrated = vaults.migrated;
865
+ summary.vaultConflicts = vaults.conflicts;
866
+ for (const rawConversationId of vaults.migrated) {
867
+ log.logInfo(`[office] Migrated vault key to office key: ${rawConversationId}`);
868
+ }
869
+ migrateConversationStateDirs(registry, options.stateDir, summary);
870
+ for (const record of registry.getState().migrations) {
871
+ if (record.status === "needs-owner")
872
+ summary.unowned.push(record.rawConversationId);
873
+ else if (record.status === "failed")
874
+ summary.failed.push(record.rawConversationId);
875
+ }
876
+ return summary;
877
+ }
878
+ /** Complete or fail every move the journal says was interrupted mid-rename. */
879
+ function recoverInterruptedMoves(registry, summary) {
880
+ for (const record of registry.getState().migrations) {
881
+ if (record.status !== "moving")
882
+ continue;
883
+ const failure = finishInterruptedMove(record);
884
+ if (failure) {
885
+ registry.markFailed(record.rawConversationId, failure);
886
+ continue;
887
+ }
888
+ registry.markCommitted(record.rawConversationId);
889
+ recordMigratedOffice(registry, record);
890
+ summary.recovered.push(record.rawConversationId);
891
+ log.logInfo(`[office] Recovered interrupted migration: ${record.rawConversationId}`);
892
+ }
893
+ }
894
+ /** Complete one interrupted rename; returns the failure reason when it cannot. */
895
+ function finishInterruptedMove(record) {
896
+ const targetDir = record.targetDir;
897
+ if (!targetDir)
898
+ return "Moving record has no target directory";
899
+ const sourceExists = pathExists(record.sourceDir);
900
+ const targetExists = pathExists(targetDir);
901
+ if (sourceExists && targetExists) {
902
+ return "Both legacy source and office target exist; merge them manually";
903
+ }
904
+ if (!sourceExists && !targetExists)
905
+ return "Neither legacy source nor office target exists";
906
+ if (sourceExists)
907
+ renameSync(record.sourceDir, targetDir);
908
+ return undefined;
909
+ }
910
+ /**
911
+ * A legacy directory is claimable unless it already failed (reported via
912
+ * summary.failed). One that reappears after a committed move is a different
913
+ * (or resurrected) office the runtime can no longer see, so refusing to boot
914
+ * beats silently ignoring its data.
915
+ */
916
+ function isClaimableLegacyDir(registry, workspaceRoot, rawConversationId) {
917
+ const existing = registry.getMigration(rawConversationId);
918
+ if (existing?.status === "committed") {
919
+ throw new Error(`Legacy office directory reappeared after migration: ${join(workspaceRoot, rawConversationId)}`);
920
+ }
921
+ return existing?.status !== "failed";
922
+ }
923
+ /** Scan the workspace root and move every claimable legacy office directory. */
924
+ function claimAndMoveLegacyDirs(registry, workspaceRoot, summary) {
925
+ for (const rawConversationId of listLegacyOfficeDirs(workspaceRoot)) {
926
+ if (!isClaimableLegacyDir(registry, workspaceRoot, rawConversationId))
927
+ continue;
928
+ const record = registry.prepareLegacyMigration({
929
+ rawConversationId,
930
+ sourceDir: join(workspaceRoot, rawConversationId),
931
+ workspaceRoot,
932
+ });
933
+ if (record.status === "needs-owner")
934
+ continue; // reported via summary.unowned
935
+ const moving = registry.markMoving(rawConversationId);
936
+ const targetDir = moving.targetDir;
937
+ if (!targetDir)
938
+ throw new Error("Moving office migration has no target directory");
939
+ renameSync(moving.sourceDir, targetDir);
940
+ registry.markCommitted(rawConversationId);
941
+ recordMigratedOffice(registry, moving);
942
+ summary.migrated.push(rawConversationId);
943
+ log.logInfo(`[office] Migrated office directory: ${rawConversationId} -> ${targetDir}`);
944
+ }
945
+ }
946
+ /**
947
+ * Move each registered office's host state tree from
948
+ * `conversations/<rawId>` to
949
+ * `conversations/<officeKey>` in one rename. Conflicts are reported for
950
+ * manual merge, never clobbered.
951
+ */
952
+ function migrateConversationStateDirs(registry, stateDir, summary) {
953
+ for (const office of registry.getOffices()) {
954
+ const legacyDir = join(stateDir, "conversations", office.conversationId);
955
+ if (!existsSync(legacyDir))
956
+ continue;
957
+ const targetDir = officeStateDir(stateDir, office);
958
+ if (existsSync(targetDir)) {
959
+ summary.stateDirConflicts.push(office.conversationId);
960
+ continue;
961
+ }
962
+ renameSync(legacyDir, targetDir);
963
+ summary.stateDirsMigrated.push(office.conversationId);
964
+ log.logInfo(`[office] Migrated host state dir to office key: ${office.conversationId}`);
965
+ }
966
+ }
967
+ /** A migrated office is an existing office; keep the directory enumerable. */
968
+ function recordMigratedOffice(registry, record) {
969
+ if (!record.ownerPlatform)
970
+ return;
971
+ registry.recordOffice({
972
+ platform: record.ownerPlatform,
973
+ conversationId: record.rawConversationId,
974
+ });
975
+ }
976
+ /**
977
+ * Legacy office candidates: regular directories that are not reserved
978
+ * infrastructure, not hidden, and not already office-key named. A symlink in
979
+ * office position is refused outright — following it could move data from
980
+ * outside the workspace root.
981
+ *
982
+ * A candidate must also look like a conversation office: every office that
983
+ * ever saw a message has a `log.jsonl`, and every office that ran the agent
984
+ * has `sessions/`. Trusted workspace roots legitimately accumulate other
985
+ * directories — repos the agent cloned, build output — which are not offices
986
+ * and must be neither renamed nor reported as unowned; they stay where they
987
+ * are (an operator can still claim one explicitly via `mikan office claim`).
988
+ */
989
+ function listLegacyOfficeDirs(workspaceRoot) {
990
+ return readdirSync(workspaceRoot, { withFileTypes: true })
991
+ .filter((entry) => isLegacyOfficeDir(workspaceRoot, entry))
992
+ .map((entry) => entry.name)
993
+ .toSorted();
994
+ }
995
+ function isLegacyOfficeDir(workspaceRoot, entry) {
996
+ if (entry.name.startsWith("."))
997
+ return false;
998
+ if (RESERVED_WORKSPACE_NAMES.has(entry.name))
999
+ return false;
1000
+ if (isOfficeKey(entry.name))
1001
+ return false;
1002
+ if (entry.isSymbolicLink()) {
1003
+ throw new Error(`Workspace entry must not be a symlink: ${join(workspaceRoot, entry.name)}`);
1004
+ }
1005
+ if (!entry.isDirectory())
1006
+ return false;
1007
+ if (looksLikeConversationOffice(join(workspaceRoot, entry.name)))
1008
+ return true;
1009
+ log.logInfo(`[office] Skipping non-office workspace directory (no log.jsonl or sessions/): ${entry.name}`);
1010
+ return false;
1011
+ }
1012
+ function looksLikeConversationOffice(dir) {
1013
+ return existsSync(join(dir, "log.jsonl")) || existsSync(join(dir, "sessions"));
1014
+ }
1015
+ /** Operator-facing boot failure for offices the engine may not move itself. */
1016
+ export function formatUnmigratedOfficesError(summary) {
1017
+ const lines = ["Conversation office migration cannot complete:"];
1018
+ if (summary.unowned.length > 0) {
1019
+ lines.push("", "These legacy conversation directories have no owning platform (several", "platforms are enabled, so ownership cannot be inferred):", ...summary.unowned.map((id) => ` - ${id}`), "", "Assign each one with:", " mikan office claim <conversationId> <platform>");
1020
+ }
1021
+ lines.push(...conflictSection(summary.failed, [
1022
+ "These migrations previously failed and need manual repair (see",
1023
+ "office-registry.json in the state dir for each error):",
1024
+ ]), ...conflictSection(summary.vaultConflicts, [
1025
+ "These conversations have credentials under both the legacy and the",
1026
+ "office-key vault directory; merge them manually under <state-dir>/vaults:",
1027
+ ]), ...conflictSection(summary.stateDirConflicts, [
1028
+ "These conversations have host state under both the legacy and the",
1029
+ "office-key directory; merge them manually under <state-dir>/conversations:",
1030
+ ]));
1031
+ return lines.join("\n");
1032
+ }
1033
+ /** One blank-separated "these need manual work" block, empty when nothing does. */
1034
+ function conflictSection(ids, explanation) {
1035
+ if (ids.length === 0)
1036
+ return [];
1037
+ return ["", ...explanation, ...ids.map((id) => ` - ${id}`)];
1038
+ }
1039
+ /**
1040
+ * Bind-spec translator for the container layout migration: rewrites every
1041
+ * host path the office migration renamed — workspace dirs, per-conversation
1042
+ * state trees, conversation vaults — and the guest workspace segment, using
1043
+ * the registry's office inventory as the raw-id ↔ office mapping. Specs that
1044
+ * reference none of the renamed paths come back unchanged, which is also how
1045
+ * an already-migrated container is recognized.
1046
+ */
1047
+ function replacePrefix(path, pairs) {
1048
+ for (const [oldPrefix, newPrefix] of pairs) {
1049
+ if (path === oldPrefix)
1050
+ return newPrefix;
1051
+ if (path.startsWith(`${oldPrefix}/`))
1052
+ return newPrefix + path.slice(oldPrefix.length);
1053
+ }
1054
+ return path;
1055
+ }
1056
+ export function buildContainerBindTranslator(options) {
1057
+ const hostPairs = [];
1058
+ const guestPairs = [];
1059
+ for (const office of options.offices) {
1060
+ const key = officeKey(office);
1061
+ const rawId = office.conversationId;
1062
+ hostPairs.push([join(options.workspaceRoot, rawId), join(options.workspaceRoot, key)]);
1063
+ hostPairs.push([
1064
+ join(options.stateDir, "conversations", rawId),
1065
+ officeStateDir(options.stateDir, office),
1066
+ ]);
1067
+ hostPairs.push([
1068
+ join(options.stateDir, "vaults", legacyConversationCredentialKey(rawId)),
1069
+ join(options.stateDir, "vaults", key),
1070
+ ]);
1071
+ guestPairs.push([`/workspace/${rawId}`, `/workspace/${key}`]);
1072
+ }
1073
+ return (bindSpec) => {
1074
+ const readOnly = bindSpec.endsWith(":ro");
1075
+ const spec = readOnly ? bindSpec.slice(0, -3) : bindSpec;
1076
+ const separator = spec.indexOf(":");
1077
+ if (separator === -1)
1078
+ return bindSpec;
1079
+ const source = replacePrefix(spec.slice(0, separator), hostPairs);
1080
+ const target = replacePrefix(spec.slice(separator + 1), guestPairs);
1081
+ return `${source}:${target}${readOnly ? ":ro" : ""}`;
1082
+ };
1083
+ }
1084
+ //# sourceMappingURL=index.js.map