@geminixiang/mikan 1.0.0-beta.94 → 1.0.0-beta.96

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 (198) hide show
  1. package/CHANGELOG.md +432 -378
  2. package/README.md +31 -40
  3. package/dist/adapters/commands/login.js +1 -1
  4. package/dist/adapters/commands/login.js.map +1 -1
  5. package/dist/adapters/commands/registry.d.ts +1 -1
  6. package/dist/adapters/commands/registry.d.ts.map +1 -1
  7. package/dist/adapters/commands/registry.js +1 -2
  8. package/dist/adapters/commands/registry.js.map +1 -1
  9. package/dist/adapters/commands/types.d.ts +2 -4
  10. package/dist/adapters/commands/types.d.ts.map +1 -1
  11. package/dist/adapters/commands/types.js.map +1 -1
  12. package/dist/adapters/github/bot.js +1 -1
  13. package/dist/adapters/github/bot.js.map +1 -1
  14. package/dist/adapters/github/policy.d.ts +2 -9
  15. package/dist/adapters/github/policy.d.ts.map +1 -1
  16. package/dist/adapters/github/policy.js +18 -26
  17. package/dist/adapters/github/policy.js.map +1 -1
  18. package/dist/adapters/slack/bot.d.ts +2 -4
  19. package/dist/adapters/slack/bot.d.ts.map +1 -1
  20. package/dist/adapters/slack/bot.js +28 -56
  21. package/dist/adapters/slack/bot.js.map +1 -1
  22. package/dist/adapters/slack/socket-agent.d.ts +9 -0
  23. package/dist/adapters/slack/socket-agent.d.ts.map +1 -0
  24. package/dist/adapters/slack/socket-agent.js +17 -0
  25. package/dist/adapters/slack/socket-agent.js.map +1 -0
  26. package/dist/adapters/telegram/bot.d.ts +1 -0
  27. package/dist/adapters/telegram/bot.d.ts.map +1 -1
  28. package/dist/adapters/telegram/bot.js +6 -1
  29. package/dist/adapters/telegram/bot.js.map +1 -1
  30. package/dist/adapters/telegram/types.d.ts +1 -0
  31. package/dist/adapters/telegram/types.d.ts.map +1 -1
  32. package/dist/adapters/telegram/types.js.map +1 -1
  33. package/dist/adapters/web/admin/portal.d.ts.map +1 -1
  34. package/dist/adapters/web/admin/portal.js +92 -173
  35. package/dist/adapters/web/admin/portal.js.map +1 -1
  36. package/dist/adapters/web/admin/types.d.ts +3 -8
  37. package/dist/adapters/web/admin/types.d.ts.map +1 -1
  38. package/dist/adapters/web/admin/types.js.map +1 -1
  39. package/dist/adapters/web/server.d.ts +1 -1
  40. package/dist/adapters/web/server.d.ts.map +1 -1
  41. package/dist/adapters/web/server.js.map +1 -1
  42. package/dist/cli/arg-grammar.d.ts +1 -3
  43. package/dist/cli/arg-grammar.d.ts.map +1 -1
  44. package/dist/cli/arg-grammar.js +2 -20
  45. package/dist/cli/arg-grammar.js.map +1 -1
  46. package/dist/cli/boot.d.ts.map +1 -1
  47. package/dist/cli/boot.js +5 -11
  48. package/dist/cli/boot.js.map +1 -1
  49. package/dist/cli/migrate.d.ts.map +1 -1
  50. package/dist/cli/migrate.js +22 -7
  51. package/dist/cli/migrate.js.map +1 -1
  52. package/dist/cli/office.d.ts.map +1 -1
  53. package/dist/cli/office.js +3 -5
  54. package/dist/cli/office.js.map +1 -1
  55. package/dist/cli/onboard.js +18 -20
  56. package/dist/cli/onboard.js.map +1 -1
  57. package/dist/cli/types.d.ts +1 -2
  58. package/dist/cli/types.d.ts.map +1 -1
  59. package/dist/cli/types.js.map +1 -1
  60. package/dist/env-manifest.d.ts +2 -1
  61. package/dist/env-manifest.d.ts.map +1 -1
  62. package/dist/env-manifest.js +76 -47
  63. package/dist/env-manifest.js.map +1 -1
  64. package/dist/events/index.d.ts +5 -5
  65. package/dist/events/index.d.ts.map +1 -1
  66. package/dist/events/index.js +1 -7
  67. package/dist/events/index.js.map +1 -1
  68. package/dist/file-guards.d.ts +1 -0
  69. package/dist/file-guards.d.ts.map +1 -1
  70. package/dist/file-guards.js +4 -1
  71. package/dist/file-guards.js.map +1 -1
  72. package/dist/harness/execution-resolver.d.ts.map +1 -1
  73. package/dist/harness/execution-resolver.js +2 -8
  74. package/dist/harness/execution-resolver.js.map +1 -1
  75. package/dist/harness/http.d.ts +1 -2
  76. package/dist/harness/http.d.ts.map +1 -1
  77. package/dist/harness/http.js +3 -16
  78. package/dist/harness/http.js.map +1 -1
  79. package/dist/harness/jev.d.ts +2 -1
  80. package/dist/harness/jev.d.ts.map +1 -1
  81. package/dist/harness/jev.js.map +1 -1
  82. package/dist/harness/models.d.ts +2 -2
  83. package/dist/harness/models.d.ts.map +1 -1
  84. package/dist/harness/models.js +4 -6
  85. package/dist/harness/models.js.map +1 -1
  86. package/dist/harness/prompt.d.ts.map +1 -1
  87. package/dist/harness/prompt.js +0 -6
  88. package/dist/harness/prompt.js.map +1 -1
  89. package/dist/harness/runner.js +1 -2
  90. package/dist/harness/runner.js.map +1 -1
  91. package/dist/harness/session.d.ts +2 -9
  92. package/dist/harness/session.d.ts.map +1 -1
  93. package/dist/harness/session.js +3 -3
  94. package/dist/harness/session.js.map +1 -1
  95. package/dist/harness/tools/event.d.ts +0 -1
  96. package/dist/harness/tools/event.d.ts.map +1 -1
  97. package/dist/harness/tools/event.js +1 -7
  98. package/dist/harness/tools/event.js.map +1 -1
  99. package/dist/harness/types.d.ts +4 -4
  100. package/dist/harness/types.d.ts.map +1 -1
  101. package/dist/harness/types.js.map +1 -1
  102. package/dist/index.d.ts +8 -31
  103. package/dist/index.d.ts.map +1 -1
  104. package/dist/index.js +3 -15
  105. package/dist/index.js.map +1 -1
  106. package/dist/main.js +29 -41
  107. package/dist/main.js.map +1 -1
  108. package/dist/migrations/index.d.ts +0 -1
  109. package/dist/migrations/index.d.ts.map +1 -1
  110. package/dist/migrations/index.js +4 -10
  111. package/dist/migrations/index.js.map +1 -1
  112. package/dist/migrations/legacy-office-files.d.ts +3 -0
  113. package/dist/migrations/legacy-office-files.d.ts.map +1 -0
  114. package/dist/migrations/legacy-office-files.js +29 -0
  115. package/dist/migrations/legacy-office-files.js.map +1 -0
  116. package/dist/migrations/session-v3.d.ts +57 -0
  117. package/dist/migrations/session-v3.d.ts.map +1 -0
  118. package/dist/migrations/session-v3.js +93 -0
  119. package/dist/migrations/session-v3.js.map +1 -0
  120. package/dist/migrations/sessions-sqlite.d.ts.map +1 -1
  121. package/dist/migrations/sessions-sqlite.js +98 -54
  122. package/dist/migrations/sessions-sqlite.js.map +1 -1
  123. package/dist/observability/instrument.js +2 -5
  124. package/dist/observability/instrument.js.map +1 -1
  125. package/dist/observability/sentry.js +1 -1
  126. package/dist/observability/sentry.js.map +1 -1
  127. package/dist/office/projection.js +2 -2
  128. package/dist/office/projection.js.map +1 -1
  129. package/dist/runtime/conversation-runtime.js +9 -14
  130. package/dist/runtime/conversation-runtime.js.map +1 -1
  131. package/dist/runtime/types.d.ts +2 -7
  132. package/dist/runtime/types.d.ts.map +1 -1
  133. package/dist/runtime/types.js.map +1 -1
  134. package/dist/sandbox/identity.d.ts +0 -1
  135. package/dist/sandbox/identity.d.ts.map +1 -1
  136. package/dist/sandbox/identity.js +0 -3
  137. package/dist/sandbox/identity.js.map +1 -1
  138. package/dist/sandbox/registry.d.ts +1 -5
  139. package/dist/sandbox/registry.d.ts.map +1 -1
  140. package/dist/sandbox/registry.js +4 -13
  141. package/dist/sandbox/registry.js.map +1 -1
  142. package/dist/sandbox/types.d.ts +1 -5
  143. package/dist/sandbox/types.d.ts.map +1 -1
  144. package/dist/sandbox/types.js.map +1 -1
  145. package/dist/sessions/types.d.ts +1 -1
  146. package/dist/sessions/types.d.ts.map +1 -1
  147. package/dist/sessions/types.js.map +1 -1
  148. package/dist/settings/apply.d.ts +1 -1
  149. package/dist/settings/apply.d.ts.map +1 -1
  150. package/dist/settings/apply.js +4 -5
  151. package/dist/settings/apply.js.map +1 -1
  152. package/dist/settings/index.d.ts +59 -5
  153. package/dist/settings/index.d.ts.map +1 -1
  154. package/dist/settings/index.js +75 -54
  155. package/dist/settings/index.js.map +1 -1
  156. package/dist/types.d.ts +3 -28
  157. package/dist/types.d.ts.map +1 -1
  158. package/dist/types.js.map +1 -1
  159. package/dist/vault/index.d.ts.map +1 -1
  160. package/dist/vault/index.js +2 -15
  161. package/dist/vault/index.js.map +1 -1
  162. package/package.json +4 -17
  163. package/dist/cli/download.d.ts +0 -2
  164. package/dist/cli/download.d.ts.map +0 -1
  165. package/dist/cli/download.js +0 -84
  166. package/dist/cli/download.js.map +0 -1
  167. package/dist/harness/index.d.ts +0 -20
  168. package/dist/harness/index.d.ts.map +0 -1
  169. package/dist/harness/index.js +0 -14
  170. package/dist/harness/index.js.map +0 -1
  171. package/dist/migrations/dream-checkpoints.d.ts +0 -3
  172. package/dist/migrations/dream-checkpoints.d.ts.map +0 -1
  173. package/dist/migrations/dream-checkpoints.js +0 -23
  174. package/dist/migrations/dream-checkpoints.js.map +0 -1
  175. package/dist/migrations/private-office-dirs.d.ts +0 -3
  176. package/dist/migrations/private-office-dirs.d.ts.map +0 -1
  177. package/dist/migrations/private-office-dirs.js +0 -24
  178. package/dist/migrations/private-office-dirs.js.map +0 -1
  179. package/dist/migrations/session-files.d.ts +0 -28
  180. package/dist/migrations/session-files.d.ts.map +0 -1
  181. package/dist/migrations/session-files.js +0 -80
  182. package/dist/migrations/session-files.js.map +0 -1
  183. package/dist/migrations/session-v4.d.ts +0 -77
  184. package/dist/migrations/session-v4.d.ts.map +0 -1
  185. package/dist/migrations/session-v4.js +0 -177
  186. package/dist/migrations/session-v4.js.map +0 -1
  187. package/dist/migrations/sessions-v3.d.ts +0 -8
  188. package/dist/migrations/sessions-v3.d.ts.map +0 -1
  189. package/dist/migrations/sessions-v3.js +0 -350
  190. package/dist/migrations/sessions-v3.js.map +0 -1
  191. package/dist/sandbox/cloudflare.d.ts +0 -17
  192. package/dist/sandbox/cloudflare.d.ts.map +0 -1
  193. package/dist/sandbox/cloudflare.js +0 -142
  194. package/dist/sandbox/cloudflare.js.map +0 -1
  195. package/dist/sandbox/index.d.ts +0 -7
  196. package/dist/sandbox/index.d.ts.map +0 -1
  197. package/dist/sandbox/index.js +0 -6
  198. package/dist/sandbox/index.js.map +0 -1
@@ -1,4 +1,4 @@
1
- import type { MessagingBot, OfficeAddress, PlatformName, RunningSession } from "../../../types.js";
1
+ import type { GlobalRunnerCacheControl, MessagingBot, PlatformName, RunnerCacheControl, RunningSession } from "../../../types.js";
2
2
  import type { Office, Workspace } from "../../../office/types.js";
3
3
  import type { LinkTokenStoreLike } from "../../commands/types.js";
4
4
  import type { SandboxConfig } from "../../../sandbox/types.js";
@@ -6,20 +6,15 @@ import type { EventStore } from "../../../events/index.js";
6
6
  import type { InMemorySessionViewTokenStore } from "../session-view/portal.js";
7
7
  import type { TokenRecord } from "../types.js";
8
8
  import type { InMemoryAdminTokenStore } from "./portal.js";
9
- export interface AdminRuntimeBridge {
9
+ export interface AdminRuntimeBridge extends RunnerCacheControl, GlobalRunnerCacheControl {
10
10
  getRunningSessions(): RunningSession[];
11
- switchConversationModel(address: OfficeAddress, provider: string, model: string): boolean;
12
- refreshConversationEnvironment(address: OfficeAddress): boolean;
13
- refreshAllConversations(): {
14
- busy: OfficeAddress[];
15
- };
16
11
  }
17
12
  export interface AdminServices {
18
13
  linkTokenStore: LinkTokenStoreLike;
19
14
  sessionViewTokenStore?: InMemorySessionViewTokenStore;
20
15
  adminTokenStore: InMemoryAdminTokenStore;
21
16
  portalBaseUrl?: string;
22
- workspace?: Workspace;
17
+ workspace: Workspace;
23
18
  eventStore?: (office: Office) => EventStore;
24
19
  sandbox?: SandboxConfig;
25
20
  runtime?: AdminRuntimeBridge;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/adapters/web/admin/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnG,OAAO,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,2BAA2B,CAAC;AAC/E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAE3D,MAAM,WAAW,kBAAkB;IACjC,kBAAkB,IAAI,cAAc,EAAE,CAAC;IACvC,uBAAuB,CAAC,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;IAC1F,8BAA8B,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC;IAChE,uBAAuB,IAAI;QAAE,IAAI,EAAE,aAAa,EAAE,CAAA;KAAE,CAAC;CACtD;AAED,MAAM,WAAW,aAAa;IAC5B,cAAc,EAAE,kBAAkB,CAAC;IACnC,qBAAqB,CAAC,EAAE,6BAA6B,CAAC;IACtD,eAAe,EAAE,uBAAuB,CAAC;IACzC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,UAAU,CAAC;IAC5C,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,OAAO,CAAC,EAAE,kBAAkB,CAAC;IAC7B,cAAc,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC,CAAC;CAC9D;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAClB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE,YAAY,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,UAAW,SAAQ,WAAW;IAC7C,QAAQ,EAAE,YAAY,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,cAAc,EAAE,MAAM,CAAC;CACxB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/adapters/web/admin/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,wBAAwB,EACxB,YAAY,EACZ,YAAY,EACZ,kBAAkB,EAClB,cAAc,EACf,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,2BAA2B,CAAC;AAC/E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAE3D,MAAM,WAAW,kBAAmB,SAAQ,kBAAkB,EAAE,wBAAwB;IACtF,kBAAkB,IAAI,cAAc,EAAE,CAAC;CACxC;AAED,MAAM,WAAW,aAAa;IAC5B,cAAc,EAAE,kBAAkB,CAAC;IACnC,qBAAqB,CAAC,EAAE,6BAA6B,CAAC;IACtD,eAAe,EAAE,uBAAuB,CAAC;IACzC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,SAAS,CAAC;IACrB,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,UAAU,CAAC;IAC5C,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,OAAO,CAAC,EAAE,kBAAkB,CAAC;IAC7B,cAAc,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC,CAAC;CAC9D;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAClB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE,YAAY,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,UAAW,SAAQ,WAAW;IAC7C,QAAQ,EAAE,YAAY,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,cAAc,EAAE,MAAM,CAAC;CACxB"}
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/adapters/web/admin/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { MessagingBot, OfficeAddress, PlatformName, RunningSession } from \"../../../types.js\";\nimport type { Office, Workspace } from \"../../../office/types.js\";\nimport type { LinkTokenStoreLike } from \"../../commands/types.js\";\nimport type { SandboxConfig } from \"../../../sandbox/types.js\";\nimport type { EventStore } from \"../../../events/index.js\";\nimport type { InMemorySessionViewTokenStore } from \"../session-view/portal.js\";\nimport type { TokenRecord } from \"../types.js\";\nimport type { InMemoryAdminTokenStore } from \"./portal.js\";\n\nexport interface AdminRuntimeBridge {\n getRunningSessions(): RunningSession[];\n switchConversationModel(address: OfficeAddress, provider: string, model: string): boolean;\n refreshConversationEnvironment(address: OfficeAddress): boolean;\n refreshAllConversations(): { busy: OfficeAddress[] };\n}\n\nexport interface AdminServices {\n linkTokenStore: LinkTokenStoreLike;\n sessionViewTokenStore?: InMemorySessionViewTokenStore;\n adminTokenStore: InMemoryAdminTokenStore;\n portalBaseUrl?: string;\n workspace?: Workspace;\n eventStore?: (office: Office) => EventStore;\n sandbox?: SandboxConfig;\n runtime?: AdminRuntimeBridge;\n botsByPlatform?: Partial<Record<PlatformName, MessagingBot>>;\n}\n\nexport interface EventSummary {\n name: string;\n size: number;\n mtimeMs: number;\n type: string | null;\n officePlatform: string;\n officeConversationId: string;\n platform: string | null;\n conversationId: string | null;\n text: string | null;\n at: string | null;\n schedule: string | null;\n timezone: string | null;\n}\n\nexport interface AdminTokenCreateOptions {\n platform: PlatformName;\n platformUserId: string;\n conversationId: string;\n platformUserName?: string;\n}\n\nexport interface AdminToken extends TokenRecord {\n platform: PlatformName;\n platformUserId: string;\n platformUserName?: string;\n conversationId: string;\n}\n"]}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/adapters/web/admin/types.ts"],"names":[],"mappings":"","sourcesContent":["import type {\n GlobalRunnerCacheControl,\n MessagingBot,\n PlatformName,\n RunnerCacheControl,\n RunningSession,\n} from \"../../../types.js\";\nimport type { Office, Workspace } from \"../../../office/types.js\";\nimport type { LinkTokenStoreLike } from \"../../commands/types.js\";\nimport type { SandboxConfig } from \"../../../sandbox/types.js\";\nimport type { EventStore } from \"../../../events/index.js\";\nimport type { InMemorySessionViewTokenStore } from \"../session-view/portal.js\";\nimport type { TokenRecord } from \"../types.js\";\nimport type { InMemoryAdminTokenStore } from \"./portal.js\";\n\nexport interface AdminRuntimeBridge extends RunnerCacheControl, GlobalRunnerCacheControl {\n getRunningSessions(): RunningSession[];\n}\n\nexport interface AdminServices {\n linkTokenStore: LinkTokenStoreLike;\n sessionViewTokenStore?: InMemorySessionViewTokenStore;\n adminTokenStore: InMemoryAdminTokenStore;\n portalBaseUrl?: string;\n workspace: Workspace;\n eventStore?: (office: Office) => EventStore;\n sandbox?: SandboxConfig;\n runtime?: AdminRuntimeBridge;\n botsByPlatform?: Partial<Record<PlatformName, MessagingBot>>;\n}\n\nexport interface EventSummary {\n name: string;\n size: number;\n mtimeMs: number;\n type: string | null;\n officePlatform: string;\n officeConversationId: string;\n platform: string | null;\n conversationId: string | null;\n text: string | null;\n at: string | null;\n schedule: string | null;\n timezone: string | null;\n}\n\nexport interface AdminTokenCreateOptions {\n platform: PlatformName;\n platformUserId: string;\n conversationId: string;\n platformUserName?: string;\n}\n\nexport interface AdminToken extends TokenRecord {\n platform: PlatformName;\n platformUserId: string;\n platformUserName?: string;\n conversationId: string;\n}\n"]}
@@ -21,7 +21,7 @@ interface StartWebServerOptions {
21
21
  sessionViewInteractive?: SessionViewInteractiveOptions;
22
22
  adminOptions?: {
23
23
  adminTokenStore: InMemoryAdminTokenStore;
24
- workspace?: Workspace;
24
+ workspace: Workspace;
25
25
  runtime?: AdminRuntimeBridge;
26
26
  sandbox?: SandboxConfig;
27
27
  botsByPlatform?: Partial<Record<PlatformName, MessagingBot>>;
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../src/adapters/web/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsC,KAAK,MAAM,EAAuB,MAAM,WAAW,CAAC;AACjG,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAGjE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAoB,KAAK,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AACjF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEzD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAGjE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAChE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEjD,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,yBAAyB,CAAC;AAC7E,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,0BAA0B,CAAC;AAC9E,OAAO,KAAK,EAAU,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAE/D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAG/D,UAAU,qBAAqB;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,sBAAsB,CAAC;IACvC,YAAY,EAAE,YAAY,CAAC;IAC3B,MAAM,EAAE,QAAQ,CAAC;IACjB,qBAAqB,CAAC,EAAE,6BAA6B,CAAC;IACtD,sBAAsB,CAAC,EAAE,6BAA6B,CAAC;IACvD,YAAY,CAAC,EAAE;QACb,eAAe,EAAE,uBAAuB,CAAC;QACzC,SAAS,CAAC,EAAE,SAAS,CAAC;QACtB,OAAO,CAAC,EAAE,kBAAkB,CAAC;QAC7B,OAAO,CAAC,EAAE,aAAa,CAAC;QACxB,cAAc,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC,CAAC;QAC7D,cAAc,CAAC,EAAE,MAAM,iBAAiB,GAAG,SAAS,CAAC;KACtD,CAAC;IACF,aAAa,CAAC,EAAE,oBAAoB,CAAC;CACtC;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,qBAAqB,GAAG,MAAM,CAuFrE;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAO7E"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../src/adapters/web/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsC,KAAK,MAAM,EAAuB,MAAM,WAAW,CAAC;AACjG,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAGjE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAoB,KAAK,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AACjF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEzD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAGjE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAChE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEjD,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,yBAAyB,CAAC;AAC7E,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,0BAA0B,CAAC;AAC9E,OAAO,KAAK,EAAU,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAE/D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAG/D,UAAU,qBAAqB;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,sBAAsB,CAAC;IACvC,YAAY,EAAE,YAAY,CAAC;IAC3B,MAAM,EAAE,QAAQ,CAAC;IACjB,qBAAqB,CAAC,EAAE,6BAA6B,CAAC;IACtD,sBAAsB,CAAC,EAAE,6BAA6B,CAAC;IACvD,YAAY,CAAC,EAAE;QACb,eAAe,EAAE,uBAAuB,CAAC;QACzC,SAAS,EAAE,SAAS,CAAC;QACrB,OAAO,CAAC,EAAE,kBAAkB,CAAC;QAC7B,OAAO,CAAC,EAAE,aAAa,CAAC;QACxB,cAAc,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC,CAAC;QAC7D,cAAc,CAAC,EAAE,MAAM,iBAAiB,GAAG,SAAS,CAAC;KACtD,CAAC;IACF,aAAa,CAAC,EAAE,oBAAoB,CAAC;CACtC;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,qBAAqB,GAAG,MAAM,CAuFrE;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAO7E"}
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../../../src/adapters/web/server.ts"],"names":[],"mappings":"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","sourcesContent":["import { createServer, type IncomingMessage, type Server, type ServerResponse } from \"node:http\";\nimport type { MessagingBot, PlatformName } from \"../../types.js\";\nimport { resolveLinkBaseUrl } from \"../../env-manifest.js\";\nimport * as log from \"../../log.js\";\nimport type { SandboxConfig } from \"../../sandbox/types.js\";\nimport { OfficeEventStore, type EventScheduleSink } from \"../../events/index.js\";\nimport type { VaultManager } from \"../../vault/types.js\";\nimport { handleAdminRequest } from \"./admin/portal.js\";\nimport type { AdminRuntimeBridge } from \"./admin/types.js\";\nimport type { InMemoryAdminTokenStore } from \"./admin/portal.js\";\nimport { createLoginRequestHandler } from \"./login/portal.js\";\nimport { requestBaseUrl } from \"./portal-shell.js\";\nimport type { InMemoryLinkTokenStore } from \"./login/portal.js\";\nimport type { NotifyFn } from \"./login/types.js\";\nimport { handleSessionViewRequest } from \"./session-view/portal.js\";\nimport type { SessionViewInteractiveOptions } from \"./session-view/types.js\";\nimport type { InMemorySessionViewTokenStore } from \"./session-view/portal.js\";\nimport type { Office, Workspace } from \"../../office/types.js\";\nimport { createGithubWebhookHandler } from \"../github/webhook.js\";\nimport type { GithubWebhookOptions } from \"../github/types.js\";\nimport { errorMessage } from \"../../unknown-values.js\";\n\ninterface StartWebServerOptions {\n port: number;\n host: string;\n linkTokenStore: InMemoryLinkTokenStore;\n vaultManager: VaultManager;\n notify: NotifyFn;\n sessionViewTokenStore?: InMemorySessionViewTokenStore;\n sessionViewInteractive?: SessionViewInteractiveOptions;\n adminOptions?: {\n adminTokenStore: InMemoryAdminTokenStore;\n workspace?: Workspace;\n runtime?: AdminRuntimeBridge;\n sandbox?: SandboxConfig;\n botsByPlatform?: Partial<Record<PlatformName, MessagingBot>>;\n eventScheduler?: () => EventScheduleSink | undefined;\n };\n githubWebhook?: GithubWebhookOptions;\n}\n\nexport function startWebServer(options: StartWebServerOptions): Server {\n const loginHandler = createLoginRequestHandler(\n options.linkTokenStore,\n options.vaultManager,\n options.notify,\n );\n\n const adminEventStore = (office: Office) =>\n new OfficeEventStore(office, options.adminOptions?.eventScheduler?.());\n\n const githubWebhook = options.githubWebhook\n ? createGithubWebhookHandler(options.githubWebhook)\n : undefined;\n\n const server = createServer(async (req: IncomingMessage, res: ServerResponse) => {\n try {\n const url = new URL(req.url ?? \"/\", requestBaseUrl(req));\n\n if (req.method === \"GET\" && url.pathname === \"/health\") {\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ ok: true }));\n return;\n }\n\n if (githubWebhook && (await githubWebhook(req, res, url))) {\n return;\n }\n\n const adminOptions = options.adminOptions;\n if (\n adminOptions?.adminTokenStore &&\n (await handleAdminRequest(req, res, url, {\n linkTokenStore: options.linkTokenStore,\n sessionViewTokenStore: options.sessionViewTokenStore,\n adminTokenStore: adminOptions.adminTokenStore,\n portalBaseUrl: resolveLinkBaseUrl() ?? undefined,\n workspace: adminOptions.workspace,\n eventStore: adminEventStore,\n runtime: adminOptions.runtime,\n sandbox: adminOptions.sandbox,\n botsByPlatform: adminOptions.botsByPlatform,\n }))\n ) {\n return;\n }\n\n if (\n await handleSessionViewRequest(\n req,\n res,\n url,\n options.sessionViewTokenStore,\n options.sessionViewInteractive,\n )\n ) {\n return;\n }\n\n if (loginHandler(req, res, url)) return;\n\n res.writeHead(404);\n res.end();\n } catch (err) {\n log.logWarning(\"Web server request error\", errorMessage(err));\n if (!res.headersSent) {\n res.writeHead(500, { \"Content-Type\": \"application/json\" });\n }\n res.end(JSON.stringify({ error: \"Internal server error\" }));\n }\n });\n\n server.listen(options.port, options.host, () => {\n log.logInfo(`Web server listening on ${options.host}:${options.port}`);\n if (!resolveLinkBaseUrl()) {\n log.logWarning(\n \"MIKAN_LINK_URL is not set — OAuth redirect_uri will be \" +\n \"derived from request headers (Host / X-Forwarded-*). Set \" +\n \"MIKAN_LINK_URL=https://your-host.example.com for production.\",\n );\n }\n });\n\n server.on(\"error\", (err) => {\n log.logWarning(\"Web server error\", err.message);\n });\n\n return server;\n}\n\nexport function closeWebServer(server: Server, graceMs: number): Promise<void> {\n const closed = new Promise<void>((resolve, reject) => {\n server.close((error) => (error ? reject(error) : resolve()));\n });\n server.closeIdleConnections();\n const forceClose = setTimeout(() => server.closeAllConnections(), graceMs);\n return closed.finally(() => clearTimeout(forceClose));\n}\n"]}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../../src/adapters/web/server.ts"],"names":[],"mappings":"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","sourcesContent":["import { createServer, type IncomingMessage, type Server, type ServerResponse } from \"node:http\";\nimport type { MessagingBot, PlatformName } from \"../../types.js\";\nimport { resolveLinkBaseUrl } from \"../../env-manifest.js\";\nimport * as log from \"../../log.js\";\nimport type { SandboxConfig } from \"../../sandbox/types.js\";\nimport { OfficeEventStore, type EventScheduleSink } from \"../../events/index.js\";\nimport type { VaultManager } from \"../../vault/types.js\";\nimport { handleAdminRequest } from \"./admin/portal.js\";\nimport type { AdminRuntimeBridge } from \"./admin/types.js\";\nimport type { InMemoryAdminTokenStore } from \"./admin/portal.js\";\nimport { createLoginRequestHandler } from \"./login/portal.js\";\nimport { requestBaseUrl } from \"./portal-shell.js\";\nimport type { InMemoryLinkTokenStore } from \"./login/portal.js\";\nimport type { NotifyFn } from \"./login/types.js\";\nimport { handleSessionViewRequest } from \"./session-view/portal.js\";\nimport type { SessionViewInteractiveOptions } from \"./session-view/types.js\";\nimport type { InMemorySessionViewTokenStore } from \"./session-view/portal.js\";\nimport type { Office, Workspace } from \"../../office/types.js\";\nimport { createGithubWebhookHandler } from \"../github/webhook.js\";\nimport type { GithubWebhookOptions } from \"../github/types.js\";\nimport { errorMessage } from \"../../unknown-values.js\";\n\ninterface StartWebServerOptions {\n port: number;\n host: string;\n linkTokenStore: InMemoryLinkTokenStore;\n vaultManager: VaultManager;\n notify: NotifyFn;\n sessionViewTokenStore?: InMemorySessionViewTokenStore;\n sessionViewInteractive?: SessionViewInteractiveOptions;\n adminOptions?: {\n adminTokenStore: InMemoryAdminTokenStore;\n workspace: Workspace;\n runtime?: AdminRuntimeBridge;\n sandbox?: SandboxConfig;\n botsByPlatform?: Partial<Record<PlatformName, MessagingBot>>;\n eventScheduler?: () => EventScheduleSink | undefined;\n };\n githubWebhook?: GithubWebhookOptions;\n}\n\nexport function startWebServer(options: StartWebServerOptions): Server {\n const loginHandler = createLoginRequestHandler(\n options.linkTokenStore,\n options.vaultManager,\n options.notify,\n );\n\n const adminEventStore = (office: Office) =>\n new OfficeEventStore(office, options.adminOptions?.eventScheduler?.());\n\n const githubWebhook = options.githubWebhook\n ? createGithubWebhookHandler(options.githubWebhook)\n : undefined;\n\n const server = createServer(async (req: IncomingMessage, res: ServerResponse) => {\n try {\n const url = new URL(req.url ?? \"/\", requestBaseUrl(req));\n\n if (req.method === \"GET\" && url.pathname === \"/health\") {\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ ok: true }));\n return;\n }\n\n if (githubWebhook && (await githubWebhook(req, res, url))) {\n return;\n }\n\n const adminOptions = options.adminOptions;\n if (\n adminOptions?.adminTokenStore &&\n (await handleAdminRequest(req, res, url, {\n linkTokenStore: options.linkTokenStore,\n sessionViewTokenStore: options.sessionViewTokenStore,\n adminTokenStore: adminOptions.adminTokenStore,\n portalBaseUrl: resolveLinkBaseUrl() ?? undefined,\n workspace: adminOptions.workspace,\n eventStore: adminEventStore,\n runtime: adminOptions.runtime,\n sandbox: adminOptions.sandbox,\n botsByPlatform: adminOptions.botsByPlatform,\n }))\n ) {\n return;\n }\n\n if (\n await handleSessionViewRequest(\n req,\n res,\n url,\n options.sessionViewTokenStore,\n options.sessionViewInteractive,\n )\n ) {\n return;\n }\n\n if (loginHandler(req, res, url)) return;\n\n res.writeHead(404);\n res.end();\n } catch (err) {\n log.logWarning(\"Web server request error\", errorMessage(err));\n if (!res.headersSent) {\n res.writeHead(500, { \"Content-Type\": \"application/json\" });\n }\n res.end(JSON.stringify({ error: \"Internal server error\" }));\n }\n });\n\n server.listen(options.port, options.host, () => {\n log.logInfo(`Web server listening on ${options.host}:${options.port}`);\n if (!resolveLinkBaseUrl()) {\n log.logWarning(\n \"MIKAN_LINK_URL is not set — OAuth redirect_uri will be \" +\n \"derived from request headers (Host / X-Forwarded-*). Set \" +\n \"MIKAN_LINK_URL=https://your-host.example.com for production.\",\n );\n }\n });\n\n server.on(\"error\", (err) => {\n log.logWarning(\"Web server error\", err.message);\n });\n\n return server;\n}\n\nexport function closeWebServer(server: Server, graceMs: number): Promise<void> {\n const closed = new Promise<void>((resolve, reject) => {\n server.close((error) => (error ? reject(error) : resolve()));\n });\n server.closeIdleConnections();\n const forceClose = setTimeout(() => server.closeAllConnections(), graceMs);\n return closed.finally(() => clearTimeout(forceClose));\n}\n"]}
@@ -2,7 +2,5 @@ import { Command } from "commander";
2
2
  export declare function cliCommand(name: string): Command;
3
3
  export declare function nonEmptyValue(value: string): string;
4
4
  export declare function commandExitCode(error: unknown, command: Command): number;
5
- export declare function defaultStateDir(): string;
6
- export declare function resolveStateDir(args?: string[], envValue?: string | undefined): string;
7
- export declare function effectiveStateDir(): string;
5
+ export declare function stateDirPath(): string;
8
6
  //# sourceMappingURL=arg-grammar.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"arg-grammar.d.ts","sourceRoot":"","sources":["../../src/cli/arg-grammar.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAwC,MAAM,WAAW,CAAC;AAK1E,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAQhD;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAKnD;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,GAAG,MAAM,CAIxE;AAED,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAED,wBAAgB,eAAe,CAC7B,IAAI,GAAE,MAAM,EAA0B,EACtC,QAAQ,GAAE,MAAM,GAAG,SAAgC,GAClD,MAAM,CAaR;AAED,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C"}
1
+ {"version":3,"file":"arg-grammar.d.ts","sourceRoot":"","sources":["../../src/cli/arg-grammar.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAwC,MAAM,WAAW,CAAC;AAI1E,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAQhD;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAKnD;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,GAAG,MAAM,CAIxE;AAED,wBAAgB,YAAY,IAAI,MAAM,CAErC"}
@@ -1,7 +1,6 @@
1
1
  import { Command, CommanderError, InvalidArgumentError } from "commander";
2
2
  import { homedir } from "node:os";
3
- import { join, resolve } from "node:path";
4
- import { readEnv } from "../env-manifest.js";
3
+ import { join } from "node:path";
5
4
  export function cliCommand(name) {
6
5
  return new Command(name)
7
6
  .configureHelp({ showGlobalOptions: true })
@@ -24,24 +23,7 @@ export function commandExitCode(error, command) {
24
23
  console.error(`${error.message}\n${command.helpInformation()}`);
25
24
  return error.exitCode;
26
25
  }
27
- export function defaultStateDir() {
26
+ export function stateDirPath() {
28
27
  return join(homedir(), ".mikan");
29
28
  }
30
- export function resolveStateDir(args = process.argv.slice(2), envValue = readEnv("STATE_DIR")) {
31
- const command = cliCommand("mikan")
32
- .helpOption(false)
33
- .allowUnknownOption()
34
- .allowExcessArguments()
35
- .option("--state-dir <dir>", "State directory", nonEmptyValue);
36
- command.parse(args, { from: "user" });
37
- const { stateDir } = command.opts();
38
- return stateDir !== undefined
39
- ? resolve(stateDir)
40
- : envValue
41
- ? resolve(envValue)
42
- : defaultStateDir();
43
- }
44
- export function effectiveStateDir() {
45
- return resolveStateDir([]);
46
- }
47
29
  //# sourceMappingURL=arg-grammar.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"arg-grammar.js","sourceRoot":"","sources":["../../src/cli/arg-grammar.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AAC1E,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAE7C,MAAM,UAAU,UAAU,CAAC,IAAY;IACrC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;SACrB,aAAa,CAAC,EAAE,iBAAiB,EAAE,IAAI,EAAE,CAAC;SAC1C,YAAY,EAAE;SACd,eAAe,CAAC;QACf,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;QAC/C,QAAQ,EAAE,GAAG,EAAE,GAAE,CAAC;KACnB,CAAC,CAAC;AACP,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,KAAa;IACzC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC3C,MAAM,IAAI,oBAAoB,CAAC,2CAA2C,CAAC,CAAC;IAC9E,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,KAAc,EAAE,OAAgB;IAC9D,IAAI,CAAC,CAAC,KAAK,YAAY,cAAc,CAAC;QAAE,MAAM,KAAK,CAAC;IACpD,IAAI,KAAK,CAAC,QAAQ,KAAK,CAAC;QAAE,OAAO,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,OAAO,KAAK,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC;IAC1F,OAAO,KAAK,CAAC,QAAQ,CAAC;AACxB,CAAC;AAED,MAAM,UAAU,eAAe;IAC7B,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,QAAQ,CAAC,CAAC;AACnC,CAAC;AAED,MAAM,UAAU,eAAe,CAC7B,IAAI,GAAa,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EACtC,QAAQ,GAAuB,OAAO,CAAC,WAAW,CAAC;IAEnD,MAAM,OAAO,GAAG,UAAU,CAAC,OAAO,CAAC;SAChC,UAAU,CAAC,KAAK,CAAC;SACjB,kBAAkB,EAAE;SACpB,oBAAoB,EAAE;SACtB,MAAM,CAAC,mBAAmB,EAAE,iBAAiB,EAAE,aAAa,CAAC,CAAC;IACjE,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;IACtC,MAAM,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,IAAI,EAAyB,CAAC;IAC3D,OAAO,QAAQ,KAAK,SAAS;QAC3B,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC;QACnB,CAAC,CAAC,QAAQ;YACR,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC;YACnB,CAAC,CAAC,eAAe,EAAE,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,iBAAiB;IAC/B,OAAO,eAAe,CAAC,EAAE,CAAC,CAAC;AAC7B,CAAC","sourcesContent":["import { Command, CommanderError, InvalidArgumentError } from \"commander\";\nimport { homedir } from \"node:os\";\nimport { join, resolve } from \"node:path\";\nimport { readEnv } from \"../env-manifest.js\";\n\nexport function cliCommand(name: string): Command {\n return new Command(name)\n .configureHelp({ showGlobalOptions: true })\n .exitOverride()\n .configureOutput({\n writeOut: (text) => console.log(text.trimEnd()),\n writeErr: () => {},\n });\n}\n\nexport function nonEmptyValue(value: string): string {\n if (!value.trim() || value.startsWith(\"-\")) {\n throw new InvalidArgumentError(\"expected a non-empty value, not an option\");\n }\n return value;\n}\n\nexport function commandExitCode(error: unknown, command: Command): number {\n if (!(error instanceof CommanderError)) throw error;\n if (error.exitCode !== 0) console.error(`${error.message}\\n${command.helpInformation()}`);\n return error.exitCode;\n}\n\nexport function defaultStateDir(): string {\n return join(homedir(), \".mikan\");\n}\n\nexport function resolveStateDir(\n args: string[] = process.argv.slice(2),\n envValue: string | undefined = readEnv(\"STATE_DIR\"),\n): string {\n const command = cliCommand(\"mikan\")\n .helpOption(false)\n .allowUnknownOption()\n .allowExcessArguments()\n .option(\"--state-dir <dir>\", \"State directory\", nonEmptyValue);\n command.parse(args, { from: \"user\" });\n const { stateDir } = command.opts<{ stateDir?: string }>();\n return stateDir !== undefined\n ? resolve(stateDir)\n : envValue\n ? resolve(envValue)\n : defaultStateDir();\n}\n\nexport function effectiveStateDir(): string {\n return resolveStateDir([]);\n}\n"]}
1
+ {"version":3,"file":"arg-grammar.js","sourceRoot":"","sources":["../../src/cli/arg-grammar.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AAC1E,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,MAAM,UAAU,UAAU,CAAC,IAAY;IACrC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;SACrB,aAAa,CAAC,EAAE,iBAAiB,EAAE,IAAI,EAAE,CAAC;SAC1C,YAAY,EAAE;SACd,eAAe,CAAC;QACf,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;QAC/C,QAAQ,EAAE,GAAG,EAAE,GAAE,CAAC;KACnB,CAAC,CAAC;AACP,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,KAAa;IACzC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC3C,MAAM,IAAI,oBAAoB,CAAC,2CAA2C,CAAC,CAAC;IAC9E,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,KAAc,EAAE,OAAgB;IAC9D,IAAI,CAAC,CAAC,KAAK,YAAY,cAAc,CAAC;QAAE,MAAM,KAAK,CAAC;IACpD,IAAI,KAAK,CAAC,QAAQ,KAAK,CAAC;QAAE,OAAO,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,OAAO,KAAK,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC;IAC1F,OAAO,KAAK,CAAC,QAAQ,CAAC;AACxB,CAAC;AAED,MAAM,UAAU,YAAY;IAC1B,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,QAAQ,CAAC,CAAC;AACnC,CAAC","sourcesContent":["import { Command, CommanderError, InvalidArgumentError } from \"commander\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\nexport function cliCommand(name: string): Command {\n return new Command(name)\n .configureHelp({ showGlobalOptions: true })\n .exitOverride()\n .configureOutput({\n writeOut: (text) => console.log(text.trimEnd()),\n writeErr: () => {},\n });\n}\n\nexport function nonEmptyValue(value: string): string {\n if (!value.trim() || value.startsWith(\"-\")) {\n throw new InvalidArgumentError(\"expected a non-empty value, not an option\");\n }\n return value;\n}\n\nexport function commandExitCode(error: unknown, command: Command): number {\n if (!(error instanceof CommanderError)) throw error;\n if (error.exitCode !== 0) console.error(`${error.message}\\n${command.helpInformation()}`);\n return error.exitCode;\n}\n\nexport function stateDirPath(): string {\n return join(homedir(), \".mikan\");\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"boot.d.ts","sourceRoot":"","sources":["../../src/cli/boot.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAgC3C,wBAAgB,WAAW,CAAC,IAAI,GAAE,MAAM,EAA0B,GAAG,QAAQ,CAoB5E;AAyBD,wBAAgB,QAAQ,IAAI,MAAM,CAcjC"}
1
+ {"version":3,"file":"boot.d.ts","sourceRoot":"","sources":["../../src/cli/boot.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAwB3C,wBAAgB,WAAW,CAAC,IAAI,GAAE,MAAM,EAA0B,GAAG,QAAQ,CAkB5E;AAwBD,wBAAgB,QAAQ,IAAI,MAAM,CAcjC"}
package/dist/cli/boot.js CHANGED
@@ -1,16 +1,14 @@
1
1
  import { join, resolve } from "node:path";
2
2
  import { envSummaryLines } from "../env-manifest.js";
3
3
  import { parseSandboxArg } from "../sandbox/registry.js";
4
- import { cliCommand, defaultStateDir, nonEmptyValue, resolveStateDir } from "./arg-grammar.js";
4
+ import { cliCommand, nonEmptyValue, stateDirPath } from "./arg-grammar.js";
5
5
  const SUBCOMMANDS = ["migrate", "office", "env"];
6
6
  function bootCommand() {
7
7
  return cliCommand("mikan")
8
8
  .description("Multi-platform chat agent daemon")
9
9
  .helpOption(false)
10
- .argument("[working-directory...]", "Workspace directory (default: <state-dir>/workspace)")
11
- .option("--state-dir <dir>", "State directory (default: ~/.mikan)", nonEmptyValue)
12
- .option("--sandbox <spec>", "host | container:<name> | image:<image[:tag]> | cloudflare:<id>", nonEmptyValue)
13
- .option("--download <channel>", "Dump a Slack channel's history, then exit", nonEmptyValue)
10
+ .argument("[working-directory...]", "Workspace directory (default: ~/.mikan/workspace)")
11
+ .option("--sandbox <spec>", "host | container:<name> | image:<image[:tag]>", nonEmptyValue)
14
12
  .option("--onboard", "Interactive first-run setup (also: mikan onboard)")
15
13
  .option("-v, --version", "Print version")
16
14
  .option("-V", "Print version")
@@ -25,23 +23,21 @@ export function resolveBoot(args = process.argv.slice(2)) {
25
23
  const options = command.opts();
26
24
  const onboardFirst = args[0] === "onboard";
27
25
  const workingDirArg = (onboardFirst ? command.args.slice(1) : command.args).at(-1);
28
- const downloadChannel = options.download;
29
26
  const sandboxArg = options.sandbox;
30
- const stateDir = resolveStateDir(args);
27
+ const stateDir = stateDirPath();
31
28
  return {
32
29
  mode: bootMode({ ...options, version: options.version || options.V }, onboardFirst),
33
30
  stateDir,
34
31
  workingDir: workingDirArg ? resolve(workingDirArg) : join(stateDir, "workspace"),
35
32
  workingDirExplicit: workingDirArg !== undefined,
36
33
  sandbox: sandboxArg === undefined ? { type: "host" } : parseSandboxArg(sandboxArg),
37
- downloadChannel,
38
34
  };
39
35
  }
40
36
  function subcommandPlan(args) {
41
37
  const mode = SUBCOMMANDS.find((name) => name === args[0]);
42
38
  if (!mode)
43
39
  return undefined;
44
- const stateDir = defaultStateDir();
40
+ const stateDir = stateDirPath();
45
41
  return {
46
42
  mode,
47
43
  migrateArgs: mode === "migrate" ? args.slice(1) : undefined,
@@ -59,8 +55,6 @@ function bootMode(options, onboardFirst) {
59
55
  return "version";
60
56
  if (onboardFirst || options.onboard)
61
57
  return "onboard";
62
- if (options.download)
63
- return "download";
64
58
  return "run";
65
59
  }
66
60
  export function helpText() {
@@ -1 +1 @@
1
- {"version":3,"file":"boot.js","sourceRoot":"","sources":["../../src/cli/boot.ts"],"names":[],"mappings":"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","sourcesContent":["import { join, resolve } from \"node:path\";\nimport { envSummaryLines } from \"../env-manifest.js\";\nimport { parseSandboxArg } from \"../sandbox/registry.js\";\nimport type { BootPlan } from \"./types.js\";\nimport { cliCommand, defaultStateDir, nonEmptyValue, resolveStateDir } from \"./arg-grammar.js\";\n\nconst SUBCOMMANDS = [\"migrate\", \"office\", \"env\"] as const;\n\ninterface BootOptions {\n stateDir?: string;\n sandbox?: string;\n download?: string;\n help?: boolean;\n version?: boolean;\n onboard?: boolean;\n}\n\nfunction bootCommand() {\n return cliCommand(\"mikan\")\n .description(\"Multi-platform chat agent daemon\")\n .helpOption(false)\n .argument(\"[working-directory...]\", \"Workspace directory (default: <state-dir>/workspace)\")\n .option(\"--state-dir <dir>\", \"State directory (default: ~/.mikan)\", nonEmptyValue)\n .option(\n \"--sandbox <spec>\",\n \"host | container:<name> | image:<image[:tag]> | cloudflare:<id>\",\n nonEmptyValue,\n )\n .option(\"--download <channel>\", \"Dump a Slack channel's history, then exit\", nonEmptyValue)\n .option(\"--onboard\", \"Interactive first-run setup (also: mikan onboard)\")\n .option(\"-v, --version\", \"Print version\")\n .option(\"-V\", \"Print version\")\n .option(\"-h, --help\", \"Show help\");\n}\n\nexport function resolveBoot(args: string[] = process.argv.slice(2)): BootPlan {\n const routed = subcommandPlan(args);\n if (routed) return routed;\n\n const command = bootCommand();\n command.parse(args, { from: \"user\" });\n const options = command.opts<BootOptions & { V?: boolean }>();\n const onboardFirst = args[0] === \"onboard\";\n const workingDirArg = (onboardFirst ? command.args.slice(1) : command.args).at(-1);\n const downloadChannel = options.download;\n const sandboxArg = options.sandbox;\n const stateDir = resolveStateDir(args);\n return {\n mode: bootMode({ ...options, version: options.version || options.V }, onboardFirst),\n stateDir,\n workingDir: workingDirArg ? resolve(workingDirArg) : join(stateDir, \"workspace\"),\n workingDirExplicit: workingDirArg !== undefined,\n sandbox: sandboxArg === undefined ? { type: \"host\" } : parseSandboxArg(sandboxArg),\n downloadChannel,\n };\n}\n\nfunction subcommandPlan(args: string[]): BootPlan | undefined {\n const mode = SUBCOMMANDS.find((name) => name === args[0]);\n if (!mode) return undefined;\n const stateDir = defaultStateDir();\n return {\n mode,\n migrateArgs: mode === \"migrate\" ? args.slice(1) : undefined,\n officeArgs: mode === \"office\" ? args.slice(1) : undefined,\n stateDir,\n workingDir: join(stateDir, \"workspace\"),\n workingDirExplicit: false,\n sandbox: { type: \"host\" },\n };\n}\n\nfunction bootMode(options: BootOptions, onboardFirst: boolean): BootPlan[\"mode\"] {\n if (options.help) return \"help\";\n if (options.version) return \"version\";\n if (onboardFirst || options.onboard) return \"onboard\";\n if (options.download) return \"download\";\n return \"run\";\n}\n\nexport function helpText(): string {\n return (\n bootCommand().helpInformation() +\n `\nCommands:\n mikan migrate --sandbox <spec> [--dry-run] Apply pending state migrations (stop the daemon first).\n mikan office list List office keys with their platform and conversation id.\n mikan env Show environment-variable inventory.\n mikan onboard Interactive first-run setup.\n\nEnvironment (platform tokens select which chat adapters start):\n${envSummaryLines().join(\"\\n\")}\nRun mikan env for the full inventory.`\n );\n}\n"]}
1
+ {"version":3,"file":"boot.js","sourceRoot":"","sources":["../../src/cli/boot.ts"],"names":[],"mappings":"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","sourcesContent":["import { join, resolve } from \"node:path\";\nimport { envSummaryLines } from \"../env-manifest.js\";\nimport { parseSandboxArg } from \"../sandbox/registry.js\";\nimport type { BootPlan } from \"./types.js\";\nimport { cliCommand, nonEmptyValue, stateDirPath } from \"./arg-grammar.js\";\n\nconst SUBCOMMANDS = [\"migrate\", \"office\", \"env\"] as const;\n\ninterface BootOptions {\n sandbox?: string;\n help?: boolean;\n version?: boolean;\n onboard?: boolean;\n}\n\nfunction bootCommand() {\n return cliCommand(\"mikan\")\n .description(\"Multi-platform chat agent daemon\")\n .helpOption(false)\n .argument(\"[working-directory...]\", \"Workspace directory (default: ~/.mikan/workspace)\")\n .option(\"--sandbox <spec>\", \"host | container:<name> | image:<image[:tag]>\", nonEmptyValue)\n .option(\"--onboard\", \"Interactive first-run setup (also: mikan onboard)\")\n .option(\"-v, --version\", \"Print version\")\n .option(\"-V\", \"Print version\")\n .option(\"-h, --help\", \"Show help\");\n}\n\nexport function resolveBoot(args: string[] = process.argv.slice(2)): BootPlan {\n const routed = subcommandPlan(args);\n if (routed) return routed;\n\n const command = bootCommand();\n command.parse(args, { from: \"user\" });\n const options = command.opts<BootOptions & { V?: boolean }>();\n const onboardFirst = args[0] === \"onboard\";\n const workingDirArg = (onboardFirst ? command.args.slice(1) : command.args).at(-1);\n const sandboxArg = options.sandbox;\n const stateDir = stateDirPath();\n return {\n mode: bootMode({ ...options, version: options.version || options.V }, onboardFirst),\n stateDir,\n workingDir: workingDirArg ? resolve(workingDirArg) : join(stateDir, \"workspace\"),\n workingDirExplicit: workingDirArg !== undefined,\n sandbox: sandboxArg === undefined ? { type: \"host\" } : parseSandboxArg(sandboxArg),\n };\n}\n\nfunction subcommandPlan(args: string[]): BootPlan | undefined {\n const mode = SUBCOMMANDS.find((name) => name === args[0]);\n if (!mode) return undefined;\n const stateDir = stateDirPath();\n return {\n mode,\n migrateArgs: mode === \"migrate\" ? args.slice(1) : undefined,\n officeArgs: mode === \"office\" ? args.slice(1) : undefined,\n stateDir,\n workingDir: join(stateDir, \"workspace\"),\n workingDirExplicit: false,\n sandbox: { type: \"host\" },\n };\n}\n\nfunction bootMode(options: BootOptions, onboardFirst: boolean): BootPlan[\"mode\"] {\n if (options.help) return \"help\";\n if (options.version) return \"version\";\n if (onboardFirst || options.onboard) return \"onboard\";\n return \"run\";\n}\n\nexport function helpText(): string {\n return (\n bootCommand().helpInformation() +\n `\nCommands:\n mikan migrate --sandbox <spec> [--dry-run] Apply pending state migrations (stop the daemon first).\n mikan office list List office keys with their platform and conversation id.\n mikan env Show environment-variable inventory.\n mikan onboard Interactive first-run setup.\n\nEnvironment (platform tokens select which chat adapters start):\n${envSummaryLines().join(\"\\n\")}\nRun mikan env for the full inventory.`\n );\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"migrate.d.ts","sourceRoot":"","sources":["../../src/cli/migrate.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AA+BxD,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,MAAM,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,CAmD3F"}
1
+ {"version":3,"file":"migrate.d.ts","sourceRoot":"","sources":["../../src/cli/migrate.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AA4CxD,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,MAAM,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,CAsD3F"}
@@ -1,14 +1,16 @@
1
1
  import { execFile } from "node:child_process";
2
+ import { existsSync } from "node:fs";
2
3
  import { homedir } from "node:os";
3
4
  import { join, resolve } from "node:path";
4
5
  import { promisify } from "node:util";
5
6
  import { InvalidArgumentError } from "commander";
6
7
  import { platformIsActive, readEnv } from "../env-manifest.js";
7
- import { runMigrations } from "../migrations/index.js";
8
+ import { pendingMigrations, runMigrations } from "../migrations/index.js";
8
9
  import { parseSandboxArg } from "../sandbox/registry.js";
10
+ import { globalSettingsPath } from "../settings/index.js";
9
11
  import { assertPlatformName } from "../office/index.js";
10
12
  import { errorMessage } from "../unknown-values.js";
11
- import { cliCommand, commandExitCode, nonEmptyValue, resolveStateDir } from "./arg-grammar.js";
13
+ import { cliCommand, commandExitCode, nonEmptyValue, stateDirPath } from "./arg-grammar.js";
12
14
  const PLATFORMS = ["slack", "telegram", "discord", "github"];
13
15
  const execFileAsync = promisify(execFile);
14
16
  const dockerCli = async (args) => (await execFileAsync("docker", [...args])).stdout;
@@ -24,12 +26,20 @@ function collectOwner(value, owners) {
24
26
  }
25
27
  return owners;
26
28
  }
29
+ function assertInstallPaths(stateDir, workspaceRoot) {
30
+ const settingsPath = globalSettingsPath(stateDir);
31
+ if (!existsSync(settingsPath)) {
32
+ throw new Error(`No settings at ${settingsPath}; move the state directory the daemon ran with to ${stateDir}`);
33
+ }
34
+ if (!existsSync(workspaceRoot)) {
35
+ throw new Error(`Workspace ${workspaceRoot} does not exist; pass the working directory the daemon ran with as --workspace`);
36
+ }
37
+ }
27
38
  export async function runMigrateCommand(argv, docker = dockerCli) {
28
39
  const command = cliCommand("mikan migrate")
29
40
  .description("Apply pending state migrations (stop the daemon first)")
30
- .option("--state-dir <dir>", "State directory", nonEmptyValue)
31
- .option("--workspace <dir>", "Workspace directory (default: <state-dir>/workspace)")
32
- .requiredOption("--sandbox <spec>", "The daemon's --sandbox value: host | container:<name> | image:<image> | cloudflare:<id>", nonEmptyValue)
41
+ .option("--workspace <dir>", "Workspace directory (default: ~/.mikan/workspace)")
42
+ .requiredOption("--sandbox <spec>", "The daemon's --sandbox value: host | container:<name> | image:<image>", nonEmptyValue)
33
43
  .option("--dry-run", "List what each pending migration would change, without writing")
34
44
  .option("--owner <conversationId=platform>", "Owning platform for a legacy conversation directory (repeatable)", collectOwner, new Map());
35
45
  try {
@@ -39,12 +49,17 @@ export async function runMigrateCommand(argv, docker = dockerCli) {
39
49
  return commandExitCode(error, command);
40
50
  }
41
51
  const options = command.opts();
42
- const stateDir = resolveStateDir(argv);
52
+ const stateDir = stateDirPath();
43
53
  const dryRun = options.dryRun ?? false;
54
+ const workspaceRoot = options.workspace
55
+ ? resolve(options.workspace)
56
+ : join(stateDir, "workspace");
44
57
  try {
45
58
  const sandbox = parseSandboxArg(options.sandbox);
59
+ if (pendingMigrations(stateDir).length > 0)
60
+ assertInstallPaths(stateDir, workspaceRoot);
46
61
  const ran = await runMigrations({
47
- workspaceRoot: options.workspace ? resolve(options.workspace) : join(stateDir, "workspace"),
62
+ workspaceRoot,
48
63
  stateDir,
49
64
  dryRun,
50
65
  owners: options.owner,
@@ -1 +1 @@
1
- {"version":3,"file":"migrate.js","sourceRoot":"","sources":["../../src/cli/migrate.ts"],"names":[],"mappings":"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","sourcesContent":["import { execFile } from \"node:child_process\";\nimport { homedir } from \"node:os\";\nimport { join, resolve } from \"node:path\";\nimport { promisify } from \"node:util\";\nimport { InvalidArgumentError } from \"commander\";\nimport { platformIsActive, readEnv } from \"../env-manifest.js\";\nimport { runMigrations } from \"../migrations/index.js\";\nimport { parseSandboxArg } from \"../sandbox/registry.js\";\nimport type { DockerCli } from \"../migrations/types.js\";\nimport { assertPlatformName } from \"../office/index.js\";\nimport type { PlatformName } from \"../types.js\";\nimport { errorMessage } from \"../unknown-values.js\";\nimport { cliCommand, commandExitCode, nonEmptyValue, resolveStateDir } from \"./arg-grammar.js\";\n\nconst PLATFORMS: readonly PlatformName[] = [\"slack\", \"telegram\", \"discord\", \"github\"];\n\nconst execFileAsync = promisify(execFile);\n\nconst dockerCli: DockerCli = async (args) => (await execFileAsync(\"docker\", [...args])).stdout;\n\nfunction collectOwner(value: string, owners: Map<string, PlatformName>): Map<string, PlatformName> {\n const separator = value.lastIndexOf(\"=\");\n if (separator <= 0) throw new InvalidArgumentError(\"expected <conversationId>=<platform>\");\n try {\n owners.set(value.slice(0, separator), assertPlatformName(value.slice(separator + 1)));\n } catch (error) {\n throw new InvalidArgumentError(errorMessage(error));\n }\n return owners;\n}\n\ninterface MigrateOptions {\n stateDir?: string;\n workspace?: string;\n dryRun?: boolean;\n sandbox: string;\n owner: Map<string, PlatformName>;\n}\n\nexport async function runMigrateCommand(argv: string[], docker = dockerCli): Promise<number> {\n const command = cliCommand(\"mikan migrate\")\n .description(\"Apply pending state migrations (stop the daemon first)\")\n .option(\"--state-dir <dir>\", \"State directory\", nonEmptyValue)\n .option(\"--workspace <dir>\", \"Workspace directory (default: <state-dir>/workspace)\")\n .requiredOption(\n \"--sandbox <spec>\",\n \"The daemon's --sandbox value: host | container:<name> | image:<image> | cloudflare:<id>\",\n nonEmptyValue,\n )\n .option(\"--dry-run\", \"List what each pending migration would change, without writing\")\n .option(\n \"--owner <conversationId=platform>\",\n \"Owning platform for a legacy conversation directory (repeatable)\",\n collectOwner,\n new Map<string, PlatformName>(),\n );\n try {\n command.parse(argv, { from: \"user\" });\n } catch (error) {\n return commandExitCode(error, command);\n }\n const options = command.opts<MigrateOptions>();\n const stateDir = resolveStateDir(argv);\n const dryRun = options.dryRun ?? false;\n try {\n const sandbox = parseSandboxArg(options.sandbox);\n const ran = await runMigrations({\n workspaceRoot: options.workspace ? resolve(options.workspace) : join(stateDir, \"workspace\"),\n stateDir,\n dryRun,\n owners: options.owner,\n sandbox,\n enabledPlatforms: PLATFORMS.filter((platform) => platformIsActive(platform)),\n piAgentDir: readEnv(\"PI_CODING_AGENT_DIR\") ?? join(homedir(), \".pi\", \"agent\"),\n modelsPath: join(stateDir, \"models.json\"),\n docker,\n report: (line) => console.log(line),\n });\n if (ran.length === 0) console.log(\"No pending migrations.\");\n else if (!dryRun) console.log(`Applied ${ran.length}.`);\n else {\n console.log(`Dry run: ${ran.length} pending.`);\n console.log(\"Each step was previewed against the files as they are now, so a step may find\");\n console.log(\"more to do once the steps before it have run.\");\n }\n return 0;\n } catch (error) {\n console.error(`Migration failed: ${errorMessage(error)}`);\n return 1;\n }\n}\n"]}
1
+ {"version":3,"file":"migrate.js","sourceRoot":"","sources":["../../src/cli/migrate.ts"],"names":[],"mappings":"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","sourcesContent":["import { execFile } from \"node:child_process\";\nimport { existsSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join, resolve } from \"node:path\";\nimport { promisify } from \"node:util\";\nimport { InvalidArgumentError } from \"commander\";\nimport { platformIsActive, readEnv } from \"../env-manifest.js\";\nimport { pendingMigrations, runMigrations } from \"../migrations/index.js\";\nimport { parseSandboxArg } from \"../sandbox/registry.js\";\nimport { globalSettingsPath } from \"../settings/index.js\";\nimport type { DockerCli } from \"../migrations/types.js\";\nimport { assertPlatformName } from \"../office/index.js\";\nimport type { PlatformName } from \"../types.js\";\nimport { errorMessage } from \"../unknown-values.js\";\nimport { cliCommand, commandExitCode, nonEmptyValue, stateDirPath } from \"./arg-grammar.js\";\n\nconst PLATFORMS: readonly PlatformName[] = [\"slack\", \"telegram\", \"discord\", \"github\"];\n\nconst execFileAsync = promisify(execFile);\n\nconst dockerCli: DockerCli = async (args) => (await execFileAsync(\"docker\", [...args])).stdout;\n\nfunction collectOwner(value: string, owners: Map<string, PlatformName>): Map<string, PlatformName> {\n const separator = value.lastIndexOf(\"=\");\n if (separator <= 0) throw new InvalidArgumentError(\"expected <conversationId>=<platform>\");\n try {\n owners.set(value.slice(0, separator), assertPlatformName(value.slice(separator + 1)));\n } catch (error) {\n throw new InvalidArgumentError(errorMessage(error));\n }\n return owners;\n}\n\nfunction assertInstallPaths(stateDir: string, workspaceRoot: string): void {\n const settingsPath = globalSettingsPath(stateDir);\n if (!existsSync(settingsPath)) {\n throw new Error(\n `No settings at ${settingsPath}; move the state directory the daemon ran with to ${stateDir}`,\n );\n }\n if (!existsSync(workspaceRoot)) {\n throw new Error(\n `Workspace ${workspaceRoot} does not exist; pass the working directory the daemon ran with as --workspace`,\n );\n }\n}\n\ninterface MigrateOptions {\n workspace?: string;\n dryRun?: boolean;\n sandbox: string;\n owner: Map<string, PlatformName>;\n}\n\nexport async function runMigrateCommand(argv: string[], docker = dockerCli): Promise<number> {\n const command = cliCommand(\"mikan migrate\")\n .description(\"Apply pending state migrations (stop the daemon first)\")\n .option(\"--workspace <dir>\", \"Workspace directory (default: ~/.mikan/workspace)\")\n .requiredOption(\n \"--sandbox <spec>\",\n \"The daemon's --sandbox value: host | container:<name> | image:<image>\",\n nonEmptyValue,\n )\n .option(\"--dry-run\", \"List what each pending migration would change, without writing\")\n .option(\n \"--owner <conversationId=platform>\",\n \"Owning platform for a legacy conversation directory (repeatable)\",\n collectOwner,\n new Map<string, PlatformName>(),\n );\n try {\n command.parse(argv, { from: \"user\" });\n } catch (error) {\n return commandExitCode(error, command);\n }\n const options = command.opts<MigrateOptions>();\n const stateDir = stateDirPath();\n const dryRun = options.dryRun ?? false;\n const workspaceRoot = options.workspace\n ? resolve(options.workspace)\n : join(stateDir, \"workspace\");\n try {\n const sandbox = parseSandboxArg(options.sandbox);\n if (pendingMigrations(stateDir).length > 0) assertInstallPaths(stateDir, workspaceRoot);\n const ran = await runMigrations({\n workspaceRoot,\n stateDir,\n dryRun,\n owners: options.owner,\n sandbox,\n enabledPlatforms: PLATFORMS.filter((platform) => platformIsActive(platform)),\n piAgentDir: readEnv(\"PI_CODING_AGENT_DIR\") ?? join(homedir(), \".pi\", \"agent\"),\n modelsPath: join(stateDir, \"models.json\"),\n docker,\n report: (line) => console.log(line),\n });\n if (ran.length === 0) console.log(\"No pending migrations.\");\n else if (!dryRun) console.log(`Applied ${ran.length}.`);\n else {\n console.log(`Dry run: ${ran.length} pending.`);\n console.log(\"Each step was previewed against the files as they are now, so a step may find\");\n console.log(\"more to do once the steps before it have run.\");\n }\n return 0;\n } catch (error) {\n console.error(`Migration failed: ${errorMessage(error)}`);\n return 1;\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"office.d.ts","sourceRoot":"","sources":["../../src/cli/office.ts"],"names":[],"mappings":"AAGA,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,CAiBvD"}
1
+ {"version":3,"file":"office.d.ts","sourceRoot":"","sources":["../../src/cli/office.ts"],"names":[],"mappings":"AAGA,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,CAevD"}
@@ -1,15 +1,13 @@
1
1
  import { officeKey, OfficeRegistry } from "../office/index.js";
2
- import { cliCommand, commandExitCode, nonEmptyValue, resolveStateDir } from "./arg-grammar.js";
2
+ import { cliCommand, commandExitCode, stateDirPath } from "./arg-grammar.js";
3
3
  export function runOfficeCommand(argv) {
4
- const command = cliCommand("mikan office")
5
- .description("Inspect conversation offices")
6
- .option("--state-dir <dir>", "State directory", nonEmptyValue);
4
+ const command = cliCommand("mikan office").description("Inspect conversation offices");
7
5
  let result = 1;
8
6
  command
9
7
  .command("list")
10
8
  .description("List each registered office key with its platform and conversation id")
11
9
  .action(() => {
12
- result = listOffices(resolveStateDir(argv));
10
+ result = listOffices(stateDirPath());
13
11
  });
14
12
  try {
15
13
  command.parse(argv, { from: "user" });
@@ -1 +1 @@
1
- {"version":3,"file":"office.js","sourceRoot":"","sources":["../../src/cli/office.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAC/D,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAE/F,MAAM,UAAU,gBAAgB,CAAC,IAAc;IAC7C,MAAM,OAAO,GAAG,UAAU,CAAC,cAAc,CAAC;SACvC,WAAW,CAAC,8BAA8B,CAAC;SAC3C,MAAM,CAAC,mBAAmB,EAAE,iBAAiB,EAAE,aAAa,CAAC,CAAC;IACjE,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,OAAO;SACJ,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,uEAAuE,CAAC;SACpF,MAAM,CAAC,GAAG,EAAE;QACX,MAAM,GAAG,WAAW,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;IACL,IAAI,CAAC;QACH,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;QACtC,OAAO,MAAM,CAAC;IAChB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,eAAe,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IACzC,CAAC;AACH,CAAC;AAED,SAAS,WAAW,CAAC,QAAgB;IACnC,MAAM,OAAO,GAAG,IAAI,cAAc,CAAC,QAAQ,CAAC,CAAC,UAAU,EAAE,CAAC;IAC1D,OAAO,CAAC,GAAG,CAAC,YAAY,OAAO,CAAC,MAAM,IAAI,CAAC,CAAC;IAC5C,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,OAAO,CAAC,GAAG,CAAC,KAAK,SAAS,CAAC,MAAM,CAAC,KAAK,MAAM,CAAC,QAAQ,KAAK,MAAM,CAAC,cAAc,EAAE,CAAC,CAAC;IACtF,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC","sourcesContent":["import { officeKey, OfficeRegistry } from \"../office/index.js\";\nimport { cliCommand, commandExitCode, nonEmptyValue, resolveStateDir } from \"./arg-grammar.js\";\n\nexport function runOfficeCommand(argv: string[]): number {\n const command = cliCommand(\"mikan office\")\n .description(\"Inspect conversation offices\")\n .option(\"--state-dir <dir>\", \"State directory\", nonEmptyValue);\n let result = 1;\n command\n .command(\"list\")\n .description(\"List each registered office key with its platform and conversation id\")\n .action(() => {\n result = listOffices(resolveStateDir(argv));\n });\n try {\n command.parse(argv, { from: \"user\" });\n return result;\n } catch (error) {\n return commandExitCode(error, command);\n }\n}\n\nfunction listOffices(stateDir: string): number {\n const offices = new OfficeRegistry(stateDir).getOffices();\n console.log(`Offices (${offices.length}):`);\n for (const office of offices) {\n console.log(` ${officeKey(office)} ${office.platform} ${office.conversationId}`);\n }\n return 0;\n}\n"]}
1
+ {"version":3,"file":"office.js","sourceRoot":"","sources":["../../src/cli/office.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAC/D,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAE7E,MAAM,UAAU,gBAAgB,CAAC,IAAc;IAC7C,MAAM,OAAO,GAAG,UAAU,CAAC,cAAc,CAAC,CAAC,WAAW,CAAC,8BAA8B,CAAC,CAAC;IACvF,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,OAAO;SACJ,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,uEAAuE,CAAC;SACpF,MAAM,CAAC,GAAG,EAAE;QACX,MAAM,GAAG,WAAW,CAAC,YAAY,EAAE,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;IACL,IAAI,CAAC;QACH,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;QACtC,OAAO,MAAM,CAAC;IAChB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,eAAe,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IACzC,CAAC;AACH,CAAC;AAED,SAAS,WAAW,CAAC,QAAgB;IACnC,MAAM,OAAO,GAAG,IAAI,cAAc,CAAC,QAAQ,CAAC,CAAC,UAAU,EAAE,CAAC;IAC1D,OAAO,CAAC,GAAG,CAAC,YAAY,OAAO,CAAC,MAAM,IAAI,CAAC,CAAC;IAC5C,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,OAAO,CAAC,GAAG,CAAC,KAAK,SAAS,CAAC,MAAM,CAAC,KAAK,MAAM,CAAC,QAAQ,KAAK,MAAM,CAAC,cAAc,EAAE,CAAC,CAAC;IACtF,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC","sourcesContent":["import { officeKey, OfficeRegistry } from \"../office/index.js\";\nimport { cliCommand, commandExitCode, stateDirPath } from \"./arg-grammar.js\";\n\nexport function runOfficeCommand(argv: string[]): number {\n const command = cliCommand(\"mikan office\").description(\"Inspect conversation offices\");\n let result = 1;\n command\n .command(\"list\")\n .description(\"List each registered office key with its platform and conversation id\")\n .action(() => {\n result = listOffices(stateDirPath());\n });\n try {\n command.parse(argv, { from: \"user\" });\n return result;\n } catch (error) {\n return commandExitCode(error, command);\n }\n}\n\nfunction listOffices(stateDir: string): number {\n const offices = new OfficeRegistry(stateDir).getOffices();\n console.log(`Offices (${offices.length}):`);\n for (const office of offices) {\n console.log(` ${officeKey(office)} ${office.platform} ${office.conversationId}`);\n }\n return 0;\n}\n"]}
@@ -1,7 +1,7 @@
1
1
  import { existsSync, readFileSync } from "node:fs";
2
2
  import { join } from "node:path";
3
3
  import * as prompts from "@clack/prompts";
4
- import { ENV_MANIFEST, envReport, readEnv } from "../env-manifest.js";
4
+ import { ENV_MANIFEST, envSetReport, readEnv } from "../env-manifest.js";
5
5
  import { createGlobalSettingsFile } from "../settings/index.js";
6
6
  import { recordAllMigrations } from "../migrations/index.js";
7
7
  import { atomicWritePrivateFile } from "../file-guards.js";
@@ -48,6 +48,15 @@ async function askAdapter(io, env) {
48
48
  for (const spec of group.vars.filter((v) => v.required)) {
49
49
  env[spec.name] = await askRequired(io, ` ${spec.name} (${spec.doc}): `, spec.secret);
50
50
  }
51
+ if (group.key !== "github")
52
+ return {};
53
+ const repos = await askRequired(io, " Repositories (owner/repo or owner/*, comma-separated): ");
54
+ return {
55
+ githubRepos: repos
56
+ .split(",")
57
+ .map((repo) => repo.trim())
58
+ .filter(Boolean),
59
+ };
51
60
  }
52
61
  async function askLlm(io, env) {
53
62
  io.print("\nStep 2/3 — LLM provider");
@@ -58,13 +67,11 @@ async function askLlm(io, env) {
58
67
  ], "Provider");
59
68
  if (index === 0) {
60
69
  env.ANTHROPIC_API_KEY = await askRequired(io, " ANTHROPIC_API_KEY: ", true);
61
- const model = (await io.ask(" Model [claude-sonnet-4-6]: ")).trim() || "claude-sonnet-4-6";
62
- return { llm: { provider: "anthropic", model } };
70
+ return { llm: { provider: "anthropic", model: "claude-sonnet-4-6" } };
63
71
  }
64
72
  if (index === 1) {
65
73
  env.OPENAI_API_KEY = await askRequired(io, " OPENAI_API_KEY: ", true);
66
- const model = (await io.ask(" Model [gpt-5.2]: ")).trim() || "gpt-5.2";
67
- return { llm: { provider: "openai", model } };
74
+ return { llm: { provider: "openai", model: "gpt-5.2" } };
68
75
  }
69
76
  const provider = (await io.ask(" Provider name [custom]: ")).trim() || "custom";
70
77
  const baseUrl = await askRequired(io, " Base URL (e.g. http://host:8080/v1): ");
@@ -88,19 +95,10 @@ async function askLlm(io, env) {
88
95
  async function askSandbox(io) {
89
96
  io.print("\nStep 3/3 — sandbox (where agent commands run)");
90
97
  const index = await askChoice(io, [
91
- "host — run directly on this machine (default)",
92
- "image — per-conversation Docker containers (needs Docker)",
93
- "other — configure later via --sandbox (cloudflare)",
98
+ "host — run directly on this machine",
99
+ "image — one Docker container per conversation (needs Docker)",
94
100
  ], "Sandbox");
95
- if (index === 0)
96
- return undefined;
97
- if (index === 1) {
98
- const image = (await io.ask(" Image [ghcr.io/geminixiang/mikan-sandbox:latest]: ")).trim() ||
99
- "ghcr.io/geminixiang/mikan-sandbox:latest";
100
- return `image:${image}`;
101
- }
102
- io.print(" See `mikan --help` for the --sandbox spec.");
103
- return undefined;
101
+ return index === 1 ? "image:ghcr.io/geminixiang/mikan-sandbox:latest" : undefined;
104
102
  }
105
103
  export function renderEnvFile(existing, vars) {
106
104
  const pending = new Map(Object.entries(vars));
@@ -132,7 +130,7 @@ export async function runOnboardWizard(stateDir, io, paths) {
132
130
  return 1;
133
131
  }
134
132
  const env = {};
135
- await askAdapter(io, env);
133
+ const { githubRepos } = await askAdapter(io, env);
136
134
  const { llm, modelsJson } = await askLlm(io, env);
137
135
  const sandboxArg = await askSandbox(io);
138
136
  const modelsPath = join(stateDir, "models.json");
@@ -145,7 +143,7 @@ export async function runOnboardWizard(stateDir, io, paths) {
145
143
  io.print("Onboarding cancelled; nothing was written.");
146
144
  return 1;
147
145
  }
148
- createGlobalSettingsFile(stateDir, llm);
146
+ createGlobalSettingsFile(stateDir, { llm, githubRepos });
149
147
  recordAllMigrations(stateDir);
150
148
  io.print(`\nWrote ${settingsPath}`);
151
149
  if (modelsJson) {
@@ -156,7 +154,7 @@ export async function runOnboardWizard(stateDir, io, paths) {
156
154
  const existing = existsSync(envFilePath) ? readFileSync(envFilePath, "utf-8") : undefined;
157
155
  atomicWritePrivateFile(envFilePath, renderEnvFile(existing, env));
158
156
  io.print(`Wrote ${envFilePath} (0600)`);
159
- io.print(`\n${envReport((name) => env[name] ?? readEnv(name))}`);
157
+ io.print(`\n${envSetReport((name) => env[name] ?? readEnv(name))}`);
160
158
  const sandboxFlag = sandboxArg ? ` --sandbox ${sandboxArg}` : "";
161
159
  io.print("Next steps:");
162
160
  io.print(` pm2: pm2 start ecosystem.config.cjs (loads ${envFilePath}; see deploy/pm2/)`);