@geminixiang/mikan 1.0.0-beta.3 → 1.0.0-beta.30

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 (545) hide show
  1. package/CHANGELOG.md +563 -0
  2. package/README.md +60 -24
  3. package/dist/adapter.d.ts +1 -1
  4. package/dist/adapter.d.ts.map +1 -1
  5. package/dist/adapter.js.map +1 -1
  6. package/dist/adapters/discord/bot.d.ts +1 -0
  7. package/dist/adapters/discord/bot.d.ts.map +1 -1
  8. package/dist/adapters/discord/bot.js +47 -65
  9. package/dist/adapters/discord/bot.js.map +1 -1
  10. package/dist/adapters/discord/context.d.ts.map +1 -1
  11. package/dist/adapters/discord/context.js +46 -211
  12. package/dist/adapters/discord/context.js.map +1 -1
  13. package/dist/adapters/github/bot.d.ts +86 -0
  14. package/dist/adapters/github/bot.d.ts.map +1 -0
  15. package/dist/adapters/github/bot.js +640 -0
  16. package/dist/adapters/github/bot.js.map +1 -0
  17. package/dist/adapters/github/client.d.ts +122 -0
  18. package/dist/adapters/github/client.d.ts.map +1 -0
  19. package/dist/adapters/github/client.js +314 -0
  20. package/dist/adapters/github/client.js.map +1 -0
  21. package/dist/adapters/github/cloudbuild.d.ts +19 -0
  22. package/dist/adapters/github/cloudbuild.d.ts.map +1 -0
  23. package/dist/adapters/github/cloudbuild.js +71 -0
  24. package/dist/adapters/github/cloudbuild.js.map +1 -0
  25. package/dist/adapters/github/context.d.ts +9 -0
  26. package/dist/adapters/github/context.d.ts.map +1 -0
  27. package/dist/adapters/github/context.js +98 -0
  28. package/dist/adapters/github/context.js.map +1 -0
  29. package/dist/adapters/github/gcp-auth.d.ts +28 -0
  30. package/dist/adapters/github/gcp-auth.d.ts.map +1 -0
  31. package/dist/adapters/github/gcp-auth.js +196 -0
  32. package/dist/adapters/github/gcp-auth.js.map +1 -0
  33. package/dist/adapters/github/github-ops.d.ts +90 -0
  34. package/dist/adapters/github/github-ops.d.ts.map +1 -0
  35. package/dist/adapters/github/github-ops.js +405 -0
  36. package/dist/adapters/github/github-ops.js.map +1 -0
  37. package/dist/adapters/github/ids.d.ts +34 -0
  38. package/dist/adapters/github/ids.d.ts.map +1 -0
  39. package/dist/adapters/github/ids.js +53 -0
  40. package/dist/adapters/github/ids.js.map +1 -0
  41. package/dist/adapters/github/repo.d.ts +32 -0
  42. package/dist/adapters/github/repo.d.ts.map +1 -0
  43. package/dist/adapters/github/repo.js +141 -0
  44. package/dist/adapters/github/repo.js.map +1 -0
  45. package/dist/adapters/github/tool-pack.d.ts +14 -0
  46. package/dist/adapters/github/tool-pack.d.ts.map +1 -0
  47. package/dist/adapters/github/tool-pack.js +56 -0
  48. package/dist/adapters/github/tool-pack.js.map +1 -0
  49. package/dist/adapters/github/tools/checks.d.ts +19 -0
  50. package/dist/adapters/github/tools/checks.d.ts.map +1 -0
  51. package/dist/adapters/github/tools/checks.js +105 -0
  52. package/dist/adapters/github/tools/checks.js.map +1 -0
  53. package/dist/adapters/github/tools/issue.d.ts +21 -0
  54. package/dist/adapters/github/tools/issue.d.ts.map +1 -0
  55. package/dist/adapters/github/tools/issue.js +48 -0
  56. package/dist/adapters/github/tools/issue.js.map +1 -0
  57. package/dist/adapters/github/tools/pr.d.ts +22 -0
  58. package/dist/adapters/github/tools/pr.d.ts.map +1 -0
  59. package/dist/adapters/github/tools/pr.js +48 -0
  60. package/dist/adapters/github/tools/pr.js.map +1 -0
  61. package/dist/adapters/github/tools/read.d.ts +21 -0
  62. package/dist/adapters/github/tools/read.d.ts.map +1 -0
  63. package/dist/adapters/github/tools/read.js +141 -0
  64. package/dist/adapters/github/tools/read.js.map +1 -0
  65. package/dist/adapters/github/tools/review-reply.d.ts +17 -0
  66. package/dist/adapters/github/tools/review-reply.d.ts.map +1 -0
  67. package/dist/adapters/github/tools/review-reply.js +38 -0
  68. package/dist/adapters/github/tools/review-reply.js.map +1 -0
  69. package/dist/adapters/github/tools/sync.d.ts +17 -0
  70. package/dist/adapters/github/tools/sync.d.ts.map +1 -0
  71. package/dist/adapters/github/tools/sync.js +34 -0
  72. package/dist/adapters/github/tools/sync.js.map +1 -0
  73. package/dist/adapters/github/types.d.ts +372 -0
  74. package/dist/adapters/github/types.d.ts.map +1 -0
  75. package/dist/adapters/github/types.js +2 -0
  76. package/dist/adapters/github/types.js.map +1 -0
  77. package/dist/adapters/intake.d.ts +16 -5
  78. package/dist/adapters/intake.d.ts.map +1 -1
  79. package/dist/adapters/intake.js +84 -22
  80. package/dist/adapters/intake.js.map +1 -1
  81. package/dist/adapters/progressive-renderer.d.ts +7 -0
  82. package/dist/adapters/progressive-renderer.d.ts.map +1 -0
  83. package/dist/adapters/progressive-renderer.js +383 -0
  84. package/dist/adapters/progressive-renderer.js.map +1 -0
  85. package/dist/adapters/slack/blocks.d.ts.map +1 -1
  86. package/dist/adapters/slack/blocks.js +111 -111
  87. package/dist/adapters/slack/blocks.js.map +1 -1
  88. package/dist/adapters/slack/bot.d.ts +10 -6
  89. package/dist/adapters/slack/bot.d.ts.map +1 -1
  90. package/dist/adapters/slack/bot.js +173 -145
  91. package/dist/adapters/slack/bot.js.map +1 -1
  92. package/dist/adapters/slack/context.d.ts.map +1 -1
  93. package/dist/adapters/slack/context.js +3 -14
  94. package/dist/adapters/slack/context.js.map +1 -1
  95. package/dist/adapters/slack/response-lifecycle.d.ts.map +1 -1
  96. package/dist/adapters/slack/response-lifecycle.js +126 -323
  97. package/dist/adapters/slack/response-lifecycle.js.map +1 -1
  98. package/dist/adapters/slack/session.d.ts.map +1 -1
  99. package/dist/adapters/slack/session.js +5 -8
  100. package/dist/adapters/slack/session.js.map +1 -1
  101. package/dist/adapters/slack/tool-pack.d.ts +11 -0
  102. package/dist/adapters/slack/tool-pack.d.ts.map +1 -0
  103. package/dist/adapters/slack/tool-pack.js +45 -0
  104. package/dist/adapters/slack/tool-pack.js.map +1 -0
  105. package/dist/adapters/slack/tools/blockkit.d.ts +14 -0
  106. package/dist/adapters/slack/tools/blockkit.d.ts.map +1 -0
  107. package/dist/adapters/slack/tools/blockkit.js +106 -0
  108. package/dist/adapters/slack/tools/blockkit.js.map +1 -0
  109. package/dist/adapters/slack/types.d.ts +37 -0
  110. package/dist/adapters/slack/types.d.ts.map +1 -1
  111. package/dist/adapters/slack/types.js.map +1 -1
  112. package/dist/adapters/telegram/bot.d.ts +1 -2
  113. package/dist/adapters/telegram/bot.d.ts.map +1 -1
  114. package/dist/adapters/telegram/bot.js +51 -63
  115. package/dist/adapters/telegram/bot.js.map +1 -1
  116. package/dist/adapters/telegram/context.d.ts.map +1 -1
  117. package/dist/adapters/telegram/context.js +55 -182
  118. package/dist/adapters/telegram/context.js.map +1 -1
  119. package/dist/adapters/types.d.ts +86 -10
  120. package/dist/adapters/types.d.ts.map +1 -1
  121. package/dist/adapters/types.js.map +1 -1
  122. package/dist/agent.d.ts +14 -19
  123. package/dist/agent.d.ts.map +1 -1
  124. package/dist/agent.js +745 -243
  125. package/dist/agent.js.map +1 -1
  126. package/dist/cli/arg-grammar.d.ts +25 -0
  127. package/dist/cli/arg-grammar.d.ts.map +1 -0
  128. package/dist/cli/arg-grammar.js +59 -0
  129. package/dist/cli/arg-grammar.js.map +1 -0
  130. package/dist/cli/boot.d.ts +5 -0
  131. package/dist/cli/boot.d.ts.map +1 -0
  132. package/dist/cli/boot.js +112 -0
  133. package/dist/cli/boot.js.map +1 -0
  134. package/dist/cli/download.d.ts.map +1 -0
  135. package/dist/cli/download.js.map +1 -0
  136. package/dist/cli/ext-dev.d.ts +2 -0
  137. package/dist/cli/ext-dev.d.ts.map +1 -0
  138. package/dist/cli/ext-dev.js +177 -0
  139. package/dist/cli/ext-dev.js.map +1 -0
  140. package/dist/cli/ext-git.d.ts +17 -0
  141. package/dist/cli/ext-git.d.ts.map +1 -0
  142. package/dist/cli/ext-git.js +107 -0
  143. package/dist/cli/ext-git.js.map +1 -0
  144. package/dist/cli/ext.d.ts +2 -0
  145. package/dist/cli/ext.d.ts.map +1 -0
  146. package/dist/cli/ext.js +222 -0
  147. package/dist/cli/ext.js.map +1 -0
  148. package/dist/cli/types.d.ts +20 -0
  149. package/dist/cli/types.d.ts.map +1 -0
  150. package/dist/cli/types.js +2 -0
  151. package/dist/cli/types.js.map +1 -0
  152. package/dist/commands/admin.d.ts.map +1 -1
  153. package/dist/commands/admin.js +2 -1
  154. package/dist/commands/admin.js.map +1 -1
  155. package/dist/commands/auto-reply.d.ts.map +1 -1
  156. package/dist/commands/auto-reply.js +2 -6
  157. package/dist/commands/auto-reply.js.map +1 -1
  158. package/dist/commands/extensions.d.ts.map +1 -1
  159. package/dist/commands/extensions.js +18 -8
  160. package/dist/commands/extensions.js.map +1 -1
  161. package/dist/commands/login.d.ts +2 -1
  162. package/dist/commands/login.d.ts.map +1 -1
  163. package/dist/commands/login.js +35 -3
  164. package/dist/commands/login.js.map +1 -1
  165. package/dist/commands/manifest.d.ts +30 -0
  166. package/dist/commands/manifest.d.ts.map +1 -0
  167. package/dist/commands/manifest.js +121 -0
  168. package/dist/commands/manifest.js.map +1 -0
  169. package/dist/commands/model.d.ts +2 -3
  170. package/dist/commands/model.d.ts.map +1 -1
  171. package/dist/commands/model.js +57 -20
  172. package/dist/commands/model.js.map +1 -1
  173. package/dist/commands/new.d.ts.map +1 -1
  174. package/dist/commands/new.js +10 -2
  175. package/dist/commands/new.js.map +1 -1
  176. package/dist/commands/registry.d.ts +2 -2
  177. package/dist/commands/registry.d.ts.map +1 -1
  178. package/dist/commands/registry.js +1 -2
  179. package/dist/commands/registry.js.map +1 -1
  180. package/dist/commands/sandbox.d.ts.map +1 -1
  181. package/dist/commands/sandbox.js +23 -17
  182. package/dist/commands/sandbox.js.map +1 -1
  183. package/dist/commands/text.d.ts +2 -0
  184. package/dist/commands/text.d.ts.map +1 -0
  185. package/dist/commands/text.js +16 -0
  186. package/dist/commands/text.js.map +1 -0
  187. package/dist/commands/types.d.ts +70 -2
  188. package/dist/commands/types.d.ts.map +1 -1
  189. package/dist/commands/types.js.map +1 -1
  190. package/dist/config.d.ts +1 -3
  191. package/dist/config.d.ts.map +1 -1
  192. package/dist/config.js +102 -95
  193. package/dist/config.js.map +1 -1
  194. package/dist/env-manifest.d.ts +28 -0
  195. package/dist/env-manifest.d.ts.map +1 -0
  196. package/dist/env-manifest.js +214 -0
  197. package/dist/env-manifest.js.map +1 -0
  198. package/dist/events.d.ts.map +1 -1
  199. package/dist/events.js +9 -73
  200. package/dist/events.js.map +1 -1
  201. package/dist/execution-resolver.d.ts +7 -6
  202. package/dist/execution-resolver.d.ts.map +1 -1
  203. package/dist/execution-resolver.js +105 -110
  204. package/dist/execution-resolver.js.map +1 -1
  205. package/dist/harness/auth.d.ts +2 -1
  206. package/dist/harness/auth.d.ts.map +1 -1
  207. package/dist/harness/auth.js +6 -0
  208. package/dist/harness/auth.js.map +1 -1
  209. package/dist/harness/event-format.d.ts +25 -0
  210. package/dist/harness/event-format.d.ts.map +1 -0
  211. package/dist/harness/event-format.js +159 -0
  212. package/dist/harness/event-format.js.map +1 -0
  213. package/dist/harness/extensions/blockkit.d.ts +19 -0
  214. package/dist/harness/extensions/blockkit.d.ts.map +1 -0
  215. package/dist/harness/extensions/blockkit.js +42 -0
  216. package/dist/harness/extensions/blockkit.js.map +1 -0
  217. package/dist/harness/extensions/loader.d.ts +25 -48
  218. package/dist/harness/extensions/loader.d.ts.map +1 -1
  219. package/dist/harness/extensions/loader.js +373 -113
  220. package/dist/harness/extensions/loader.js.map +1 -1
  221. package/dist/harness/extensions/registry.d.ts +75 -2
  222. package/dist/harness/extensions/registry.d.ts.map +1 -1
  223. package/dist/harness/extensions/registry.js +239 -0
  224. package/dist/harness/extensions/registry.js.map +1 -1
  225. package/dist/harness/extensions/types.d.ts +318 -25
  226. package/dist/harness/extensions/types.d.ts.map +1 -1
  227. package/dist/harness/extensions/types.js.map +1 -1
  228. package/dist/harness/index.d.ts +18 -8
  229. package/dist/harness/index.d.ts.map +1 -1
  230. package/dist/harness/index.js +7 -4
  231. package/dist/harness/index.js.map +1 -1
  232. package/dist/harness/models.d.ts +7 -4
  233. package/dist/harness/models.d.ts.map +1 -1
  234. package/dist/harness/models.js +10 -0
  235. package/dist/harness/models.js.map +1 -1
  236. package/dist/harness/runner.d.ts +50 -54
  237. package/dist/harness/runner.d.ts.map +1 -1
  238. package/dist/harness/runner.js +230 -44
  239. package/dist/harness/runner.js.map +1 -1
  240. package/dist/harness/session-store.d.ts +9 -5
  241. package/dist/harness/session-store.d.ts.map +1 -1
  242. package/dist/harness/session-store.js +131 -30
  243. package/dist/harness/session-store.js.map +1 -1
  244. package/dist/harness/settings.d.ts +2 -20
  245. package/dist/harness/settings.d.ts.map +1 -1
  246. package/dist/harness/settings.js +11 -0
  247. package/dist/harness/settings.js.map +1 -1
  248. package/dist/harness/skills.d.ts +2 -29
  249. package/dist/harness/skills.d.ts.map +1 -1
  250. package/dist/harness/skills.js.map +1 -1
  251. package/dist/harness/subagent-profiles.d.ts +8 -0
  252. package/dist/harness/subagent-profiles.d.ts.map +1 -0
  253. package/dist/harness/subagent-profiles.js +290 -0
  254. package/dist/harness/subagent-profiles.js.map +1 -0
  255. package/dist/harness/subagent-runner.d.ts +39 -0
  256. package/dist/harness/subagent-runner.d.ts.map +1 -0
  257. package/dist/harness/subagent-runner.js +615 -0
  258. package/dist/harness/subagent-runner.js.map +1 -0
  259. package/dist/harness/types.d.ts +263 -1
  260. package/dist/harness/types.d.ts.map +1 -1
  261. package/dist/harness/types.js.map +1 -1
  262. package/dist/harness/usage.d.ts +6 -0
  263. package/dist/harness/usage.d.ts.map +1 -0
  264. package/dist/harness/usage.js +32 -0
  265. package/dist/harness/usage.js.map +1 -0
  266. package/dist/index.d.ts +33 -8
  267. package/dist/index.d.ts.map +1 -1
  268. package/dist/index.js +20 -6
  269. package/dist/index.js.map +1 -1
  270. package/dist/main.js +253 -109
  271. package/dist/main.js.map +1 -1
  272. package/dist/observability/instrument.js +6 -4
  273. package/dist/observability/instrument.js.map +1 -1
  274. package/dist/observability/sentry.d.ts.map +1 -1
  275. package/dist/observability/sentry.js +3 -2
  276. package/dist/observability/sentry.js.map +1 -1
  277. package/dist/packages/admin.d.ts +17 -0
  278. package/dist/packages/admin.d.ts.map +1 -0
  279. package/dist/packages/admin.js +96 -0
  280. package/dist/packages/admin.js.map +1 -0
  281. package/dist/packages/index.d.ts +6 -0
  282. package/dist/packages/index.d.ts.map +1 -0
  283. package/dist/packages/index.js +6 -0
  284. package/dist/packages/index.js.map +1 -0
  285. package/dist/packages/inspect.d.ts +11 -0
  286. package/dist/packages/inspect.d.ts.map +1 -0
  287. package/dist/packages/inspect.js +100 -0
  288. package/dist/packages/inspect.js.map +1 -0
  289. package/dist/packages/materialize.d.ts +39 -0
  290. package/dist/packages/materialize.d.ts.map +1 -0
  291. package/dist/packages/materialize.js +300 -0
  292. package/dist/packages/materialize.js.map +1 -0
  293. package/dist/packages/resolve.d.ts +25 -0
  294. package/dist/packages/resolve.d.ts.map +1 -0
  295. package/dist/packages/resolve.js +212 -0
  296. package/dist/packages/resolve.js.map +1 -0
  297. package/dist/packages/source.d.ts +33 -0
  298. package/dist/packages/source.d.ts.map +1 -0
  299. package/dist/packages/source.js +177 -0
  300. package/dist/packages/source.js.map +1 -0
  301. package/dist/packages/types.d.ts +104 -0
  302. package/dist/packages/types.d.ts.map +1 -0
  303. package/dist/packages/types.js +2 -0
  304. package/dist/packages/types.js.map +1 -0
  305. package/dist/provisioner.d.ts.map +1 -1
  306. package/dist/provisioner.js +6 -6
  307. package/dist/provisioner.js.map +1 -1
  308. package/dist/runtime/conversation-runtime.d.ts +1 -1
  309. package/dist/runtime/conversation-runtime.d.ts.map +1 -1
  310. package/dist/runtime/conversation-runtime.js +481 -98
  311. package/dist/runtime/conversation-runtime.js.map +1 -1
  312. package/dist/runtime/session-lifecycle.d.ts +28 -0
  313. package/dist/runtime/session-lifecycle.d.ts.map +1 -0
  314. package/dist/runtime/session-lifecycle.js +161 -0
  315. package/dist/runtime/session-lifecycle.js.map +1 -0
  316. package/dist/runtime/types.d.ts +45 -5
  317. package/dist/runtime/types.d.ts.map +1 -1
  318. package/dist/runtime/types.js.map +1 -1
  319. package/dist/sandbox/cloudflare.d.ts +3 -0
  320. package/dist/sandbox/cloudflare.d.ts.map +1 -1
  321. package/dist/sandbox/cloudflare.js +11 -0
  322. package/dist/sandbox/cloudflare.js.map +1 -1
  323. package/dist/sandbox/container.d.ts +4 -0
  324. package/dist/sandbox/container.d.ts.map +1 -1
  325. package/dist/sandbox/container.js +12 -2
  326. package/dist/sandbox/container.js.map +1 -1
  327. package/dist/sandbox/firecracker.d.ts +3 -0
  328. package/dist/sandbox/firecracker.d.ts.map +1 -1
  329. package/dist/sandbox/firecracker.js +11 -1
  330. package/dist/sandbox/firecracker.js.map +1 -1
  331. package/dist/sandbox/gondolin.d.ts +57 -0
  332. package/dist/sandbox/gondolin.d.ts.map +1 -0
  333. package/dist/sandbox/gondolin.js +764 -0
  334. package/dist/sandbox/gondolin.js.map +1 -0
  335. package/dist/sandbox/host.d.ts +4 -0
  336. package/dist/sandbox/host.d.ts.map +1 -1
  337. package/dist/sandbox/host.js +52 -0
  338. package/dist/sandbox/host.js.map +1 -1
  339. package/dist/sandbox/identity.d.ts +16 -0
  340. package/dist/sandbox/identity.d.ts.map +1 -0
  341. package/dist/sandbox/identity.js +42 -0
  342. package/dist/sandbox/identity.js.map +1 -0
  343. package/dist/sandbox/image.d.ts.map +1 -1
  344. package/dist/sandbox/image.js +1 -0
  345. package/dist/sandbox/image.js.map +1 -1
  346. package/dist/sandbox/index.d.ts +15 -4
  347. package/dist/sandbox/index.d.ts.map +1 -1
  348. package/dist/sandbox/index.js +25 -3
  349. package/dist/sandbox/index.js.map +1 -1
  350. package/dist/sandbox/path-context.js +18 -8
  351. package/dist/sandbox/path-context.js.map +1 -1
  352. package/dist/sandbox/types.d.ts +65 -1
  353. package/dist/sandbox/types.d.ts.map +1 -1
  354. package/dist/sandbox/types.js.map +1 -1
  355. package/dist/sandbox/utils.d.ts +12 -0
  356. package/dist/sandbox/utils.d.ts.map +1 -1
  357. package/dist/sandbox/utils.js +38 -0
  358. package/dist/sandbox/utils.js.map +1 -1
  359. package/dist/sessions/chat-history-sync.d.ts +25 -0
  360. package/dist/sessions/chat-history-sync.d.ts.map +1 -0
  361. package/dist/sessions/{agent-memory-file-manager.js → chat-history-sync.js} +98 -124
  362. package/dist/sessions/chat-history-sync.js.map +1 -0
  363. package/dist/sessions/conversation-log.d.ts +9 -0
  364. package/dist/sessions/conversation-log.d.ts.map +1 -0
  365. package/dist/sessions/conversation-log.js +47 -0
  366. package/dist/sessions/conversation-log.js.map +1 -0
  367. package/dist/sessions/history-line.d.ts +20 -0
  368. package/dist/sessions/history-line.d.ts.map +1 -0
  369. package/dist/sessions/history-line.js +24 -0
  370. package/dist/sessions/history-line.js.map +1 -0
  371. package/dist/sessions/policy.d.ts.map +1 -1
  372. package/dist/sessions/policy.js +5 -3
  373. package/dist/sessions/policy.js.map +1 -1
  374. package/dist/sessions/rotation.d.ts +2 -0
  375. package/dist/sessions/rotation.d.ts.map +1 -0
  376. package/dist/sessions/rotation.js +39 -0
  377. package/dist/sessions/rotation.js.map +1 -0
  378. package/dist/sessions/session-key.d.ts +40 -0
  379. package/dist/sessions/session-key.d.ts.map +1 -0
  380. package/dist/sessions/session-key.js +92 -0
  381. package/dist/sessions/session-key.js.map +1 -0
  382. package/dist/sessions/store.d.ts.map +1 -1
  383. package/dist/sessions/store.js +40 -18
  384. package/dist/sessions/store.js.map +1 -1
  385. package/dist/sessions/types.d.ts +17 -4
  386. package/dist/sessions/types.d.ts.map +1 -1
  387. package/dist/sessions/types.js.map +1 -1
  388. package/dist/settings-mutation.d.ts +8 -0
  389. package/dist/settings-mutation.d.ts.map +1 -0
  390. package/dist/settings-mutation.js +43 -0
  391. package/dist/settings-mutation.js.map +1 -0
  392. package/dist/subagent-progress.d.ts +43 -0
  393. package/dist/subagent-progress.d.ts.map +1 -0
  394. package/dist/subagent-progress.js +220 -0
  395. package/dist/subagent-progress.js.map +1 -0
  396. package/dist/tools/bash.d.ts +3 -1
  397. package/dist/tools/bash.d.ts.map +1 -1
  398. package/dist/tools/bash.js +25 -17
  399. package/dist/tools/bash.js.map +1 -1
  400. package/dist/tools/edit.d.ts.map +1 -1
  401. package/dist/tools/edit.js +10 -12
  402. package/dist/tools/edit.js.map +1 -1
  403. package/dist/tools/event.d.ts +1 -1
  404. package/dist/tools/event.d.ts.map +1 -1
  405. package/dist/tools/event.js +53 -43
  406. package/dist/tools/event.js.map +1 -1
  407. package/dist/tools/generate-image.d.ts +17 -0
  408. package/dist/tools/generate-image.d.ts.map +1 -0
  409. package/dist/tools/generate-image.js +63 -0
  410. package/dist/tools/generate-image.js.map +1 -0
  411. package/dist/tools/host-fn-tool.d.ts +21 -0
  412. package/dist/tools/host-fn-tool.d.ts.map +1 -0
  413. package/dist/tools/host-fn-tool.js +32 -0
  414. package/dist/tools/host-fn-tool.js.map +1 -0
  415. package/dist/tools/index.d.ts +14 -2
  416. package/dist/tools/index.d.ts.map +1 -1
  417. package/dist/tools/index.js +28 -3
  418. package/dist/tools/index.js.map +1 -1
  419. package/dist/tools/react.d.ts +15 -0
  420. package/dist/tools/react.d.ts.map +1 -0
  421. package/dist/tools/react.js +29 -0
  422. package/dist/tools/react.js.map +1 -0
  423. package/dist/tools/read.d.ts +1 -0
  424. package/dist/tools/read.d.ts.map +1 -1
  425. package/dist/tools/read.js +37 -31
  426. package/dist/tools/read.js.map +1 -1
  427. package/dist/tools/sandbox.d.ts +2 -2
  428. package/dist/tools/sandbox.d.ts.map +1 -1
  429. package/dist/tools/sandbox.js +14 -9
  430. package/dist/tools/sandbox.js.map +1 -1
  431. package/dist/tools/subagent-slots.d.ts +28 -0
  432. package/dist/tools/subagent-slots.d.ts.map +1 -0
  433. package/dist/tools/subagent-slots.js +72 -0
  434. package/dist/tools/subagent-slots.js.map +1 -0
  435. package/dist/tools/subagent.d.ts +54 -0
  436. package/dist/tools/subagent.d.ts.map +1 -0
  437. package/dist/tools/subagent.js +401 -0
  438. package/dist/tools/subagent.js.map +1 -0
  439. package/dist/tools/types.d.ts +40 -6
  440. package/dist/tools/types.d.ts.map +1 -1
  441. package/dist/tools/types.js.map +1 -1
  442. package/dist/tools/write.d.ts.map +1 -1
  443. package/dist/tools/write.js +2 -8
  444. package/dist/tools/write.js.map +1 -1
  445. package/dist/trigger.d.ts.map +1 -1
  446. package/dist/trigger.js +1 -2
  447. package/dist/trigger.js.map +1 -1
  448. package/dist/types.d.ts +232 -32
  449. package/dist/types.d.ts.map +1 -1
  450. package/dist/types.js.map +1 -1
  451. package/dist/utils/date.d.ts +1 -1
  452. package/dist/utils/date.js +1 -1
  453. package/dist/utils/date.js.map +1 -1
  454. package/dist/vault/disabled.d.ts +9 -0
  455. package/dist/vault/disabled.d.ts.map +1 -0
  456. package/dist/vault/disabled.js +22 -0
  457. package/dist/vault/disabled.js.map +1 -0
  458. package/dist/vault/index.d.ts +0 -2
  459. package/dist/vault/index.d.ts.map +1 -1
  460. package/dist/vault/index.js +30 -33
  461. package/dist/vault/index.js.map +1 -1
  462. package/dist/vault/injection.d.ts +10 -0
  463. package/dist/vault/injection.d.ts.map +1 -0
  464. package/dist/vault/injection.js +30 -0
  465. package/dist/vault/injection.js.map +1 -0
  466. package/dist/vault/policy.d.ts +20 -0
  467. package/dist/vault/policy.d.ts.map +1 -0
  468. package/dist/vault/policy.js +20 -0
  469. package/dist/vault/policy.js.map +1 -0
  470. package/dist/vault/types.d.ts +4 -2
  471. package/dist/vault/types.d.ts.map +1 -1
  472. package/dist/vault/types.js.map +1 -1
  473. package/dist/web/admin/portal.d.ts +17 -2
  474. package/dist/web/admin/portal.d.ts.map +1 -1
  475. package/dist/web/admin/portal.js +385 -155
  476. package/dist/web/admin/portal.js.map +1 -1
  477. package/dist/web/admin/types.d.ts +18 -0
  478. package/dist/web/admin/types.d.ts.map +1 -1
  479. package/dist/web/admin/types.js.map +1 -1
  480. package/dist/web/agent-events/portal.d.ts.map +1 -1
  481. package/dist/web/agent-events/portal.js +2 -1
  482. package/dist/web/agent-events/portal.js.map +1 -1
  483. package/dist/web/login/oauth.d.ts +2 -3
  484. package/dist/web/login/oauth.d.ts.map +1 -1
  485. package/dist/web/login/oauth.js +0 -31
  486. package/dist/web/login/oauth.js.map +1 -1
  487. package/dist/web/login/portal.js +1 -1
  488. package/dist/web/login/portal.js.map +1 -1
  489. package/dist/web/login/types.d.ts +0 -11
  490. package/dist/web/login/types.d.ts.map +1 -1
  491. package/dist/web/login/types.js.map +1 -1
  492. package/dist/web/portal-shell.d.ts +4 -0
  493. package/dist/web/portal-shell.d.ts.map +1 -0
  494. package/dist/{portal-shell.js → web/portal-shell.js} +2 -2
  495. package/dist/web/portal-shell.js.map +1 -0
  496. package/dist/web/server.d.ts.map +1 -1
  497. package/dist/web/server.js +7 -0
  498. package/dist/web/server.js.map +1 -1
  499. package/dist/web/session-view/command.d.ts.map +1 -1
  500. package/dist/web/session-view/command.js +4 -1
  501. package/dist/web/session-view/command.js.map +1 -1
  502. package/dist/web/session-view/portal.d.ts.map +1 -1
  503. package/dist/web/session-view/portal.js +4 -3
  504. package/dist/web/session-view/portal.js.map +1 -1
  505. package/dist/web/session-view/service.d.ts.map +1 -1
  506. package/dist/web/session-view/service.js +2 -1
  507. package/dist/web/session-view/service.js.map +1 -1
  508. package/dist/web/session-view/types.d.ts +2 -1
  509. package/dist/web/session-view/types.d.ts.map +1 -1
  510. package/dist/web/session-view/types.js.map +1 -1
  511. package/dist/workspace-projection/index.d.ts +5 -0
  512. package/dist/workspace-projection/index.d.ts.map +1 -0
  513. package/dist/workspace-projection/index.js +71 -0
  514. package/dist/workspace-projection/index.js.map +1 -0
  515. package/dist/workspace-projection/types.d.ts +7 -0
  516. package/dist/workspace-projection/types.d.ts.map +1 -0
  517. package/dist/workspace-projection/types.js +2 -0
  518. package/dist/workspace-projection/types.js.map +1 -0
  519. package/package.json +28 -15
  520. package/dist/adapters/streaming.d.ts +0 -18
  521. package/dist/adapters/streaming.d.ts.map +0 -1
  522. package/dist/adapters/streaming.js +0 -44
  523. package/dist/adapters/streaming.js.map +0 -1
  524. package/dist/download.d.ts.map +0 -1
  525. package/dist/download.js.map +0 -1
  526. package/dist/model-registry.d.ts +0 -4
  527. package/dist/model-registry.d.ts.map +0 -1
  528. package/dist/model-registry.js +0 -7
  529. package/dist/model-registry.js.map +0 -1
  530. package/dist/portal-shell.d.ts +0 -4
  531. package/dist/portal-shell.d.ts.map +0 -1
  532. package/dist/portal-shell.js.map +0 -1
  533. package/dist/runtime/agent-run-controller.d.ts +0 -31
  534. package/dist/runtime/agent-run-controller.d.ts.map +0 -1
  535. package/dist/runtime/agent-run-controller.js +0 -195
  536. package/dist/runtime/agent-run-controller.js.map +0 -1
  537. package/dist/sessions/agent-memory-file-manager.d.ts +0 -19
  538. package/dist/sessions/agent-memory-file-manager.d.ts.map +0 -1
  539. package/dist/sessions/agent-memory-file-manager.js.map +0 -1
  540. package/dist/vault/routing.d.ts +0 -3
  541. package/dist/vault/routing.d.ts.map +0 -1
  542. package/dist/vault/routing.js +0 -13
  543. package/dist/vault/routing.js.map +0 -1
  544. /package/dist/{download.d.ts → cli/download.d.ts} +0 -0
  545. /package/dist/{download.js → cli/download.js} +0 -0
@@ -0,0 +1,212 @@
1
+ /**
2
+ * What a conversation actually loads: the two scopes' declared packages
3
+ * combined, collisions resolved, and each surviving package turned into the
4
+ * directories the extension loader and the skill loader consume.
5
+ *
6
+ * Two rules do all the work here:
7
+ *
8
+ * - **Additive scopes.** `global` packages load for every conversation; a
9
+ * conversation's packages load on top. Neither list replaces the other.
10
+ * - **Narrower scope wins.** When both scopes declare the same package
11
+ * ({@link sourceIdentity}, which ignores the ref), only the conversation's
12
+ * copy loads. That is what makes "pin this one channel to v2 while everyone
13
+ * else stays on v1" work, and it is why the same package installed twice
14
+ * cannot activate twice.
15
+ *
16
+ * Resolution never throws. A conversation with one malformed or unfetchable
17
+ * source still loads every other package, and the failure is reported through
18
+ * {@link ResolvedPackages.errors} for the portal and the logs. The alternative
19
+ * — one bad string in settings taking a conversation offline — is a far worse
20
+ * failure mode than a missing feature.
21
+ */
22
+ import { createHash } from "node:crypto";
23
+ import { existsSync, statSync } from "node:fs";
24
+ import { join } from "node:path";
25
+ import { loadGlobalSettings, resolveConversationSettings } from "../config.js";
26
+ import * as log from "../log.js";
27
+ import { materializeSource, packageScopeDir } from "./materialize.js";
28
+ import { parseSource, sourceIdentity } from "./source.js";
29
+ /** Conventional resource directories inside a package, mirroring pi's layout. */
30
+ const EXTENSIONS_SUBDIR = "extensions";
31
+ const SKILLS_SUBDIR = "skills";
32
+ /** Slug length cap; long identities keep a digest tail instead of colliding. */
33
+ const SLUG_MAX_LENGTH = 96;
34
+ /**
35
+ * Where package resources appear inside the sandbox.
36
+ *
37
+ * Deliberately OUTSIDE `/workspace`. In `full` workspace-mount mode
38
+ * `/workspace` is the entire working directory, so a `/workspace/packages`
39
+ * mount would shadow a real `packages/` directory in the user's tree — mikan's
40
+ * own repository has one. Living outside also keeps
41
+ * `translateMountedRuntimePathToHost` correct by construction: it maps only
42
+ * the `/workspace` prefix and returns everything else untouched, so a package
43
+ * path can never be mistranslated into a host path that does not exist.
44
+ *
45
+ * Skills are referenced by absolute path in the system prompt, so the location
46
+ * costs nothing in usability.
47
+ */
48
+ const PACKAGE_RUNTIME_ROOT = "/mikan/packages";
49
+ /** Runtime path a package's skills directory is mounted at. */
50
+ export function packageSkillRuntimeDir(slug) {
51
+ return `${PACKAGE_RUNTIME_ROOT}/${slug}/${SKILLS_SUBDIR}`;
52
+ }
53
+ /**
54
+ * Read-only mounts exposing every resolved package's skills to the sandbox.
55
+ *
56
+ * Read-only rather than read-write because the host owns these files: the
57
+ * directory is a git checkout that an update replaces wholesale, so an agent
58
+ * edit would be silently discarded on the next refresh. Making the filesystem
59
+ * refuse the write turns a confusing data-loss bug into an obvious error.
60
+ *
61
+ * Resolution is offline, so building the mount list never reaches the network.
62
+ */
63
+ export function conversationPackageSkillMounts(options) {
64
+ return resolveConversationPackages(options).skillDirs.map(({ slug, dir }) => ({
65
+ source: dir,
66
+ target: packageSkillRuntimeDir(slug),
67
+ readOnly: true,
68
+ }));
69
+ }
70
+ /**
71
+ * Resolve the package set for one conversation. Reads both scopes' settings,
72
+ * dedups, and reports the directories to load from.
73
+ */
74
+ export function resolveConversationPackages(options) {
75
+ const declarations = [
76
+ ...readScope("global", undefined, options),
77
+ ...readScope("conversation", options.conversationId, options),
78
+ ];
79
+ const errors = [];
80
+ const byIdentity = new Map();
81
+ for (const declaration of declarations) {
82
+ let identity;
83
+ try {
84
+ identity = sourceIdentity(parseSource(declaration.source));
85
+ }
86
+ catch (err) {
87
+ errors.push({ source: declaration.source, message: messageOf(err) });
88
+ continue;
89
+ }
90
+ // Later scopes overwrite earlier ones: global is read first, so a
91
+ // conversation declaring the same package shadows it.
92
+ const existing = byIdentity.get(identity);
93
+ if (existing && existing.scope !== declaration.scope) {
94
+ log.logInfo(`Package ${identity} declared in both scopes; using the conversation's copy`);
95
+ }
96
+ const materialized = materialize(declaration, options, errors);
97
+ if (materialized)
98
+ byIdentity.set(identity, materialized);
99
+ else
100
+ byIdentity.delete(identity);
101
+ }
102
+ const packages = [...byIdentity.values()].toSorted(scopeOrder);
103
+ const targets = packages.map(packageExtensionTargets);
104
+ return {
105
+ packages,
106
+ extensionDirs: [...scopeConventionDirs(options), ...targets.flatMap((target) => target.dirs)],
107
+ extensionRoots: targets.flatMap((target) => target.roots),
108
+ skillDirs: packages.flatMap(packageSkillDir),
109
+ errors,
110
+ };
111
+ }
112
+ function readScope(scope, conversationId, options) {
113
+ try {
114
+ const sources = scope === "global"
115
+ ? loadGlobalSettings().packages
116
+ : resolveConversationSettings(options.conversationDir).packages;
117
+ return (sources ?? []).map((source) => ({ source, scope }));
118
+ }
119
+ catch (err) {
120
+ // Unreadable settings must not take the conversation down; the other
121
+ // scope, and the convention directories, still load.
122
+ log.logWarning(`Could not read ${scope} package list`, messageOf(err));
123
+ void conversationId;
124
+ return [];
125
+ }
126
+ }
127
+ function materialize(declaration, options, errors) {
128
+ try {
129
+ return materializeSource(declaration.source, {
130
+ scope: declaration.scope,
131
+ conversationId: options.conversationId,
132
+ stateDir: options.stateDir,
133
+ mode: options.fetchMissing ? "fetch" : "offline",
134
+ });
135
+ }
136
+ catch (err) {
137
+ errors.push({ source: declaration.source, message: messageOf(err) });
138
+ return undefined;
139
+ }
140
+ }
141
+ /**
142
+ * The convention directories that need no declaration:
143
+ * `<stateDir>/global/extensions` and
144
+ * `<stateDir>/conversations/<id>/extensions`. These are the directories
145
+ * `mikan ext install` writes into, so CLI installs and portal-declared
146
+ * packages coexist.
147
+ */
148
+ function scopeConventionDirs(options) {
149
+ return [
150
+ join(packageScopeDir("global", undefined, options.stateDir), EXTENSIONS_SUBDIR),
151
+ join(packageScopeDir("conversation", options.conversationId, options.stateDir), EXTENSIONS_SUBDIR),
152
+ ];
153
+ }
154
+ /**
155
+ * How a package contributes extensions. Two shapes are accepted, and which one
156
+ * applies is decided by the package's own layout rather than by configuration:
157
+ *
158
+ * - **Collection**: an `extensions/` subdirectory, scanned for named children.
159
+ * This is the shape a repository shipping several extensions has.
160
+ * - **Single extension**: no `extensions/` subdirectory, but the package root
161
+ * is itself a loadable extension (an index file, or a `package.json` with
162
+ * `mikan.extensions`). This is what a one-extension repo looks like, and it
163
+ * is what a developer's working copy looks like — so `mikan ext dev` needs
164
+ * no special case.
165
+ *
166
+ * The slug comes from the package directory name in the single-extension
167
+ * shape, so a repo named for its extension gets the identity its author
168
+ * expects.
169
+ */
170
+ function packageExtensionTargets(pkg) {
171
+ const collection = join(pkg.dir, EXTENSIONS_SUBDIR);
172
+ if (existsSync(collection))
173
+ return { dirs: [collection], roots: [] };
174
+ return { dirs: [], roots: [pkg.dir] };
175
+ }
176
+ function packageSkillDir(pkg) {
177
+ const dir = join(pkg.dir, SKILLS_SUBDIR);
178
+ if (!existsSync(dir) || !statSync(dir).isDirectory())
179
+ return [];
180
+ return [{ slug: packageSlug(pkg), dir }];
181
+ }
182
+ /**
183
+ * Filesystem-safe, collision-resistant name for a package, used as the mount
184
+ * path segment for its skills. Derived from the identity rather than the
185
+ * source string so the same package spelled two ways gets one name.
186
+ */
187
+ function packageSlug(pkg) {
188
+ const readable = pkg.identity
189
+ .replace(/^(git|local):/, "")
190
+ .toLowerCase()
191
+ .replace(/[^a-z0-9._-]+/g, "-")
192
+ .replace(/^-+|-+$/g, "");
193
+ if (readable.length <= SLUG_MAX_LENGTH)
194
+ return readable;
195
+ // Truncation alone would let two long identities sharing a prefix (deeply
196
+ // nested self-hosted groups, file:// paths) land on the same slug — and
197
+ // therefore the same mount target, where one package's skills would quietly
198
+ // replace the other's. The digest makes the tail collision-resistant.
199
+ const digest = createHash("sha256").update(pkg.identity).digest("hex").slice(0, 8);
200
+ return `${readable.slice(0, SLUG_MAX_LENGTH - digest.length - 1)}-${digest}`;
201
+ }
202
+ /** Global packages load before conversation ones. */
203
+ function scopeRank(scope) {
204
+ return scope === "global" ? 0 : 1;
205
+ }
206
+ function scopeOrder(a, b) {
207
+ return scopeRank(a.scope) - scopeRank(b.scope);
208
+ }
209
+ function messageOf(err) {
210
+ return err instanceof Error ? err.message : String(err);
211
+ }
212
+ //# sourceMappingURL=resolve.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../src/packages/resolve.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * What a conversation actually loads: the two scopes' declared packages\n * combined, collisions resolved, and each surviving package turned into the\n * directories the extension loader and the skill loader consume.\n *\n * Two rules do all the work here:\n *\n * - **Additive scopes.** `global` packages load for every conversation; a\n * conversation's packages load on top. Neither list replaces the other.\n * - **Narrower scope wins.** When both scopes declare the same package\n * ({@link sourceIdentity}, which ignores the ref), only the conversation's\n * copy loads. That is what makes \"pin this one channel to v2 while everyone\n * else stays on v1\" work, and it is why the same package installed twice\n * cannot activate twice.\n *\n * Resolution never throws. A conversation with one malformed or unfetchable\n * source still loads every other package, and the failure is reported through\n * {@link ResolvedPackages.errors} for the portal and the logs. The alternative\n * — one bad string in settings taking a conversation offline — is a far worse\n * failure mode than a missing feature.\n */\nimport { createHash } from \"node:crypto\";\nimport { existsSync, statSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { loadGlobalSettings, resolveConversationSettings } from \"../config.js\";\nimport * as log from \"../log.js\";\nimport { materializeSource, packageScopeDir } from \"./materialize.js\";\nimport { parseSource, sourceIdentity } from \"./source.js\";\nimport type {\n MaterializedPackage,\n PackageError,\n PackageScope,\n PackageSkillDir,\n ResolvePackagesOptions,\n ResolvedPackages,\n} from \"./types.js\";\n\nexport type { ResolvePackagesOptions, ResolvedPackages } from \"./types.js\";\n\n/** Conventional resource directories inside a package, mirroring pi's layout. */\nconst EXTENSIONS_SUBDIR = \"extensions\";\nconst SKILLS_SUBDIR = \"skills\";\n/** Slug length cap; long identities keep a digest tail instead of colliding. */\nconst SLUG_MAX_LENGTH = 96;\n\n/**\n * Where package resources appear inside the sandbox.\n *\n * Deliberately OUTSIDE `/workspace`. In `full` workspace-mount mode\n * `/workspace` is the entire working directory, so a `/workspace/packages`\n * mount would shadow a real `packages/` directory in the user's tree — mikan's\n * own repository has one. Living outside also keeps\n * `translateMountedRuntimePathToHost` correct by construction: it maps only\n * the `/workspace` prefix and returns everything else untouched, so a package\n * path can never be mistranslated into a host path that does not exist.\n *\n * Skills are referenced by absolute path in the system prompt, so the location\n * costs nothing in usability.\n */\nconst PACKAGE_RUNTIME_ROOT = \"/mikan/packages\";\n\n/** Runtime path a package's skills directory is mounted at. */\nexport function packageSkillRuntimeDir(slug: string): string {\n return `${PACKAGE_RUNTIME_ROOT}/${slug}/${SKILLS_SUBDIR}`;\n}\n\n/**\n * Read-only mounts exposing every resolved package's skills to the sandbox.\n *\n * Read-only rather than read-write because the host owns these files: the\n * directory is a git checkout that an update replaces wholesale, so an agent\n * edit would be silently discarded on the next refresh. Making the filesystem\n * refuse the write turns a confusing data-loss bug into an obvious error.\n *\n * Resolution is offline, so building the mount list never reaches the network.\n */\nexport function conversationPackageSkillMounts(\n options: ResolvePackagesOptions,\n): Array<{ source: string; target: string; readOnly: true }> {\n return resolveConversationPackages(options).skillDirs.map(({ slug, dir }) => ({\n source: dir,\n target: packageSkillRuntimeDir(slug),\n readOnly: true,\n }));\n}\n\n/**\n * Resolve the package set for one conversation. Reads both scopes' settings,\n * dedups, and reports the directories to load from.\n */\nexport function resolveConversationPackages(options: ResolvePackagesOptions): ResolvedPackages {\n const declarations = [\n ...readScope(\"global\", undefined, options),\n ...readScope(\"conversation\", options.conversationId, options),\n ];\n\n const errors: PackageError[] = [];\n const byIdentity = new Map<string, MaterializedPackage>();\n\n for (const declaration of declarations) {\n let identity: string;\n try {\n identity = sourceIdentity(parseSource(declaration.source));\n } catch (err) {\n errors.push({ source: declaration.source, message: messageOf(err) });\n continue;\n }\n // Later scopes overwrite earlier ones: global is read first, so a\n // conversation declaring the same package shadows it.\n const existing = byIdentity.get(identity);\n if (existing && existing.scope !== declaration.scope) {\n log.logInfo(`Package ${identity} declared in both scopes; using the conversation's copy`);\n }\n const materialized = materialize(declaration, options, errors);\n if (materialized) byIdentity.set(identity, materialized);\n else byIdentity.delete(identity);\n }\n\n const packages = [...byIdentity.values()].toSorted(scopeOrder);\n const targets = packages.map(packageExtensionTargets);\n return {\n packages,\n extensionDirs: [...scopeConventionDirs(options), ...targets.flatMap((target) => target.dirs)],\n extensionRoots: targets.flatMap((target) => target.roots),\n skillDirs: packages.flatMap(packageSkillDir),\n errors,\n };\n}\n\ninterface Declaration {\n source: string;\n scope: PackageScope;\n}\n\nfunction readScope(\n scope: PackageScope,\n conversationId: string | undefined,\n options: ResolvePackagesOptions,\n): Declaration[] {\n try {\n const sources =\n scope === \"global\"\n ? loadGlobalSettings().packages\n : resolveConversationSettings(options.conversationDir).packages;\n return (sources ?? []).map((source) => ({ source, scope }));\n } catch (err) {\n // Unreadable settings must not take the conversation down; the other\n // scope, and the convention directories, still load.\n log.logWarning(`Could not read ${scope} package list`, messageOf(err));\n void conversationId;\n return [];\n }\n}\n\nfunction materialize(\n declaration: Declaration,\n options: ResolvePackagesOptions,\n errors: PackageError[],\n): MaterializedPackage | undefined {\n try {\n return materializeSource(declaration.source, {\n scope: declaration.scope,\n conversationId: options.conversationId,\n stateDir: options.stateDir,\n mode: options.fetchMissing ? \"fetch\" : \"offline\",\n });\n } catch (err) {\n errors.push({ source: declaration.source, message: messageOf(err) });\n return undefined;\n }\n}\n\n/**\n * The convention directories that need no declaration:\n * `<stateDir>/global/extensions` and\n * `<stateDir>/conversations/<id>/extensions`. These are the directories\n * `mikan ext install` writes into, so CLI installs and portal-declared\n * packages coexist.\n */\nfunction scopeConventionDirs(options: ResolvePackagesOptions): string[] {\n return [\n join(packageScopeDir(\"global\", undefined, options.stateDir), EXTENSIONS_SUBDIR),\n join(\n packageScopeDir(\"conversation\", options.conversationId, options.stateDir),\n EXTENSIONS_SUBDIR,\n ),\n ];\n}\n\n/**\n * How a package contributes extensions. Two shapes are accepted, and which one\n * applies is decided by the package's own layout rather than by configuration:\n *\n * - **Collection**: an `extensions/` subdirectory, scanned for named children.\n * This is the shape a repository shipping several extensions has.\n * - **Single extension**: no `extensions/` subdirectory, but the package root\n * is itself a loadable extension (an index file, or a `package.json` with\n * `mikan.extensions`). This is what a one-extension repo looks like, and it\n * is what a developer's working copy looks like — so `mikan ext dev` needs\n * no special case.\n *\n * The slug comes from the package directory name in the single-extension\n * shape, so a repo named for its extension gets the identity its author\n * expects.\n */\nfunction packageExtensionTargets(pkg: MaterializedPackage): { dirs: string[]; roots: string[] } {\n const collection = join(pkg.dir, EXTENSIONS_SUBDIR);\n if (existsSync(collection)) return { dirs: [collection], roots: [] };\n return { dirs: [], roots: [pkg.dir] };\n}\n\nfunction packageSkillDir(pkg: MaterializedPackage): PackageSkillDir[] {\n const dir = join(pkg.dir, SKILLS_SUBDIR);\n if (!existsSync(dir) || !statSync(dir).isDirectory()) return [];\n return [{ slug: packageSlug(pkg), dir }];\n}\n\n/**\n * Filesystem-safe, collision-resistant name for a package, used as the mount\n * path segment for its skills. Derived from the identity rather than the\n * source string so the same package spelled two ways gets one name.\n */\nfunction packageSlug(pkg: MaterializedPackage): string {\n const readable = pkg.identity\n .replace(/^(git|local):/, \"\")\n .toLowerCase()\n .replace(/[^a-z0-9._-]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\");\n if (readable.length <= SLUG_MAX_LENGTH) return readable;\n // Truncation alone would let two long identities sharing a prefix (deeply\n // nested self-hosted groups, file:// paths) land on the same slug — and\n // therefore the same mount target, where one package's skills would quietly\n // replace the other's. The digest makes the tail collision-resistant.\n const digest = createHash(\"sha256\").update(pkg.identity).digest(\"hex\").slice(0, 8);\n return `${readable.slice(0, SLUG_MAX_LENGTH - digest.length - 1)}-${digest}`;\n}\n\n/** Global packages load before conversation ones. */\nfunction scopeRank(scope: PackageScope): number {\n return scope === \"global\" ? 0 : 1;\n}\n\nfunction scopeOrder(a: MaterializedPackage, b: MaterializedPackage): number {\n return scopeRank(a.scope) - scopeRank(b.scope);\n}\n\nfunction messageOf(err: unknown): string {\n return err instanceof Error ? err.message : String(err);\n}\n"]}
@@ -0,0 +1,33 @@
1
+ import type { PackageIdentity, ParsedSource } from "./types.js";
2
+ /**
3
+ * Parse a source string. Throws with a user-facing message rather than
4
+ * returning undefined: every caller (portal, settings load, CLI) needs to tell
5
+ * the human what was wrong with what they typed.
6
+ */
7
+ export declare function parseSource(source: string): ParsedSource;
8
+ /**
9
+ * Identity of the package a source refers to — the key for deduplication and
10
+ * for letting a conversation's copy shadow the global one.
11
+ *
12
+ * Deliberate choices:
13
+ * - The ref is excluded: the same repo pinned to two refs in two scopes is one
14
+ * package installed twice, and the narrower scope wins.
15
+ * - The subpath is included: two extensions living at different paths in one
16
+ * monorepo are two packages.
17
+ * - Transport is excluded: `git@github.com:o/r`, `https://github.com/o/r.git`
18
+ * and `ssh://git@github.com/o/r` all identify the same package, so mixing
19
+ * SSH and HTTPS spellings across scopes still dedups.
20
+ */
21
+ export declare function sourceIdentity(parsed: ParsedSource): PackageIdentity;
22
+ /**
23
+ * Transport-independent `<host>/<path>` of a git URL, lowercased host, no
24
+ * `.git` suffix, no credentials. It is the base of the on-disk clone layout,
25
+ * so it must stay free of anything that is not a safe path segment.
26
+ */
27
+ export declare function gitRepoPath(url: string): string;
28
+ /**
29
+ * Canonical string form, used when writing settings so the stored value is
30
+ * stable regardless of how the human spelled it.
31
+ */
32
+ export declare function formatSource(parsed: ParsedSource): string;
33
+ //# sourceMappingURL=source.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"source.d.ts","sourceRoot":"","sources":["../../src/packages/source.ts"],"names":[],"mappings":"AA6BA,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAKhE;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY,CAsCxD;AA2CD;;;;;;;;;;;;GAYG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,YAAY,GAAG,eAAe,CAIpE;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAc/C;AAgBD;;;GAGG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAKzD"}
@@ -0,0 +1,177 @@
1
+ /**
2
+ * The package source grammar: one place that turns a human-written source
3
+ * string into a {@link ParsedSource}, and one place that decides when two
4
+ * sources are the same package ({@link sourceIdentity}).
5
+ *
6
+ * Only git and local-path sources are implemented. The tagged union and the
7
+ * identity function are the seams a future `npm:` source slots into: adding it
8
+ * means a new arm here and a new materializer, with nothing downstream —
9
+ * resolution, scope precedence, the portal — needing to know.
10
+ *
11
+ * Grammar:
12
+ *
13
+ * <locator>[@<ref>][#<subpath>]
14
+ *
15
+ * locator: https://… http://… ssh://… git://… file://…
16
+ * git@host:owner/repo
17
+ * git:<any of the above, or host/owner/repo shorthand>
18
+ * github:owner/repo
19
+ * /abs/path ./rel/path (local, used by reference)
20
+ *
21
+ * `@<ref>` is recognized only when what follows the last `@` contains no `/`
22
+ * and no `:` — otherwise the `@` belongs to the URL's authority
23
+ * (`git@github.com:…`). A consequence: refs containing a slash
24
+ * (`release/1.0`) cannot be written in the string form; pin to a tag or a
25
+ * commit sha instead. The admin portal takes the URL and the ref as separate
26
+ * inputs and assembles a canonical string, so this only constrains
27
+ * hand-edited settings.
28
+ */
29
+ import { isAbsolute, resolve } from "node:path";
30
+ const PROTOCOL_PREFIXES = ["https://", "http://", "ssh://", "git://", "file://"];
31
+ const SCP_LIKE = /^[^@/\s]+@[^:/\s]+:/;
32
+ /**
33
+ * Parse a source string. Throws with a user-facing message rather than
34
+ * returning undefined: every caller (portal, settings load, CLI) needs to tell
35
+ * the human what was wrong with what they typed.
36
+ */
37
+ export function parseSource(source) {
38
+ const trimmed = source.trim();
39
+ if (!trimmed)
40
+ throw new Error("Package source is empty");
41
+ const { rest: withoutSubpath, subpath } = splitSubpath(trimmed);
42
+ const { rest: locator, ref } = splitRef(withoutSubpath);
43
+ if (locator.startsWith("github:")) {
44
+ const repo = stripGitSuffix(locator.slice("github:".length).replace(/^\/+/, ""));
45
+ if (!repo.includes("/")) {
46
+ throw new Error(`github: source must be owner/repo, got ${JSON.stringify(locator)}`);
47
+ }
48
+ return git(`https://github.com/${repo}.git`, ref, subpath);
49
+ }
50
+ if (locator.startsWith("git:")) {
51
+ const inner = locator.slice("git:".length);
52
+ if (isProtocolUrl(inner) || SCP_LIKE.test(inner))
53
+ return git(inner, ref, subpath);
54
+ // Shorthand: host/owner/repo — only meaningful with the git: prefix,
55
+ // since bare host/owner/repo is ambiguous with a relative path.
56
+ if (!inner.includes("/")) {
57
+ throw new Error(`git: source must include a path, got ${JSON.stringify(locator)}`);
58
+ }
59
+ return git(`https://${stripGitSuffix(inner)}.git`, ref, subpath);
60
+ }
61
+ if (isProtocolUrl(locator) || SCP_LIKE.test(locator))
62
+ return git(locator, ref, subpath);
63
+ if (isAbsolute(locator) || locator.startsWith("./") || locator.startsWith("../")) {
64
+ if (ref)
65
+ throw new Error("A local path source cannot carry an @ref");
66
+ if (subpath)
67
+ throw new Error("A local path source cannot carry a #subpath");
68
+ return { type: "local", path: resolve(locator) };
69
+ }
70
+ throw new Error(`Unrecognized package source ${JSON.stringify(source)}. ` +
71
+ "Use a git URL, github:owner/repo, git:host/owner/repo, or an absolute/relative path.");
72
+ }
73
+ function git(url, ref, subpath) {
74
+ return { type: "git", url, ...(ref ? { ref } : {}), ...(subpath ? { subpath } : {}) };
75
+ }
76
+ function isProtocolUrl(value) {
77
+ return PROTOCOL_PREFIXES.some((prefix) => value.startsWith(prefix));
78
+ }
79
+ function stripGitSuffix(value) {
80
+ return value.replace(/\.git$/, "").replace(/\/+$/, "");
81
+ }
82
+ function splitSubpath(source) {
83
+ const hash = source.indexOf("#");
84
+ if (hash === -1)
85
+ return { rest: source };
86
+ const subpath = source.slice(hash + 1).trim();
87
+ if (!subpath)
88
+ return { rest: source.slice(0, hash) };
89
+ assertSafeRelativePath(subpath, "#subpath");
90
+ return { rest: source.slice(0, hash), subpath };
91
+ }
92
+ /**
93
+ * Split a trailing `@ref`. The `@` in `git@github.com:owner/repo` is part of
94
+ * the authority, not a ref, so a candidate only counts when its suffix looks
95
+ * like a bare ref (no `/`, no `:`).
96
+ */
97
+ function splitRef(source) {
98
+ const at = source.lastIndexOf("@");
99
+ if (at <= 0)
100
+ return { rest: source };
101
+ const candidate = source.slice(at + 1);
102
+ if (!candidate || candidate.includes("/") || candidate.includes(":"))
103
+ return { rest: source };
104
+ return { rest: source.slice(0, at), ref: candidate };
105
+ }
106
+ /** Reject traversal and absolute escapes in the parts that become paths. */
107
+ function assertSafeRelativePath(value, label) {
108
+ if (isAbsolute(value) || value.split(/[\\/]/).some((segment) => segment === "..")) {
109
+ throw new Error(`${label} must be a relative path without '..': ${JSON.stringify(value)}`);
110
+ }
111
+ }
112
+ /**
113
+ * Identity of the package a source refers to — the key for deduplication and
114
+ * for letting a conversation's copy shadow the global one.
115
+ *
116
+ * Deliberate choices:
117
+ * - The ref is excluded: the same repo pinned to two refs in two scopes is one
118
+ * package installed twice, and the narrower scope wins.
119
+ * - The subpath is included: two extensions living at different paths in one
120
+ * monorepo are two packages.
121
+ * - Transport is excluded: `git@github.com:o/r`, `https://github.com/o/r.git`
122
+ * and `ssh://git@github.com/o/r` all identify the same package, so mixing
123
+ * SSH and HTTPS spellings across scopes still dedups.
124
+ */
125
+ export function sourceIdentity(parsed) {
126
+ if (parsed.type === "local")
127
+ return `local:${parsed.path}`;
128
+ const repo = gitRepoPath(parsed.url);
129
+ return parsed.subpath ? `git:${repo}#${parsed.subpath}` : `git:${repo}`;
130
+ }
131
+ /**
132
+ * Transport-independent `<host>/<path>` of a git URL, lowercased host, no
133
+ * `.git` suffix, no credentials. It is the base of the on-disk clone layout,
134
+ * so it must stay free of anything that is not a safe path segment.
135
+ */
136
+ export function gitRepoPath(url) {
137
+ let remainder = url;
138
+ for (const prefix of PROTOCOL_PREFIXES) {
139
+ if (remainder.startsWith(prefix)) {
140
+ remainder = remainder.slice(prefix.length);
141
+ break;
142
+ }
143
+ }
144
+ // Drop any credentials in the authority (`user:pass@host`, `git@host`).
145
+ const scpMatch = /^([^@/\s]+@)?([^:/\s]+)[:/](.+)$/.exec(remainder);
146
+ if (!scpMatch)
147
+ return sanitizeRepoPath(stripGitSuffix(remainder));
148
+ const host = scpMatch[2].toLowerCase();
149
+ const path = stripGitSuffix(scpMatch[3].replace(/^\/+/, ""));
150
+ return sanitizeRepoPath(`${host}/${path}`);
151
+ }
152
+ /**
153
+ * `file://` URLs used in tests and local mirrors have no host, so the repo path
154
+ * is an absolute filesystem path. Keep every segment filesystem-safe and drop
155
+ * traversal, since this string becomes a directory under the state dir.
156
+ */
157
+ function sanitizeRepoPath(value) {
158
+ const segments = value
159
+ .split(/[\\/]/)
160
+ .map((segment) => segment.replace(/[^A-Za-z0-9._-]+/g, "-").replace(/^\.+$/, ""))
161
+ .filter((segment) => segment.length > 0);
162
+ if (segments.length === 0)
163
+ throw new Error(`Cannot derive a package path from ${value}`);
164
+ return segments.join("/");
165
+ }
166
+ /**
167
+ * Canonical string form, used when writing settings so the stored value is
168
+ * stable regardless of how the human spelled it.
169
+ */
170
+ export function formatSource(parsed) {
171
+ if (parsed.type === "local")
172
+ return parsed.path;
173
+ const ref = parsed.ref ? `@${parsed.ref}` : "";
174
+ const subpath = parsed.subpath ? `#${parsed.subpath}` : "";
175
+ return `${parsed.url}${ref}${subpath}`;
176
+ }
177
+ //# sourceMappingURL=source.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"source.js","sourceRoot":"","sources":["../../src/packages/source.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The package source grammar: one place that turns a human-written source\n * string into a {@link ParsedSource}, and one place that decides when two\n * sources are the same package ({@link sourceIdentity}).\n *\n * Only git and local-path sources are implemented. The tagged union and the\n * identity function are the seams a future `npm:` source slots into: adding it\n * means a new arm here and a new materializer, with nothing downstream —\n * resolution, scope precedence, the portal — needing to know.\n *\n * Grammar:\n *\n * <locator>[@<ref>][#<subpath>]\n *\n * locator: https://… http://… ssh://… git://… file://…\n * git@host:owner/repo\n * git:<any of the above, or host/owner/repo shorthand>\n * github:owner/repo\n * /abs/path ./rel/path (local, used by reference)\n *\n * `@<ref>` is recognized only when what follows the last `@` contains no `/`\n * and no `:` — otherwise the `@` belongs to the URL's authority\n * (`git@github.com:…`). A consequence: refs containing a slash\n * (`release/1.0`) cannot be written in the string form; pin to a tag or a\n * commit sha instead. The admin portal takes the URL and the ref as separate\n * inputs and assembles a canonical string, so this only constrains\n * hand-edited settings.\n */\nimport { isAbsolute, resolve } from \"node:path\";\nimport type { PackageIdentity, ParsedSource } from \"./types.js\";\n\nconst PROTOCOL_PREFIXES = [\"https://\", \"http://\", \"ssh://\", \"git://\", \"file://\"];\nconst SCP_LIKE = /^[^@/\\s]+@[^:/\\s]+:/;\n\n/**\n * Parse a source string. Throws with a user-facing message rather than\n * returning undefined: every caller (portal, settings load, CLI) needs to tell\n * the human what was wrong with what they typed.\n */\nexport function parseSource(source: string): ParsedSource {\n const trimmed = source.trim();\n if (!trimmed) throw new Error(\"Package source is empty\");\n\n const { rest: withoutSubpath, subpath } = splitSubpath(trimmed);\n const { rest: locator, ref } = splitRef(withoutSubpath);\n\n if (locator.startsWith(\"github:\")) {\n const repo = stripGitSuffix(locator.slice(\"github:\".length).replace(/^\\/+/, \"\"));\n if (!repo.includes(\"/\")) {\n throw new Error(`github: source must be owner/repo, got ${JSON.stringify(locator)}`);\n }\n return git(`https://github.com/${repo}.git`, ref, subpath);\n }\n\n if (locator.startsWith(\"git:\")) {\n const inner = locator.slice(\"git:\".length);\n if (isProtocolUrl(inner) || SCP_LIKE.test(inner)) return git(inner, ref, subpath);\n // Shorthand: host/owner/repo — only meaningful with the git: prefix,\n // since bare host/owner/repo is ambiguous with a relative path.\n if (!inner.includes(\"/\")) {\n throw new Error(`git: source must include a path, got ${JSON.stringify(locator)}`);\n }\n return git(`https://${stripGitSuffix(inner)}.git`, ref, subpath);\n }\n\n if (isProtocolUrl(locator) || SCP_LIKE.test(locator)) return git(locator, ref, subpath);\n\n if (isAbsolute(locator) || locator.startsWith(\"./\") || locator.startsWith(\"../\")) {\n if (ref) throw new Error(\"A local path source cannot carry an @ref\");\n if (subpath) throw new Error(\"A local path source cannot carry a #subpath\");\n return { type: \"local\", path: resolve(locator) };\n }\n\n throw new Error(\n `Unrecognized package source ${JSON.stringify(source)}. ` +\n \"Use a git URL, github:owner/repo, git:host/owner/repo, or an absolute/relative path.\",\n );\n}\n\nfunction git(url: string, ref: string | undefined, subpath: string | undefined): ParsedSource {\n return { type: \"git\", url, ...(ref ? { ref } : {}), ...(subpath ? { subpath } : {}) };\n}\n\nfunction isProtocolUrl(value: string): boolean {\n return PROTOCOL_PREFIXES.some((prefix) => value.startsWith(prefix));\n}\n\nfunction stripGitSuffix(value: string): string {\n return value.replace(/\\.git$/, \"\").replace(/\\/+$/, \"\");\n}\n\nfunction splitSubpath(source: string): { rest: string; subpath?: string } {\n const hash = source.indexOf(\"#\");\n if (hash === -1) return { rest: source };\n const subpath = source.slice(hash + 1).trim();\n if (!subpath) return { rest: source.slice(0, hash) };\n assertSafeRelativePath(subpath, \"#subpath\");\n return { rest: source.slice(0, hash), subpath };\n}\n\n/**\n * Split a trailing `@ref`. The `@` in `git@github.com:owner/repo` is part of\n * the authority, not a ref, so a candidate only counts when its suffix looks\n * like a bare ref (no `/`, no `:`).\n */\nfunction splitRef(source: string): { rest: string; ref?: string } {\n const at = source.lastIndexOf(\"@\");\n if (at <= 0) return { rest: source };\n const candidate = source.slice(at + 1);\n if (!candidate || candidate.includes(\"/\") || candidate.includes(\":\")) return { rest: source };\n return { rest: source.slice(0, at), ref: candidate };\n}\n\n/** Reject traversal and absolute escapes in the parts that become paths. */\nfunction assertSafeRelativePath(value: string, label: string): void {\n if (isAbsolute(value) || value.split(/[\\\\/]/).some((segment) => segment === \"..\")) {\n throw new Error(`${label} must be a relative path without '..': ${JSON.stringify(value)}`);\n }\n}\n\n/**\n * Identity of the package a source refers to — the key for deduplication and\n * for letting a conversation's copy shadow the global one.\n *\n * Deliberate choices:\n * - The ref is excluded: the same repo pinned to two refs in two scopes is one\n * package installed twice, and the narrower scope wins.\n * - The subpath is included: two extensions living at different paths in one\n * monorepo are two packages.\n * - Transport is excluded: `git@github.com:o/r`, `https://github.com/o/r.git`\n * and `ssh://git@github.com/o/r` all identify the same package, so mixing\n * SSH and HTTPS spellings across scopes still dedups.\n */\nexport function sourceIdentity(parsed: ParsedSource): PackageIdentity {\n if (parsed.type === \"local\") return `local:${parsed.path}`;\n const repo = gitRepoPath(parsed.url);\n return parsed.subpath ? `git:${repo}#${parsed.subpath}` : `git:${repo}`;\n}\n\n/**\n * Transport-independent `<host>/<path>` of a git URL, lowercased host, no\n * `.git` suffix, no credentials. It is the base of the on-disk clone layout,\n * so it must stay free of anything that is not a safe path segment.\n */\nexport function gitRepoPath(url: string): string {\n let remainder = url;\n for (const prefix of PROTOCOL_PREFIXES) {\n if (remainder.startsWith(prefix)) {\n remainder = remainder.slice(prefix.length);\n break;\n }\n }\n // Drop any credentials in the authority (`user:pass@host`, `git@host`).\n const scpMatch = /^([^@/\\s]+@)?([^:/\\s]+)[:/](.+)$/.exec(remainder);\n if (!scpMatch) return sanitizeRepoPath(stripGitSuffix(remainder));\n const host = scpMatch[2].toLowerCase();\n const path = stripGitSuffix(scpMatch[3].replace(/^\\/+/, \"\"));\n return sanitizeRepoPath(`${host}/${path}`);\n}\n\n/**\n * `file://` URLs used in tests and local mirrors have no host, so the repo path\n * is an absolute filesystem path. Keep every segment filesystem-safe and drop\n * traversal, since this string becomes a directory under the state dir.\n */\nfunction sanitizeRepoPath(value: string): string {\n const segments = value\n .split(/[\\\\/]/)\n .map((segment) => segment.replace(/[^A-Za-z0-9._-]+/g, \"-\").replace(/^\\.+$/, \"\"))\n .filter((segment) => segment.length > 0);\n if (segments.length === 0) throw new Error(`Cannot derive a package path from ${value}`);\n return segments.join(\"/\");\n}\n\n/**\n * Canonical string form, used when writing settings so the stored value is\n * stable regardless of how the human spelled it.\n */\nexport function formatSource(parsed: ParsedSource): string {\n if (parsed.type === \"local\") return parsed.path;\n const ref = parsed.ref ? `@${parsed.ref}` : \"\";\n const subpath = parsed.subpath ? `#${parsed.subpath}` : \"\";\n return `${parsed.url}${ref}${subpath}`;\n}\n"]}
@@ -0,0 +1,104 @@
1
+ /**
2
+ * A package source as written by a human: the string stored in `packages[]`
3
+ * in global or conversation settings, and the string typed into the admin
4
+ * portal. Parsing it is {@link parseSource}'s job.
5
+ */
6
+ export type PackageSourceString = string;
7
+ /** Scope a package belongs to. `global` spans every conversation. */
8
+ export type PackageScope = "global" | "conversation";
9
+ /**
10
+ * A git source. `ref` is a tag, branch, or commit — absent means "whatever the
11
+ * remote's default branch points at now", which only moves on an explicit
12
+ * update. `subpath` addresses a package inside a larger repository.
13
+ */
14
+ interface GitSource {
15
+ type: "git";
16
+ /** Clone URL handed to `git`, after shorthand expansion. */
17
+ url: string;
18
+ ref?: string;
19
+ subpath?: string;
20
+ }
21
+ /**
22
+ * A directory on the mikan host, used by reference — never copied. Editing the
23
+ * directory is picked up by the next harness instance, which is what makes
24
+ * host-side development of an extension bearable.
25
+ */
26
+ interface LocalSource {
27
+ type: "local";
28
+ path: string;
29
+ }
30
+ export type ParsedSource = GitSource | LocalSource;
31
+ /**
32
+ * Stable identity of a package, independent of version and of the scope it is
33
+ * installed in. Two sources with the same identity are the same package, so
34
+ * the conversation scope's copy can shadow the global one.
35
+ *
36
+ * Deliberately excludes the ref: `…/repo@v1` in global and `…/repo@v2` in a
37
+ * conversation are one package pinned two ways, and the conversation wins.
38
+ */
39
+ export type PackageIdentity = string;
40
+ /** Where a materialized package's files live, plus how it got there. */
41
+ export interface MaterializedPackage {
42
+ source: PackageSourceString;
43
+ parsed: ParsedSource;
44
+ identity: PackageIdentity;
45
+ /**
46
+ * Directory holding the package's files. For git this is inside the state
47
+ * dir (a clone, plus `subpath`); for local it is the referenced path itself.
48
+ */
49
+ dir: string;
50
+ scope: PackageScope;
51
+ }
52
+ /** A source that failed to materialize, reported back to whoever asked. */
53
+ export interface PackageError {
54
+ source: PackageSourceString;
55
+ message: string;
56
+ }
57
+ export interface ResolvedPackages {
58
+ packages: MaterializedPackage[];
59
+ extensionDirs: string[];
60
+ extensionRoots: string[];
61
+ skillDirs: PackageSkillDir[];
62
+ errors: PackageError[];
63
+ }
64
+ export interface PackageSkillDir {
65
+ slug: string;
66
+ dir: string;
67
+ }
68
+ export interface ResolvePackagesOptions {
69
+ conversationId: string;
70
+ stateDir: string;
71
+ conversationDir: string;
72
+ fetchMissing?: boolean;
73
+ }
74
+ export type MaterializeMode = "offline" | "fetch" | "refresh";
75
+ export interface MaterializeOptions {
76
+ scope: PackageScope;
77
+ conversationId?: string;
78
+ stateDir: string;
79
+ mode?: MaterializeMode;
80
+ }
81
+ export interface PackageStatus {
82
+ source: string;
83
+ scope: PackageScope;
84
+ ready: boolean;
85
+ error?: string;
86
+ dir?: string;
87
+ shadowed?: boolean;
88
+ extensions: string[];
89
+ skills: string[];
90
+ }
91
+ export interface PackageInventory {
92
+ global: PackageStatus[];
93
+ conversation: PackageStatus[];
94
+ }
95
+ export interface PackageAdminContext extends ResolvePackagesOptions {
96
+ workingDir: string;
97
+ runtime?: import("../types.js").RunnerCacheControl & import("../types.js").GlobalRunnerCacheControl;
98
+ }
99
+ export interface PackageWriteResult {
100
+ source: string;
101
+ dir: string;
102
+ }
103
+ export {};
104
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/packages/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,MAAM,mBAAmB,GAAG,MAAM,CAAC;AAEzC,qEAAqE;AACrE,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,cAAc,CAAC;AAErD;;;;GAIG;AACH,UAAU,SAAS;IACjB,IAAI,EAAE,KAAK,CAAC;IACZ,4DAA4D;IAC5D,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;GAIG;AACH,UAAU,WAAW;IACnB,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,WAAW,CAAC;AAEnD;;;;;;;GAOG;AACH,MAAM,MAAM,eAAe,GAAG,MAAM,CAAC;AAErC,wEAAwE;AACxE,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,mBAAmB,CAAC;IAC5B,MAAM,EAAE,YAAY,CAAC;IACrB,QAAQ,EAAE,eAAe,CAAC;IAC1B;;;OAGG;IACH,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,YAAY,CAAC;CACrB;AAED,2EAA2E;AAC3E,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,mBAAmB,CAAC;IAC5B,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,mBAAmB,EAAE,CAAC;IAChC,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,SAAS,EAAE,eAAe,EAAE,CAAC;IAC7B,MAAM,EAAE,YAAY,EAAE,CAAC;CACxB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,sBAAsB;IACrC,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;AAE9D,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,YAAY,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,eAAe,CAAC;CACxB;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,YAAY,CAAC;IACpB,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,aAAa,EAAE,CAAC;IACxB,YAAY,EAAE,aAAa,EAAE,CAAC;CAC/B;AAED,MAAM,WAAW,mBAAoB,SAAQ,sBAAsB;IACjE,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,aAAa,EAAE,kBAAkB,GAChD,OAAO,aAAa,EAAE,wBAAwB,CAAC;CAClD;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;CACb"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/packages/types.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * A package source as written by a human: the string stored in `packages[]`\n * in global or conversation settings, and the string typed into the admin\n * portal. Parsing it is {@link parseSource}'s job.\n */\nexport type PackageSourceString = string;\n\n/** Scope a package belongs to. `global` spans every conversation. */\nexport type PackageScope = \"global\" | \"conversation\";\n\n/**\n * A git source. `ref` is a tag, branch, or commit — absent means \"whatever the\n * remote's default branch points at now\", which only moves on an explicit\n * update. `subpath` addresses a package inside a larger repository.\n */\ninterface GitSource {\n type: \"git\";\n /** Clone URL handed to `git`, after shorthand expansion. */\n url: string;\n ref?: string;\n subpath?: string;\n}\n\n/**\n * A directory on the mikan host, used by reference — never copied. Editing the\n * directory is picked up by the next harness instance, which is what makes\n * host-side development of an extension bearable.\n */\ninterface LocalSource {\n type: \"local\";\n path: string;\n}\n\nexport type ParsedSource = GitSource | LocalSource;\n\n/**\n * Stable identity of a package, independent of version and of the scope it is\n * installed in. Two sources with the same identity are the same package, so\n * the conversation scope's copy can shadow the global one.\n *\n * Deliberately excludes the ref: `…/repo@v1` in global and `…/repo@v2` in a\n * conversation are one package pinned two ways, and the conversation wins.\n */\nexport type PackageIdentity = string;\n\n/** Where a materialized package's files live, plus how it got there. */\nexport interface MaterializedPackage {\n source: PackageSourceString;\n parsed: ParsedSource;\n identity: PackageIdentity;\n /**\n * Directory holding the package's files. For git this is inside the state\n * dir (a clone, plus `subpath`); for local it is the referenced path itself.\n */\n dir: string;\n scope: PackageScope;\n}\n\n/** A source that failed to materialize, reported back to whoever asked. */\nexport interface PackageError {\n source: PackageSourceString;\n message: string;\n}\n\nexport interface ResolvedPackages {\n packages: MaterializedPackage[];\n extensionDirs: string[];\n extensionRoots: string[];\n skillDirs: PackageSkillDir[];\n errors: PackageError[];\n}\n\nexport interface PackageSkillDir {\n slug: string;\n dir: string;\n}\n\nexport interface ResolvePackagesOptions {\n conversationId: string;\n stateDir: string;\n conversationDir: string;\n fetchMissing?: boolean;\n}\n\nexport type MaterializeMode = \"offline\" | \"fetch\" | \"refresh\";\n\nexport interface MaterializeOptions {\n scope: PackageScope;\n conversationId?: string;\n stateDir: string;\n mode?: MaterializeMode;\n}\n\nexport interface PackageStatus {\n source: string;\n scope: PackageScope;\n ready: boolean;\n error?: string;\n dir?: string;\n shadowed?: boolean;\n extensions: string[];\n skills: string[];\n}\n\nexport interface PackageInventory {\n global: PackageStatus[];\n conversation: PackageStatus[];\n}\n\nexport interface PackageAdminContext extends ResolvePackagesOptions {\n workingDir: string;\n runtime?: import(\"../types.js\").RunnerCacheControl &\n import(\"../types.js\").GlobalRunnerCacheControl;\n}\n\nexport interface PackageWriteResult {\n source: string;\n dir: string;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"provisioner.d.ts","sourceRoot":"","sources":["../src/provisioner.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"provisioner.d.ts","sourceRoot":"","sources":["../src/provisioner.ts"],"names":[],"mappings":"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"}