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

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 (497) hide show
  1. package/CHANGELOG.md +388 -0
  2. package/README.md +49 -16
  3. package/dist/adapter.d.ts +1 -1
  4. package/dist/adapter.d.ts.map +1 -1
  5. package/dist/adapter.js.map +1 -1
  6. package/dist/adapters/buffered-responder.d.ts +60 -0
  7. package/dist/adapters/buffered-responder.d.ts.map +1 -0
  8. package/dist/adapters/buffered-responder.js +201 -0
  9. package/dist/adapters/buffered-responder.js.map +1 -0
  10. package/dist/adapters/discord/bot.d.ts +1 -0
  11. package/dist/adapters/discord/bot.d.ts.map +1 -1
  12. package/dist/adapters/discord/bot.js +36 -67
  13. package/dist/adapters/discord/bot.js.map +1 -1
  14. package/dist/adapters/discord/context.d.ts.map +1 -1
  15. package/dist/adapters/discord/context.js +44 -204
  16. package/dist/adapters/discord/context.js.map +1 -1
  17. package/dist/adapters/github/bot.d.ts +86 -0
  18. package/dist/adapters/github/bot.d.ts.map +1 -0
  19. package/dist/adapters/github/bot.js +640 -0
  20. package/dist/adapters/github/bot.js.map +1 -0
  21. package/dist/adapters/github/client.d.ts +122 -0
  22. package/dist/adapters/github/client.d.ts.map +1 -0
  23. package/dist/adapters/github/client.js +314 -0
  24. package/dist/adapters/github/client.js.map +1 -0
  25. package/dist/adapters/github/cloudbuild.d.ts +24 -0
  26. package/dist/adapters/github/cloudbuild.d.ts.map +1 -0
  27. package/dist/adapters/github/cloudbuild.js +71 -0
  28. package/dist/adapters/github/cloudbuild.js.map +1 -0
  29. package/dist/adapters/github/context.d.ts +9 -0
  30. package/dist/adapters/github/context.d.ts.map +1 -0
  31. package/dist/adapters/github/context.js +103 -0
  32. package/dist/adapters/github/context.js.map +1 -0
  33. package/dist/adapters/github/gcp-auth.d.ts +31 -0
  34. package/dist/adapters/github/gcp-auth.d.ts.map +1 -0
  35. package/dist/adapters/github/gcp-auth.js +196 -0
  36. package/dist/adapters/github/gcp-auth.js.map +1 -0
  37. package/dist/adapters/github/github-ops.d.ts +90 -0
  38. package/dist/adapters/github/github-ops.d.ts.map +1 -0
  39. package/dist/adapters/github/github-ops.js +405 -0
  40. package/dist/adapters/github/github-ops.js.map +1 -0
  41. package/dist/adapters/github/ids.d.ts +34 -0
  42. package/dist/adapters/github/ids.d.ts.map +1 -0
  43. package/dist/adapters/github/ids.js +53 -0
  44. package/dist/adapters/github/ids.js.map +1 -0
  45. package/dist/adapters/github/repo.d.ts +32 -0
  46. package/dist/adapters/github/repo.d.ts.map +1 -0
  47. package/dist/adapters/github/repo.js +141 -0
  48. package/dist/adapters/github/repo.js.map +1 -0
  49. package/dist/adapters/github/tool-pack.d.ts +14 -0
  50. package/dist/adapters/github/tool-pack.d.ts.map +1 -0
  51. package/dist/adapters/github/tool-pack.js +56 -0
  52. package/dist/adapters/github/tool-pack.js.map +1 -0
  53. package/dist/adapters/github/tools/checks.d.ts +24 -0
  54. package/dist/adapters/github/tools/checks.d.ts.map +1 -0
  55. package/dist/adapters/github/tools/checks.js +105 -0
  56. package/dist/adapters/github/tools/checks.js.map +1 -0
  57. package/dist/adapters/github/tools/issue.d.ts +22 -0
  58. package/dist/adapters/github/tools/issue.d.ts.map +1 -0
  59. package/dist/adapters/github/tools/issue.js +48 -0
  60. package/dist/adapters/github/tools/issue.js.map +1 -0
  61. package/dist/adapters/github/tools/pr.d.ts +22 -0
  62. package/dist/adapters/github/tools/pr.d.ts.map +1 -0
  63. package/dist/adapters/github/tools/pr.js +48 -0
  64. package/dist/adapters/github/tools/pr.js.map +1 -0
  65. package/dist/adapters/github/tools/read.d.ts +22 -0
  66. package/dist/adapters/github/tools/read.d.ts.map +1 -0
  67. package/dist/adapters/github/tools/read.js +141 -0
  68. package/dist/adapters/github/tools/read.js.map +1 -0
  69. package/dist/adapters/github/tools/review-reply.d.ts +19 -0
  70. package/dist/adapters/github/tools/review-reply.d.ts.map +1 -0
  71. package/dist/adapters/github/tools/review-reply.js +38 -0
  72. package/dist/adapters/github/tools/review-reply.js.map +1 -0
  73. package/dist/adapters/github/tools/sync.d.ts +17 -0
  74. package/dist/adapters/github/tools/sync.d.ts.map +1 -0
  75. package/dist/adapters/github/tools/sync.js +34 -0
  76. package/dist/adapters/github/tools/sync.js.map +1 -0
  77. package/dist/adapters/github/types.d.ts +350 -0
  78. package/dist/adapters/github/types.d.ts.map +1 -0
  79. package/dist/adapters/github/types.js +2 -0
  80. package/dist/adapters/github/types.js.map +1 -0
  81. package/dist/adapters/intake.d.ts +16 -5
  82. package/dist/adapters/intake.d.ts.map +1 -1
  83. package/dist/adapters/intake.js +79 -22
  84. package/dist/adapters/intake.js.map +1 -1
  85. package/dist/adapters/slack/bot.d.ts +8 -6
  86. package/dist/adapters/slack/bot.d.ts.map +1 -1
  87. package/dist/adapters/slack/bot.js +82 -134
  88. package/dist/adapters/slack/bot.js.map +1 -1
  89. package/dist/adapters/slack/context.d.ts.map +1 -1
  90. package/dist/adapters/slack/context.js +3 -14
  91. package/dist/adapters/slack/context.js.map +1 -1
  92. package/dist/adapters/slack/response-lifecycle.d.ts.map +1 -1
  93. package/dist/adapters/slack/response-lifecycle.js +14 -17
  94. package/dist/adapters/slack/response-lifecycle.js.map +1 -1
  95. package/dist/adapters/slack/session.d.ts.map +1 -1
  96. package/dist/adapters/slack/session.js +5 -8
  97. package/dist/adapters/slack/session.js.map +1 -1
  98. package/dist/adapters/streaming.d.ts +4 -0
  99. package/dist/adapters/streaming.d.ts.map +1 -1
  100. package/dist/adapters/streaming.js +11 -0
  101. package/dist/adapters/streaming.js.map +1 -1
  102. package/dist/adapters/telegram/bot.d.ts +1 -2
  103. package/dist/adapters/telegram/bot.d.ts.map +1 -1
  104. package/dist/adapters/telegram/bot.js +27 -62
  105. package/dist/adapters/telegram/bot.js.map +1 -1
  106. package/dist/adapters/telegram/context.d.ts.map +1 -1
  107. package/dist/adapters/telegram/context.js +37 -174
  108. package/dist/adapters/telegram/context.js.map +1 -1
  109. package/dist/adapters/types.d.ts +28 -2
  110. package/dist/adapters/types.d.ts.map +1 -1
  111. package/dist/adapters/types.js.map +1 -1
  112. package/dist/agent.d.ts +37 -14
  113. package/dist/agent.d.ts.map +1 -1
  114. package/dist/agent.js +359 -229
  115. package/dist/agent.js.map +1 -1
  116. package/dist/cli/arg-grammar.d.ts +25 -0
  117. package/dist/cli/arg-grammar.d.ts.map +1 -0
  118. package/dist/cli/arg-grammar.js +59 -0
  119. package/dist/cli/arg-grammar.js.map +1 -0
  120. package/dist/cli/boot.d.ts +16 -0
  121. package/dist/cli/boot.d.ts.map +1 -0
  122. package/dist/cli/boot.js +119 -0
  123. package/dist/cli/boot.js.map +1 -0
  124. package/dist/cli/download.d.ts.map +1 -0
  125. package/dist/cli/download.js.map +1 -0
  126. package/dist/cli/ext-git.d.ts +22 -0
  127. package/dist/cli/ext-git.d.ts.map +1 -0
  128. package/dist/cli/ext-git.js +76 -0
  129. package/dist/cli/ext-git.js.map +1 -0
  130. package/dist/cli/ext.d.ts +2 -0
  131. package/dist/cli/ext.d.ts.map +1 -0
  132. package/dist/cli/ext.js +215 -0
  133. package/dist/cli/ext.js.map +1 -0
  134. package/dist/commands/admin.d.ts.map +1 -1
  135. package/dist/commands/admin.js +2 -1
  136. package/dist/commands/admin.js.map +1 -1
  137. package/dist/commands/auto-reply.d.ts.map +1 -1
  138. package/dist/commands/auto-reply.js +2 -6
  139. package/dist/commands/auto-reply.js.map +1 -1
  140. package/dist/commands/extensions.d.ts.map +1 -1
  141. package/dist/commands/extensions.js +18 -8
  142. package/dist/commands/extensions.js.map +1 -1
  143. package/dist/commands/login.d.ts +2 -1
  144. package/dist/commands/login.d.ts.map +1 -1
  145. package/dist/commands/login.js +35 -3
  146. package/dist/commands/login.js.map +1 -1
  147. package/dist/commands/manifest.d.ts +72 -0
  148. package/dist/commands/manifest.d.ts.map +1 -0
  149. package/dist/commands/manifest.js +121 -0
  150. package/dist/commands/manifest.js.map +1 -0
  151. package/dist/commands/model.d.ts.map +1 -1
  152. package/dist/commands/model.js +11 -9
  153. package/dist/commands/model.js.map +1 -1
  154. package/dist/commands/new.d.ts.map +1 -1
  155. package/dist/commands/new.js +2 -1
  156. package/dist/commands/new.js.map +1 -1
  157. package/dist/commands/sandbox.d.ts.map +1 -1
  158. package/dist/commands/sandbox.js +23 -17
  159. package/dist/commands/sandbox.js.map +1 -1
  160. package/dist/commands/text.d.ts +2 -0
  161. package/dist/commands/text.d.ts.map +1 -0
  162. package/dist/commands/text.js +16 -0
  163. package/dist/commands/text.js.map +1 -0
  164. package/dist/commands/types.d.ts +14 -1
  165. package/dist/commands/types.d.ts.map +1 -1
  166. package/dist/commands/types.js.map +1 -1
  167. package/dist/config.d.ts +1 -3
  168. package/dist/config.d.ts.map +1 -1
  169. package/dist/config.js +98 -95
  170. package/dist/config.js.map +1 -1
  171. package/dist/env-manifest.d.ts +35 -0
  172. package/dist/env-manifest.d.ts.map +1 -0
  173. package/dist/env-manifest.js +225 -0
  174. package/dist/env-manifest.js.map +1 -0
  175. package/dist/events.d.ts.map +1 -1
  176. package/dist/events.js +9 -73
  177. package/dist/events.js.map +1 -1
  178. package/dist/execution-resolver.d.ts +4 -2
  179. package/dist/execution-resolver.d.ts.map +1 -1
  180. package/dist/execution-resolver.js +54 -41
  181. package/dist/execution-resolver.js.map +1 -1
  182. package/dist/harness/event-format.d.ts +66 -0
  183. package/dist/harness/event-format.d.ts.map +1 -0
  184. package/dist/harness/event-format.js +112 -0
  185. package/dist/harness/event-format.js.map +1 -0
  186. package/dist/harness/extensions/loader.d.ts +44 -11
  187. package/dist/harness/extensions/loader.d.ts.map +1 -1
  188. package/dist/harness/extensions/loader.js +273 -84
  189. package/dist/harness/extensions/loader.js.map +1 -1
  190. package/dist/harness/extensions/registry.d.ts +48 -1
  191. package/dist/harness/extensions/registry.d.ts.map +1 -1
  192. package/dist/harness/extensions/registry.js +146 -0
  193. package/dist/harness/extensions/registry.js.map +1 -1
  194. package/dist/harness/extensions/types.d.ts +165 -22
  195. package/dist/harness/extensions/types.d.ts.map +1 -1
  196. package/dist/harness/extensions/types.js.map +1 -1
  197. package/dist/harness/index.d.ts +6 -5
  198. package/dist/harness/index.d.ts.map +1 -1
  199. package/dist/harness/index.js +3 -2
  200. package/dist/harness/index.js.map +1 -1
  201. package/dist/harness/models.d.ts +5 -0
  202. package/dist/harness/models.d.ts.map +1 -1
  203. package/dist/harness/models.js +10 -0
  204. package/dist/harness/models.js.map +1 -1
  205. package/dist/harness/runner.d.ts +37 -2
  206. package/dist/harness/runner.d.ts.map +1 -1
  207. package/dist/harness/runner.js +107 -23
  208. package/dist/harness/runner.js.map +1 -1
  209. package/dist/harness/session-store.d.ts +4 -1
  210. package/dist/harness/session-store.d.ts.map +1 -1
  211. package/dist/harness/session-store.js +11 -2
  212. package/dist/harness/session-store.js.map +1 -1
  213. package/dist/harness/subagent-runner.d.ts +34 -0
  214. package/dist/harness/subagent-runner.d.ts.map +1 -0
  215. package/dist/harness/subagent-runner.js +339 -0
  216. package/dist/harness/subagent-runner.js.map +1 -0
  217. package/dist/harness/types.d.ts +53 -0
  218. package/dist/harness/types.d.ts.map +1 -1
  219. package/dist/harness/types.js.map +1 -1
  220. package/dist/index.d.ts +3 -3
  221. package/dist/index.d.ts.map +1 -1
  222. package/dist/index.js +2 -2
  223. package/dist/index.js.map +1 -1
  224. package/dist/main.js +260 -109
  225. package/dist/main.js.map +1 -1
  226. package/dist/observability/instrument.js +6 -4
  227. package/dist/observability/instrument.js.map +1 -1
  228. package/dist/observability/sentry.d.ts.map +1 -1
  229. package/dist/observability/sentry.js +3 -2
  230. package/dist/observability/sentry.js.map +1 -1
  231. package/dist/provisioner.d.ts.map +1 -1
  232. package/dist/provisioner.js +2 -5
  233. package/dist/provisioner.js.map +1 -1
  234. package/dist/runtime/conversation-runtime.d.ts +1 -1
  235. package/dist/runtime/conversation-runtime.d.ts.map +1 -1
  236. package/dist/runtime/conversation-runtime.js +276 -43
  237. package/dist/runtime/conversation-runtime.js.map +1 -1
  238. package/dist/runtime/types.d.ts +36 -5
  239. package/dist/runtime/types.d.ts.map +1 -1
  240. package/dist/runtime/types.js.map +1 -1
  241. package/dist/sandbox/cloudflare.d.ts +3 -0
  242. package/dist/sandbox/cloudflare.d.ts.map +1 -1
  243. package/dist/sandbox/cloudflare.js +10 -0
  244. package/dist/sandbox/cloudflare.js.map +1 -1
  245. package/dist/sandbox/container.d.ts +4 -0
  246. package/dist/sandbox/container.d.ts.map +1 -1
  247. package/dist/sandbox/container.js +11 -2
  248. package/dist/sandbox/container.js.map +1 -1
  249. package/dist/sandbox/firecracker.d.ts +3 -0
  250. package/dist/sandbox/firecracker.d.ts.map +1 -1
  251. package/dist/sandbox/firecracker.js +10 -1
  252. package/dist/sandbox/firecracker.js.map +1 -1
  253. package/dist/sandbox/gondolin-bootstrap.d.ts +26 -0
  254. package/dist/sandbox/gondolin-bootstrap.d.ts.map +1 -0
  255. package/dist/sandbox/gondolin-bootstrap.js +27 -0
  256. package/dist/sandbox/gondolin-bootstrap.js.map +1 -0
  257. package/dist/sandbox/gondolin-contract.d.ts +125 -0
  258. package/dist/sandbox/gondolin-contract.d.ts.map +1 -0
  259. package/dist/sandbox/gondolin-contract.js +155 -0
  260. package/dist/sandbox/gondolin-contract.js.map +1 -0
  261. package/dist/sandbox/gondolin-fleet.d.ts +104 -0
  262. package/dist/sandbox/gondolin-fleet.d.ts.map +1 -0
  263. package/dist/sandbox/gondolin-fleet.js +330 -0
  264. package/dist/sandbox/gondolin-fleet.js.map +1 -0
  265. package/dist/sandbox/gondolin-gateway.d.ts +86 -0
  266. package/dist/sandbox/gondolin-gateway.d.ts.map +1 -0
  267. package/dist/sandbox/gondolin-gateway.js +407 -0
  268. package/dist/sandbox/gondolin-gateway.js.map +1 -0
  269. package/dist/sandbox/gondolin-inventory.d.ts +75 -0
  270. package/dist/sandbox/gondolin-inventory.d.ts.map +1 -0
  271. package/dist/sandbox/gondolin-inventory.js +257 -0
  272. package/dist/sandbox/gondolin-inventory.js.map +1 -0
  273. package/dist/sandbox/gondolin-join.d.ts +62 -0
  274. package/dist/sandbox/gondolin-join.d.ts.map +1 -0
  275. package/dist/sandbox/gondolin-join.js +261 -0
  276. package/dist/sandbox/gondolin-join.js.map +1 -0
  277. package/dist/sandbox/gondolin-nfs-advisory.d.ts +15 -0
  278. package/dist/sandbox/gondolin-nfs-advisory.d.ts.map +1 -0
  279. package/dist/sandbox/gondolin-nfs-advisory.js +60 -0
  280. package/dist/sandbox/gondolin-nfs-advisory.js.map +1 -0
  281. package/dist/sandbox/gondolin-placement.d.ts +30 -0
  282. package/dist/sandbox/gondolin-placement.d.ts.map +1 -0
  283. package/dist/sandbox/gondolin-placement.js +77 -0
  284. package/dist/sandbox/gondolin-placement.js.map +1 -0
  285. package/dist/sandbox/gondolin-recovery.d.ts +33 -0
  286. package/dist/sandbox/gondolin-recovery.d.ts.map +1 -0
  287. package/dist/sandbox/gondolin-recovery.js +39 -0
  288. package/dist/sandbox/gondolin-recovery.js.map +1 -0
  289. package/dist/sandbox/gondolin-remote.d.ts +70 -0
  290. package/dist/sandbox/gondolin-remote.d.ts.map +1 -0
  291. package/dist/sandbox/gondolin-remote.js +325 -0
  292. package/dist/sandbox/gondolin-remote.js.map +1 -0
  293. package/dist/sandbox/gondolin-worker-client.d.ts +135 -0
  294. package/dist/sandbox/gondolin-worker-client.d.ts.map +1 -0
  295. package/dist/sandbox/gondolin-worker-client.js +323 -0
  296. package/dist/sandbox/gondolin-worker-client.js.map +1 -0
  297. package/dist/sandbox/gondolin-worker-main.d.ts +2 -0
  298. package/dist/sandbox/gondolin-worker-main.d.ts.map +1 -0
  299. package/dist/sandbox/gondolin-worker-main.js +22 -0
  300. package/dist/sandbox/gondolin-worker-main.js.map +1 -0
  301. package/dist/sandbox/gondolin-worker.d.ts +17 -0
  302. package/dist/sandbox/gondolin-worker.d.ts.map +1 -0
  303. package/dist/sandbox/gondolin-worker.js +201 -0
  304. package/dist/sandbox/gondolin-worker.js.map +1 -0
  305. package/dist/sandbox/gondolin.d.ts +53 -0
  306. package/dist/sandbox/gondolin.d.ts.map +1 -0
  307. package/dist/sandbox/gondolin.js +429 -0
  308. package/dist/sandbox/gondolin.js.map +1 -0
  309. package/dist/sandbox/host.d.ts +3 -0
  310. package/dist/sandbox/host.d.ts.map +1 -1
  311. package/dist/sandbox/host.js +14 -0
  312. package/dist/sandbox/host.js.map +1 -1
  313. package/dist/sandbox/identity.d.ts +21 -0
  314. package/dist/sandbox/identity.d.ts.map +1 -0
  315. package/dist/sandbox/identity.js +36 -0
  316. package/dist/sandbox/identity.js.map +1 -0
  317. package/dist/sandbox/index.d.ts +13 -4
  318. package/dist/sandbox/index.d.ts.map +1 -1
  319. package/dist/sandbox/index.js +19 -3
  320. package/dist/sandbox/index.js.map +1 -1
  321. package/dist/sandbox/types.d.ts +31 -1
  322. package/dist/sandbox/types.d.ts.map +1 -1
  323. package/dist/sandbox/types.js.map +1 -1
  324. package/dist/sandbox/utils.d.ts +12 -0
  325. package/dist/sandbox/utils.d.ts.map +1 -1
  326. package/dist/sandbox/utils.js +38 -0
  327. package/dist/sandbox/utils.js.map +1 -1
  328. package/dist/sessions/chat-history-sync.d.ts +32 -0
  329. package/dist/sessions/chat-history-sync.d.ts.map +1 -0
  330. package/dist/sessions/{agent-memory-file-manager.js → chat-history-sync.js} +40 -113
  331. package/dist/sessions/chat-history-sync.js.map +1 -0
  332. package/dist/sessions/conversation-log.d.ts +13 -0
  333. package/dist/sessions/conversation-log.d.ts.map +1 -0
  334. package/dist/sessions/conversation-log.js +47 -0
  335. package/dist/sessions/conversation-log.js.map +1 -0
  336. package/dist/sessions/history-line.d.ts +20 -0
  337. package/dist/sessions/history-line.d.ts.map +1 -0
  338. package/dist/sessions/history-line.js +24 -0
  339. package/dist/sessions/history-line.js.map +1 -0
  340. package/dist/sessions/policy.d.ts.map +1 -1
  341. package/dist/sessions/policy.js +5 -3
  342. package/dist/sessions/policy.js.map +1 -1
  343. package/dist/sessions/rotation.d.ts +2 -0
  344. package/dist/sessions/rotation.d.ts.map +1 -0
  345. package/dist/sessions/rotation.js +39 -0
  346. package/dist/sessions/rotation.js.map +1 -0
  347. package/dist/sessions/session-key.d.ts +31 -0
  348. package/dist/sessions/session-key.d.ts.map +1 -0
  349. package/dist/sessions/session-key.js +44 -0
  350. package/dist/sessions/session-key.js.map +1 -0
  351. package/dist/sessions/store.d.ts.map +1 -1
  352. package/dist/sessions/store.js +6 -12
  353. package/dist/sessions/store.js.map +1 -1
  354. package/dist/sessions/types.d.ts +2 -2
  355. package/dist/sessions/types.d.ts.map +1 -1
  356. package/dist/sessions/types.js.map +1 -1
  357. package/dist/settings-mutation.d.ts +23 -0
  358. package/dist/settings-mutation.d.ts.map +1 -0
  359. package/dist/settings-mutation.js +42 -0
  360. package/dist/settings-mutation.js.map +1 -0
  361. package/dist/tools/bash.d.ts +3 -1
  362. package/dist/tools/bash.d.ts.map +1 -1
  363. package/dist/tools/bash.js +24 -17
  364. package/dist/tools/bash.js.map +1 -1
  365. package/dist/tools/edit.d.ts.map +1 -1
  366. package/dist/tools/edit.js +9 -12
  367. package/dist/tools/edit.js.map +1 -1
  368. package/dist/tools/event.d.ts +1 -1
  369. package/dist/tools/event.d.ts.map +1 -1
  370. package/dist/tools/event.js +53 -43
  371. package/dist/tools/event.js.map +1 -1
  372. package/dist/tools/generate-image.d.ts +17 -0
  373. package/dist/tools/generate-image.d.ts.map +1 -0
  374. package/dist/tools/generate-image.js +63 -0
  375. package/dist/tools/generate-image.js.map +1 -0
  376. package/dist/tools/host-fn-tool.d.ts +21 -0
  377. package/dist/tools/host-fn-tool.d.ts.map +1 -0
  378. package/dist/tools/host-fn-tool.js +32 -0
  379. package/dist/tools/host-fn-tool.js.map +1 -0
  380. package/dist/tools/index.d.ts +17 -2
  381. package/dist/tools/index.d.ts.map +1 -1
  382. package/dist/tools/index.js +28 -3
  383. package/dist/tools/index.js.map +1 -1
  384. package/dist/tools/react.d.ts +15 -0
  385. package/dist/tools/react.d.ts.map +1 -0
  386. package/dist/tools/react.js +29 -0
  387. package/dist/tools/react.js.map +1 -0
  388. package/dist/tools/read.d.ts.map +1 -1
  389. package/dist/tools/read.js +7 -26
  390. package/dist/tools/read.js.map +1 -1
  391. package/dist/tools/sandbox.d.ts +2 -2
  392. package/dist/tools/sandbox.d.ts.map +1 -1
  393. package/dist/tools/sandbox.js +13 -9
  394. package/dist/tools/sandbox.js.map +1 -1
  395. package/dist/tools/subagent-slots.d.ts +28 -0
  396. package/dist/tools/subagent-slots.d.ts.map +1 -0
  397. package/dist/tools/subagent-slots.js +57 -0
  398. package/dist/tools/subagent-slots.js.map +1 -0
  399. package/dist/tools/subagent.d.ts +74 -0
  400. package/dist/tools/subagent.d.ts.map +1 -0
  401. package/dist/tools/subagent.js +335 -0
  402. package/dist/tools/subagent.js.map +1 -0
  403. package/dist/tools/types.d.ts +40 -6
  404. package/dist/tools/types.d.ts.map +1 -1
  405. package/dist/tools/types.js.map +1 -1
  406. package/dist/tools/write.d.ts.map +1 -1
  407. package/dist/tools/write.js +1 -8
  408. package/dist/tools/write.js.map +1 -1
  409. package/dist/trigger.d.ts.map +1 -1
  410. package/dist/trigger.js +1 -2
  411. package/dist/trigger.js.map +1 -1
  412. package/dist/types.d.ts +144 -31
  413. package/dist/types.d.ts.map +1 -1
  414. package/dist/types.js.map +1 -1
  415. package/dist/utils/date.d.ts +1 -1
  416. package/dist/utils/date.js +1 -1
  417. package/dist/utils/date.js.map +1 -1
  418. package/dist/vault/disabled.d.ts +9 -0
  419. package/dist/vault/disabled.d.ts.map +1 -0
  420. package/dist/vault/disabled.js +22 -0
  421. package/dist/vault/disabled.js.map +1 -0
  422. package/dist/vault/index.d.ts +0 -2
  423. package/dist/vault/index.d.ts.map +1 -1
  424. package/dist/vault/index.js +1 -32
  425. package/dist/vault/index.js.map +1 -1
  426. package/dist/vault/injection.d.ts +20 -0
  427. package/dist/vault/injection.d.ts.map +1 -0
  428. package/dist/vault/injection.js +27 -0
  429. package/dist/vault/injection.js.map +1 -0
  430. package/dist/vault/policy.d.ts +20 -0
  431. package/dist/vault/policy.d.ts.map +1 -0
  432. package/dist/vault/policy.js +20 -0
  433. package/dist/vault/policy.js.map +1 -0
  434. package/dist/vault/types.d.ts +0 -2
  435. package/dist/vault/types.d.ts.map +1 -1
  436. package/dist/vault/types.js.map +1 -1
  437. package/dist/web/admin/portal.d.ts +27 -0
  438. package/dist/web/admin/portal.d.ts.map +1 -1
  439. package/dist/web/admin/portal.js +117 -154
  440. package/dist/web/admin/portal.js.map +1 -1
  441. package/dist/web/admin/types.d.ts +6 -0
  442. package/dist/web/admin/types.d.ts.map +1 -1
  443. package/dist/web/admin/types.js.map +1 -1
  444. package/dist/web/agent-events/portal.d.ts.map +1 -1
  445. package/dist/web/agent-events/portal.js +2 -1
  446. package/dist/web/agent-events/portal.js.map +1 -1
  447. package/dist/web/login/oauth.d.ts +2 -3
  448. package/dist/web/login/oauth.d.ts.map +1 -1
  449. package/dist/web/login/oauth.js +0 -31
  450. package/dist/web/login/oauth.js.map +1 -1
  451. package/dist/web/login/portal.js +1 -1
  452. package/dist/web/login/portal.js.map +1 -1
  453. package/dist/web/login/types.d.ts +0 -11
  454. package/dist/web/login/types.d.ts.map +1 -1
  455. package/dist/web/login/types.js.map +1 -1
  456. package/dist/web/portal-shell.d.ts +4 -0
  457. package/dist/web/portal-shell.d.ts.map +1 -0
  458. package/dist/{portal-shell.js → web/portal-shell.js} +2 -2
  459. package/dist/web/portal-shell.js.map +1 -0
  460. package/dist/web/server.d.ts.map +1 -1
  461. package/dist/web/server.js +7 -0
  462. package/dist/web/server.js.map +1 -1
  463. package/dist/web/session-view/command.d.ts.map +1 -1
  464. package/dist/web/session-view/command.js +4 -1
  465. package/dist/web/session-view/command.js.map +1 -1
  466. package/dist/web/session-view/portal.d.ts.map +1 -1
  467. package/dist/web/session-view/portal.js +4 -3
  468. package/dist/web/session-view/portal.js.map +1 -1
  469. package/dist/web/session-view/service.d.ts.map +1 -1
  470. package/dist/web/session-view/service.js +2 -1
  471. package/dist/web/session-view/service.js.map +1 -1
  472. package/dist/web/session-view/types.d.ts +2 -1
  473. package/dist/web/session-view/types.d.ts.map +1 -1
  474. package/dist/web/session-view/types.js.map +1 -1
  475. package/package.json +7 -4
  476. package/dist/download.d.ts.map +0 -1
  477. package/dist/download.js.map +0 -1
  478. package/dist/model-registry.d.ts +0 -4
  479. package/dist/model-registry.d.ts.map +0 -1
  480. package/dist/model-registry.js +0 -7
  481. package/dist/model-registry.js.map +0 -1
  482. package/dist/portal-shell.d.ts +0 -4
  483. package/dist/portal-shell.d.ts.map +0 -1
  484. package/dist/portal-shell.js.map +0 -1
  485. package/dist/runtime/agent-run-controller.d.ts +0 -31
  486. package/dist/runtime/agent-run-controller.d.ts.map +0 -1
  487. package/dist/runtime/agent-run-controller.js +0 -195
  488. package/dist/runtime/agent-run-controller.js.map +0 -1
  489. package/dist/sessions/agent-memory-file-manager.d.ts +0 -19
  490. package/dist/sessions/agent-memory-file-manager.d.ts.map +0 -1
  491. package/dist/sessions/agent-memory-file-manager.js.map +0 -1
  492. package/dist/vault/routing.d.ts +0 -3
  493. package/dist/vault/routing.d.ts.map +0 -1
  494. package/dist/vault/routing.js +0 -13
  495. package/dist/vault/routing.js.map +0 -1
  496. /package/dist/{download.d.ts → cli/download.d.ts} +0 -0
  497. /package/dist/{download.js → cli/download.js} +0 -0
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Shared pieces of the CLI flag grammar.
3
+ *
4
+ * `resolveBoot` (cli/boot.ts) is the daemon's only full argv parser. This
5
+ * module holds what other scanners must agree with it on: the value-flag
6
+ * spelling (`--flag value` / `--flag=value`) via `takeValueFlag`, the default
7
+ * state dir, and an early `--state-dir` probe for import-time consumers
8
+ * (Sentry instrumentation) that must not load the boot path.
9
+ */
10
+ import { homedir } from "os";
11
+ import { join, resolve } from "path";
12
+ import { readEnv } from "../utils/env.js";
13
+ export function defaultStateDir() {
14
+ return join(homedir(), ".mikan");
15
+ }
16
+ /**
17
+ * Match `args[i]` against a value flag, accepting both `--name value` and
18
+ * `--name=value`. Returns the raw value and the index of the last argv slot
19
+ * consumed, or undefined when `args[i]` is not this flag.
20
+ */
21
+ export function takeValueFlag(args, i, name) {
22
+ const arg = args[i];
23
+ if (arg === name)
24
+ return { value: args[i + 1] ?? "", lastIndex: i + 1 };
25
+ if (arg.startsWith(name + "="))
26
+ return { value: arg.slice(name.length + 1), lastIndex: i };
27
+ return undefined;
28
+ }
29
+ /**
30
+ * Effective state dir — the ONE place its precedence is decided:
31
+ * `--state-dir` flag (last occurrence wins) > STATE_DIR / MIKAN_STATE_DIR
32
+ * env > `~/.mikan`. Boot writes the resolved value back into the env
33
+ * (setEnvAliases) purely as a compatibility channel for code that runs
34
+ * without access to the boot plan — see `effectiveStateDir`.
35
+ */
36
+ export function resolveStateDir(args = process.argv.slice(2), envValue = readEnv("STATE_DIR")) {
37
+ let flagValue;
38
+ for (let i = 0; i < args.length; i++) {
39
+ const taken = takeValueFlag(args, i, "--state-dir");
40
+ if (taken) {
41
+ flagValue = taken.value;
42
+ i = taken.lastIndex;
43
+ }
44
+ }
45
+ if (flagValue !== undefined)
46
+ return resolve(flagValue);
47
+ if (envValue)
48
+ return resolve(envValue);
49
+ return defaultStateDir();
50
+ }
51
+ /**
52
+ * State dir for post-boot readers: the env channel (which boot populated
53
+ * from the resolved plan) with the shared default. Never re-reads argv —
54
+ * by the time this runs, any `--state-dir` flag is already folded in.
55
+ */
56
+ export function effectiveStateDir() {
57
+ return resolveStateDir([]);
58
+ }
59
+ //# sourceMappingURL=arg-grammar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"arg-grammar.js","sourceRoot":"","sources":["../../src/cli/arg-grammar.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAC7B,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAE1C,MAAM,UAAU,eAAe;IAC7B,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,QAAQ,CAAC,CAAC;AACnC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAC3B,IAAc,EACd,CAAS,EACT,IAAY;IAEZ,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,IAAI,GAAG,KAAK,IAAI;QAAE,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC;IACxE,IAAI,GAAG,CAAC,UAAU,CAAC,IAAI,GAAG,GAAG,CAAC;QAAE,OAAO,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC;IAC3F,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAC7B,IAAI,GAAa,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EACtC,QAAQ,GAAuB,OAAO,CAAC,WAAW,CAAC;IAEnD,IAAI,SAA6B,CAAC;IAClC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,MAAM,KAAK,GAAG,aAAa,CAAC,IAAI,EAAE,CAAC,EAAE,aAAa,CAAC,CAAC;QACpD,IAAI,KAAK,EAAE,CAAC;YACV,SAAS,GAAG,KAAK,CAAC,KAAK,CAAC;YACxB,CAAC,GAAG,KAAK,CAAC,SAAS,CAAC;QACtB,CAAC;IACH,CAAC;IACD,IAAI,SAAS,KAAK,SAAS;QAAE,OAAO,OAAO,CAAC,SAAS,CAAC,CAAC;IACvD,IAAI,QAAQ;QAAE,OAAO,OAAO,CAAC,QAAQ,CAAC,CAAC;IACvC,OAAO,eAAe,EAAE,CAAC;AAC3B,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB;IAC/B,OAAO,eAAe,CAAC,EAAE,CAAC,CAAC;AAC7B,CAAC","sourcesContent":["/**\n * Shared pieces of the CLI flag grammar.\n *\n * `resolveBoot` (cli/boot.ts) is the daemon's only full argv parser. This\n * module holds what other scanners must agree with it on: the value-flag\n * spelling (`--flag value` / `--flag=value`) via `takeValueFlag`, the default\n * state dir, and an early `--state-dir` probe for import-time consumers\n * (Sentry instrumentation) that must not load the boot path.\n */\nimport { homedir } from \"os\";\nimport { join, resolve } from \"path\";\nimport { readEnv } from \"../utils/env.js\";\n\nexport function defaultStateDir(): string {\n return join(homedir(), \".mikan\");\n}\n\n/**\n * Match `args[i]` against a value flag, accepting both `--name value` and\n * `--name=value`. Returns the raw value and the index of the last argv slot\n * consumed, or undefined when `args[i]` is not this flag.\n */\nexport function takeValueFlag(\n args: string[],\n i: number,\n name: string,\n): { value: string; lastIndex: number } | undefined {\n const arg = args[i];\n if (arg === name) return { value: args[i + 1] ?? \"\", lastIndex: i + 1 };\n if (arg.startsWith(name + \"=\")) return { value: arg.slice(name.length + 1), lastIndex: i };\n return undefined;\n}\n\n/**\n * Effective state dir — the ONE place its precedence is decided:\n * `--state-dir` flag (last occurrence wins) > STATE_DIR / MIKAN_STATE_DIR\n * env > `~/.mikan`. Boot writes the resolved value back into the env\n * (setEnvAliases) purely as a compatibility channel for code that runs\n * without access to the boot plan — see `effectiveStateDir`.\n */\nexport function resolveStateDir(\n args: string[] = process.argv.slice(2),\n envValue: string | undefined = readEnv(\"STATE_DIR\"),\n): string {\n let flagValue: string | undefined;\n for (let i = 0; i < args.length; i++) {\n const taken = takeValueFlag(args, i, \"--state-dir\");\n if (taken) {\n flagValue = taken.value;\n i = taken.lastIndex;\n }\n }\n if (flagValue !== undefined) return resolve(flagValue);\n if (envValue) return resolve(envValue);\n return defaultStateDir();\n}\n\n/**\n * State dir for post-boot readers: the env channel (which boot populated\n * from the resolved plan) with the shared default. Never re-reads argv —\n * by the time this runs, any `--state-dir` flag is already folded in.\n */\nexport function effectiveStateDir(): string {\n return resolveStateDir([]);\n}\n"]}
@@ -0,0 +1,16 @@
1
+ import { type SandboxConfig } from "../sandbox/index.js";
2
+ export interface BootPlan {
3
+ mode: "ext" | "env" | "help" | "version" | "worker-token" | "onboard" | "download" | "run";
4
+ /** argv after `ext`, handed to runExtCommand. Only set for mode "ext". */
5
+ extArgs?: string[];
6
+ stateDir: string;
7
+ /** Resolved working directory; defaults to `<stateDir>/workspace`. */
8
+ workingDir: string;
9
+ /** True when the working directory came from argv (then it is not auto-created). */
10
+ workingDirExplicit: boolean;
11
+ sandbox: SandboxConfig;
12
+ downloadChannel?: string;
13
+ }
14
+ export declare function resolveBoot(args?: string[]): BootPlan;
15
+ export declare function helpText(): string;
16
+ //# sourceMappingURL=boot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"boot.d.ts","sourceRoot":"","sources":["../../src/cli/boot.ts"],"names":[],"mappings":"AAWA,OAAO,EAAmB,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAG1E,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,KAAK,GAAG,KAAK,GAAG,MAAM,GAAG,SAAS,GAAG,cAAc,GAAG,SAAS,GAAG,UAAU,GAAG,KAAK,CAAC;IAC3F,0EAA0E;IAC1E,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,sEAAsE;IACtE,UAAU,EAAE,MAAM,CAAC;IACnB,oFAAoF;IACpF,kBAAkB,EAAE,OAAO,CAAC;IAC5B,OAAO,EAAE,aAAa,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,wBAAgB,WAAW,CAAC,IAAI,GAAE,MAAM,EAA0B,GAAG,QAAQ,CAmE5E;AAED,wBAAgB,QAAQ,IAAI,MAAM,CA+BjC"}
@@ -0,0 +1,119 @@
1
+ /**
2
+ * Boot resolution for the `mikan` binary: argv → a BootPlan saying which mode
3
+ * to run and with what configuration. Pure — no side effects, no exits — so
4
+ * the grammar that actually drives the daemon is testable without spawning a
5
+ * process; main.ts just executes the plan.
6
+ *
7
+ * Modes, highest priority first: `ext` (own grammar, never flag-parsed here),
8
+ * `help`, `version`, `worker-token`, `onboard`, `download`, `run`.
9
+ */
10
+ import { join, resolve } from "path";
11
+ import { envSummaryLines } from "../env-manifest.js";
12
+ import { parseSandboxArg } from "../sandbox/index.js";
13
+ import { defaultStateDir, resolveStateDir, takeValueFlag } from "./arg-grammar.js";
14
+ export function resolveBoot(args = process.argv.slice(2)) {
15
+ if (args[0] === "ext" || args[0] === "env") {
16
+ return {
17
+ mode: args[0],
18
+ ...(args[0] === "ext" ? { extArgs: args.slice(1) } : {}),
19
+ stateDir: defaultStateDir(),
20
+ workingDir: join(defaultStateDir(), "workspace"),
21
+ workingDirExplicit: false,
22
+ sandbox: { type: "host" },
23
+ };
24
+ }
25
+ let sandbox = { type: "host" };
26
+ let workingDirArg;
27
+ let downloadChannel;
28
+ let help = false;
29
+ let version = false;
30
+ let onboard = false;
31
+ let workerToken = false;
32
+ for (let i = 0; i < args.length; i++) {
33
+ const arg = args[i];
34
+ let taken;
35
+ if (arg === "--help" || arg === "-h") {
36
+ help = true;
37
+ }
38
+ else if (arg === "--version" || arg === "-v" || arg === "-V") {
39
+ version = true;
40
+ }
41
+ else if (arg === "--onboard") {
42
+ onboard = true;
43
+ }
44
+ else if (arg === "--worker-token") {
45
+ workerToken = true;
46
+ }
47
+ else if ((taken = takeValueFlag(args, i, "--sandbox"))) {
48
+ sandbox = parseSandboxArg(taken.value);
49
+ i = taken.lastIndex;
50
+ }
51
+ else if ((taken = takeValueFlag(args, i, "--state-dir"))) {
52
+ // Consumed here so its value never reads as the positional working
53
+ // dir; the value itself is resolved by resolveStateDir below.
54
+ i = taken.lastIndex;
55
+ }
56
+ else if ((taken = takeValueFlag(args, i, "--download"))) {
57
+ downloadChannel = taken.value;
58
+ i = taken.lastIndex;
59
+ }
60
+ else if (!arg.startsWith("-")) {
61
+ workingDirArg = arg;
62
+ }
63
+ else {
64
+ throw new Error(`Unknown flag: ${arg}. Run \`mikan --help\` for usage.`);
65
+ }
66
+ }
67
+ const stateDir = resolveStateDir(args);
68
+ return {
69
+ mode: help
70
+ ? "help"
71
+ : version
72
+ ? "version"
73
+ : workerToken
74
+ ? "worker-token"
75
+ : onboard
76
+ ? "onboard"
77
+ : downloadChannel
78
+ ? "download"
79
+ : "run",
80
+ stateDir,
81
+ workingDir: workingDirArg ? resolve(workingDirArg) : join(stateDir, "workspace"),
82
+ workingDirExplicit: workingDirArg !== undefined,
83
+ sandbox,
84
+ downloadChannel,
85
+ };
86
+ }
87
+ export function helpText() {
88
+ return `mikan — multi-platform chat agent daemon
89
+
90
+ Usage:
91
+ mikan [options] [working-directory]
92
+ Start the daemon. The working directory defaults to <state-dir>/workspace.
93
+ mikan ext <install|validate|list|remove> …
94
+ Manage extensions (run \`mikan ext\` for details).
95
+ mikan env
96
+ Show the full environment-variable inventory and what is currently set.
97
+
98
+ Options:
99
+ --state-dir <dir> State directory (settings.json, vaults, extensions).
100
+ Default: ~/.mikan
101
+ --sandbox <spec> Execution sandbox. One of:
102
+ host
103
+ container:<existing-container-name>
104
+ image:<image[:tag]>
105
+ gondolin:default | gondolin:remote
106
+ firecracker:<vm-id>:<host-path>[:<ssh-user>[:<ssh-port>]]
107
+ cloudflare:<sandbox-id>
108
+ Default: host
109
+ --onboard Create <state-dir>/settings.json from a template, then exit.
110
+ --worker-token Mint a one-time gondolin worker join token, then exit.
111
+ --download <channel> Dump a Slack channel's history (Slack only), then exit.
112
+ --version, -v Print the version.
113
+ --help, -h Show this help.
114
+
115
+ Environment (platform tokens select which chat adapters start):
116
+ ${envSummaryLines().join("\n")}
117
+ Run \`mikan env\` for the full inventory.`;
118
+ }
119
+ //# sourceMappingURL=boot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"boot.js","sourceRoot":"","sources":["../../src/cli/boot.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Boot resolution for the `mikan` binary: argv → a BootPlan saying which mode\n * to run and with what configuration. Pure — no side effects, no exits — so\n * the grammar that actually drives the daemon is testable without spawning a\n * process; main.ts just executes the plan.\n *\n * Modes, highest priority first: `ext` (own grammar, never flag-parsed here),\n * `help`, `version`, `worker-token`, `onboard`, `download`, `run`.\n */\nimport { join, resolve } from \"path\";\nimport { envSummaryLines } from \"../env-manifest.js\";\nimport { parseSandboxArg, type SandboxConfig } from \"../sandbox/index.js\";\nimport { defaultStateDir, resolveStateDir, takeValueFlag } from \"./arg-grammar.js\";\n\nexport interface BootPlan {\n mode: \"ext\" | \"env\" | \"help\" | \"version\" | \"worker-token\" | \"onboard\" | \"download\" | \"run\";\n /** argv after `ext`, handed to runExtCommand. Only set for mode \"ext\". */\n extArgs?: string[];\n stateDir: string;\n /** Resolved working directory; defaults to `<stateDir>/workspace`. */\n workingDir: string;\n /** True when the working directory came from argv (then it is not auto-created). */\n workingDirExplicit: boolean;\n sandbox: SandboxConfig;\n downloadChannel?: string;\n}\n\nexport function resolveBoot(args: string[] = process.argv.slice(2)): BootPlan {\n if (args[0] === \"ext\" || args[0] === \"env\") {\n return {\n mode: args[0],\n ...(args[0] === \"ext\" ? { extArgs: args.slice(1) } : {}),\n stateDir: defaultStateDir(),\n workingDir: join(defaultStateDir(), \"workspace\"),\n workingDirExplicit: false,\n sandbox: { type: \"host\" },\n };\n }\n\n let sandbox: SandboxConfig = { type: \"host\" };\n let workingDirArg: string | undefined;\n let downloadChannel: string | undefined;\n let help = false;\n let version = false;\n let onboard = false;\n let workerToken = false;\n\n for (let i = 0; i < args.length; i++) {\n const arg = args[i];\n let taken;\n if (arg === \"--help\" || arg === \"-h\") {\n help = true;\n } else if (arg === \"--version\" || arg === \"-v\" || arg === \"-V\") {\n version = true;\n } else if (arg === \"--onboard\") {\n onboard = true;\n } else if (arg === \"--worker-token\") {\n workerToken = true;\n } else if ((taken = takeValueFlag(args, i, \"--sandbox\"))) {\n sandbox = parseSandboxArg(taken.value);\n i = taken.lastIndex;\n } else if ((taken = takeValueFlag(args, i, \"--state-dir\"))) {\n // Consumed here so its value never reads as the positional working\n // dir; the value itself is resolved by resolveStateDir below.\n i = taken.lastIndex;\n } else if ((taken = takeValueFlag(args, i, \"--download\"))) {\n downloadChannel = taken.value;\n i = taken.lastIndex;\n } else if (!arg.startsWith(\"-\")) {\n workingDirArg = arg;\n } else {\n throw new Error(`Unknown flag: ${arg}. Run \\`mikan --help\\` for usage.`);\n }\n }\n\n const stateDir = resolveStateDir(args);\n return {\n mode: help\n ? \"help\"\n : version\n ? \"version\"\n : workerToken\n ? \"worker-token\"\n : onboard\n ? \"onboard\"\n : downloadChannel\n ? \"download\"\n : \"run\",\n stateDir,\n workingDir: workingDirArg ? resolve(workingDirArg) : join(stateDir, \"workspace\"),\n workingDirExplicit: workingDirArg !== undefined,\n sandbox,\n downloadChannel,\n };\n}\n\nexport function helpText(): string {\n return `mikan — multi-platform chat agent daemon\n\nUsage:\n mikan [options] [working-directory]\n Start the daemon. The working directory defaults to <state-dir>/workspace.\n mikan ext <install|validate|list|remove> …\n Manage extensions (run \\`mikan ext\\` for details).\n mikan env\n Show the full environment-variable inventory and what is currently set.\n\nOptions:\n --state-dir <dir> State directory (settings.json, vaults, extensions).\n Default: ~/.mikan\n --sandbox <spec> Execution sandbox. One of:\n host\n container:<existing-container-name>\n image:<image[:tag]>\n gondolin:default | gondolin:remote\n firecracker:<vm-id>:<host-path>[:<ssh-user>[:<ssh-port>]]\n cloudflare:<sandbox-id>\n Default: host\n --onboard Create <state-dir>/settings.json from a template, then exit.\n --worker-token Mint a one-time gondolin worker join token, then exit.\n --download <channel> Dump a Slack channel's history (Slack only), then exit.\n --version, -v Print the version.\n --help, -h Show this help.\n\nEnvironment (platform tokens select which chat adapters start):\n${envSummaryLines().join(\"\\n\")}\nRun \\`mikan env\\` for the full inventory.`;\n}\n"]}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"download.d.ts","sourceRoot":"","sources":["../../src/cli/download.ts"],"names":[],"mappings":"AA6BA,wBAAsB,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAuFxF"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"download.js","sourceRoot":"","sources":["../../src/cli/download.ts"],"names":[],"mappings":"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","sourcesContent":["import { LogLevel, WebClient } from \"@slack/web-api\";\n\ninterface Message {\n ts: string;\n user?: string;\n text?: string;\n thread_ts?: string;\n reply_count?: number;\n files?: Array<{ name: string; url_private?: string }>;\n}\n\nfunction formatTs(ts: string): string {\n const date = new Date(parseFloat(ts) * 1000);\n return date\n .toISOString()\n .replace(\"T\", \" \")\n .replace(/\\.\\d+Z$/, \"\");\n}\n\nfunction formatMessage(ts: string, user: string, text: string, indent = \"\"): string {\n const prefix = `[${formatTs(ts)}] ${user}: `;\n const lines = text.split(\"\\n\");\n const firstLine = `${indent}${prefix}${lines[0]}`;\n if (lines.length === 1) return firstLine;\n // All continuation lines get same indent as content start\n const contentIndent = indent + \" \".repeat(prefix.length);\n return [firstLine, ...lines.slice(1).map((l) => contentIndent + l)].join(\"\\n\");\n}\n\nexport async function downloadChannel(channelId: string, botToken: string): Promise<void> {\n const client = new WebClient(botToken, { logLevel: LogLevel.ERROR });\n\n console.error(`Fetching channel info for ${channelId}...`);\n\n // Get channel info\n let channelName = channelId;\n try {\n const info = await client.conversations.info({ channel: channelId });\n channelName = typeof info.channel?.name === \"string\" ? info.channel.name : channelId;\n } catch {\n // DM channels don't have names, that's fine\n }\n\n console.error(`Downloading history for #${channelName} (${channelId})...`);\n\n // Fetch all messages\n const messages: Message[] = [];\n let cursor: string | undefined;\n\n do {\n const response = await client.conversations.history({\n channel: channelId,\n limit: 200,\n cursor,\n });\n\n if (response.messages) {\n messages.push(...(response.messages as Message[]));\n }\n\n cursor = response.response_metadata?.next_cursor;\n console.error(` Fetched ${messages.length} messages...`);\n } while (cursor);\n\n // Reverse to chronological order\n messages.reverse();\n\n // Build map of thread replies\n const threadReplies = new Map<string, Message[]>();\n const threadsToFetch = messages.filter((m) => m.reply_count && m.reply_count > 0);\n\n console.error(`Fetching ${threadsToFetch.length} threads...`);\n\n for (let i = 0; i < threadsToFetch.length; i++) {\n const parent = threadsToFetch[i];\n console.error(` Thread ${i + 1}/${threadsToFetch.length} (${parent.reply_count} replies)...`);\n\n const replies: Message[] = [];\n let threadCursor: string | undefined;\n\n do {\n const response = await client.conversations.replies({\n channel: channelId,\n ts: parent.ts,\n limit: 200,\n cursor: threadCursor,\n });\n\n if (response.messages) {\n // Skip the first message (it's the parent)\n replies.push(...(response.messages as Message[]).slice(1));\n }\n\n threadCursor = response.response_metadata?.next_cursor;\n } while (threadCursor);\n\n threadReplies.set(parent.ts, replies);\n }\n\n // Output messages with thread replies interleaved\n let totalReplies = 0;\n for (const msg of messages) {\n // Output the message\n console.log(formatMessage(msg.ts, msg.user || \"unknown\", msg.text || \"\"));\n\n // Output thread replies right after parent (indented)\n const replies = threadReplies.get(msg.ts);\n if (replies) {\n for (const reply of replies) {\n console.log(formatMessage(reply.ts, reply.user || \"unknown\", reply.text || \"\", \" \"));\n totalReplies++;\n }\n }\n }\n\n console.error(`Done! ${messages.length} messages, ${totalReplies} thread replies`);\n}\n"]}
@@ -0,0 +1,22 @@
1
+ export interface ResolvedGitSource {
2
+ /** Local directory holding the extension (clone root or a subpath within). */
3
+ dir: string;
4
+ /** Remove the temporary clone. */
5
+ cleanup: () => void;
6
+ }
7
+ interface GitSpec {
8
+ url: string;
9
+ subpath?: string;
10
+ }
11
+ /**
12
+ * Recognize a git source and split off an optional `#subpath`:
13
+ * https://host/owner/repo.git#dir/ext → { url, subpath }
14
+ * git@host:owner/repo.git → { url }
15
+ * github:owner/repo → expands to https clone URL
16
+ * Returns undefined for anything that looks like a local path.
17
+ */
18
+ export declare function parseGitSource(source: string): GitSpec | undefined;
19
+ /** Clone a git source (shallow) and resolve the extension directory within it. */
20
+ export declare function resolveGitSource(spec: GitSpec): ResolvedGitSource;
21
+ export {};
22
+ //# sourceMappingURL=ext-git.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ext-git.d.ts","sourceRoot":"","sources":["../../src/cli/ext-git.ts"],"names":[],"mappings":"AAWA,MAAM,WAAW,iBAAiB;IAChC,8EAA8E;IAC9E,GAAG,EAAE,MAAM,CAAC;IACZ,kCAAkC;IAClC,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,UAAU,OAAO;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAkBlE;AAQD,kFAAkF;AAClF,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,OAAO,GAAG,iBAAiB,CAuBjE"}
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Resolve a `mikan ext install` source that points at a git repository into a
3
+ * local directory: clone it, descend into an optional `#subpath`, and run
4
+ * `npm install --omit=dev` when the extension declares dependencies. The
5
+ * caller validates + copies the returned directory, then calls cleanup().
6
+ */
7
+ import { execFileSync } from "node:child_process";
8
+ import { existsSync, mkdtempSync, readFileSync, rmSync } from "node:fs";
9
+ import { tmpdir } from "node:os";
10
+ import { join } from "node:path";
11
+ /**
12
+ * Recognize a git source and split off an optional `#subpath`:
13
+ * https://host/owner/repo.git#dir/ext → { url, subpath }
14
+ * git@host:owner/repo.git → { url }
15
+ * github:owner/repo → expands to https clone URL
16
+ * Returns undefined for anything that looks like a local path.
17
+ */
18
+ export function parseGitSource(source) {
19
+ const [locator, subpath] = splitSubpath(source);
20
+ if (locator.startsWith("github:")) {
21
+ const repo = locator.slice("github:".length).replace(/\.git$/, "");
22
+ return { url: `https://github.com/${repo}.git`, subpath };
23
+ }
24
+ if (locator.startsWith("https://") ||
25
+ locator.startsWith("http://") ||
26
+ locator.startsWith("git://") ||
27
+ locator.startsWith("ssh://") ||
28
+ locator.startsWith("file://") ||
29
+ /^git@[^:]+:/.test(locator)) {
30
+ return { url: locator, subpath };
31
+ }
32
+ return undefined;
33
+ }
34
+ function splitSubpath(source) {
35
+ const hash = source.indexOf("#");
36
+ if (hash === -1)
37
+ return [source, undefined];
38
+ return [source.slice(0, hash), source.slice(hash + 1) || undefined];
39
+ }
40
+ /** Clone a git source (shallow) and resolve the extension directory within it. */
41
+ export function resolveGitSource(spec) {
42
+ const tempRoot = mkdtempSync(join(tmpdir(), "mikan-ext-git-"));
43
+ const cleanup = () => rmSync(tempRoot, { recursive: true, force: true });
44
+ try {
45
+ execFileSync("git", ["clone", "--depth", "1", spec.url, tempRoot], { stdio: "inherit" });
46
+ const dir = spec.subpath ? join(tempRoot, spec.subpath) : tempRoot;
47
+ if (!existsSync(dir)) {
48
+ throw new Error(`Subpath not found in repository: ${spec.subpath}`);
49
+ }
50
+ // Install runtime dependencies only when the extension declares any.
51
+ if (hasDependencies(dir)) {
52
+ execFileSync("npm", ["install", "--omit=dev", "--no-audit", "--no-fund"], {
53
+ cwd: dir,
54
+ stdio: "inherit",
55
+ });
56
+ }
57
+ return { dir, cleanup };
58
+ }
59
+ catch (err) {
60
+ cleanup();
61
+ throw err;
62
+ }
63
+ }
64
+ function hasDependencies(dir) {
65
+ const packageJsonPath = join(dir, "package.json");
66
+ if (!existsSync(packageJsonPath))
67
+ return false;
68
+ try {
69
+ const pkg = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
70
+ return Boolean(pkg.dependencies && Object.keys(pkg.dependencies).length > 0);
71
+ }
72
+ catch {
73
+ return false;
74
+ }
75
+ }
76
+ //# sourceMappingURL=ext-git.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ext-git.js","sourceRoot":"","sources":["../../src/cli/ext-git.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Resolve a `mikan ext install` source that points at a git repository into a\n * local directory: clone it, descend into an optional `#subpath`, and run\n * `npm install --omit=dev` when the extension declares dependencies. The\n * caller validates + copies the returned directory, then calls cleanup().\n */\nimport { execFileSync } from \"node:child_process\";\nimport { existsSync, mkdtempSync, readFileSync, rmSync } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\n\nexport interface ResolvedGitSource {\n /** Local directory holding the extension (clone root or a subpath within). */\n dir: string;\n /** Remove the temporary clone. */\n cleanup: () => void;\n}\n\ninterface GitSpec {\n url: string;\n subpath?: string;\n}\n\n/**\n * Recognize a git source and split off an optional `#subpath`:\n * https://host/owner/repo.git#dir/ext → { url, subpath }\n * git@host:owner/repo.git → { url }\n * github:owner/repo → expands to https clone URL\n * Returns undefined for anything that looks like a local path.\n */\nexport function parseGitSource(source: string): GitSpec | undefined {\n const [locator, subpath] = splitSubpath(source);\n\n if (locator.startsWith(\"github:\")) {\n const repo = locator.slice(\"github:\".length).replace(/\\.git$/, \"\");\n return { url: `https://github.com/${repo}.git`, subpath };\n }\n if (\n locator.startsWith(\"https://\") ||\n locator.startsWith(\"http://\") ||\n locator.startsWith(\"git://\") ||\n locator.startsWith(\"ssh://\") ||\n locator.startsWith(\"file://\") ||\n /^git@[^:]+:/.test(locator)\n ) {\n return { url: locator, subpath };\n }\n return undefined;\n}\n\nfunction splitSubpath(source: string): [string, string | undefined] {\n const hash = source.indexOf(\"#\");\n if (hash === -1) return [source, undefined];\n return [source.slice(0, hash), source.slice(hash + 1) || undefined];\n}\n\n/** Clone a git source (shallow) and resolve the extension directory within it. */\nexport function resolveGitSource(spec: GitSpec): ResolvedGitSource {\n const tempRoot = mkdtempSync(join(tmpdir(), \"mikan-ext-git-\"));\n const cleanup = () => rmSync(tempRoot, { recursive: true, force: true });\n try {\n execFileSync(\"git\", [\"clone\", \"--depth\", \"1\", spec.url, tempRoot], { stdio: \"inherit\" });\n\n const dir = spec.subpath ? join(tempRoot, spec.subpath) : tempRoot;\n if (!existsSync(dir)) {\n throw new Error(`Subpath not found in repository: ${spec.subpath}`);\n }\n\n // Install runtime dependencies only when the extension declares any.\n if (hasDependencies(dir)) {\n execFileSync(\"npm\", [\"install\", \"--omit=dev\", \"--no-audit\", \"--no-fund\"], {\n cwd: dir,\n stdio: \"inherit\",\n });\n }\n return { dir, cleanup };\n } catch (err) {\n cleanup();\n throw err;\n }\n}\n\nfunction hasDependencies(dir: string): boolean {\n const packageJsonPath = join(dir, \"package.json\");\n if (!existsSync(packageJsonPath)) return false;\n try {\n const pkg = JSON.parse(readFileSync(packageJsonPath, \"utf-8\")) as {\n dependencies?: Record<string, string>;\n };\n return Boolean(pkg.dependencies && Object.keys(pkg.dependencies).length > 0);\n } catch {\n return false;\n }\n}\n"]}
@@ -0,0 +1,2 @@
1
+ export declare function runExtCommand(argv: string[]): Promise<number>;
2
+ //# sourceMappingURL=ext.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ext.d.ts","sourceRoot":"","sources":["../../src/cli/ext.ts"],"names":[],"mappings":"AA2EA,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAgBnE"}
@@ -0,0 +1,215 @@
1
+ /**
2
+ * `mikan ext` — manage extensions from the CLI.
3
+ *
4
+ * mikan ext install <source> [--global | --conversation <id>] [--state-dir <dir>]
5
+ * mikan ext validate <path>
6
+ * mikan ext list [--conversation <id>] [--state-dir <dir>]
7
+ * mikan ext remove <slug> (--global | --conversation <id>) [--state-dir <dir>]
8
+ *
9
+ * `<source>` is a local path or a git URL (https://…, git@…, or github:owner/repo)
10
+ * with an optional `#subpath` for extensions inside a repo. Reinstalling over an
11
+ * existing extension updates it (data is preserved). Extensions install into the
12
+ * host-only state dir (never the workspace); see src/harness/extensions/LAYOUT.md.
13
+ */
14
+ import { cpSync, existsSync, mkdirSync, rmSync } from "node:fs";
15
+ import { basename, join, resolve } from "node:path";
16
+ import { defaultExtensionDirs, listInstalledExtensions, validateExtension, } from "../harness/index.js";
17
+ import { resolveStateDir, takeValueFlag } from "./arg-grammar.js";
18
+ import { parseGitSource, resolveGitSource } from "./ext-git.js";
19
+ function parseExtArgs(argv) {
20
+ // Shares the daemon's state-dir precedence: --state-dir > env > ~/.mikan.
21
+ const stateDir = resolveStateDir(argv);
22
+ let scope;
23
+ let conversationId;
24
+ const positional = [];
25
+ for (let i = 0; i < argv.length; i++) {
26
+ const arg = argv[i];
27
+ let taken;
28
+ if (arg === "--global")
29
+ scope = "global";
30
+ else if ((taken = takeValueFlag(argv, i, "--conversation"))) {
31
+ scope = "conversation";
32
+ conversationId = taken.value || undefined;
33
+ i = taken.lastIndex;
34
+ }
35
+ else if ((taken = takeValueFlag(argv, i, "--state-dir"))) {
36
+ i = taken.lastIndex; // value already folded in by resolveStateDir
37
+ }
38
+ else
39
+ positional.push(arg);
40
+ }
41
+ return { action: positional[0], target: positional[1], stateDir, scope, conversationId };
42
+ }
43
+ /** Directory that extension CODE for the chosen scope lives in. */
44
+ function scopeExtensionsDir(args) {
45
+ if (args.scope === "global")
46
+ return join(args.stateDir, "global", "extensions");
47
+ if (args.scope === "conversation" && args.conversationId) {
48
+ // defaultExtensionDirs returns [global, conversation]; take the conversation one.
49
+ return defaultExtensionDirs(args.conversationId, args.stateDir)[1];
50
+ }
51
+ throw new Error("Specify a scope: --global or --conversation <id>");
52
+ }
53
+ const USAGE = `Usage:
54
+ mikan ext install <source> (--global | --conversation <id>) [--state-dir <dir>]
55
+ <source>: a local path, or a git URL / github:owner/repo with optional #subpath
56
+ e.g. github:geminixiang/mikan#examples/extensions/agent-pm
57
+ Reinstalling over an existing extension updates it (data preserved).
58
+ mikan ext validate <path>
59
+ mikan ext list [--conversation <id>] [--state-dir <dir>]
60
+ mikan ext remove <slug> (--global | --conversation <id>) [--state-dir <dir>]`;
61
+ function noop() { }
62
+ export async function runExtCommand(argv) {
63
+ const args = parseExtArgs(argv);
64
+ switch (args.action) {
65
+ case "validate":
66
+ return validateAction(args);
67
+ case "install":
68
+ return installAction(args);
69
+ case "list":
70
+ return listAction(args);
71
+ case "remove":
72
+ return removeAction(args);
73
+ default:
74
+ console.error(USAGE);
75
+ return 1;
76
+ }
77
+ }
78
+ async function validateAction(args) {
79
+ if (!args.target) {
80
+ console.error("ext validate: missing <path>");
81
+ return 1;
82
+ }
83
+ const result = await validateExtension(resolve(args.target));
84
+ printValidation(result);
85
+ return result.ok ? 0 : 1;
86
+ }
87
+ async function installAction(args) {
88
+ if (!args.target) {
89
+ console.error("ext install: missing <path>");
90
+ return 1;
91
+ }
92
+ let destDir;
93
+ try {
94
+ destDir = scopeExtensionsDir(args);
95
+ }
96
+ catch (err) {
97
+ console.error(err instanceof Error ? err.message : String(err));
98
+ return 1;
99
+ }
100
+ // Resolve the source: a git URL (optionally with #subpath) is cloned to a
101
+ // temp dir; a local path is used directly.
102
+ const gitSpec = parseGitSource(args.target);
103
+ let source;
104
+ let cleanup = noop;
105
+ if (gitSpec) {
106
+ try {
107
+ const resolved = resolveGitSource(gitSpec);
108
+ source = resolved.dir;
109
+ cleanup = resolved.cleanup;
110
+ }
111
+ catch (err) {
112
+ console.error(`Failed to fetch ${gitSpec.url}: ${err instanceof Error ? err.message : err}`);
113
+ return 1;
114
+ }
115
+ }
116
+ else {
117
+ source = resolve(args.target);
118
+ }
119
+ try {
120
+ return await installResolved(args, source, destDir);
121
+ }
122
+ finally {
123
+ cleanup();
124
+ }
125
+ }
126
+ async function installResolved(args, source, destDir) {
127
+ const result = await validateExtension(source);
128
+ printValidation(result);
129
+ if (!result.ok) {
130
+ console.error("Refusing to install: fix the errors above.");
131
+ return 1;
132
+ }
133
+ // Install into a named subdirectory so the slug never degenerates to the
134
+ // scope name. A bare file installs as <name>.<ext>; a directory as <name>/.
135
+ const destName = basename(source);
136
+ const dest = join(destDir, destName);
137
+ mkdirSync(destDir, { recursive: true });
138
+ // Reinstalling over an existing install is how updates work: replace it.
139
+ const replaced = existsSync(dest);
140
+ if (replaced)
141
+ rmSync(dest, { recursive: true, force: true });
142
+ cpSync(source, dest, { recursive: true });
143
+ const scopeLabel = args.scope === "global" ? "all conversations" : `conversation ${args.conversationId}`;
144
+ const dataDir = args.scope === "global"
145
+ ? join(args.stateDir, "global", "extension-data", result.slug)
146
+ : join(args.stateDir, "conversations", args.conversationId, "extension-data", result.slug);
147
+ const verb = replaced ? "Reinstalled" : "Installed";
148
+ console.log(`\n${verb} ${result.name} (slug: ${result.slug}) for ${scopeLabel}.`);
149
+ console.log(` code: ${dest}`);
150
+ console.log(` data: ${dataDir} (created on first use, preserved on reinstall)`);
151
+ console.log("Run /pi-new in the conversation to activate.");
152
+ return 0;
153
+ }
154
+ function listAction(args) {
155
+ // List the requested scope, or both when no conversation is given.
156
+ const dirs = args.conversationId
157
+ ? defaultExtensionDirs(args.conversationId, args.stateDir)
158
+ : [join(args.stateDir, "global", "extensions")];
159
+ const installed = listInstalledExtensions(dirs);
160
+ if (installed.length === 0) {
161
+ console.log("No extensions installed.");
162
+ return 0;
163
+ }
164
+ for (const info of installed) {
165
+ const scope = basename(resolve(info.dir, "..")) === "global" ? "global" : "conversation";
166
+ const version = info.version ? `@${info.version}` : "";
167
+ console.log(`${info.name}${version} [${scope}] slug=${info.slug}`);
168
+ if (info.description)
169
+ console.log(` ${info.description}`);
170
+ if (info.skillNames.length > 0)
171
+ console.log(` skills: ${info.skillNames.join(", ")}`);
172
+ }
173
+ return 0;
174
+ }
175
+ function removeAction(args) {
176
+ if (!args.target) {
177
+ console.error("ext remove: missing <slug>");
178
+ return 1;
179
+ }
180
+ let destDir;
181
+ try {
182
+ destDir = scopeExtensionsDir(args);
183
+ }
184
+ catch (err) {
185
+ console.error(err instanceof Error ? err.message : String(err));
186
+ return 1;
187
+ }
188
+ // Match by installed slug so the caller doesn't need the exact dir name.
189
+ const match = listInstalledExtensions([destDir]).find((info) => info.slug === args.target);
190
+ if (!match) {
191
+ console.error(`No extension with slug '${args.target}' in ${destDir}`);
192
+ return 1;
193
+ }
194
+ // match.path is the entrypoint. Dir-form: its parent is the extension dir to
195
+ // remove. Bare-file: the parent is the scan dir, so remove the file itself.
196
+ const parent = resolve(match.path, "..");
197
+ const removeTarget = parent === resolve(destDir) ? match.path : parent;
198
+ rmSync(removeTarget, { recursive: true, force: true });
199
+ console.log(`Removed ${match.name} (slug: ${match.slug}). Data left in place.`);
200
+ console.log("Run /pi-new in the conversation to apply.");
201
+ return 0;
202
+ }
203
+ function printValidation(result) {
204
+ console.log(`${result.name}${result.version ? `@${result.version}` : ""} (slug: ${result.slug})`);
205
+ if (result.entrypoint)
206
+ console.log(` entrypoint: ${result.entrypoint}`);
207
+ if (result.skillNames.length > 0)
208
+ console.log(` skills: ${result.skillNames.join(", ")}`);
209
+ for (const warning of result.warnings)
210
+ console.log(` warning: ${warning}`);
211
+ for (const error of result.errors)
212
+ console.error(` error: ${error}`);
213
+ console.log(result.ok ? " ✓ valid" : " ✗ invalid");
214
+ }
215
+ //# sourceMappingURL=ext.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ext.js","sourceRoot":"","sources":["../../src/cli/ext.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * `mikan ext` — manage extensions from the CLI.\n *\n * mikan ext install <source> [--global | --conversation <id>] [--state-dir <dir>]\n * mikan ext validate <path>\n * mikan ext list [--conversation <id>] [--state-dir <dir>]\n * mikan ext remove <slug> (--global | --conversation <id>) [--state-dir <dir>]\n *\n * `<source>` is a local path or a git URL (https://…, git@…, or github:owner/repo)\n * with an optional `#subpath` for extensions inside a repo. Reinstalling over an\n * existing extension updates it (data is preserved). Extensions install into the\n * host-only state dir (never the workspace); see src/harness/extensions/LAYOUT.md.\n */\nimport { cpSync, existsSync, mkdirSync, rmSync } from \"node:fs\";\nimport { basename, join, resolve } from \"node:path\";\nimport {\n defaultExtensionDirs,\n listInstalledExtensions,\n validateExtension,\n} from \"../harness/index.js\";\nimport { resolveStateDir, takeValueFlag } from \"./arg-grammar.js\";\nimport { parseGitSource, resolveGitSource } from \"./ext-git.js\";\n\ninterface ExtArgs {\n action?: string;\n target?: string;\n stateDir: string;\n scope: \"global\" | \"conversation\" | undefined;\n conversationId?: string;\n}\n\nfunction parseExtArgs(argv: string[]): ExtArgs {\n // Shares the daemon's state-dir precedence: --state-dir > env > ~/.mikan.\n const stateDir = resolveStateDir(argv);\n let scope: ExtArgs[\"scope\"];\n let conversationId: string | undefined;\n const positional: string[] = [];\n\n for (let i = 0; i < argv.length; i++) {\n const arg = argv[i];\n let taken;\n if (arg === \"--global\") scope = \"global\";\n else if ((taken = takeValueFlag(argv, i, \"--conversation\"))) {\n scope = \"conversation\";\n conversationId = taken.value || undefined;\n i = taken.lastIndex;\n } else if ((taken = takeValueFlag(argv, i, \"--state-dir\"))) {\n i = taken.lastIndex; // value already folded in by resolveStateDir\n } else positional.push(arg);\n }\n\n return { action: positional[0], target: positional[1], stateDir, scope, conversationId };\n}\n\n/** Directory that extension CODE for the chosen scope lives in. */\nfunction scopeExtensionsDir(args: ExtArgs): string {\n if (args.scope === \"global\") return join(args.stateDir, \"global\", \"extensions\");\n if (args.scope === \"conversation\" && args.conversationId) {\n // defaultExtensionDirs returns [global, conversation]; take the conversation one.\n return defaultExtensionDirs(args.conversationId, args.stateDir)[1];\n }\n throw new Error(\"Specify a scope: --global or --conversation <id>\");\n}\n\nconst USAGE = `Usage:\n mikan ext install <source> (--global | --conversation <id>) [--state-dir <dir>]\n <source>: a local path, or a git URL / github:owner/repo with optional #subpath\n e.g. github:geminixiang/mikan#examples/extensions/agent-pm\n Reinstalling over an existing extension updates it (data preserved).\n mikan ext validate <path>\n mikan ext list [--conversation <id>] [--state-dir <dir>]\n mikan ext remove <slug> (--global | --conversation <id>) [--state-dir <dir>]`;\n\nfunction noop(): void {}\n\nexport async function runExtCommand(argv: string[]): Promise<number> {\n const args = parseExtArgs(argv);\n\n switch (args.action) {\n case \"validate\":\n return validateAction(args);\n case \"install\":\n return installAction(args);\n case \"list\":\n return listAction(args);\n case \"remove\":\n return removeAction(args);\n default:\n console.error(USAGE);\n return 1;\n }\n}\n\nasync function validateAction(args: ExtArgs): Promise<number> {\n if (!args.target) {\n console.error(\"ext validate: missing <path>\");\n return 1;\n }\n const result = await validateExtension(resolve(args.target));\n printValidation(result);\n return result.ok ? 0 : 1;\n}\n\nasync function installAction(args: ExtArgs): Promise<number> {\n if (!args.target) {\n console.error(\"ext install: missing <path>\");\n return 1;\n }\n let destDir: string;\n try {\n destDir = scopeExtensionsDir(args);\n } catch (err) {\n console.error(err instanceof Error ? err.message : String(err));\n return 1;\n }\n\n // Resolve the source: a git URL (optionally with #subpath) is cloned to a\n // temp dir; a local path is used directly.\n const gitSpec = parseGitSource(args.target);\n let source: string;\n let cleanup = noop;\n if (gitSpec) {\n try {\n const resolved = resolveGitSource(gitSpec);\n source = resolved.dir;\n cleanup = resolved.cleanup;\n } catch (err) {\n console.error(`Failed to fetch ${gitSpec.url}: ${err instanceof Error ? err.message : err}`);\n return 1;\n }\n } else {\n source = resolve(args.target);\n }\n\n try {\n return await installResolved(args, source, destDir);\n } finally {\n cleanup();\n }\n}\n\nasync function installResolved(args: ExtArgs, source: string, destDir: string): Promise<number> {\n const result = await validateExtension(source);\n printValidation(result);\n if (!result.ok) {\n console.error(\"Refusing to install: fix the errors above.\");\n return 1;\n }\n\n // Install into a named subdirectory so the slug never degenerates to the\n // scope name. A bare file installs as <name>.<ext>; a directory as <name>/.\n const destName = basename(source);\n const dest = join(destDir, destName);\n mkdirSync(destDir, { recursive: true });\n // Reinstalling over an existing install is how updates work: replace it.\n const replaced = existsSync(dest);\n if (replaced) rmSync(dest, { recursive: true, force: true });\n cpSync(source, dest, { recursive: true });\n\n const scopeLabel =\n args.scope === \"global\" ? \"all conversations\" : `conversation ${args.conversationId}`;\n const dataDir =\n args.scope === \"global\"\n ? join(args.stateDir, \"global\", \"extension-data\", result.slug)\n : join(args.stateDir, \"conversations\", args.conversationId!, \"extension-data\", result.slug);\n const verb = replaced ? \"Reinstalled\" : \"Installed\";\n console.log(`\\n${verb} ${result.name} (slug: ${result.slug}) for ${scopeLabel}.`);\n console.log(` code: ${dest}`);\n console.log(` data: ${dataDir} (created on first use, preserved on reinstall)`);\n console.log(\"Run /pi-new in the conversation to activate.\");\n return 0;\n}\n\nfunction listAction(args: ExtArgs): number {\n // List the requested scope, or both when no conversation is given.\n const dirs = args.conversationId\n ? defaultExtensionDirs(args.conversationId, args.stateDir)\n : [join(args.stateDir, \"global\", \"extensions\")];\n const installed = listInstalledExtensions(dirs);\n if (installed.length === 0) {\n console.log(\"No extensions installed.\");\n return 0;\n }\n for (const info of installed) {\n const scope = basename(resolve(info.dir, \"..\")) === \"global\" ? \"global\" : \"conversation\";\n const version = info.version ? `@${info.version}` : \"\";\n console.log(`${info.name}${version} [${scope}] slug=${info.slug}`);\n if (info.description) console.log(` ${info.description}`);\n if (info.skillNames.length > 0) console.log(` skills: ${info.skillNames.join(\", \")}`);\n }\n return 0;\n}\n\nfunction removeAction(args: ExtArgs): number {\n if (!args.target) {\n console.error(\"ext remove: missing <slug>\");\n return 1;\n }\n let destDir: string;\n try {\n destDir = scopeExtensionsDir(args);\n } catch (err) {\n console.error(err instanceof Error ? err.message : String(err));\n return 1;\n }\n // Match by installed slug so the caller doesn't need the exact dir name.\n const match = listInstalledExtensions([destDir]).find((info) => info.slug === args.target);\n if (!match) {\n console.error(`No extension with slug '${args.target}' in ${destDir}`);\n return 1;\n }\n // match.path is the entrypoint. Dir-form: its parent is the extension dir to\n // remove. Bare-file: the parent is the scan dir, so remove the file itself.\n const parent = resolve(match.path, \"..\");\n const removeTarget = parent === resolve(destDir) ? match.path : parent;\n rmSync(removeTarget, { recursive: true, force: true });\n console.log(`Removed ${match.name} (slug: ${match.slug}). Data left in place.`);\n console.log(\"Run /pi-new in the conversation to apply.\");\n return 0;\n}\n\nfunction printValidation(result: {\n ok: boolean;\n name: string;\n slug: string;\n version?: string;\n entrypoint?: string;\n skillNames: string[];\n errors: string[];\n warnings: string[];\n}): void {\n console.log(`${result.name}${result.version ? `@${result.version}` : \"\"} (slug: ${result.slug})`);\n if (result.entrypoint) console.log(` entrypoint: ${result.entrypoint}`);\n if (result.skillNames.length > 0) console.log(` skills: ${result.skillNames.join(\", \")}`);\n for (const warning of result.warnings) console.log(` warning: ${warning}`);\n for (const error of result.errors) console.error(` error: ${error}`);\n console.log(result.ok ? \" ✓ valid\" : \" ✗ invalid\");\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"admin.d.ts","sourceRoot":"","sources":["../../src/commands/admin.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAKjE,qBAAa,mBAAoB,YAAW,cAAc;IAClD,SAAS,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC,CAkCzD;CACF"}
1
+ {"version":3,"file":"admin.d.ts","sourceRoot":"","sources":["../../src/commands/admin.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAKjE,qBAAa,mBAAoB,YAAW,cAAc;IAClD,SAAS,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC,CAkCzD;CACF"}