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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (292) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/README.md +18 -11
  3. package/dist/adapters/buffered-responder.d.ts +60 -0
  4. package/dist/adapters/buffered-responder.d.ts.map +1 -0
  5. package/dist/adapters/buffered-responder.js +201 -0
  6. package/dist/adapters/buffered-responder.js.map +1 -0
  7. package/dist/adapters/discord/context.d.ts.map +1 -1
  8. package/dist/adapters/discord/context.js +42 -177
  9. package/dist/adapters/discord/context.js.map +1 -1
  10. package/dist/adapters/github/bot.d.ts +14 -76
  11. package/dist/adapters/github/bot.d.ts.map +1 -1
  12. package/dist/adapters/github/bot.js +52 -443
  13. package/dist/adapters/github/bot.js.map +1 -1
  14. package/dist/adapters/github/client.d.ts +4 -0
  15. package/dist/adapters/github/client.d.ts.map +1 -1
  16. package/dist/adapters/github/client.js +5 -0
  17. package/dist/adapters/github/client.js.map +1 -1
  18. package/dist/adapters/github/context.d.ts.map +1 -1
  19. package/dist/adapters/github/context.js +32 -104
  20. package/dist/adapters/github/context.js.map +1 -1
  21. package/dist/adapters/github/github-ops.d.ts +90 -0
  22. package/dist/adapters/github/github-ops.d.ts.map +1 -0
  23. package/dist/adapters/github/github-ops.js +405 -0
  24. package/dist/adapters/github/github-ops.js.map +1 -0
  25. package/dist/adapters/github/repo.d.ts +2 -0
  26. package/dist/adapters/github/repo.d.ts.map +1 -1
  27. package/dist/adapters/github/repo.js +5 -0
  28. package/dist/adapters/github/repo.js.map +1 -1
  29. package/dist/adapters/github/tools/checks.d.ts.map +1 -1
  30. package/dist/adapters/github/tools/checks.js +6 -17
  31. package/dist/adapters/github/tools/checks.js.map +1 -1
  32. package/dist/adapters/github/tools/issue.d.ts.map +1 -1
  33. package/dist/adapters/github/tools/issue.js +6 -17
  34. package/dist/adapters/github/tools/issue.js.map +1 -1
  35. package/dist/adapters/github/tools/pr.d.ts.map +1 -1
  36. package/dist/adapters/github/tools/pr.js +6 -17
  37. package/dist/adapters/github/tools/pr.js.map +1 -1
  38. package/dist/adapters/github/tools/read.d.ts.map +1 -1
  39. package/dist/adapters/github/tools/read.js +6 -17
  40. package/dist/adapters/github/tools/read.js.map +1 -1
  41. package/dist/adapters/github/tools/review-reply.d.ts.map +1 -1
  42. package/dist/adapters/github/tools/review-reply.js +6 -17
  43. package/dist/adapters/github/tools/review-reply.js.map +1 -1
  44. package/dist/adapters/github/tools/sync.d.ts.map +1 -1
  45. package/dist/adapters/github/tools/sync.js +6 -17
  46. package/dist/adapters/github/tools/sync.js.map +1 -1
  47. package/dist/adapters/slack/bot.js +1 -1
  48. package/dist/adapters/slack/bot.js.map +1 -1
  49. package/dist/adapters/telegram/context.d.ts.map +1 -1
  50. package/dist/adapters/telegram/context.js +33 -151
  51. package/dist/adapters/telegram/context.js.map +1 -1
  52. package/dist/agent.d.ts +0 -1
  53. package/dist/agent.d.ts.map +1 -1
  54. package/dist/agent.js +28 -32
  55. package/dist/agent.js.map +1 -1
  56. package/dist/cli/arg-grammar.d.ts +25 -0
  57. package/dist/cli/arg-grammar.d.ts.map +1 -0
  58. package/dist/cli/arg-grammar.js +59 -0
  59. package/dist/cli/arg-grammar.js.map +1 -0
  60. package/dist/cli/boot.d.ts +16 -0
  61. package/dist/cli/boot.d.ts.map +1 -0
  62. package/dist/cli/boot.js +119 -0
  63. package/dist/cli/boot.js.map +1 -0
  64. package/dist/cli/ext.js +9 -11
  65. package/dist/cli/ext.js.map +1 -1
  66. package/dist/commands/extensions.js +2 -2
  67. package/dist/commands/extensions.js.map +1 -1
  68. package/dist/commands/login.d.ts.map +1 -1
  69. package/dist/commands/login.js +5 -2
  70. package/dist/commands/login.js.map +1 -1
  71. package/dist/commands/model.d.ts.map +1 -1
  72. package/dist/commands/model.js +8 -8
  73. package/dist/commands/model.js.map +1 -1
  74. package/dist/commands/sandbox.d.ts.map +1 -1
  75. package/dist/commands/sandbox.js +7 -5
  76. package/dist/commands/sandbox.js.map +1 -1
  77. package/dist/config.d.ts +0 -2
  78. package/dist/config.d.ts.map +1 -1
  79. package/dist/config.js +8 -41
  80. package/dist/config.js.map +1 -1
  81. package/dist/env-manifest.d.ts +35 -0
  82. package/dist/env-manifest.d.ts.map +1 -0
  83. package/dist/env-manifest.js +225 -0
  84. package/dist/env-manifest.js.map +1 -0
  85. package/dist/events.d.ts +0 -10
  86. package/dist/events.d.ts.map +1 -1
  87. package/dist/events.js +9 -82
  88. package/dist/events.js.map +1 -1
  89. package/dist/execution-resolver.d.ts +1 -0
  90. package/dist/execution-resolver.d.ts.map +1 -1
  91. package/dist/execution-resolver.js +33 -36
  92. package/dist/execution-resolver.js.map +1 -1
  93. package/dist/harness/event-format.d.ts +66 -0
  94. package/dist/harness/event-format.d.ts.map +1 -0
  95. package/dist/harness/event-format.js +112 -0
  96. package/dist/harness/event-format.js.map +1 -0
  97. package/dist/harness/extensions/loader.d.ts +9 -6
  98. package/dist/harness/extensions/loader.d.ts.map +1 -1
  99. package/dist/harness/extensions/loader.js +35 -50
  100. package/dist/harness/extensions/loader.js.map +1 -1
  101. package/dist/harness/extensions/types.d.ts +10 -14
  102. package/dist/harness/extensions/types.d.ts.map +1 -1
  103. package/dist/harness/extensions/types.js.map +1 -1
  104. package/dist/harness/index.d.ts +1 -0
  105. package/dist/harness/index.d.ts.map +1 -1
  106. package/dist/harness/index.js +1 -0
  107. package/dist/harness/index.js.map +1 -1
  108. package/dist/harness/runner.d.ts +16 -0
  109. package/dist/harness/runner.d.ts.map +1 -1
  110. package/dist/harness/runner.js +27 -1
  111. package/dist/harness/runner.js.map +1 -1
  112. package/dist/harness/subagent-runner.d.ts +18 -1
  113. package/dist/harness/subagent-runner.d.ts.map +1 -1
  114. package/dist/harness/subagent-runner.js +62 -30
  115. package/dist/harness/subagent-runner.js.map +1 -1
  116. package/dist/index.d.ts +2 -2
  117. package/dist/index.d.ts.map +1 -1
  118. package/dist/index.js +2 -2
  119. package/dist/index.js.map +1 -1
  120. package/dist/main.js +69 -121
  121. package/dist/main.js.map +1 -1
  122. package/dist/observability/instrument.js +6 -4
  123. package/dist/observability/instrument.js.map +1 -1
  124. package/dist/observability/sentry.d.ts.map +1 -1
  125. package/dist/observability/sentry.js +3 -2
  126. package/dist/observability/sentry.js.map +1 -1
  127. package/dist/runtime/conversation-runtime.js +13 -3
  128. package/dist/runtime/conversation-runtime.js.map +1 -1
  129. package/dist/runtime/types.d.ts +4 -0
  130. package/dist/runtime/types.d.ts.map +1 -1
  131. package/dist/runtime/types.js.map +1 -1
  132. package/dist/sandbox/cloudflare.d.ts +1 -0
  133. package/dist/sandbox/cloudflare.d.ts.map +1 -1
  134. package/dist/sandbox/cloudflare.js +4 -1
  135. package/dist/sandbox/cloudflare.js.map +1 -1
  136. package/dist/sandbox/container.d.ts +1 -0
  137. package/dist/sandbox/container.d.ts.map +1 -1
  138. package/dist/sandbox/container.js +4 -1
  139. package/dist/sandbox/container.js.map +1 -1
  140. package/dist/sandbox/firecracker.d.ts +1 -0
  141. package/dist/sandbox/firecracker.d.ts.map +1 -1
  142. package/dist/sandbox/firecracker.js +4 -1
  143. package/dist/sandbox/firecracker.js.map +1 -1
  144. package/dist/sandbox/gondolin-bootstrap.d.ts +26 -0
  145. package/dist/sandbox/gondolin-bootstrap.d.ts.map +1 -0
  146. package/dist/sandbox/gondolin-bootstrap.js +27 -0
  147. package/dist/sandbox/gondolin-bootstrap.js.map +1 -0
  148. package/dist/sandbox/gondolin-contract.d.ts +125 -0
  149. package/dist/sandbox/gondolin-contract.d.ts.map +1 -0
  150. package/dist/sandbox/gondolin-contract.js +155 -0
  151. package/dist/sandbox/gondolin-contract.js.map +1 -0
  152. package/dist/sandbox/gondolin-fleet.d.ts +1 -1
  153. package/dist/sandbox/gondolin-fleet.d.ts.map +1 -1
  154. package/dist/sandbox/gondolin-fleet.js +1 -1
  155. package/dist/sandbox/gondolin-fleet.js.map +1 -1
  156. package/dist/sandbox/gondolin-gateway.d.ts +1 -0
  157. package/dist/sandbox/gondolin-gateway.d.ts.map +1 -1
  158. package/dist/sandbox/gondolin-gateway.js +13 -6
  159. package/dist/sandbox/gondolin-gateway.js.map +1 -1
  160. package/dist/sandbox/gondolin-inventory.d.ts +2 -16
  161. package/dist/sandbox/gondolin-inventory.d.ts.map +1 -1
  162. package/dist/sandbox/gondolin-inventory.js +2 -12
  163. package/dist/sandbox/gondolin-inventory.js.map +1 -1
  164. package/dist/sandbox/gondolin-placement.d.ts +0 -2
  165. package/dist/sandbox/gondolin-placement.d.ts.map +1 -1
  166. package/dist/sandbox/gondolin-placement.js +0 -6
  167. package/dist/sandbox/gondolin-placement.js.map +1 -1
  168. package/dist/sandbox/gondolin-recovery.d.ts +33 -0
  169. package/dist/sandbox/gondolin-recovery.d.ts.map +1 -0
  170. package/dist/sandbox/gondolin-recovery.js +39 -0
  171. package/dist/sandbox/gondolin-recovery.js.map +1 -0
  172. package/dist/sandbox/gondolin-remote.d.ts +2 -5
  173. package/dist/sandbox/gondolin-remote.d.ts.map +1 -1
  174. package/dist/sandbox/gondolin-remote.js +12 -39
  175. package/dist/sandbox/gondolin-remote.js.map +1 -1
  176. package/dist/sandbox/gondolin-worker-client.d.ts +8 -12
  177. package/dist/sandbox/gondolin-worker-client.d.ts.map +1 -1
  178. package/dist/sandbox/gondolin-worker-client.js +13 -15
  179. package/dist/sandbox/gondolin-worker-client.js.map +1 -1
  180. package/dist/sandbox/gondolin-worker.d.ts +2 -40
  181. package/dist/sandbox/gondolin-worker.d.ts.map +1 -1
  182. package/dist/sandbox/gondolin-worker.js.map +1 -1
  183. package/dist/sandbox/gondolin.d.ts +1 -0
  184. package/dist/sandbox/gondolin.d.ts.map +1 -1
  185. package/dist/sandbox/gondolin.js +8 -4
  186. package/dist/sandbox/gondolin.js.map +1 -1
  187. package/dist/sandbox/host.d.ts +1 -0
  188. package/dist/sandbox/host.d.ts.map +1 -1
  189. package/dist/sandbox/host.js +3 -0
  190. package/dist/sandbox/host.js.map +1 -1
  191. package/dist/sandbox/index.d.ts +9 -1
  192. package/dist/sandbox/index.d.ts.map +1 -1
  193. package/dist/sandbox/index.js +14 -0
  194. package/dist/sandbox/index.js.map +1 -1
  195. package/dist/sandbox/types.d.ts +5 -0
  196. package/dist/sandbox/types.d.ts.map +1 -1
  197. package/dist/sandbox/types.js.map +1 -1
  198. package/dist/sandbox/utils.d.ts +1 -0
  199. package/dist/sandbox/utils.d.ts.map +1 -1
  200. package/dist/sandbox/utils.js +5 -2
  201. package/dist/sandbox/utils.js.map +1 -1
  202. package/dist/sessions/chat-history-sync.d.ts +32 -0
  203. package/dist/sessions/chat-history-sync.d.ts.map +1 -0
  204. package/dist/sessions/{agent-memory-file-manager.js → chat-history-sync.js} +24 -83
  205. package/dist/sessions/chat-history-sync.js.map +1 -0
  206. package/dist/sessions/conversation-log.d.ts +13 -0
  207. package/dist/sessions/conversation-log.d.ts.map +1 -0
  208. package/dist/sessions/conversation-log.js +47 -0
  209. package/dist/sessions/conversation-log.js.map +1 -0
  210. package/dist/sessions/rotation.d.ts +2 -0
  211. package/dist/sessions/rotation.d.ts.map +1 -0
  212. package/dist/sessions/rotation.js +39 -0
  213. package/dist/sessions/rotation.js.map +1 -0
  214. package/dist/sessions/store.d.ts.map +1 -1
  215. package/dist/sessions/store.js +4 -10
  216. package/dist/sessions/store.js.map +1 -1
  217. package/dist/sessions/types.d.ts +2 -2
  218. package/dist/sessions/types.d.ts.map +1 -1
  219. package/dist/sessions/types.js.map +1 -1
  220. package/dist/settings-mutation.d.ts +23 -0
  221. package/dist/settings-mutation.d.ts.map +1 -0
  222. package/dist/settings-mutation.js +42 -0
  223. package/dist/settings-mutation.js.map +1 -0
  224. package/dist/tools/event.d.ts.map +1 -1
  225. package/dist/tools/event.js +27 -46
  226. package/dist/tools/event.js.map +1 -1
  227. package/dist/tools/host-fn-tool.d.ts +21 -0
  228. package/dist/tools/host-fn-tool.d.ts.map +1 -0
  229. package/dist/tools/host-fn-tool.js +32 -0
  230. package/dist/tools/host-fn-tool.js.map +1 -0
  231. package/dist/tools/index.d.ts +1 -0
  232. package/dist/tools/index.d.ts.map +1 -1
  233. package/dist/tools/index.js +1 -0
  234. package/dist/tools/index.js.map +1 -1
  235. package/dist/tools/react.d.ts.map +1 -1
  236. package/dist/tools/react.js +6 -17
  237. package/dist/tools/react.js.map +1 -1
  238. package/dist/tools/read.d.ts.map +1 -1
  239. package/dist/tools/read.js +7 -26
  240. package/dist/tools/read.js.map +1 -1
  241. package/dist/tools/sandbox.d.ts.map +1 -1
  242. package/dist/tools/sandbox.js +5 -2
  243. package/dist/tools/sandbox.js.map +1 -1
  244. package/dist/tools/subagent-slots.d.ts +28 -0
  245. package/dist/tools/subagent-slots.d.ts.map +1 -0
  246. package/dist/tools/subagent-slots.js +57 -0
  247. package/dist/tools/subagent-slots.js.map +1 -0
  248. package/dist/tools/subagent.d.ts +7 -2
  249. package/dist/tools/subagent.d.ts.map +1 -1
  250. package/dist/tools/subagent.js +160 -111
  251. package/dist/tools/subagent.js.map +1 -1
  252. package/dist/tools/types.d.ts +10 -9
  253. package/dist/tools/types.d.ts.map +1 -1
  254. package/dist/tools/types.js.map +1 -1
  255. package/dist/types.d.ts +5 -24
  256. package/dist/types.d.ts.map +1 -1
  257. package/dist/types.js.map +1 -1
  258. package/dist/utils/date.d.ts +1 -1
  259. package/dist/utils/date.js +1 -1
  260. package/dist/utils/date.js.map +1 -1
  261. package/dist/vault/disabled.d.ts.map +1 -1
  262. package/dist/vault/disabled.js +0 -1
  263. package/dist/vault/disabled.js.map +1 -1
  264. package/dist/vault/index.d.ts +0 -2
  265. package/dist/vault/index.d.ts.map +1 -1
  266. package/dist/vault/index.js +0 -10
  267. package/dist/vault/index.js.map +1 -1
  268. package/dist/vault/injection.d.ts +20 -0
  269. package/dist/vault/injection.d.ts.map +1 -0
  270. package/dist/vault/injection.js +27 -0
  271. package/dist/vault/injection.js.map +1 -0
  272. package/dist/vault/types.d.ts +0 -2
  273. package/dist/vault/types.d.ts.map +1 -1
  274. package/dist/vault/types.js.map +1 -1
  275. package/dist/web/admin/portal.d.ts +3 -3
  276. package/dist/web/admin/portal.d.ts.map +1 -1
  277. package/dist/web/admin/portal.js +41 -39
  278. package/dist/web/admin/portal.js.map +1 -1
  279. package/dist/web/admin/types.d.ts +3 -0
  280. package/dist/web/admin/types.d.ts.map +1 -1
  281. package/dist/web/admin/types.js.map +1 -1
  282. package/dist/web/agent-events/portal.d.ts.map +1 -1
  283. package/dist/web/agent-events/portal.js +2 -1
  284. package/dist/web/agent-events/portal.js.map +1 -1
  285. package/package.json +1 -1
  286. package/dist/sessions/agent-memory-file-manager.d.ts +0 -19
  287. package/dist/sessions/agent-memory-file-manager.d.ts.map +0 -1
  288. package/dist/sessions/agent-memory-file-manager.js.map +0 -1
  289. package/dist/vault/routing.d.ts +0 -4
  290. package/dist/vault/routing.d.ts.map +0 -1
  291. package/dist/vault/routing.js +0 -6
  292. package/dist/vault/routing.js.map +0 -1
@@ -1,7 +1,6 @@
1
- import { join } from "node:path";
2
- import { updateConversationSettings } from "../config.js";
3
1
  import { readConversationWorkspaceMountMode } from "../execution-resolver.js";
4
- import { resolveActorVaultKey } from "../vault/routing.js";
2
+ import { applyConversationSettings } from "../settings-mutation.js";
3
+ import { actorKey } from "../sandbox/identity.js";
5
4
  import { slashForms } from "./manifest.js";
6
5
  import { matchCommand } from "./parse.js";
7
6
  import { formatCommandSummary, replyDiagnosticWithContext } from "./utils.js";
@@ -28,9 +27,12 @@ export class SandboxCommandHandler {
28
27
  ]), { style: "muted" });
29
28
  return true;
30
29
  }
31
- const containerKey = resolveActorVaultKey(context.services.sandbox, context.platformUserId, context.conversationId);
30
+ const containerKey = actorKey(context.services.sandbox, {
31
+ userId: context.platformUserId,
32
+ conversationId: context.conversationId,
33
+ });
32
34
  if (parsed.action === "private" || parsed.action === "full") {
33
- updateConversationSettings(join(context.services.workingDir, context.conversationId), {
35
+ applyConversationSettings(context.services.runtime, context.services.workingDir, context.conversationId, {
34
36
  sandbox: { image: { workspaceMount: parsed.action } },
35
37
  });
36
38
  await replyDiagnosticWithContext(context.responder, formatCommandSummary("Sandbox Workspace", [
@@ -1 +1 @@
1
- {"version":3,"file":"sandbox.js","sourceRoot":"","sources":["../../src/commands/sandbox.ts"],"names":[],"mappings":"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","sourcesContent":["import { join } from \"node:path\";\nimport { updateConversationSettings } from \"../config.js\";\nimport { readConversationWorkspaceMountMode } from \"../execution-resolver.js\";\nimport { resolveActorVaultKey } from \"../vault/routing.js\";\nimport { slashForms } from \"./manifest.js\";\nimport { matchCommand } from \"./parse.js\";\nimport type { CommandContext, CommandHandler, ParsedSandboxCommand } from \"./types.js\";\nimport { formatCommandSummary, replyDiagnosticWithContext } from \"./utils.js\";\n\nexport type { ParsedSandboxCommand } from \"./types.js\";\n\nconst SANDBOX_COMMANDS = slashForms(\"sandbox\");\n\nexport function parseSandboxCommand(text: string): ParsedSandboxCommand | null {\n const matched = matchCommand(text, SANDBOX_COMMANDS, { stripMention: true });\n if (!matched) return null;\n\n const action = matched.args.length === 1 ? matched.args[0].toLowerCase() : undefined;\n if (action === \"boost\" || action === \"private\" || action === \"full\") {\n return { action };\n }\n return {};\n}\n\nexport class SandboxCommandHandler implements CommandHandler {\n async tryHandle(context: CommandContext): Promise<boolean> {\n const parsed = parseSandboxCommand(context.commandText);\n if (!parsed) return false;\n\n if (\n (context.services.sandbox.type !== \"image\" && context.services.sandbox.type !== \"gondolin\") ||\n !context.services.resourceController\n ) {\n await replyDiagnosticWithContext(\n context.responder,\n formatCommandSummary(\"Sandbox\", [\n \"`/pi-sandbox` 目前只支援 `image:*` 與 `gondolin:*` managed sandbox。\",\n ]),\n { style: \"muted\" },\n );\n return true;\n }\n\n const containerKey = resolveActorVaultKey(\n context.services.sandbox,\n context.platformUserId,\n context.conversationId,\n );\n\n if (parsed.action === \"private\" || parsed.action === \"full\") {\n updateConversationSettings(join(context.services.workingDir, context.conversationId), {\n sandbox: { image: { workspaceMount: parsed.action } },\n });\n await replyDiagnosticWithContext(\n context.responder,\n formatCommandSummary(\"Sandbox Workspace\", [\n parsed.action === \"full\"\n ? \"已將此 conversation 的 sandbox 設為 full workspace mode。\"\n : \"已將此 conversation 的 sandbox 設為 private workspace mode。\",\n `Workspace mount: ${parsed.action}`,\n parsed.action === \"full\"\n ? \"之後這個 runtime 會把整個 host workspace 掛到 /workspace。\"\n : \"之後這個 runtime 只會掛載 private workspace 檔案與當前 conversation 目錄。\",\n ]),\n { style: \"muted\" },\n );\n return true;\n }\n\n if (parsed.action === \"boost\") {\n const boostLimits = context.services.resourceController.getBoostLimits();\n if (!boostLimits?.cpus && !boostLimits?.memory) {\n await replyDiagnosticWithContext(\n context.responder,\n formatCommandSummary(\"Sandbox Boost\", [\n \"此 mikan instance 尚未設定 sandbox boost 規格。\",\n \"請先在全域 settings.json 設定 `sandbox.boost`。\",\n ]),\n { style: \"muted\" },\n );\n return true;\n }\n\n const status = await context.services.resourceController.boost(containerKey);\n await replyDiagnosticWithContext(\n context.responder,\n formatCommandSummary(\"Sandbox Boost\", [\n \"已暫時提升此 conversation 的 sandbox 規格。\",\n `Current: ${formatLimits(status.limits)}`,\n \"boost 會在此 sandbox runtime 關閉後結束。\",\n ]),\n { style: \"muted\" },\n );\n return true;\n }\n\n const status = context.services.resourceController.getLimitStatus(containerKey);\n const defaultLimits = context.services.resourceController.getDefaultLimits();\n const boostLimits = context.services.resourceController.getBoostLimits();\n const workspaceMount = readConversationWorkspaceMountMode(\n context.services.workingDir,\n context.conversationId,\n );\n await replyDiagnosticWithContext(\n context.responder,\n formatCommandSummary(\n \"Sandbox\",\n [\n `Current: ${formatLimits(status.limits)}`,\n `Status: ${status.boosted ? \"boosted\" : \"default\"}`,\n `Workspace mount: ${workspaceMount}`,\n \"\",\n `Default: ${formatLimits(defaultLimits)}`,\n boostLimits ? `Boost: ${formatLimits({ ...defaultLimits, ...boostLimits })}` : undefined,\n ].filter((line): line is string => line !== undefined),\n ),\n { style: \"muted\" },\n );\n return true;\n }\n}\n\nfunction formatLimits(limits: { cpus?: string; memory?: string } | undefined): string {\n return `CPU ${limits?.cpus ?? \"unlimited\"} / Memory ${limits?.memory ?? \"unlimited\"}`;\n}\n"]}
1
+ {"version":3,"file":"sandbox.js","sourceRoot":"","sources":["../../src/commands/sandbox.ts"],"names":[],"mappings":"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","sourcesContent":["import { readConversationWorkspaceMountMode } from \"../execution-resolver.js\";\nimport { applyConversationSettings } from \"../settings-mutation.js\";\nimport { actorKey } from \"../sandbox/identity.js\";\nimport { slashForms } from \"./manifest.js\";\nimport { matchCommand } from \"./parse.js\";\nimport type { CommandContext, CommandHandler, ParsedSandboxCommand } from \"./types.js\";\nimport { formatCommandSummary, replyDiagnosticWithContext } from \"./utils.js\";\n\nexport type { ParsedSandboxCommand } from \"./types.js\";\n\nconst SANDBOX_COMMANDS = slashForms(\"sandbox\");\n\nexport function parseSandboxCommand(text: string): ParsedSandboxCommand | null {\n const matched = matchCommand(text, SANDBOX_COMMANDS, { stripMention: true });\n if (!matched) return null;\n\n const action = matched.args.length === 1 ? matched.args[0].toLowerCase() : undefined;\n if (action === \"boost\" || action === \"private\" || action === \"full\") {\n return { action };\n }\n return {};\n}\n\nexport class SandboxCommandHandler implements CommandHandler {\n async tryHandle(context: CommandContext): Promise<boolean> {\n const parsed = parseSandboxCommand(context.commandText);\n if (!parsed) return false;\n\n if (\n (context.services.sandbox.type !== \"image\" && context.services.sandbox.type !== \"gondolin\") ||\n !context.services.resourceController\n ) {\n await replyDiagnosticWithContext(\n context.responder,\n formatCommandSummary(\"Sandbox\", [\n \"`/pi-sandbox` 目前只支援 `image:*` 與 `gondolin:*` managed sandbox。\",\n ]),\n { style: \"muted\" },\n );\n return true;\n }\n\n const containerKey = actorKey(context.services.sandbox, {\n userId: context.platformUserId,\n conversationId: context.conversationId,\n });\n\n if (parsed.action === \"private\" || parsed.action === \"full\") {\n applyConversationSettings(\n context.services.runtime,\n context.services.workingDir,\n context.conversationId,\n {\n sandbox: { image: { workspaceMount: parsed.action } },\n },\n );\n await replyDiagnosticWithContext(\n context.responder,\n formatCommandSummary(\"Sandbox Workspace\", [\n parsed.action === \"full\"\n ? \"已將此 conversation 的 sandbox 設為 full workspace mode。\"\n : \"已將此 conversation 的 sandbox 設為 private workspace mode。\",\n `Workspace mount: ${parsed.action}`,\n parsed.action === \"full\"\n ? \"之後這個 runtime 會把整個 host workspace 掛到 /workspace。\"\n : \"之後這個 runtime 只會掛載 private workspace 檔案與當前 conversation 目錄。\",\n ]),\n { style: \"muted\" },\n );\n return true;\n }\n\n if (parsed.action === \"boost\") {\n const boostLimits = context.services.resourceController.getBoostLimits();\n if (!boostLimits?.cpus && !boostLimits?.memory) {\n await replyDiagnosticWithContext(\n context.responder,\n formatCommandSummary(\"Sandbox Boost\", [\n \"此 mikan instance 尚未設定 sandbox boost 規格。\",\n \"請先在全域 settings.json 設定 `sandbox.boost`。\",\n ]),\n { style: \"muted\" },\n );\n return true;\n }\n\n const status = await context.services.resourceController.boost(containerKey);\n await replyDiagnosticWithContext(\n context.responder,\n formatCommandSummary(\"Sandbox Boost\", [\n \"已暫時提升此 conversation 的 sandbox 規格。\",\n `Current: ${formatLimits(status.limits)}`,\n \"boost 會在此 sandbox runtime 關閉後結束。\",\n ]),\n { style: \"muted\" },\n );\n return true;\n }\n\n const status = context.services.resourceController.getLimitStatus(containerKey);\n const defaultLimits = context.services.resourceController.getDefaultLimits();\n const boostLimits = context.services.resourceController.getBoostLimits();\n const workspaceMount = readConversationWorkspaceMountMode(\n context.services.workingDir,\n context.conversationId,\n );\n await replyDiagnosticWithContext(\n context.responder,\n formatCommandSummary(\n \"Sandbox\",\n [\n `Current: ${formatLimits(status.limits)}`,\n `Status: ${status.boosted ? \"boosted\" : \"default\"}`,\n `Workspace mount: ${workspaceMount}`,\n \"\",\n `Default: ${formatLimits(defaultLimits)}`,\n boostLimits ? `Boost: ${formatLimits({ ...defaultLimits, ...boostLimits })}` : undefined,\n ].filter((line): line is string => line !== undefined),\n ),\n { style: \"muted\" },\n );\n return true;\n }\n}\n\nfunction formatLimits(limits: { cpus?: string; memory?: string } | undefined): string {\n return `CPU ${limits?.cpus ?? \"unlimited\"} / Memory ${limits?.memory ?? \"unlimited\"}`;\n}\n"]}
package/dist/config.d.ts CHANGED
@@ -48,8 +48,6 @@ export declare function loadConversationAutoReplyConfig(conversationDir: string)
48
48
  * @deprecated Auto-reply is kept for compatibility while its future is undecided.
49
49
  */
50
50
  export declare function saveConversationAutoReplyConfig(conversationDir: string, config: AutoReplyConfig): void;
51
- export declare function resolveWorkspaceDirFromArgv(args?: string[]): string | undefined;
52
- export declare function resolveStateDirFromArgv(args?: string[]): string;
53
51
  /**
54
52
  * True when `child` is `parent` or a path inside it. Purely lexical (no
55
53
  * symlink resolution) — used for configuration sanity checks, not as the
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAUA,qBAAa,0BAA2B,SAAQ,KAAK;aACvB,YAAY,EAAE,MAAM;IAAhD,YAA4B,YAAY,EAAE,MAAM,EAG/C;CACF;AAED,YAAY,EAAE,WAAW,EAAE,eAAe,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAClG,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,gBAAgB,EAAmB,MAAM,YAAY,CAAC;AAiQlG,wBAAgB,kBAAkB,IAAI,WAAW,CAEhD;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,wBAAwB,CAAC,eAAe,EAAE,MAAM,GAAG,MAAM,CA2BxE;AAED,wBAAgB,2BAA2B,CAAC,eAAe,EAAE,MAAM,GAAG,WAAW,CAahF;AAED;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CAAC,eAAe,CAAC,EAAE,MAAM,GAAG,gBAAgB,CAUlF;AAUD;;;;;;;;GAQG;AACH,wBAAgB,+BAA+B,CAAC,eAAe,EAAE,MAAM,GAAG,eAAe,CAYxF;AAED;;;;GAIG;AACH,wBAAgB,+BAA+B,CAC7C,eAAe,EAAE,MAAM,EACvB,MAAM,EAAE,eAAe,GACtB,IAAI,CAaN;AAED,wBAAgB,2BAA2B,CAAC,IAAI,WAAwB,GAAG,MAAM,GAAG,SAAS,CA2B5F;AAED,wBAAgB,uBAAuB,CAAC,IAAI,WAAwB,GAAG,MAAM,CAY5E;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAInE;AAED;;;;;;;GAOG;AACH,wBAAgB,8BAA8B,CAC5C,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,GAClB,IAAI,CAWN;AAED,wBAAgB,gBAAgB,IAAI,MAAM,GAAG,SAAS,CAOrD;AAED,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAQjE;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,GAAG,SAAS,CAIvD;AAqED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,CAAC,WAAW,CAAC,GAAG,IAAI,CAEtE;AAED,wBAAgB,0BAA0B,CACxC,eAAe,EAAE,MAAM,EACvB,KAAK,EAAE,OAAO,CAAC,WAAW,CAAC,GAC1B,IAAI,CAEN"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAUA,qBAAa,0BAA2B,SAAQ,KAAK;aACvB,YAAY,EAAE,MAAM;IAAhD,YAA4B,YAAY,EAAE,MAAM,EAG/C;CACF;AAED,YAAY,EAAE,WAAW,EAAE,eAAe,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAClG,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,gBAAgB,EAAmB,MAAM,YAAY,CAAC;AAgQlG,wBAAgB,kBAAkB,IAAI,WAAW,CAEhD;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,wBAAwB,CAAC,eAAe,EAAE,MAAM,GAAG,MAAM,CA2BxE;AAED,wBAAgB,2BAA2B,CAAC,eAAe,EAAE,MAAM,GAAG,WAAW,CAahF;AAED;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CAAC,eAAe,CAAC,EAAE,MAAM,GAAG,gBAAgB,CAUlF;AAUD;;;;;;;;GAQG;AACH,wBAAgB,+BAA+B,CAAC,eAAe,EAAE,MAAM,GAAG,eAAe,CAYxF;AAED;;;;GAIG;AACH,wBAAgB,+BAA+B,CAC7C,eAAe,EAAE,MAAM,EACvB,MAAM,EAAE,eAAe,GACtB,IAAI,CAaN;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAInE;AAED;;;;;;;GAOG;AACH,wBAAgB,8BAA8B,CAC5C,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,GAClB,IAAI,CAWN;AAOD,wBAAgB,gBAAgB,IAAI,MAAM,GAAG,SAAS,CAGrD;AAED,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAQjE;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,GAAG,SAAS,CAIvD;AAqED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,CAAC,WAAW,CAAC,GAAG,IAAI,CAEtE;AAED,wBAAgB,0BAA0B,CACxC,eAAe,EAAE,MAAM,EACvB,KAAK,EAAE,OAAO,CAAC,WAAW,CAAC,GAC1B,IAAI,CAEN"}
package/dist/config.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { Type } from "@sinclair/typebox";
2
2
  import { existsSync, readFileSync, renameSync, rmSync } from "fs";
3
- import { homedir } from "os";
4
3
  import { basename, dirname, join, resolve } from "path";
4
+ import { effectiveStateDir } from "./cli/arg-grammar.js";
5
5
  import { readEnv } from "./utils/env.js";
6
6
  import { ensureDirExists, readJsonSchemaFileIfExists } from "./utils/file-guards.js";
7
7
  import { atomicWritePrivateFile } from "./utils/fs-atomic.js";
@@ -120,8 +120,7 @@ function loadSettingsFile(settingsPath) {
120
120
  : `Malformed settings file at ${settingsPath}: ${detail}`);
121
121
  }
122
122
  function getStateDir() {
123
- const raw = readEnv("STATE_DIR");
124
- return raw ? resolve(raw) : join(homedir(), ".mikan");
123
+ return effectiveStateDir();
125
124
  }
126
125
  function normalizeSettingsConfig(config) {
127
126
  return {
@@ -197,7 +196,7 @@ function toAgentConfig(fromFile) {
197
196
  const provider = requireString(fromFile.provider, "llm.provider");
198
197
  const model = requireString(fromFile.model, "llm.model");
199
198
  const thinkingLevel = requireThinkingLevel(fromFile.thinkingLevel);
200
- const sentryDsn = fromFile.sentryDsn ?? process.env.SENTRY_DSN;
199
+ const sentryDsn = sentryDsnFrom(fromFile.sentryDsn);
201
200
  const sandbox = fromFile.sandbox;
202
201
  const slack = fromFile.slack;
203
202
  return {
@@ -334,39 +333,6 @@ export function saveConversationAutoReplyConfig(conversationDir, config) {
334
333
  }
335
334
  atomicWritePrivateFile(targetPath, config.rules.join("\n"));
336
335
  }
337
- export function resolveWorkspaceDirFromArgv(args = process.argv.slice(2)) {
338
- for (let i = 0; i < args.length; i++) {
339
- const arg = args[i];
340
- if (arg === "--sandbox" || arg === "--download" || arg === "--state-dir") {
341
- i += 1;
342
- continue;
343
- }
344
- if (arg === "--version" || arg === "-v" || arg === "-V" || arg === "--onboard") {
345
- continue;
346
- }
347
- if (arg.startsWith("--sandbox=") ||
348
- arg.startsWith("--download=") ||
349
- arg.startsWith("--state-dir=")) {
350
- continue;
351
- }
352
- if (!arg.startsWith("-")) {
353
- return arg;
354
- }
355
- }
356
- return undefined;
357
- }
358
- export function resolveStateDirFromArgv(args = process.argv.slice(2)) {
359
- for (let i = 0; i < args.length; i++) {
360
- const arg = args[i];
361
- if (arg.startsWith("--state-dir=")) {
362
- return resolve(arg.slice("--state-dir=".length));
363
- }
364
- if (arg === "--state-dir") {
365
- return resolve(args[++i] || "");
366
- }
367
- }
368
- return join(homedir(), ".mikan");
369
- }
370
336
  /**
371
337
  * True when `child` is `parent` or a path inside it. Purely lexical (no
372
338
  * symlink resolution) — used for configuration sanity checks, not as the
@@ -397,12 +363,13 @@ export function assertStateDirOutsideWorkspace(stateDir, workingDir, sandboxType
397
363
  }
398
364
  throw new Error(message);
399
365
  }
366
+ /** Settings-file DSN wins over SENTRY_DSN env — the rule lives only here. */
367
+ function sentryDsnFrom(fromFile) {
368
+ return fromFile || readEnv("SENTRY_DSN");
369
+ }
400
370
  export function resolveSentryDsn() {
401
371
  const fromFile = normalizeSettingsConfig(loadSettingsFile(getSettingsPath()) ?? {});
402
- if (fromFile.sentryDsn) {
403
- return fromFile.sentryDsn;
404
- }
405
- return process.env.SENTRY_DSN;
372
+ return sentryDsnFrom(fromFile.sentryDsn);
406
373
  }
407
374
  export function createGlobalSettingsFile(stateDir) {
408
375
  const settingsPath = join(stateDir, "settings.json");
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAe,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,IAAI,CAAC;AAClE,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACxD,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AACzC,OAAO,EAAE,eAAe,EAAE,0BAA0B,EAAE,MAAM,wBAAwB,CAAC;AACrF,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,KAAK,GAAG,MAAM,UAAU,CAAC;AAEhC,MAAM,OAAO,0BAA2B,SAAQ,KAAK;IACnD,YAA4B,YAAoB;QAC9C,KAAK,CAAC,mCAAmC,YAAY,EAAE,CAAC,CAAC;4BAD/B,YAAY;QAEtC,IAAI,CAAC,IAAI,GAAG,4BAA4B,CAAC;IAC3C,CAAC;CACF;AAKD,MAAM,gBAAgB,GAAuB;IAC3C,GAAG,EAAE;QACH,QAAQ,EAAE,WAAW;QACrB,KAAK,EAAE,mBAAmB;QAC1B,aAAa,EAAE,KAAK;QACpB,SAAS,EAAE;YACT,QAAQ,EAAE,WAAW;YACrB,KAAK,EAAE,kBAAkB;SAC1B;KACF;IACD,KAAK,EAAE;QACL,SAAS,EAAE,WAAW;KACvB;IACD,OAAO,EAAE;QACP,IAAI,EAAE,KAAK;QACX,MAAM,EAAE,IAAI;QACZ,KAAK,EAAE;YACL,IAAI,EAAE,GAAG;YACT,MAAM,EAAE,IAAI;SACb;QACD,KAAK,EAAE;YACL,cAAc,EAAE,SAAS;SAC1B;QACD,kBAAkB,EAAE,EAAE;KACvB;CACF,CAAC;AAEF,MAAM,kBAAkB,GAAG,IAAI,CAAC,MAAM,CAAC;IACrC,GAAG,EAAE,IAAI,CAAC,QAAQ,CAChB,IAAI,CAAC,MAAM,CAAC;QACV,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;QACtC,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;QACnC,aAAa,EAAE,IAAI,CAAC,QAAQ,CAC1B,IAAI,CAAC,KAAK,CAAC;YACT,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;YACnB,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC;YACvB,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;YACnB,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC;YACtB,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;YACpB,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC;YACrB,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;SACpB,CAAC,CACH;QACD,SAAS,EAAE,IAAI,CAAC,QAAQ,CACtB,IAAI,CAAC,MAAM,CAAC;YACV,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACtC,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;SACpC,CAAC,CACH;KACF,CAAC,CACH;IACD,MAAM,EAAE,IAAI,CAAC,QAAQ,CACnB,IAAI,CAAC,MAAM,CAAC;QACV,GAAG,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;KAClC,CAAC,CACH;IACD,KAAK,EAAE,IAAI,CAAC,QAAQ,CAClB,IAAI,CAAC,MAAM,CAAC;QACV,SAAS,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;KAC1F,CAAC,CACH;IACD,OAAO,EAAE,IAAI,CAAC,QAAQ,CACpB,IAAI,CAAC,MAAM,CAAC;QACV,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;QAClC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;QACpC,KAAK,EAAE,IAAI,CAAC,QAAQ,CAClB,IAAI,CAAC,MAAM,CAAC;YACV,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YAClC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;SACrC,CAAC,CACH;QACD,KAAK,EAAE,IAAI,CAAC,QAAQ,CAClB,IAAI,CAAC,MAAM,CAAC;YACV,cAAc,EAAE,IAAI,CAAC,QAAQ,CAC3B,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAC5D;SACF,CAAC,CACH;QACD,QAAQ,EAAE,IAAI,CAAC,QAAQ,CACrB,IAAI,CAAC,MAAM,CAAC;YACV,MAAM,EAAE,IAAI,CAAC,QAAQ,CACnB,IAAI,CAAC,MAAM,CAAC;gBACV,GAAG,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;gBACjC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;gBACpC,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;gBACtC,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;gBACrC,aAAa,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;gBAC3C,WAAW,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;gBACzC,aAAa,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;gBAC3C,gBAAgB,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;gBAC9C,OAAO,EAAE,IAAI,CAAC,QAAQ,CACpB,IAAI,CAAC,KAAK,CACR,IAAI,CAAC,MAAM,CAAC;oBACV,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;oBAClC,GAAG,EAAE,IAAI,CAAC,MAAM,EAAE;oBAClB,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;oBACpC,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;oBACtC,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;oBACrC,aAAa,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;oBAC3C,WAAW,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;oBACzC,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;iBACxC,CAAC,CACH,CACF;gBACD,OAAO,EAAE,IAAI,CAAC,QAAQ,CACpB,IAAI,CAAC,MAAM,CAAC;oBACV,IAAI,EAAE,IAAI,CAAC,MAAM,EAAE;oBACnB,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;oBACtC,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;oBACrC,YAAY,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;oBAC1C,SAAS,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;oBACnD,aAAa,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;oBAC3C,OAAO,EAAE,IAAI,CAAC,QAAQ,CACpB,IAAI,CAAC,MAAM,CACT,IAAI,CAAC,MAAM,EAAE,EACb,IAAI,CAAC,MAAM,CAAC;wBACV,WAAW,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;wBACzC,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;qBACxC,CAAC,CACH,CACF;iBACF,CAAC,CACH;aACF,CAAC,CACH;SACF,CAAC,CACH;QACD,kBAAkB,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;KACjD,CAAC,CACH;IACD,SAAS,EAAE,IAAI,CAAC,QAAQ,CACtB,IAAI,CAAC,MAAM,CAAC;QACV,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;QACtC,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;KAChD,CAAC,CACH;CACF,CAAC,CAAC;AAIH,SAAS,gBAAgB,CAAC,YAAoB;IAC5C,OAAO,0BAA0B,CAAC,YAAY,EAAE,kBAAkB,EAAE,CAAC,MAAM,EAAE,EAAE,CAC7E,MAAM,KAAK,uBAAuB;QAChC,CAAC,CAAC,8BAA8B,YAAY,2CAA2C;QACvF,CAAC,CAAC,8BAA8B,YAAY,KAAK,MAAM,EAAE,CAC5D,CAAC;AACJ,CAAC;AAED,SAAS,WAAW;IAClB,MAAM,GAAG,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IACjC,OAAO,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,QAAQ,CAAC,CAAC;AACxD,CAAC;AAED,SAAS,uBAAuB,CAAC,MAA0B;IACzD,OAAO;QACL,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAChF,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACvE,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,MAAM,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/F,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7E,GAAG,CAAC,MAAM,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,wBAAwB,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9F,GAAG,CAAC,MAAM,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC/D,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,SAAS,wBAAwB,CAAC,OAAwB;IACxD,MAAM,kBAAkB,GAAG,OAAO,CAAC,kBAAkB,EAAE,IAAI,EAAE,CAAC;IAC9D,OAAO;QACL,GAAG,CAAC,OAAO,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7D,GAAG,CAAC,OAAO,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACnE,GAAG,CAAC,OAAO,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAChE,GAAG,CAAC,OAAO,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAChE,GAAG,CAAC,OAAO,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACzE,GAAG,CAAC,kBAAkB,CAAC,CAAC,CAAC,EAAE,kBAAkB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACtD,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,SAAS,oBAAoB,CAC3B,IAAiC,EACjC,QAAqC;IAErC,IAAI,CAAC,IAAI;QAAE,OAAO,QAAQ,CAAC;IAC3B,IAAI,CAAC,QAAQ;QAAE,OAAO,IAAI,CAAC;IAC3B,OAAO;QACL,GAAG,IAAI;QACP,GAAG,QAAQ;QACX,GAAG,CAAC,IAAI,CAAC,KAAK,IAAI,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,GAAG,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACxF,GAAG,CAAC,IAAI,CAAC,KAAK,IAAI,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,GAAG,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACxF,yEAAyE;QACzE,0EAA0E;QAC1E,GAAG,CAAC,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,QAAQ;YACpC,CAAC,CAAC,EAAE,QAAQ,EAAE,EAAE,GAAG,IAAI,CAAC,QAAQ,EAAE,GAAG,QAAQ,CAAC,QAAQ,EAAE,EAAE;YAC1D,CAAC,CAAC,EAAE,CAAC;KACR,CAAC;AACJ,CAAC;AAED,SAAS,eAAe;IACtB,OAAO,IAAI,CAAC,WAAW,EAAE,EAAE,eAAe,CAAC,CAAC;AAC9C,CAAC;AAED,SAAS,qBAAqB;IAC5B,MAAM,YAAY,GAAG,eAAe,EAAE,CAAC;IACvC,MAAM,MAAM,GAAG,gBAAgB,CAAC,YAAY,CAAC,CAAC;IAC9C,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,0BAA0B,CAAC,YAAY,CAAC,CAAC;IACrD,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,aAAa,CAAC,KAAyB,EAAE,IAAY;IAC5D,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CACb,oCAAoC,IAAI,oDAAoD,CAC7F,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,oBAAoB,CAAC,KAAgC;IAC5D,OAAO,aAAa,CAAC,KAAK,EAAE,mBAAmB,CAAkB,CAAC;AACpE,CAAC;AAED,SAAS,aAAa,CAAC,QAA8B;IACnD,MAAM,QAAQ,GAAG,aAAa,CAAC,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;IAClE,MAAM,KAAK,GAAG,aAAa,CAAC,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;IACzD,MAAM,aAAa,GAAG,oBAAoB,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;IACnE,MAAM,SAAS,GAAG,QAAQ,CAAC,SAAS,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC;IAC/D,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC;IACjC,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC;IAE7B,OAAO;QACL,QAAQ;QACR,KAAK;QACL,aAAa;QACb,SAAS;QACT,OAAO;QACP,KAAK;KACN,CAAC;AACJ,CAAC;AAED,SAAS,qBAAqB;IAC5B,OAAO,uBAAuB,CAAC,qBAAqB,EAAE,CAAC,CAAC;AAC1D,CAAC;AAED,MAAM,UAAU,kBAAkB;IAChC,OAAO,aAAa,CAAC,qBAAqB,EAAE,CAAC,CAAC;AAChD,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,wBAAwB,CAAC,eAAuB;IAC9D,MAAM,cAAc,GAAG,QAAQ,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC;IAC1D,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE,EAAE,eAAe,EAAE,cAAc,EAAE,eAAe,CAAC,CAAC;IACvF,IAAI,UAAU,CAAC,QAAQ,CAAC;QAAE,OAAO,QAAQ,CAAC;IAE1C,eAAe,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;IACnC,MAAM,UAAU,GAAG,IAAI,CAAC,eAAe,EAAE,eAAe,CAAC,CAAC;IAC1D,IAAI,OAAO,GAAG,MAAM,CAAC;IACrB,IAAI,QAAQ,GAAG,KAAK,CAAC;IACrB,IAAI,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC3B,IAAI,CAAC;YACH,OAAO,GAAG,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;YAC5C,QAAQ,GAAG,IAAI,CAAC;QAClB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,GAAG,CAAC,UAAU,CAAC,gDAAgD,UAAU,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QAC5F,CAAC;IACH,CAAC;IACD,sBAAsB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC1C,IAAI,QAAQ,EAAE,CAAC;QACb,IAAI,CAAC;YACH,MAAM,CAAC,UAAU,CAAC,CAAC;QACrB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,GAAG,CAAC,UAAU,CAAC,kDAAkD,UAAU,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QAC9F,CAAC;QACD,GAAG,CAAC,OAAO,CAAC,qDAAqD,QAAQ,EAAE,CAAC,CAAC;IAC/E,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,2BAA2B,CAAC,eAAuB;IACjE,MAAM,YAAY,GAAG,qBAAqB,EAAE,CAAC;IAC7C,MAAM,kBAAkB,GAAG,uBAAuB,CAChD,gBAAgB,CAAC,wBAAwB,CAAC,eAAe,CAAC,CAAC,IAAI,EAAE,CAClE,CAAC;IACF,yEAAyE;IACzE,8EAA8E;IAC9E,MAAM,OAAO,GAAG,oBAAoB,CAAC,YAAY,CAAC,OAAO,EAAE,kBAAkB,CAAC,OAAO,CAAC,CAAC;IACvF,OAAO,aAAa,CAAC;QACnB,GAAG,YAAY;QACf,GAAG,kBAAkB;QACrB,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAChC,CAAC,CAAC;AACL,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,uBAAuB,CAAC,eAAwB;IAC9D,MAAM,MAAM,GAAG,qBAAqB,EAAE,CAAC;IACvC,MAAM,KAAK,GAAG,eAAe;QAC3B,CAAC,CAAC,CAAC,gBAAgB,CAAC,wBAAwB,CAAC,eAAe,CAAC,CAAC,IAAI,EAAE,CAAC;QACrE,CAAC,CAAC,EAAE,CAAC;IACP,MAAM,MAAM,GAA8B,EAAE,GAAG,MAAM,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,GAAG,EAAE,CAAC;IAC1E,MAAM,KAAK,GAAG,EAAE,GAAG,MAAM,CAAC,GAAG,EAAE,SAAS,EAAE,GAAG,KAAK,CAAC,GAAG,EAAE,SAAS,EAAE,CAAC;IACpE,MAAM,QAAQ,GAAG,aAAa,CAAC,KAAK,CAAC,QAAQ,IAAI,MAAM,EAAE,QAAQ,EAAE,wBAAwB,CAAC,CAAC;IAC7F,MAAM,KAAK,GAAG,aAAa,CAAC,KAAK,CAAC,KAAK,IAAI,MAAM,EAAE,KAAK,EAAE,qBAAqB,CAAC,CAAC;IACjF,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;AAC7B,CAAC;AAED,MAAM,eAAe,GAAG,YAAY,CAAC;AACrC,MAAM,wBAAwB,GAAG,qBAAqB,CAAC;AAEvD,SAAS,sBAAsB,CAAC,IAAY;IAC1C,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;IAChD,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AAC5B,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,+BAA+B,CAAC,eAAuB;IACrE,MAAM,WAAW,GAAG,IAAI,CAAC,eAAe,EAAE,eAAe,CAAC,CAAC;IAC3D,IAAI,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAC5B,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,sBAAsB,CAAC,WAAW,CAAC,EAAE,CAAC;IACvE,CAAC;IAED,MAAM,YAAY,GAAG,IAAI,CAAC,eAAe,EAAE,wBAAwB,CAAC,CAAC;IACrE,IAAI,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QAC7B,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,sBAAsB,CAAC,YAAY,CAAC,EAAE,CAAC;IACzE,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;AACvC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,+BAA+B,CAC7C,eAAuB,EACvB,MAAuB;IAEvB,eAAe,CAAC,eAAe,CAAC,CAAC;IAEjC,MAAM,WAAW,GAAG,IAAI,CAAC,eAAe,EAAE,eAAe,CAAC,CAAC;IAC3D,MAAM,YAAY,GAAG,IAAI,CAAC,eAAe,EAAE,wBAAwB,CAAC,CAAC;IACrE,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,YAAY,CAAC;IAC/D,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,WAAW,CAAC;IAE9D,IAAI,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC1B,UAAU,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;IACpC,CAAC;IAED,sBAAsB,CAAC,UAAU,EAAE,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;AAC9D,CAAC;AAED,MAAM,UAAU,2BAA2B,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IACtE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAEpB,IAAI,GAAG,KAAK,WAAW,IAAI,GAAG,KAAK,YAAY,IAAI,GAAG,KAAK,aAAa,EAAE,CAAC;YACzE,CAAC,IAAI,CAAC,CAAC;YACP,SAAS;QACX,CAAC;QAED,IAAI,GAAG,KAAK,WAAW,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,KAAK,WAAW,EAAE,CAAC;YAC/E,SAAS;QACX,CAAC;QAED,IACE,GAAG,CAAC,UAAU,CAAC,YAAY,CAAC;YAC5B,GAAG,CAAC,UAAU,CAAC,aAAa,CAAC;YAC7B,GAAG,CAAC,UAAU,CAAC,cAAc,CAAC,EAC9B,CAAC;YACD,SAAS;QACX,CAAC;QAED,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACzB,OAAO,GAAG,CAAC;QACb,CAAC;IACH,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IAClE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACpB,IAAI,GAAG,CAAC,UAAU,CAAC,cAAc,CAAC,EAAE,CAAC;YACnC,OAAO,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC;QACnD,CAAC;QACD,IAAI,GAAG,KAAK,aAAa,EAAE,CAAC;YAC1B,OAAO,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QAClC,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,QAAQ,CAAC,CAAC;AACnC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,KAAa,EAAE,MAAc;IACxD,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACnC,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;IACjC,OAAO,SAAS,KAAK,UAAU,IAAI,SAAS,CAAC,UAAU,CAAC,UAAU,GAAG,GAAG,CAAC,CAAC;AAC5E,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,8BAA8B,CAC5C,QAAgB,EAChB,UAAkB,EAClB,WAAmB;IAEnB,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,UAAU,CAAC;QAAE,OAAO;IAChD,MAAM,OAAO,GACX,gBAAgB,QAAQ,+CAA+C,UAAU,KAAK;QACtF,0EAA0E;QAC1E,qEAAqE,CAAC;IACxE,IAAI,WAAW,KAAK,MAAM,EAAE,CAAC;QAC3B,GAAG,CAAC,UAAU,CAAC,6BAA6B,EAAE,OAAO,CAAC,CAAC;QACvD,OAAO;IACT,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC;AAC3B,CAAC;AAED,MAAM,UAAU,gBAAgB;IAC9B,MAAM,QAAQ,GAAG,uBAAuB,CAAC,gBAAgB,CAAC,eAAe,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC;IACpF,IAAI,QAAQ,CAAC,SAAS,EAAE,CAAC;QACvB,OAAO,QAAQ,CAAC,SAAS,CAAC;IAC5B,CAAC;IAED,OAAO,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC;AAChC,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,QAAgB;IACvD,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC;IACrD,IAAI,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CAAC,qCAAqC,YAAY,EAAE,CAAC,CAAC;IACvE,CAAC;IACD,eAAe,CAAC,QAAQ,CAAC,CAAC;IAC1B,sBAAsB,CAAC,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,gBAAgB,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAChF,OAAO,YAAY,CAAC;AACtB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,kBAAkB;IAChC,MAAM,GAAG,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IAChC,IAAI,CAAC,GAAG;QAAE,OAAO,SAAS,CAAC;IAC3B,OAAO,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AACjC,CAAC;AAED,SAAS,eAAe,CAAC,MAA2C;IAClE,OAAO,MAAM,KAAK,SAAS,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC;AAC5F,CAAC;AAED,SAAS,qBAAqB,CAAC,MAA0B;IACvD,OAAO;QACL,GAAG,CAAC,eAAe,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3D,GAAG,CAAC,eAAe,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACpE,GAAG,CAAC,eAAe,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACvE,GAAG,CAAC,eAAe,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7E,GAAG,CAAC,eAAe,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAClE,CAAC;AACJ,CAAC;AAED,SAAS,mBAAmB,CAC1B,QAA4B,EAC5B,MAA4B;IAE5B,MAAM,OAAO,GAAuB;QAClC,GAAG,QAAQ;QACX,GAAG,EAAE;YACH,GAAG,QAAQ,CAAC,GAAG;YACf,GAAG,CAAC,MAAM,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACvE,GAAG,CAAC,MAAM,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC9D,GAAG,CAAC,MAAM,CAAC,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACvF;QACD,MAAM,EAAE;YACN,GAAG,QAAQ,CAAC,MAAM;YAClB,GAAG,CAAC,MAAM,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACrE;QACD,0EAA0E;QAC1E,6EAA6E;QAC7E,mEAAmE;QACnE,OAAO,EAAE,oBAAoB,CAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE;QACrE,KAAK,EAAE;YACL,GAAG,QAAQ,CAAC,KAAK;YACjB,GAAG,MAAM,CAAC,KAAK;SAChB;KACF,CAAC;IACF,OAAO,qBAAqB,CAAC,OAAO,CAAC,CAAC;AACxC,CAAC;AAED,SAAS,kBAAkB,CACzB,YAAoB,EACpB,KAA2B,EAC3B,eAAmC;IAEnC,IAAI,QAAQ,GAAG,eAAe,CAAC;IAC/B,IAAI,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QAC7B,IAAI,CAAC;YACH,QAAQ,GAAG,gBAAgB,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC;QAClD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,MAAM,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAChE,MAAM,OAAO,GAAG,MAAM,CAAC,UAAU,CAAC,yBAAyB,CAAC;gBAC1D,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,yBAAyB,EAAE,+CAA+C,CAAC;gBAC5F,CAAC,CAAC,MAAM,CAAC;YACX,MAAM,IAAI,KAAK,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;QAC3C,CAAC;IACH,CAAC;IAED,eAAe,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC;IACvC,sBAAsB,CACpB,YAAY,EACZ,IAAI,CAAC,SAAS,CAAC,mBAAmB,CAAC,QAAQ,EAAE,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAC9D,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,KAA2B;IAC9D,kBAAkB,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,eAAe,CAAC,EAAE,KAAK,EAAE,gBAAgB,CAAC,CAAC;AACpF,CAAC;AAED,MAAM,UAAU,0BAA0B,CACxC,eAAuB,EACvB,KAA2B;IAE3B,kBAAkB,CAAC,wBAAwB,CAAC,eAAe,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;AAC3E,CAAC","sourcesContent":["import type { ThinkingLevel } from \"@earendil-works/pi-agent-core\";\nimport { Type, type Static } from \"@sinclair/typebox\";\nimport { existsSync, readFileSync, renameSync, rmSync } from \"fs\";\nimport { homedir } from \"os\";\nimport { basename, dirname, join, resolve } from \"path\";\nimport { readEnv } from \"./utils/env.js\";\nimport { ensureDirExists, readJsonSchemaFileIfExists } from \"./utils/file-guards.js\";\nimport { atomicWritePrivateFile } from \"./utils/fs-atomic.js\";\nimport * as log from \"./log.js\";\n\nexport class MissingGlobalSettingsError extends Error {\n constructor(public readonly settingsPath: string) {\n super(`Missing global settings file at ${settingsPath}`);\n this.name = \"MissingGlobalSettingsError\";\n }\n}\n\nexport type { AgentConfig, AutoReplyConfig, JudgeModelConfig, SandboxSettings } from \"./types.js\";\nimport type { AgentConfig, AutoReplyConfig, JudgeModelConfig, SandboxSettings } from \"./types.js\";\n\nconst ONBOARD_SETTINGS: SettingsFileConfig = {\n llm: {\n provider: \"anthropic\",\n model: \"claude-sonnet-4-6\",\n thinkingLevel: \"off\",\n autoReply: {\n provider: \"anthropic\",\n model: \"claude-haiku-4-5\",\n },\n },\n slack: {\n replyMode: \"top-level\",\n },\n sandbox: {\n cpus: \"0.5\",\n memory: \"1g\",\n boost: {\n cpus: \"2\",\n memory: \"4g\",\n },\n image: {\n workspaceMount: \"private\",\n },\n defaultSharedVault: \"\",\n },\n};\n\nconst SettingsFileSchema = Type.Object({\n llm: Type.Optional(\n Type.Object({\n provider: Type.Optional(Type.String()),\n model: Type.Optional(Type.String()),\n thinkingLevel: Type.Optional(\n Type.Union([\n Type.Literal(\"off\"),\n Type.Literal(\"minimal\"),\n Type.Literal(\"low\"),\n Type.Literal(\"medium\"),\n Type.Literal(\"high\"),\n Type.Literal(\"xhigh\"),\n Type.Literal(\"max\"),\n ]),\n ),\n autoReply: Type.Optional(\n Type.Object({\n provider: Type.Optional(Type.String()),\n model: Type.Optional(Type.String()),\n }),\n ),\n }),\n ),\n sentry: Type.Optional(\n Type.Object({\n dsn: Type.Optional(Type.String()),\n }),\n ),\n slack: Type.Optional(\n Type.Object({\n replyMode: Type.Optional(Type.Union([Type.Literal(\"top-level\"), Type.Literal(\"thread\")])),\n }),\n ),\n sandbox: Type.Optional(\n Type.Object({\n cpus: Type.Optional(Type.String()),\n memory: Type.Optional(Type.String()),\n boost: Type.Optional(\n Type.Object({\n cpus: Type.Optional(Type.String()),\n memory: Type.Optional(Type.String()),\n }),\n ),\n image: Type.Optional(\n Type.Object({\n workspaceMount: Type.Optional(\n Type.Union([Type.Literal(\"private\"), Type.Literal(\"full\")]),\n ),\n }),\n ),\n gondolin: Type.Optional(\n Type.Object({\n remote: Type.Optional(\n Type.Object({\n url: Type.Optional(Type.String()),\n caFile: Type.Optional(Type.String()),\n certFile: Type.Optional(Type.String()),\n keyFile: Type.Optional(Type.String()),\n workspaceRoot: Type.Optional(Type.String()),\n maxRuntimes: Type.Optional(Type.Number()),\n imageSelector: Type.Optional(Type.String()),\n queueWaitSeconds: Type.Optional(Type.Number()),\n workers: Type.Optional(\n Type.Array(\n Type.Object({\n name: Type.Optional(Type.String()),\n url: Type.String(),\n caFile: Type.Optional(Type.String()),\n certFile: Type.Optional(Type.String()),\n keyFile: Type.Optional(Type.String()),\n workspaceRoot: Type.Optional(Type.String()),\n maxRuntimes: Type.Optional(Type.Number()),\n draining: Type.Optional(Type.Boolean()),\n }),\n ),\n ),\n gateway: Type.Optional(\n Type.Object({\n port: Type.Number(),\n certFile: Type.Optional(Type.String()),\n keyFile: Type.Optional(Type.String()),\n clientCaFile: Type.Optional(Type.String()),\n hostnames: Type.Optional(Type.Array(Type.String())),\n workspaceRoot: Type.Optional(Type.String()),\n workers: Type.Optional(\n Type.Record(\n Type.String(),\n Type.Object({\n maxRuntimes: Type.Optional(Type.Number()),\n draining: Type.Optional(Type.Boolean()),\n }),\n ),\n ),\n }),\n ),\n }),\n ),\n }),\n ),\n defaultSharedVault: Type.Optional(Type.String()),\n }),\n ),\n autoReply: Type.Optional(\n Type.Object({\n enabled: Type.Optional(Type.Boolean()),\n rules: Type.Optional(Type.Array(Type.String())),\n }),\n ),\n});\n\ntype SettingsFileConfig = Static<typeof SettingsFileSchema>;\n\nfunction loadSettingsFile(settingsPath: string): SettingsFileConfig | undefined {\n return readJsonSchemaFileIfExists(settingsPath, SettingsFileSchema, (detail) =>\n detail === \"unexpected JSON shape\"\n ? `Malformed settings file at ${settingsPath}: expected a JSON object at the top level`\n : `Malformed settings file at ${settingsPath}: ${detail}`,\n );\n}\n\nfunction getStateDir(): string {\n const raw = readEnv(\"STATE_DIR\");\n return raw ? resolve(raw) : join(homedir(), \".mikan\");\n}\n\nfunction normalizeSettingsConfig(config: SettingsFileConfig): Partial<AgentConfig> {\n return {\n ...(config.llm?.provider !== undefined ? { provider: config.llm.provider } : {}),\n ...(config.llm?.model !== undefined ? { model: config.llm.model } : {}),\n ...(config.llm?.thinkingLevel !== undefined ? { thinkingLevel: config.llm.thinkingLevel } : {}),\n ...(config.sentry?.dsn !== undefined ? { sentryDsn: config.sentry.dsn } : {}),\n ...(config.sandbox !== undefined ? { sandbox: normalizeSandboxSettings(config.sandbox) } : {}),\n ...(config.slack !== undefined ? { slack: config.slack } : {}),\n };\n}\n\n/**\n * File shape → in-memory shape for the sandbox group. An empty or\n * whitespace-only `defaultSharedVault` means \"no default\" and is dropped;\n * non-empty values are trimmed. Everything else passes through as-is.\n */\nfunction normalizeSandboxSettings(sandbox: SandboxSettings): SandboxSettings {\n const defaultSharedVault = sandbox.defaultSharedVault?.trim();\n return {\n ...(sandbox.cpus !== undefined ? { cpus: sandbox.cpus } : {}),\n ...(sandbox.memory !== undefined ? { memory: sandbox.memory } : {}),\n ...(sandbox.boost !== undefined ? { boost: sandbox.boost } : {}),\n ...(sandbox.image !== undefined ? { image: sandbox.image } : {}),\n ...(sandbox.gondolin !== undefined ? { gondolin: sandbox.gondolin } : {}),\n ...(defaultSharedVault ? { defaultSharedVault } : {}),\n };\n}\n\n/**\n * Merge two sandbox settings groups. The merge invariant is LEAF-LEVEL:\n * an override that only sets `sandbox.memory` keeps the base `sandbox.cpus`,\n * and an override that only sets `boost.memory` keeps the base `boost.cpus`\n * (same for `image`). This mirrors how the fields merged when they were\n * flat top-level keys; a group-level spread would silently drop base leaves.\n */\nfunction mergeSandboxSettings(\n base: SandboxSettings | undefined,\n override: SandboxSettings | undefined,\n): SandboxSettings | undefined {\n if (!base) return override;\n if (!override) return base;\n return {\n ...base,\n ...override,\n ...(base.boost || override.boost ? { boost: { ...base.boost, ...override.boost } } : {}),\n ...(base.image || override.image ? { image: { ...base.image, ...override.image } } : {}),\n // `remote` is one connection description; merging two halves of it would\n // pair a URL with the wrong certificates, so the override wins wholesale.\n ...(base.gondolin || override.gondolin\n ? { gondolin: { ...base.gondolin, ...override.gondolin } }\n : {}),\n };\n}\n\nfunction getSettingsPath(): string {\n return join(getStateDir(), \"settings.json\");\n}\n\nfunction requireGlobalSettings(): SettingsFileConfig {\n const settingsPath = getSettingsPath();\n const config = loadSettingsFile(settingsPath);\n if (!config) {\n throw new MissingGlobalSettingsError(settingsPath);\n }\n return config;\n}\n\nfunction requireString(value: string | undefined, path: string): string {\n if (!value) {\n throw new Error(\n `Missing required global setting: ${path}. Run \\`mikan --onboard\\` to create settings.json.`,\n );\n }\n return value;\n}\n\nfunction requireThinkingLevel(value: ThinkingLevel | undefined): ThinkingLevel {\n return requireString(value, \"llm.thinkingLevel\") as ThinkingLevel;\n}\n\nfunction toAgentConfig(fromFile: Partial<AgentConfig>): AgentConfig {\n const provider = requireString(fromFile.provider, \"llm.provider\");\n const model = requireString(fromFile.model, \"llm.model\");\n const thinkingLevel = requireThinkingLevel(fromFile.thinkingLevel);\n const sentryDsn = fromFile.sentryDsn ?? process.env.SENTRY_DSN;\n const sandbox = fromFile.sandbox;\n const slack = fromFile.slack;\n\n return {\n provider,\n model,\n thinkingLevel,\n sentryDsn,\n sandbox,\n slack,\n };\n}\n\nfunction loadRawGlobalSettings(): Partial<AgentConfig> {\n return normalizeSettingsConfig(requireGlobalSettings());\n}\n\nexport function loadGlobalSettings(): AgentConfig {\n return toAgentConfig(loadRawGlobalSettings());\n}\n\n/**\n * Host-authoritative location of a conversation's settings file:\n * `<stateDir>/conversations/<conversationId>/settings.json`.\n *\n * Conversation settings used to live at `<conversationDir>/settings.json`,\n * but conversation dirs are bind-mounted read-write into sandbox containers\n * in image mode — code inside the sandbox could edit its own settings.json\n * and flip `sandbox.image.workspaceMount` to \"full\", remounting the entire\n * workspace into its container (cross-conversation access). Settings are an\n * administrator surface, so they live under the host-only state dir.\n *\n * Migration: on first access per conversation, a legacy\n * `<conversationDir>/settings.json` is moved here. The new file's existence\n * (an empty `{}` is written when there is nothing to migrate) is the\n * migration marker — a legacy file (re)appearing later, e.g. planted from\n * inside the sandbox, is never read again.\n */\nexport function conversationSettingsPath(conversationDir: string): string {\n const conversationId = basename(resolve(conversationDir));\n const hostPath = join(getStateDir(), \"conversations\", conversationId, \"settings.json\");\n if (existsSync(hostPath)) return hostPath;\n\n ensureDirExists(dirname(hostPath));\n const legacyPath = join(conversationDir, \"settings.json\");\n let content = \"{}\\n\";\n let migrated = false;\n if (existsSync(legacyPath)) {\n try {\n content = readFileSync(legacyPath, \"utf-8\");\n migrated = true;\n } catch (err) {\n log.logWarning(`Could not read legacy conversation settings: ${legacyPath}`, String(err));\n }\n }\n atomicWritePrivateFile(hostPath, content);\n if (migrated) {\n try {\n rmSync(legacyPath);\n } catch (err) {\n log.logWarning(`Could not remove legacy conversation settings: ${legacyPath}`, String(err));\n }\n log.logInfo(`Migrated conversation settings to host-only path: ${hostPath}`);\n }\n return hostPath;\n}\n\nexport function resolveConversationSettings(conversationDir: string): AgentConfig {\n const globalConfig = loadRawGlobalSettings();\n const conversationConfig = normalizeSettingsConfig(\n loadSettingsFile(conversationSettingsPath(conversationDir)) ?? {},\n );\n // The sandbox group merges at the leaf level (see mergeSandboxSettings):\n // a conversation that only sets sandbox.memory keeps the global sandbox.cpus.\n const sandbox = mergeSandboxSettings(globalConfig.sandbox, conversationConfig.sandbox);\n return toAgentConfig({\n ...globalConfig,\n ...conversationConfig,\n ...(sandbox ? { sandbox } : {}),\n });\n}\n\n/**\n * Resolve the model used to judge auto-reply rules. Falls back to the main\n * llm.{provider,model} when llm.autoReply is not set, so a missing override\n * keeps current behavior.\n *\n * @deprecated Auto-reply is kept for compatibility while its future is undecided.\n */\nexport function loadAutoReplyJudgeModel(conversationDir?: string): JudgeModelConfig {\n const global = requireGlobalSettings();\n const local = conversationDir\n ? (loadSettingsFile(conversationSettingsPath(conversationDir)) ?? {})\n : {};\n const merged: SettingsFileConfig[\"llm\"] = { ...global.llm, ...local.llm };\n const judge = { ...global.llm?.autoReply, ...local.llm?.autoReply };\n const provider = requireString(judge.provider ?? merged?.provider, \"llm.autoReply.provider\");\n const model = requireString(judge.model ?? merged?.model, \"llm.autoReply.model\");\n return { provider, model };\n}\n\nconst AUTO_REPLY_FILE = \"auto-reply\";\nconst AUTO_REPLY_DISABLED_FILE = \"auto-reply.disabled\";\n\nfunction readAutoReplyRulesFile(path: string): string[] {\n const text = readFileSync(path, \"utf-8\").trim();\n return text ? [text] : [];\n}\n\n/**\n * Load the mom-compatible auto-reply marker file state for a conversation.\n *\n * - `auto-reply` exists: enabled; empty file means reply to any top-level message.\n * - `auto-reply.disabled` exists: disabled, preserving any rules text for re-enable.\n * - neither exists: disabled.\n *\n * @deprecated Auto-reply is kept for compatibility while its future is undecided.\n */\nexport function loadConversationAutoReplyConfig(conversationDir: string): AutoReplyConfig {\n const enabledPath = join(conversationDir, AUTO_REPLY_FILE);\n if (existsSync(enabledPath)) {\n return { enabled: true, rules: readAutoReplyRulesFile(enabledPath) };\n }\n\n const disabledPath = join(conversationDir, AUTO_REPLY_DISABLED_FILE);\n if (existsSync(disabledPath)) {\n return { enabled: false, rules: readAutoReplyRulesFile(disabledPath) };\n }\n\n return { enabled: false, rules: [] };\n}\n\n/**\n * Save auto-reply state using mom-compatible marker files.\n *\n * @deprecated Auto-reply is kept for compatibility while its future is undecided.\n */\nexport function saveConversationAutoReplyConfig(\n conversationDir: string,\n config: AutoReplyConfig,\n): void {\n ensureDirExists(conversationDir);\n\n const enabledPath = join(conversationDir, AUTO_REPLY_FILE);\n const disabledPath = join(conversationDir, AUTO_REPLY_DISABLED_FILE);\n const targetPath = config.enabled ? enabledPath : disabledPath;\n const otherPath = config.enabled ? disabledPath : enabledPath;\n\n if (existsSync(otherPath)) {\n renameSync(otherPath, targetPath);\n }\n\n atomicWritePrivateFile(targetPath, config.rules.join(\"\\n\"));\n}\n\nexport function resolveWorkspaceDirFromArgv(args = process.argv.slice(2)): string | undefined {\n for (let i = 0; i < args.length; i++) {\n const arg = args[i];\n\n if (arg === \"--sandbox\" || arg === \"--download\" || arg === \"--state-dir\") {\n i += 1;\n continue;\n }\n\n if (arg === \"--version\" || arg === \"-v\" || arg === \"-V\" || arg === \"--onboard\") {\n continue;\n }\n\n if (\n arg.startsWith(\"--sandbox=\") ||\n arg.startsWith(\"--download=\") ||\n arg.startsWith(\"--state-dir=\")\n ) {\n continue;\n }\n\n if (!arg.startsWith(\"-\")) {\n return arg;\n }\n }\n\n return undefined;\n}\n\nexport function resolveStateDirFromArgv(args = process.argv.slice(2)): string {\n for (let i = 0; i < args.length; i++) {\n const arg = args[i];\n if (arg.startsWith(\"--state-dir=\")) {\n return resolve(arg.slice(\"--state-dir=\".length));\n }\n if (arg === \"--state-dir\") {\n return resolve(args[++i] || \"\");\n }\n }\n\n return join(homedir(), \".mikan\");\n}\n\n/**\n * True when `child` is `parent` or a path inside it. Purely lexical (no\n * symlink resolution) — used for configuration sanity checks, not as the\n * final security boundary.\n */\nexport function isPathInside(child: string, parent: string): boolean {\n const parentPath = resolve(parent);\n const childPath = resolve(child);\n return childPath === parentPath || childPath.startsWith(parentPath + \"/\");\n}\n\n/**\n * The state dir (extensions code, extension data, vaults, auth.json) must\n * never live inside the working dir: conversation opt-in \"full\" mode mounts\n * the entire working dir read-write into sandbox containers, and a mounted\n * state dir would let sandboxed code plant extension modules that the host\n * process later imports — a sandbox escape. Fatal under sandboxed modes;\n * host mode has no mounts, so only warn about the bad hygiene.\n */\nexport function assertStateDirOutsideWorkspace(\n stateDir: string,\n workingDir: string,\n sandboxType: string,\n): void {\n if (!isPathInside(stateDir, workingDir)) return;\n const message =\n `--state-dir (${stateDir}) must not be inside the working directory (${workingDir}): ` +\n `sandbox containers mount the working directory, and a mounted state dir ` +\n `would expose extensions, vaults, and credentials to sandboxed code.`;\n if (sandboxType === \"host\") {\n log.logWarning(\"Insecure state dir location\", message);\n return;\n }\n throw new Error(message);\n}\n\nexport function resolveSentryDsn(): string | undefined {\n const fromFile = normalizeSettingsConfig(loadSettingsFile(getSettingsPath()) ?? {});\n if (fromFile.sentryDsn) {\n return fromFile.sentryDsn;\n }\n\n return process.env.SENTRY_DSN;\n}\n\nexport function createGlobalSettingsFile(stateDir: string): string {\n const settingsPath = join(stateDir, \"settings.json\");\n if (existsSync(settingsPath)) {\n throw new Error(`Global settings already exists at ${settingsPath}`);\n }\n ensureDirExists(stateDir);\n atomicWritePrivateFile(settingsPath, JSON.stringify(ONBOARD_SETTINGS, null, 2));\n return settingsPath;\n}\n\n/**\n * Externally-visible base URL of the link/OAuth server, e.g.\n * `https://mikan.example.com` (no trailing slash). Read from `LINK_URL` or\n * `MIKAN_LINK_URL`, the same env var the bot uses to build credential onboarding links.\n */\nexport function resolveLinkBaseUrl(): string | undefined {\n const raw = readEnv(\"LINK_URL\");\n if (!raw) return undefined;\n return raw.replace(/\\/+$/, \"\");\n}\n\nfunction hasDefinedValue(values: Record<string, unknown> | undefined): boolean {\n return values !== undefined && Object.values(values).some((value) => value !== undefined);\n}\n\nfunction compactSettingsConfig(config: SettingsFileConfig): SettingsFileConfig {\n return {\n ...(hasDefinedValue(config.llm) ? { llm: config.llm } : {}),\n ...(hasDefinedValue(config.sentry) ? { sentry: config.sentry } : {}),\n ...(hasDefinedValue(config.sandbox) ? { sandbox: config.sandbox } : {}),\n ...(hasDefinedValue(config.autoReply) ? { autoReply: config.autoReply } : {}),\n ...(hasDefinedValue(config.slack) ? { slack: config.slack } : {}),\n };\n}\n\nfunction patchSettingsConfig(\n existing: SettingsFileConfig,\n config: Partial<AgentConfig>,\n): SettingsFileConfig {\n const patched: SettingsFileConfig = {\n ...existing,\n llm: {\n ...existing.llm,\n ...(config.provider !== undefined ? { provider: config.provider } : {}),\n ...(config.model !== undefined ? { model: config.model } : {}),\n ...(config.thinkingLevel !== undefined ? { thinkingLevel: config.thinkingLevel } : {}),\n },\n sentry: {\n ...existing.sentry,\n ...(config.sentryDsn !== undefined ? { dsn: config.sentryDsn } : {}),\n },\n // Leaf-level merge: a patch that only sets sandbox.boost.memory keeps the\n // existing boost.cpus (and every other existing leaf). compactSettingsConfig\n // drops the group entirely when it ends up with no defined values.\n sandbox: mergeSandboxSettings(existing.sandbox, config.sandbox) ?? {},\n slack: {\n ...existing.slack,\n ...config.slack,\n },\n };\n return compactSettingsConfig(patched);\n}\n\nfunction updateSettingsFile(\n settingsPath: string,\n patch: Partial<AgentConfig>,\n defaultSettings: SettingsFileConfig,\n): void {\n let existing = defaultSettings;\n if (existsSync(settingsPath)) {\n try {\n existing = loadSettingsFile(settingsPath) ?? {};\n } catch (err) {\n const detail = err instanceof Error ? err.message : String(err);\n const message = detail.startsWith(\"Malformed settings file\")\n ? detail.replace(\"Malformed settings file\", \"Refusing to overwrite malformed settings file\")\n : detail;\n throw new Error(message, { cause: err });\n }\n }\n\n ensureDirExists(dirname(settingsPath));\n atomicWritePrivateFile(\n settingsPath,\n JSON.stringify(patchSettingsConfig(existing, patch), null, 2),\n );\n}\n\nexport function updateGlobalSettings(patch: Partial<AgentConfig>): void {\n updateSettingsFile(join(getStateDir(), \"settings.json\"), patch, ONBOARD_SETTINGS);\n}\n\nexport function updateConversationSettings(\n conversationDir: string,\n patch: Partial<AgentConfig>,\n): void {\n updateSettingsFile(conversationSettingsPath(conversationDir), patch, {});\n}\n"]}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ThinkingLevel } from \"@earendil-works/pi-agent-core\";\nimport { Type, type Static } from \"@sinclair/typebox\";\nimport { existsSync, readFileSync, renameSync, rmSync } from \"fs\";\nimport { basename, dirname, join, resolve } from \"path\";\nimport { effectiveStateDir } from \"./cli/arg-grammar.js\";\nimport { readEnv } from \"./utils/env.js\";\nimport { ensureDirExists, readJsonSchemaFileIfExists } from \"./utils/file-guards.js\";\nimport { atomicWritePrivateFile } from \"./utils/fs-atomic.js\";\nimport * as log from \"./log.js\";\n\nexport class MissingGlobalSettingsError extends Error {\n constructor(public readonly settingsPath: string) {\n super(`Missing global settings file at ${settingsPath}`);\n this.name = \"MissingGlobalSettingsError\";\n }\n}\n\nexport type { AgentConfig, AutoReplyConfig, JudgeModelConfig, SandboxSettings } from \"./types.js\";\nimport type { AgentConfig, AutoReplyConfig, JudgeModelConfig, SandboxSettings } from \"./types.js\";\n\nconst ONBOARD_SETTINGS: SettingsFileConfig = {\n llm: {\n provider: \"anthropic\",\n model: \"claude-sonnet-4-6\",\n thinkingLevel: \"off\",\n autoReply: {\n provider: \"anthropic\",\n model: \"claude-haiku-4-5\",\n },\n },\n slack: {\n replyMode: \"top-level\",\n },\n sandbox: {\n cpus: \"0.5\",\n memory: \"1g\",\n boost: {\n cpus: \"2\",\n memory: \"4g\",\n },\n image: {\n workspaceMount: \"private\",\n },\n defaultSharedVault: \"\",\n },\n};\n\nconst SettingsFileSchema = Type.Object({\n llm: Type.Optional(\n Type.Object({\n provider: Type.Optional(Type.String()),\n model: Type.Optional(Type.String()),\n thinkingLevel: Type.Optional(\n Type.Union([\n Type.Literal(\"off\"),\n Type.Literal(\"minimal\"),\n Type.Literal(\"low\"),\n Type.Literal(\"medium\"),\n Type.Literal(\"high\"),\n Type.Literal(\"xhigh\"),\n Type.Literal(\"max\"),\n ]),\n ),\n autoReply: Type.Optional(\n Type.Object({\n provider: Type.Optional(Type.String()),\n model: Type.Optional(Type.String()),\n }),\n ),\n }),\n ),\n sentry: Type.Optional(\n Type.Object({\n dsn: Type.Optional(Type.String()),\n }),\n ),\n slack: Type.Optional(\n Type.Object({\n replyMode: Type.Optional(Type.Union([Type.Literal(\"top-level\"), Type.Literal(\"thread\")])),\n }),\n ),\n sandbox: Type.Optional(\n Type.Object({\n cpus: Type.Optional(Type.String()),\n memory: Type.Optional(Type.String()),\n boost: Type.Optional(\n Type.Object({\n cpus: Type.Optional(Type.String()),\n memory: Type.Optional(Type.String()),\n }),\n ),\n image: Type.Optional(\n Type.Object({\n workspaceMount: Type.Optional(\n Type.Union([Type.Literal(\"private\"), Type.Literal(\"full\")]),\n ),\n }),\n ),\n gondolin: Type.Optional(\n Type.Object({\n remote: Type.Optional(\n Type.Object({\n url: Type.Optional(Type.String()),\n caFile: Type.Optional(Type.String()),\n certFile: Type.Optional(Type.String()),\n keyFile: Type.Optional(Type.String()),\n workspaceRoot: Type.Optional(Type.String()),\n maxRuntimes: Type.Optional(Type.Number()),\n imageSelector: Type.Optional(Type.String()),\n queueWaitSeconds: Type.Optional(Type.Number()),\n workers: Type.Optional(\n Type.Array(\n Type.Object({\n name: Type.Optional(Type.String()),\n url: Type.String(),\n caFile: Type.Optional(Type.String()),\n certFile: Type.Optional(Type.String()),\n keyFile: Type.Optional(Type.String()),\n workspaceRoot: Type.Optional(Type.String()),\n maxRuntimes: Type.Optional(Type.Number()),\n draining: Type.Optional(Type.Boolean()),\n }),\n ),\n ),\n gateway: Type.Optional(\n Type.Object({\n port: Type.Number(),\n certFile: Type.Optional(Type.String()),\n keyFile: Type.Optional(Type.String()),\n clientCaFile: Type.Optional(Type.String()),\n hostnames: Type.Optional(Type.Array(Type.String())),\n workspaceRoot: Type.Optional(Type.String()),\n workers: Type.Optional(\n Type.Record(\n Type.String(),\n Type.Object({\n maxRuntimes: Type.Optional(Type.Number()),\n draining: Type.Optional(Type.Boolean()),\n }),\n ),\n ),\n }),\n ),\n }),\n ),\n }),\n ),\n defaultSharedVault: Type.Optional(Type.String()),\n }),\n ),\n autoReply: Type.Optional(\n Type.Object({\n enabled: Type.Optional(Type.Boolean()),\n rules: Type.Optional(Type.Array(Type.String())),\n }),\n ),\n});\n\ntype SettingsFileConfig = Static<typeof SettingsFileSchema>;\n\nfunction loadSettingsFile(settingsPath: string): SettingsFileConfig | undefined {\n return readJsonSchemaFileIfExists(settingsPath, SettingsFileSchema, (detail) =>\n detail === \"unexpected JSON shape\"\n ? `Malformed settings file at ${settingsPath}: expected a JSON object at the top level`\n : `Malformed settings file at ${settingsPath}: ${detail}`,\n );\n}\n\nfunction getStateDir(): string {\n return effectiveStateDir();\n}\n\nfunction normalizeSettingsConfig(config: SettingsFileConfig): Partial<AgentConfig> {\n return {\n ...(config.llm?.provider !== undefined ? { provider: config.llm.provider } : {}),\n ...(config.llm?.model !== undefined ? { model: config.llm.model } : {}),\n ...(config.llm?.thinkingLevel !== undefined ? { thinkingLevel: config.llm.thinkingLevel } : {}),\n ...(config.sentry?.dsn !== undefined ? { sentryDsn: config.sentry.dsn } : {}),\n ...(config.sandbox !== undefined ? { sandbox: normalizeSandboxSettings(config.sandbox) } : {}),\n ...(config.slack !== undefined ? { slack: config.slack } : {}),\n };\n}\n\n/**\n * File shape → in-memory shape for the sandbox group. An empty or\n * whitespace-only `defaultSharedVault` means \"no default\" and is dropped;\n * non-empty values are trimmed. Everything else passes through as-is.\n */\nfunction normalizeSandboxSettings(sandbox: SandboxSettings): SandboxSettings {\n const defaultSharedVault = sandbox.defaultSharedVault?.trim();\n return {\n ...(sandbox.cpus !== undefined ? { cpus: sandbox.cpus } : {}),\n ...(sandbox.memory !== undefined ? { memory: sandbox.memory } : {}),\n ...(sandbox.boost !== undefined ? { boost: sandbox.boost } : {}),\n ...(sandbox.image !== undefined ? { image: sandbox.image } : {}),\n ...(sandbox.gondolin !== undefined ? { gondolin: sandbox.gondolin } : {}),\n ...(defaultSharedVault ? { defaultSharedVault } : {}),\n };\n}\n\n/**\n * Merge two sandbox settings groups. The merge invariant is LEAF-LEVEL:\n * an override that only sets `sandbox.memory` keeps the base `sandbox.cpus`,\n * and an override that only sets `boost.memory` keeps the base `boost.cpus`\n * (same for `image`). This mirrors how the fields merged when they were\n * flat top-level keys; a group-level spread would silently drop base leaves.\n */\nfunction mergeSandboxSettings(\n base: SandboxSettings | undefined,\n override: SandboxSettings | undefined,\n): SandboxSettings | undefined {\n if (!base) return override;\n if (!override) return base;\n return {\n ...base,\n ...override,\n ...(base.boost || override.boost ? { boost: { ...base.boost, ...override.boost } } : {}),\n ...(base.image || override.image ? { image: { ...base.image, ...override.image } } : {}),\n // `remote` is one connection description; merging two halves of it would\n // pair a URL with the wrong certificates, so the override wins wholesale.\n ...(base.gondolin || override.gondolin\n ? { gondolin: { ...base.gondolin, ...override.gondolin } }\n : {}),\n };\n}\n\nfunction getSettingsPath(): string {\n return join(getStateDir(), \"settings.json\");\n}\n\nfunction requireGlobalSettings(): SettingsFileConfig {\n const settingsPath = getSettingsPath();\n const config = loadSettingsFile(settingsPath);\n if (!config) {\n throw new MissingGlobalSettingsError(settingsPath);\n }\n return config;\n}\n\nfunction requireString(value: string | undefined, path: string): string {\n if (!value) {\n throw new Error(\n `Missing required global setting: ${path}. Run \\`mikan --onboard\\` to create settings.json.`,\n );\n }\n return value;\n}\n\nfunction requireThinkingLevel(value: ThinkingLevel | undefined): ThinkingLevel {\n return requireString(value, \"llm.thinkingLevel\") as ThinkingLevel;\n}\n\nfunction toAgentConfig(fromFile: Partial<AgentConfig>): AgentConfig {\n const provider = requireString(fromFile.provider, \"llm.provider\");\n const model = requireString(fromFile.model, \"llm.model\");\n const thinkingLevel = requireThinkingLevel(fromFile.thinkingLevel);\n const sentryDsn = sentryDsnFrom(fromFile.sentryDsn);\n const sandbox = fromFile.sandbox;\n const slack = fromFile.slack;\n\n return {\n provider,\n model,\n thinkingLevel,\n sentryDsn,\n sandbox,\n slack,\n };\n}\n\nfunction loadRawGlobalSettings(): Partial<AgentConfig> {\n return normalizeSettingsConfig(requireGlobalSettings());\n}\n\nexport function loadGlobalSettings(): AgentConfig {\n return toAgentConfig(loadRawGlobalSettings());\n}\n\n/**\n * Host-authoritative location of a conversation's settings file:\n * `<stateDir>/conversations/<conversationId>/settings.json`.\n *\n * Conversation settings used to live at `<conversationDir>/settings.json`,\n * but conversation dirs are bind-mounted read-write into sandbox containers\n * in image mode — code inside the sandbox could edit its own settings.json\n * and flip `sandbox.image.workspaceMount` to \"full\", remounting the entire\n * workspace into its container (cross-conversation access). Settings are an\n * administrator surface, so they live under the host-only state dir.\n *\n * Migration: on first access per conversation, a legacy\n * `<conversationDir>/settings.json` is moved here. The new file's existence\n * (an empty `{}` is written when there is nothing to migrate) is the\n * migration marker — a legacy file (re)appearing later, e.g. planted from\n * inside the sandbox, is never read again.\n */\nexport function conversationSettingsPath(conversationDir: string): string {\n const conversationId = basename(resolve(conversationDir));\n const hostPath = join(getStateDir(), \"conversations\", conversationId, \"settings.json\");\n if (existsSync(hostPath)) return hostPath;\n\n ensureDirExists(dirname(hostPath));\n const legacyPath = join(conversationDir, \"settings.json\");\n let content = \"{}\\n\";\n let migrated = false;\n if (existsSync(legacyPath)) {\n try {\n content = readFileSync(legacyPath, \"utf-8\");\n migrated = true;\n } catch (err) {\n log.logWarning(`Could not read legacy conversation settings: ${legacyPath}`, String(err));\n }\n }\n atomicWritePrivateFile(hostPath, content);\n if (migrated) {\n try {\n rmSync(legacyPath);\n } catch (err) {\n log.logWarning(`Could not remove legacy conversation settings: ${legacyPath}`, String(err));\n }\n log.logInfo(`Migrated conversation settings to host-only path: ${hostPath}`);\n }\n return hostPath;\n}\n\nexport function resolveConversationSettings(conversationDir: string): AgentConfig {\n const globalConfig = loadRawGlobalSettings();\n const conversationConfig = normalizeSettingsConfig(\n loadSettingsFile(conversationSettingsPath(conversationDir)) ?? {},\n );\n // The sandbox group merges at the leaf level (see mergeSandboxSettings):\n // a conversation that only sets sandbox.memory keeps the global sandbox.cpus.\n const sandbox = mergeSandboxSettings(globalConfig.sandbox, conversationConfig.sandbox);\n return toAgentConfig({\n ...globalConfig,\n ...conversationConfig,\n ...(sandbox ? { sandbox } : {}),\n });\n}\n\n/**\n * Resolve the model used to judge auto-reply rules. Falls back to the main\n * llm.{provider,model} when llm.autoReply is not set, so a missing override\n * keeps current behavior.\n *\n * @deprecated Auto-reply is kept for compatibility while its future is undecided.\n */\nexport function loadAutoReplyJudgeModel(conversationDir?: string): JudgeModelConfig {\n const global = requireGlobalSettings();\n const local = conversationDir\n ? (loadSettingsFile(conversationSettingsPath(conversationDir)) ?? {})\n : {};\n const merged: SettingsFileConfig[\"llm\"] = { ...global.llm, ...local.llm };\n const judge = { ...global.llm?.autoReply, ...local.llm?.autoReply };\n const provider = requireString(judge.provider ?? merged?.provider, \"llm.autoReply.provider\");\n const model = requireString(judge.model ?? merged?.model, \"llm.autoReply.model\");\n return { provider, model };\n}\n\nconst AUTO_REPLY_FILE = \"auto-reply\";\nconst AUTO_REPLY_DISABLED_FILE = \"auto-reply.disabled\";\n\nfunction readAutoReplyRulesFile(path: string): string[] {\n const text = readFileSync(path, \"utf-8\").trim();\n return text ? [text] : [];\n}\n\n/**\n * Load the mom-compatible auto-reply marker file state for a conversation.\n *\n * - `auto-reply` exists: enabled; empty file means reply to any top-level message.\n * - `auto-reply.disabled` exists: disabled, preserving any rules text for re-enable.\n * - neither exists: disabled.\n *\n * @deprecated Auto-reply is kept for compatibility while its future is undecided.\n */\nexport function loadConversationAutoReplyConfig(conversationDir: string): AutoReplyConfig {\n const enabledPath = join(conversationDir, AUTO_REPLY_FILE);\n if (existsSync(enabledPath)) {\n return { enabled: true, rules: readAutoReplyRulesFile(enabledPath) };\n }\n\n const disabledPath = join(conversationDir, AUTO_REPLY_DISABLED_FILE);\n if (existsSync(disabledPath)) {\n return { enabled: false, rules: readAutoReplyRulesFile(disabledPath) };\n }\n\n return { enabled: false, rules: [] };\n}\n\n/**\n * Save auto-reply state using mom-compatible marker files.\n *\n * @deprecated Auto-reply is kept for compatibility while its future is undecided.\n */\nexport function saveConversationAutoReplyConfig(\n conversationDir: string,\n config: AutoReplyConfig,\n): void {\n ensureDirExists(conversationDir);\n\n const enabledPath = join(conversationDir, AUTO_REPLY_FILE);\n const disabledPath = join(conversationDir, AUTO_REPLY_DISABLED_FILE);\n const targetPath = config.enabled ? enabledPath : disabledPath;\n const otherPath = config.enabled ? disabledPath : enabledPath;\n\n if (existsSync(otherPath)) {\n renameSync(otherPath, targetPath);\n }\n\n atomicWritePrivateFile(targetPath, config.rules.join(\"\\n\"));\n}\n\n/**\n * True when `child` is `parent` or a path inside it. Purely lexical (no\n * symlink resolution) — used for configuration sanity checks, not as the\n * final security boundary.\n */\nexport function isPathInside(child: string, parent: string): boolean {\n const parentPath = resolve(parent);\n const childPath = resolve(child);\n return childPath === parentPath || childPath.startsWith(parentPath + \"/\");\n}\n\n/**\n * The state dir (extensions code, extension data, vaults, auth.json) must\n * never live inside the working dir: conversation opt-in \"full\" mode mounts\n * the entire working dir read-write into sandbox containers, and a mounted\n * state dir would let sandboxed code plant extension modules that the host\n * process later imports — a sandbox escape. Fatal under sandboxed modes;\n * host mode has no mounts, so only warn about the bad hygiene.\n */\nexport function assertStateDirOutsideWorkspace(\n stateDir: string,\n workingDir: string,\n sandboxType: string,\n): void {\n if (!isPathInside(stateDir, workingDir)) return;\n const message =\n `--state-dir (${stateDir}) must not be inside the working directory (${workingDir}): ` +\n `sandbox containers mount the working directory, and a mounted state dir ` +\n `would expose extensions, vaults, and credentials to sandboxed code.`;\n if (sandboxType === \"host\") {\n log.logWarning(\"Insecure state dir location\", message);\n return;\n }\n throw new Error(message);\n}\n\n/** Settings-file DSN wins over SENTRY_DSN env — the rule lives only here. */\nfunction sentryDsnFrom(fromFile: string | undefined): string | undefined {\n return fromFile || readEnv(\"SENTRY_DSN\");\n}\n\nexport function resolveSentryDsn(): string | undefined {\n const fromFile = normalizeSettingsConfig(loadSettingsFile(getSettingsPath()) ?? {});\n return sentryDsnFrom(fromFile.sentryDsn);\n}\n\nexport function createGlobalSettingsFile(stateDir: string): string {\n const settingsPath = join(stateDir, \"settings.json\");\n if (existsSync(settingsPath)) {\n throw new Error(`Global settings already exists at ${settingsPath}`);\n }\n ensureDirExists(stateDir);\n atomicWritePrivateFile(settingsPath, JSON.stringify(ONBOARD_SETTINGS, null, 2));\n return settingsPath;\n}\n\n/**\n * Externally-visible base URL of the link/OAuth server, e.g.\n * `https://mikan.example.com` (no trailing slash). Read from `LINK_URL` or\n * `MIKAN_LINK_URL`, the same env var the bot uses to build credential onboarding links.\n */\nexport function resolveLinkBaseUrl(): string | undefined {\n const raw = readEnv(\"LINK_URL\");\n if (!raw) return undefined;\n return raw.replace(/\\/+$/, \"\");\n}\n\nfunction hasDefinedValue(values: Record<string, unknown> | undefined): boolean {\n return values !== undefined && Object.values(values).some((value) => value !== undefined);\n}\n\nfunction compactSettingsConfig(config: SettingsFileConfig): SettingsFileConfig {\n return {\n ...(hasDefinedValue(config.llm) ? { llm: config.llm } : {}),\n ...(hasDefinedValue(config.sentry) ? { sentry: config.sentry } : {}),\n ...(hasDefinedValue(config.sandbox) ? { sandbox: config.sandbox } : {}),\n ...(hasDefinedValue(config.autoReply) ? { autoReply: config.autoReply } : {}),\n ...(hasDefinedValue(config.slack) ? { slack: config.slack } : {}),\n };\n}\n\nfunction patchSettingsConfig(\n existing: SettingsFileConfig,\n config: Partial<AgentConfig>,\n): SettingsFileConfig {\n const patched: SettingsFileConfig = {\n ...existing,\n llm: {\n ...existing.llm,\n ...(config.provider !== undefined ? { provider: config.provider } : {}),\n ...(config.model !== undefined ? { model: config.model } : {}),\n ...(config.thinkingLevel !== undefined ? { thinkingLevel: config.thinkingLevel } : {}),\n },\n sentry: {\n ...existing.sentry,\n ...(config.sentryDsn !== undefined ? { dsn: config.sentryDsn } : {}),\n },\n // Leaf-level merge: a patch that only sets sandbox.boost.memory keeps the\n // existing boost.cpus (and every other existing leaf). compactSettingsConfig\n // drops the group entirely when it ends up with no defined values.\n sandbox: mergeSandboxSettings(existing.sandbox, config.sandbox) ?? {},\n slack: {\n ...existing.slack,\n ...config.slack,\n },\n };\n return compactSettingsConfig(patched);\n}\n\nfunction updateSettingsFile(\n settingsPath: string,\n patch: Partial<AgentConfig>,\n defaultSettings: SettingsFileConfig,\n): void {\n let existing = defaultSettings;\n if (existsSync(settingsPath)) {\n try {\n existing = loadSettingsFile(settingsPath) ?? {};\n } catch (err) {\n const detail = err instanceof Error ? err.message : String(err);\n const message = detail.startsWith(\"Malformed settings file\")\n ? detail.replace(\"Malformed settings file\", \"Refusing to overwrite malformed settings file\")\n : detail;\n throw new Error(message, { cause: err });\n }\n }\n\n ensureDirExists(dirname(settingsPath));\n atomicWritePrivateFile(\n settingsPath,\n JSON.stringify(patchSettingsConfig(existing, patch), null, 2),\n );\n}\n\nexport function updateGlobalSettings(patch: Partial<AgentConfig>): void {\n updateSettingsFile(join(getStateDir(), \"settings.json\"), patch, ONBOARD_SETTINGS);\n}\n\nexport function updateConversationSettings(\n conversationDir: string,\n patch: Partial<AgentConfig>,\n): void {\n updateSettingsFile(conversationSettingsPath(conversationDir), patch, {});\n}\n"]}
@@ -0,0 +1,35 @@
1
+ interface EnvVarSpec {
2
+ name: string;
3
+ /** Required for a platform group to activate. */
4
+ required?: boolean;
5
+ secret?: boolean;
6
+ /** False for niche knobs that the deploy template doesn't enumerate. */
7
+ deploy?: boolean;
8
+ doc: string;
9
+ }
10
+ export interface EnvGroup {
11
+ key: string;
12
+ title: string;
13
+ /** Platform groups start chat adapters; feature groups are optional. */
14
+ kind: "platform" | "feature";
15
+ vars: EnvVarSpec[];
16
+ /** Additional activation requirement: at least one of these must be set. */
17
+ anyOf?: readonly string[];
18
+ doc?: string;
19
+ }
20
+ export declare const ENV_MANIFEST: readonly EnvGroup[];
21
+ type EnvLookup = (name: string) => string | undefined;
22
+ /** A platform group activates when all required vars (and one anyOf) are set. */
23
+ export declare function platformIsActive(key: string, env?: EnvLookup): boolean;
24
+ export declare function activePlatformKeys(env?: EnvLookup): string[];
25
+ export declare function noPlatformsMessage(): string;
26
+ /** The `--help` environment section, derived from the platform groups. */
27
+ export declare function envSummaryLines(): string[];
28
+ /** Every var an operator may set; `deployOnly` filters to template-listed ones. */
29
+ export declare function manifestVarNames(options?: {
30
+ deployOnly?: boolean;
31
+ }): string[];
32
+ /** `mikan env` output: every group and var with set/unset status. No values. */
33
+ export declare function envReport(env?: EnvLookup): string;
34
+ export {};
35
+ //# sourceMappingURL=env-manifest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env-manifest.d.ts","sourceRoot":"","sources":["../src/env-manifest.ts"],"names":[],"mappings":"AAaA,UAAU,UAAU;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,iDAAiD;IACjD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,wEAAwE;IACxE,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,QAAQ;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,wEAAwE;IACxE,IAAI,EAAE,UAAU,GAAG,SAAS,CAAC;IAC7B,IAAI,EAAE,UAAU,EAAE,CAAC;IACnB,4EAA4E;IAC5E,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1B,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,eAAO,MAAM,YAAY,EAAE,SAAS,QAAQ,EAoJ3C,CAAC;AAEF,KAAK,SAAS,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;AAQtD,iFAAiF;AACjF,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,GAAE,SAAmB,GAAG,OAAO,CAM/E;AAED,wBAAgB,kBAAkB,CAAC,GAAG,GAAE,SAAmB,GAAG,MAAM,EAAE,CAIrE;AASD,wBAAgB,kBAAkB,IAAI,MAAM,CAK3C;AAED,0EAA0E;AAC1E,wBAAgB,eAAe,IAAI,MAAM,EAAE,CAI1C;AAED,mFAAmF;AACnF,wBAAgB,gBAAgB,CAAC,OAAO,CAAC,EAAE;IAAE,UAAU,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,MAAM,EAAE,CAM7E;AAED,gFAAgF;AAChF,wBAAgB,SAAS,CAAC,GAAG,GAAE,SAAmB,GAAG,MAAM,CAuB1D"}
@@ -0,0 +1,225 @@
1
+ /**
2
+ * The daemon's environment interface, declared as data — the one inventory
3
+ * that startup validation, `mikan env`, `--help`, and the pm2 deploy
4
+ * template check all derive from. Add a var here and every derived surface
5
+ * picks it up; a var read anywhere else but not listed here is a bug.
6
+ *
7
+ * Names are the un-prefixed spelling; `readEnv` accepts a `MIKAN_`-prefixed
8
+ * alias for each. Not covered: dynamic OAuth service keys from
9
+ * OAUTH_SERVICES_JSON (data-driven by design) and standard proxy vars
10
+ * (HTTPS_PROXY/HTTP_PROXY/NO_PROXY).
11
+ */
12
+ import { readEnv } from "./utils/env.js";
13
+ export const ENV_MANIFEST = [
14
+ {
15
+ key: "slack",
16
+ title: "Slack",
17
+ kind: "platform",
18
+ vars: [
19
+ {
20
+ name: "SLACK_APP_TOKEN",
21
+ required: true,
22
+ secret: true,
23
+ doc: "Socket-mode app token (xapp-…)",
24
+ },
25
+ { name: "SLACK_BOT_TOKEN", required: true, secret: true, doc: "Bot token (xoxb-…)" },
26
+ ],
27
+ },
28
+ {
29
+ key: "telegram",
30
+ title: "Telegram",
31
+ kind: "platform",
32
+ vars: [{ name: "TELEGRAM_BOT_TOKEN", required: true, secret: true, doc: "BotFather token" }],
33
+ },
34
+ {
35
+ key: "discord",
36
+ title: "Discord",
37
+ kind: "platform",
38
+ vars: [{ name: "DISCORD_BOT_TOKEN", required: true, secret: true, doc: "Bot token" }],
39
+ },
40
+ {
41
+ key: "github",
42
+ title: "GitHub",
43
+ kind: "platform",
44
+ doc: "Issue/PR conversations via a GitHub App (polling, no webhook)",
45
+ vars: [
46
+ { name: "GITHUB_APP_ID", required: true, doc: "GitHub App id" },
47
+ { name: "GITHUB_INSTALLATION_ID", required: true, doc: "App installation id" },
48
+ {
49
+ name: "GITHUB_APP_PRIVATE_KEY_PATH",
50
+ doc: "Path to the App private key .pem (preferred; keep outside any repo)",
51
+ },
52
+ {
53
+ name: "GITHUB_APP_PRIVATE_KEY",
54
+ secret: true,
55
+ deploy: false,
56
+ doc: "App private key PEM with literal \\n newlines (fallback)",
57
+ },
58
+ {
59
+ name: "GITHUB_REPOS",
60
+ doc: "Comma-separated owner/repo allowlist (default: all installed)",
61
+ },
62
+ { name: "GITHUB_POLL_INTERVAL", doc: "Poll interval in seconds (default 60)" },
63
+ ],
64
+ anyOf: ["GITHUB_APP_PRIVATE_KEY", "GITHUB_APP_PRIVATE_KEY_PATH"],
65
+ },
66
+ {
67
+ key: "llm",
68
+ title: "LLM providers",
69
+ kind: "feature",
70
+ doc: "Provider keys can also live in <state-dir>/auth.json",
71
+ vars: [
72
+ { name: "ANTHROPIC_API_KEY", secret: true, doc: "Anthropic API key" },
73
+ { name: "OPENAI_API_KEY", secret: true, doc: "OpenAI API key" },
74
+ ],
75
+ },
76
+ {
77
+ key: "link",
78
+ title: "Link/OAuth server",
79
+ kind: "feature",
80
+ doc: "Credential onboarding links, session view, and the Admin portal",
81
+ vars: [
82
+ { name: "LINK_URL", doc: "Externally visible base URL, e.g. https://mikan.example.com" },
83
+ { name: "LINK_PORT", doc: "Listen port (default 8181 when LINK_URL is set)" },
84
+ { name: "GITHUB_OAUTH_CLIENT_ID", doc: "GitHub OAuth app for /login linking" },
85
+ { name: "GITHUB_OAUTH_CLIENT_SECRET", secret: true, doc: "GitHub OAuth app secret" },
86
+ { name: "GOOGLE_WORKSPACE_CLI_CLIENT_ID", doc: "Google Workspace OAuth client for /login" },
87
+ {
88
+ name: "GOOGLE_WORKSPACE_CLI_CLIENT_SECRET",
89
+ secret: true,
90
+ doc: "Google Workspace OAuth secret",
91
+ },
92
+ { name: "GOOGLE_CLOUD_SDK_CLIENT_ID", doc: "Google Cloud SDK OAuth client for /login" },
93
+ {
94
+ name: "GOOGLE_CLOUD_SDK_CLIENT_SECRET",
95
+ secret: true,
96
+ doc: "Google Cloud SDK OAuth secret",
97
+ },
98
+ ],
99
+ },
100
+ {
101
+ key: "cloudbuild",
102
+ title: "Cloud Build logs",
103
+ kind: "feature",
104
+ doc: "Host-side GCP credentials unlock Cloud Build logs in github_checks",
105
+ vars: [
106
+ {
107
+ name: "GOOGLE_APPLICATION_CREDENTIALS",
108
+ doc: "Path to a GCP credentials file (e.g. WIF external_account)",
109
+ },
110
+ { name: "GOOGLE_CLOUD_PROJECT", doc: "Fallback GCP project id" },
111
+ ],
112
+ },
113
+ {
114
+ key: "cloudflare",
115
+ title: "Cloudflare sandbox",
116
+ kind: "feature",
117
+ doc: "For --sandbox=cloudflare:<id> via the bridge worker",
118
+ vars: [
119
+ { name: "CLOUDFLARE_SANDBOX_URL", doc: "Bridge worker URL" },
120
+ { name: "CLOUDFLARE_SANDBOX_TOKEN", secret: true, doc: "Bridge worker auth token" },
121
+ {
122
+ name: "CLOUDFLARE_SANDBOX_CWD",
123
+ deploy: false,
124
+ doc: "Exec cwd inside the sandbox (default /workspace)",
125
+ },
126
+ ],
127
+ },
128
+ {
129
+ key: "observability",
130
+ title: "Observability",
131
+ kind: "feature",
132
+ vars: [
133
+ { name: "SENTRY_DSN", doc: "Sentry DSN (settings.json sentry.dsn wins over this)" },
134
+ {
135
+ name: "SENTRY_ENVIRONMENT",
136
+ deploy: false,
137
+ doc: "Sentry environment tag (default production)",
138
+ },
139
+ { name: "SENTRY_ENABLED", deploy: false, doc: "Set to false to disable Sentry" },
140
+ ],
141
+ },
142
+ {
143
+ key: "runtime",
144
+ title: "Runtime",
145
+ kind: "feature",
146
+ vars: [
147
+ { name: "STATE_DIR", deploy: false, doc: "State dir override (same as --state-dir)" },
148
+ {
149
+ name: "HTTP_IDLE_TIMEOUT",
150
+ deploy: false,
151
+ doc: "Idle timeout in ms for outbound HTTP streams",
152
+ },
153
+ {
154
+ name: "AGENT_EVENTS_TOKEN",
155
+ secret: true,
156
+ deploy: false,
157
+ doc: "Bearer token guarding the agent-events stream",
158
+ },
159
+ ],
160
+ },
161
+ ];
162
+ function groupByKey(key) {
163
+ const group = ENV_MANIFEST.find((candidate) => candidate.key === key);
164
+ if (!group)
165
+ throw new Error(`Unknown env-manifest group: ${key}`);
166
+ return group;
167
+ }
168
+ /** A platform group activates when all required vars (and one anyOf) are set. */
169
+ export function platformIsActive(key, env = readEnv) {
170
+ const group = groupByKey(key);
171
+ const required = group.vars.filter((spec) => spec.required);
172
+ if (!required.every((spec) => env(spec.name)))
173
+ return false;
174
+ if (group.anyOf && !group.anyOf.some((name) => env(name)))
175
+ return false;
176
+ return true;
177
+ }
178
+ export function activePlatformKeys(env = readEnv) {
179
+ return ENV_MANIFEST.filter((group) => group.kind === "platform" && platformIsActive(group.key, env)).map((group) => group.key);
180
+ }
181
+ /** One line per platform group: the vars an operator must set to activate it. */
182
+ function platformRecipe(group) {
183
+ const required = group.vars.filter((spec) => spec.required).map((spec) => spec.name);
184
+ const alternative = group.anyOf ? ` + ${group.anyOf.join(" | ")}` : "";
185
+ return `${group.title}: ${required.join(" + ")}${alternative}`;
186
+ }
187
+ export function noPlatformsMessage() {
188
+ const recipes = ENV_MANIFEST.filter((group) => group.kind === "platform")
189
+ .map((group) => ` ${platformRecipe(group)}`)
190
+ .join("\n");
191
+ return `No platform tokens found. Set one of:\n${recipes}`;
192
+ }
193
+ /** The `--help` environment section, derived from the platform groups. */
194
+ export function envSummaryLines() {
195
+ return ENV_MANIFEST.filter((group) => group.kind === "platform").map((group) => ` ${platformRecipe(group)}`);
196
+ }
197
+ /** Every var an operator may set; `deployOnly` filters to template-listed ones. */
198
+ export function manifestVarNames(options) {
199
+ return ENV_MANIFEST.flatMap((group) => group.vars
200
+ .filter((spec) => !options?.deployOnly || spec.deploy !== false)
201
+ .map((spec) => spec.name));
202
+ }
203
+ /** `mikan env` output: every group and var with set/unset status. No values. */
204
+ export function envReport(env = readEnv) {
205
+ const lines = [];
206
+ for (const group of ENV_MANIFEST) {
207
+ const active = group.kind === "platform"
208
+ ? platformIsActive(group.key, env)
209
+ ? " — active"
210
+ : " — inactive"
211
+ : "";
212
+ lines.push(`${group.title}${active}${group.doc ? ` · ${group.doc}` : ""}`);
213
+ for (const spec of group.vars) {
214
+ const status = env(spec.name) ? "set" : "unset";
215
+ const marks = [spec.required ? "required" : "", spec.secret ? "secret" : ""]
216
+ .filter(Boolean)
217
+ .join(", ");
218
+ lines.push(` ${spec.name.padEnd(36)} ${status.padEnd(6)}${marks ? ` [${marks}]` : ""} ${spec.doc}`);
219
+ }
220
+ lines.push("");
221
+ }
222
+ lines.push("Each var also accepts a MIKAN_-prefixed alias (e.g. MIKAN_LINK_URL).");
223
+ return lines.join("\n");
224
+ }
225
+ //# sourceMappingURL=env-manifest.js.map