@geminixiang/mikan 1.4.0-beta.0 → 1.5.0-beta.0

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 (108) hide show
  1. package/CHANGELOG.md +43 -3
  2. package/dist/adapters/commands/desktop.d.ts +5 -0
  3. package/dist/adapters/commands/desktop.d.ts.map +1 -0
  4. package/dist/adapters/commands/desktop.js +58 -0
  5. package/dist/adapters/commands/desktop.js.map +1 -0
  6. package/dist/adapters/commands/manifest.d.ts.map +1 -1
  7. package/dist/adapters/commands/manifest.js +8 -0
  8. package/dist/adapters/commands/manifest.js.map +1 -1
  9. package/dist/adapters/commands/registry.d.ts.map +1 -1
  10. package/dist/adapters/commands/registry.js +2 -0
  11. package/dist/adapters/commands/registry.js.map +1 -1
  12. package/dist/adapters/commands/types.d.ts +3 -1
  13. package/dist/adapters/commands/types.d.ts.map +1 -1
  14. package/dist/adapters/commands/types.js.map +1 -1
  15. package/dist/adapters/slack/app-config.d.ts +27 -0
  16. package/dist/adapters/slack/app-config.d.ts.map +1 -0
  17. package/dist/adapters/slack/app-config.js +241 -0
  18. package/dist/adapters/slack/app-config.js.map +1 -0
  19. package/dist/adapters/slack/types.d.ts +46 -1
  20. package/dist/adapters/slack/types.d.ts.map +1 -1
  21. package/dist/adapters/slack/types.js.map +1 -1
  22. package/dist/adapters/web/desktop/index.d.ts +16 -0
  23. package/dist/adapters/web/desktop/index.d.ts.map +1 -0
  24. package/dist/adapters/web/desktop/index.js +163 -0
  25. package/dist/adapters/web/desktop/index.js.map +1 -0
  26. package/dist/adapters/web/desktop/page.d.ts +2 -0
  27. package/dist/adapters/web/desktop/page.d.ts.map +1 -0
  28. package/dist/adapters/web/desktop/page.js +83 -0
  29. package/dist/adapters/web/desktop/page.js.map +1 -0
  30. package/dist/adapters/web/desktop/types.d.ts +8 -0
  31. package/dist/adapters/web/desktop/types.d.ts.map +1 -0
  32. package/dist/adapters/web/desktop/types.js +2 -0
  33. package/dist/adapters/web/desktop/types.js.map +1 -0
  34. package/dist/adapters/web/server.d.ts +2 -0
  35. package/dist/adapters/web/server.d.ts.map +1 -1
  36. package/dist/adapters/web/server.js +19 -0
  37. package/dist/adapters/web/server.js.map +1 -1
  38. package/dist/cli/boot.d.ts.map +1 -1
  39. package/dist/cli/boot.js +4 -1
  40. package/dist/cli/boot.js.map +1 -1
  41. package/dist/cli/onboard.d.ts +3 -0
  42. package/dist/cli/onboard.d.ts.map +1 -1
  43. package/dist/cli/onboard.js +79 -3
  44. package/dist/cli/onboard.js.map +1 -1
  45. package/dist/cli/slack.d.ts +9 -0
  46. package/dist/cli/slack.d.ts.map +1 -0
  47. package/dist/cli/slack.js +96 -0
  48. package/dist/cli/slack.js.map +1 -0
  49. package/dist/cli/types.d.ts +2 -1
  50. package/dist/cli/types.d.ts.map +1 -1
  51. package/dist/cli/types.js.map +1 -1
  52. package/dist/harness/desktop.d.ts +16 -0
  53. package/dist/harness/desktop.d.ts.map +1 -0
  54. package/dist/harness/desktop.js +6 -0
  55. package/dist/harness/desktop.js.map +1 -0
  56. package/dist/harness/execution-resolver.d.ts +1 -0
  57. package/dist/harness/execution-resolver.d.ts.map +1 -1
  58. package/dist/harness/execution-resolver.js +5 -0
  59. package/dist/harness/execution-resolver.js.map +1 -1
  60. package/dist/harness/presenter.d.ts.map +1 -1
  61. package/dist/harness/presenter.js +6 -1
  62. package/dist/harness/presenter.js.map +1 -1
  63. package/dist/harness/runner.d.ts.map +1 -1
  64. package/dist/harness/runner.js +22 -1
  65. package/dist/harness/runner.js.map +1 -1
  66. package/dist/harness/session.d.ts +1 -1
  67. package/dist/harness/session.d.ts.map +1 -1
  68. package/dist/harness/session.js +30 -9
  69. package/dist/harness/session.js.map +1 -1
  70. package/dist/harness/tools/codemode.d.ts.map +1 -1
  71. package/dist/harness/tools/codemode.js +2 -2
  72. package/dist/harness/tools/codemode.js.map +1 -1
  73. package/dist/harness/tools/index.d.ts +2 -2
  74. package/dist/harness/tools/index.d.ts.map +1 -1
  75. package/dist/harness/tools/index.js +10 -2
  76. package/dist/harness/tools/index.js.map +1 -1
  77. package/dist/harness/tools/jev-browser.d.ts +12 -1
  78. package/dist/harness/tools/jev-browser.d.ts.map +1 -1
  79. package/dist/harness/tools/jev-browser.js +189 -30
  80. package/dist/harness/tools/jev-browser.js.map +1 -1
  81. package/dist/harness/tools/pi-tools.d.ts.map +1 -1
  82. package/dist/harness/tools/pi-tools.js +2 -1
  83. package/dist/harness/tools/pi-tools.js.map +1 -1
  84. package/dist/harness/tools/types.d.ts +4 -0
  85. package/dist/harness/tools/types.d.ts.map +1 -1
  86. package/dist/harness/tools/types.js.map +1 -1
  87. package/dist/harness/types.d.ts +2 -1
  88. package/dist/harness/types.d.ts.map +1 -1
  89. package/dist/harness/types.js.map +1 -1
  90. package/dist/main.js +29 -0
  91. package/dist/main.js.map +1 -1
  92. package/dist/runtime/conversation-runtime.js +7 -0
  93. package/dist/runtime/conversation-runtime.js.map +1 -1
  94. package/dist/sandbox/desktop.d.ts +30 -0
  95. package/dist/sandbox/desktop.d.ts.map +1 -0
  96. package/dist/sandbox/desktop.js +112 -0
  97. package/dist/sandbox/desktop.js.map +1 -0
  98. package/dist/sandbox/provisioner.d.ts +6 -2
  99. package/dist/sandbox/provisioner.d.ts.map +1 -1
  100. package/dist/sandbox/provisioner.js +41 -6
  101. package/dist/sandbox/provisioner.js.map +1 -1
  102. package/dist/sandbox/types.d.ts +19 -0
  103. package/dist/sandbox/types.d.ts.map +1 -1
  104. package/dist/sandbox/types.js.map +1 -1
  105. package/dist/types.d.ts +17 -1
  106. package/dist/types.d.ts.map +1 -1
  107. package/dist/types.js.map +1 -1
  108. package/package.json +9 -8
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../../../src/adapters/web/server.ts"],"names":[],"mappings":"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","sourcesContent":["import { createServer, type IncomingMessage, type Server, type ServerResponse } from \"node:http\";\nimport type { MessagingBot, PlatformName } from \"../../types.js\";\nimport { resolveLinkBaseUrl } from \"../../env-manifest.js\";\nimport * as log from \"../../log.js\";\nimport type { SandboxConfig } from \"../../sandbox/types.js\";\nimport { OfficeEventStore, type EventScheduleSink } from \"../../events/index.js\";\nimport type { VaultManager } from \"../../vault/types.js\";\nimport { handleAdminRequest } from \"./admin/portal.js\";\nimport type { AdminRuntimeBridge } from \"./admin/types.js\";\nimport type { InMemoryAdminTokenStore } from \"./admin/portal.js\";\nimport { createLoginRequestHandler } from \"./login/portal.js\";\nimport { requestBaseUrl } from \"./portal-shell.js\";\nimport type { InMemoryLinkTokenStore } from \"./login/portal.js\";\nimport type { NotifyFn } from \"./login/types.js\";\nimport { handleSessionViewRequest } from \"./session-view/portal.js\";\nimport type { SessionViewInteractiveOptions } from \"./session-view/types.js\";\nimport type { InMemorySessionViewTokenStore } from \"./session-view/portal.js\";\nimport type { Office, Workspace } from \"../../office/types.js\";\nimport { createGithubWebhookHandler } from \"../github/webhook.js\";\nimport type { GithubWebhookOptions } from \"../github/types.js\";\nimport { errorMessage } from \"../../unknown-values.js\";\n\ninterface StartWebServerOptions {\n port: number;\n host: string;\n linkTokenStore: InMemoryLinkTokenStore;\n vaultManager: VaultManager;\n notify: NotifyFn;\n sessionViewTokenStore?: InMemorySessionViewTokenStore;\n sessionViewInteractive?: SessionViewInteractiveOptions;\n adminOptions?: {\n adminTokenStore: InMemoryAdminTokenStore;\n workspace: Workspace;\n runtime?: AdminRuntimeBridge;\n sandbox?: SandboxConfig;\n botsByPlatform?: Partial<Record<PlatformName, MessagingBot>>;\n eventScheduler?: () => EventScheduleSink | undefined;\n };\n githubWebhook?: GithubWebhookOptions;\n}\n\nexport function startWebServer(options: StartWebServerOptions): Server {\n const loginHandler = createLoginRequestHandler(\n options.linkTokenStore,\n options.vaultManager,\n options.notify,\n );\n\n const adminEventStore = (office: Office) =>\n new OfficeEventStore(office, options.adminOptions?.eventScheduler?.());\n\n const githubWebhook = options.githubWebhook\n ? createGithubWebhookHandler(options.githubWebhook)\n : undefined;\n\n const server = createServer(async (req: IncomingMessage, res: ServerResponse) => {\n try {\n const url = new URL(req.url ?? \"/\", requestBaseUrl(req));\n\n if (req.method === \"GET\" && url.pathname === \"/health\") {\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ ok: true }));\n return;\n }\n\n if (githubWebhook && (await githubWebhook(req, res, url))) {\n return;\n }\n\n const adminOptions = options.adminOptions;\n if (\n adminOptions?.adminTokenStore &&\n (await handleAdminRequest(req, res, url, {\n linkTokenStore: options.linkTokenStore,\n sessionViewTokenStore: options.sessionViewTokenStore,\n adminTokenStore: adminOptions.adminTokenStore,\n portalBaseUrl: resolveLinkBaseUrl() ?? undefined,\n workspace: adminOptions.workspace,\n eventStore: adminEventStore,\n runtime: adminOptions.runtime,\n sandbox: adminOptions.sandbox,\n botsByPlatform: adminOptions.botsByPlatform,\n }))\n ) {\n return;\n }\n\n if (\n await handleSessionViewRequest(\n req,\n res,\n url,\n options.sessionViewTokenStore,\n options.sessionViewInteractive,\n )\n ) {\n return;\n }\n\n if (loginHandler(req, res, url)) return;\n\n res.writeHead(404);\n res.end();\n } catch (err) {\n log.logWarning(\"Web server request error\", errorMessage(err));\n if (!res.headersSent) {\n res.writeHead(500, { \"Content-Type\": \"application/json\" });\n }\n res.end(JSON.stringify({ error: \"Internal server error\" }));\n }\n });\n\n server.listen(options.port, options.host, () => {\n log.logInfo(`Web server listening on ${options.host}:${options.port}`);\n if (!resolveLinkBaseUrl()) {\n log.logWarning(\n \"MIKAN_LINK_URL is not set — OAuth redirect_uri will be \" +\n \"derived from request headers (Host / X-Forwarded-*). Set \" +\n \"MIKAN_LINK_URL=https://your-host.example.com for production.\",\n );\n }\n });\n\n server.on(\"error\", (err) => {\n log.logWarning(\"Web server error\", err.message);\n });\n\n return server;\n}\n\nexport function closeWebServer(server: Server, graceMs: number): Promise<void> {\n const closed = new Promise<void>((resolve, reject) => {\n server.close((error) => (error ? reject(error) : resolve()));\n });\n server.closeIdleConnections();\n const forceClose = setTimeout(() => server.closeAllConnections(), graceMs);\n return closed.finally(() => clearTimeout(forceClose));\n}\n"]}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../../src/adapters/web/server.ts"],"names":[],"mappings":"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","sourcesContent":["import { createServer, type IncomingMessage, type Server, type ServerResponse } from \"node:http\";\nimport type { Duplex } from \"node:stream\";\nimport {\n handleDesktopRequest,\n handleDesktopUpgrade,\n type DesktopWebOptions,\n} from \"./desktop/index.js\";\nimport type { MessagingBot, PlatformName } from \"../../types.js\";\nimport { resolveLinkBaseUrl } from \"../../env-manifest.js\";\nimport * as log from \"../../log.js\";\nimport type { SandboxConfig } from \"../../sandbox/types.js\";\nimport { OfficeEventStore, type EventScheduleSink } from \"../../events/index.js\";\nimport type { VaultManager } from \"../../vault/types.js\";\nimport { handleAdminRequest } from \"./admin/portal.js\";\nimport type { AdminRuntimeBridge } from \"./admin/types.js\";\nimport type { InMemoryAdminTokenStore } from \"./admin/portal.js\";\nimport { createLoginRequestHandler } from \"./login/portal.js\";\nimport { requestBaseUrl } from \"./portal-shell.js\";\nimport type { InMemoryLinkTokenStore } from \"./login/portal.js\";\nimport type { NotifyFn } from \"./login/types.js\";\nimport { handleSessionViewRequest } from \"./session-view/portal.js\";\nimport type { SessionViewInteractiveOptions } from \"./session-view/types.js\";\nimport type { InMemorySessionViewTokenStore } from \"./session-view/portal.js\";\nimport type { Office, Workspace } from \"../../office/types.js\";\nimport { createGithubWebhookHandler } from \"../github/webhook.js\";\nimport type { GithubWebhookOptions } from \"../github/types.js\";\nimport { errorMessage } from \"../../unknown-values.js\";\n\ninterface StartWebServerOptions {\n port: number;\n host: string;\n linkTokenStore: InMemoryLinkTokenStore;\n vaultManager: VaultManager;\n notify: NotifyFn;\n sessionViewTokenStore?: InMemorySessionViewTokenStore;\n sessionViewInteractive?: SessionViewInteractiveOptions;\n adminOptions?: {\n adminTokenStore: InMemoryAdminTokenStore;\n workspace: Workspace;\n runtime?: AdminRuntimeBridge;\n sandbox?: SandboxConfig;\n botsByPlatform?: Partial<Record<PlatformName, MessagingBot>>;\n eventScheduler?: () => EventScheduleSink | undefined;\n };\n githubWebhook?: GithubWebhookOptions;\n desktop?: DesktopWebOptions;\n}\n\nexport function startWebServer(options: StartWebServerOptions): Server {\n const loginHandler = createLoginRequestHandler(\n options.linkTokenStore,\n options.vaultManager,\n options.notify,\n );\n\n const adminEventStore = (office: Office) =>\n new OfficeEventStore(office, options.adminOptions?.eventScheduler?.());\n\n const githubWebhook = options.githubWebhook\n ? createGithubWebhookHandler(options.githubWebhook)\n : undefined;\n\n const server = createServer(async (req: IncomingMessage, res: ServerResponse) => {\n try {\n const url = new URL(req.url ?? \"/\", requestBaseUrl(req));\n\n if (req.method === \"GET\" && url.pathname === \"/health\") {\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ ok: true }));\n return;\n }\n\n if (githubWebhook && (await githubWebhook(req, res, url))) {\n return;\n }\n\n const adminOptions = options.adminOptions;\n if (\n adminOptions?.adminTokenStore &&\n (await handleAdminRequest(req, res, url, {\n linkTokenStore: options.linkTokenStore,\n sessionViewTokenStore: options.sessionViewTokenStore,\n adminTokenStore: adminOptions.adminTokenStore,\n portalBaseUrl: resolveLinkBaseUrl() ?? undefined,\n workspace: adminOptions.workspace,\n eventStore: adminEventStore,\n runtime: adminOptions.runtime,\n sandbox: adminOptions.sandbox,\n botsByPlatform: adminOptions.botsByPlatform,\n }))\n ) {\n return;\n }\n\n if (\n await handleSessionViewRequest(\n req,\n res,\n url,\n options.sessionViewTokenStore,\n options.sessionViewInteractive,\n )\n ) {\n return;\n }\n\n if (await handleDesktopRequest(req, res, url, options.desktop)) return;\n\n if (loginHandler(req, res, url)) return;\n\n res.writeHead(404);\n res.end();\n } catch (err) {\n log.logWarning(\"Web server request error\", errorMessage(err));\n if (!res.headersSent) {\n res.writeHead(500, { \"Content-Type\": \"application/json\" });\n }\n res.end(JSON.stringify({ error: \"Internal server error\" }));\n }\n });\n\n server.listen(options.port, options.host, () => {\n log.logInfo(`Web server listening on ${options.host}:${options.port}`);\n if (!resolveLinkBaseUrl()) {\n log.logWarning(\n \"MIKAN_LINK_URL is not set — OAuth redirect_uri will be \" +\n \"derived from request headers (Host / X-Forwarded-*). Set \" +\n \"MIKAN_LINK_URL=https://your-host.example.com for production.\",\n );\n }\n });\n\n server.on(\"upgrade\", (req: IncomingMessage, socket: Duplex, head: Buffer) => {\n socket.on(\"error\", () => socket.destroy());\n Promise.resolve()\n .then(() => {\n const url = new URL(req.url ?? \"/\", requestBaseUrl(req));\n return handleDesktopUpgrade(req, socket, head, url, options.desktop);\n })\n .then((handled) => {\n if (!handled) socket.destroy();\n })\n .catch((err: unknown) => {\n log.logWarning(\"Web server upgrade error\", errorMessage(err));\n socket.destroy();\n });\n });\n\n server.on(\"error\", (err) => {\n log.logWarning(\"Web server error\", err.message);\n });\n\n return server;\n}\n\nexport function closeWebServer(server: Server, graceMs: number): Promise<void> {\n const closed = new Promise<void>((resolve, reject) => {\n server.close((error) => (error ? reject(error) : resolve()));\n });\n server.closeIdleConnections();\n const forceClose = setTimeout(() => server.closeAllConnections(), graceMs);\n return closed.finally(() => clearTimeout(forceClose));\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"boot.d.ts","sourceRoot":"","sources":["../../src/cli/boot.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAwB3C,wBAAgB,WAAW,CAAC,IAAI,GAAE,MAAM,EAA0B,GAAG,QAAQ,CAkB5E;AAwBD,wBAAgB,QAAQ,IAAI,MAAM,CAcjC"}
1
+ {"version":3,"file":"boot.d.ts","sourceRoot":"","sources":["../../src/cli/boot.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAwB3C,wBAAgB,WAAW,CAAC,IAAI,GAAE,MAAM,EAA0B,GAAG,QAAQ,CAkB5E;AAyBD,wBAAgB,QAAQ,IAAI,MAAM,CAgBjC"}
package/dist/cli/boot.js CHANGED
@@ -2,7 +2,7 @@ import { join, resolve } from "node:path";
2
2
  import { envSummaryLines } from "../env-manifest.js";
3
3
  import { parseSandboxArg } from "../sandbox/registry.js";
4
4
  import { cliCommand, nonEmptyValue, stateDirPath } from "./arg-grammar.js";
5
- const SUBCOMMANDS = ["migrate", "office", "env"];
5
+ const SUBCOMMANDS = ["migrate", "office", "env", "slack"];
6
6
  function bootCommand() {
7
7
  return cliCommand("mikan")
8
8
  .description("Multi-platform chat agent daemon")
@@ -42,6 +42,7 @@ function subcommandPlan(args) {
42
42
  mode,
43
43
  migrateArgs: mode === "migrate" ? args.slice(1) : undefined,
44
44
  officeArgs: mode === "office" ? args.slice(1) : undefined,
45
+ slackArgs: mode === "slack" ? args.slice(1) : undefined,
45
46
  stateDir,
46
47
  workingDir: join(stateDir, "workspace"),
47
48
  workingDirExplicit: false,
@@ -64,6 +65,8 @@ Commands:
64
65
  mikan migrate --sandbox <spec> [--dry-run] Apply pending state migrations (stop the daemon first).
65
66
  mikan office list List office keys with their platform and conversation id.
66
67
  mikan env Show environment-variable inventory.
68
+ mikan slack token Store a Slack configuration token; mikan then keeps the Slack app configured.
69
+ mikan slack set --name … Customize the Slack app's name and description.
67
70
  mikan onboard Interactive first-run setup.
68
71
 
69
72
  Environment (platform tokens select which chat adapters start):
@@ -1 +1 @@
1
- {"version":3,"file":"boot.js","sourceRoot":"","sources":["../../src/cli/boot.ts"],"names":[],"mappings":"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","sourcesContent":["import { join, resolve } from \"node:path\";\nimport { envSummaryLines } from \"../env-manifest.js\";\nimport { parseSandboxArg } from \"../sandbox/registry.js\";\nimport type { BootPlan } from \"./types.js\";\nimport { cliCommand, nonEmptyValue, stateDirPath } from \"./arg-grammar.js\";\n\nconst SUBCOMMANDS = [\"migrate\", \"office\", \"env\"] as const;\n\ninterface BootOptions {\n sandbox?: string;\n help?: boolean;\n version?: boolean;\n onboard?: boolean;\n}\n\nfunction bootCommand() {\n return cliCommand(\"mikan\")\n .description(\"Multi-platform chat agent daemon\")\n .helpOption(false)\n .argument(\"[working-directory...]\", \"Workspace directory (default: ~/.mikan/workspace)\")\n .option(\"--sandbox <spec>\", \"host | container:<name> | oci | oci:<image[:tag]>\", nonEmptyValue)\n .option(\"--onboard\", \"Interactive first-run setup (also: mikan onboard)\")\n .option(\"-v, --version\", \"Print version\")\n .option(\"-V\", \"Print version\")\n .option(\"-h, --help\", \"Show help\");\n}\n\nexport function resolveBoot(args: string[] = process.argv.slice(2)): BootPlan {\n const routed = subcommandPlan(args);\n if (routed) return routed;\n\n const command = bootCommand();\n command.parse(args, { from: \"user\" });\n const options = command.opts<BootOptions & { V?: boolean }>();\n const onboardFirst = args[0] === \"onboard\";\n const workingDirArg = (onboardFirst ? command.args.slice(1) : command.args).at(-1);\n const sandboxArg = options.sandbox;\n const stateDir = stateDirPath();\n return {\n mode: bootMode({ ...options, version: options.version || options.V }, onboardFirst),\n stateDir,\n workingDir: workingDirArg ? resolve(workingDirArg) : join(stateDir, \"workspace\"),\n workingDirExplicit: workingDirArg !== undefined,\n sandbox: sandboxArg === undefined ? { type: \"host\" } : parseSandboxArg(sandboxArg),\n };\n}\n\nfunction subcommandPlan(args: string[]): BootPlan | undefined {\n const mode = SUBCOMMANDS.find((name) => name === args[0]);\n if (!mode) return undefined;\n const stateDir = stateDirPath();\n return {\n mode,\n migrateArgs: mode === \"migrate\" ? args.slice(1) : undefined,\n officeArgs: mode === \"office\" ? args.slice(1) : undefined,\n stateDir,\n workingDir: join(stateDir, \"workspace\"),\n workingDirExplicit: false,\n sandbox: { type: \"host\" },\n };\n}\n\nfunction bootMode(options: BootOptions, onboardFirst: boolean): BootPlan[\"mode\"] {\n if (options.help) return \"help\";\n if (options.version) return \"version\";\n if (onboardFirst || options.onboard) return \"onboard\";\n return \"run\";\n}\n\nexport function helpText(): string {\n return (\n bootCommand().helpInformation() +\n `\nCommands:\n mikan migrate --sandbox <spec> [--dry-run] Apply pending state migrations (stop the daemon first).\n mikan office list List office keys with their platform and conversation id.\n mikan env Show environment-variable inventory.\n mikan onboard Interactive first-run setup.\n\nEnvironment (platform tokens select which chat adapters start):\n${envSummaryLines().join(\"\\n\")}\nRun mikan env for the full inventory.`\n );\n}\n"]}
1
+ {"version":3,"file":"boot.js","sourceRoot":"","sources":["../../src/cli/boot.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzD,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAE3E,MAAM,WAAW,GAAG,CAAC,SAAS,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,CAAU,CAAC;AASnE,SAAS,WAAW;IAClB,OAAO,UAAU,CAAC,OAAO,CAAC;SACvB,WAAW,CAAC,kCAAkC,CAAC;SAC/C,UAAU,CAAC,KAAK,CAAC;SACjB,QAAQ,CAAC,wBAAwB,EAAE,mDAAmD,CAAC;SACvF,MAAM,CAAC,kBAAkB,EAAE,mDAAmD,EAAE,aAAa,CAAC;SAC9F,MAAM,CAAC,WAAW,EAAE,mDAAmD,CAAC;SACxE,MAAM,CAAC,eAAe,EAAE,eAAe,CAAC;SACxC,MAAM,CAAC,IAAI,EAAE,eAAe,CAAC;SAC7B,MAAM,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC;AACvC,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,IAAI,GAAa,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IAChE,MAAM,MAAM,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;IACpC,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC;IAE1B,MAAM,OAAO,GAAG,WAAW,EAAE,CAAC;IAC9B,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;IACtC,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,EAAiC,CAAC;IAC9D,MAAM,YAAY,GAAG,IAAI,CAAC,CAAC,CAAC,KAAK,SAAS,CAAC;IAC3C,MAAM,aAAa,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IACnF,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC;IACnC,MAAM,QAAQ,GAAG,YAAY,EAAE,CAAC;IAChC,OAAO;QACL,IAAI,EAAE,QAAQ,CAAC,EAAE,GAAG,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,CAAC,EAAE,EAAE,YAAY,CAAC;QACnF,QAAQ;QACR,UAAU,EAAE,aAAa,CAAC,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,WAAW,CAAC;QAChF,kBAAkB,EAAE,aAAa,KAAK,SAAS;QAC/C,OAAO,EAAE,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,eAAe,CAAC,UAAU,CAAC;KACnF,CAAC;AACJ,CAAC;AAED,SAAS,cAAc,CAAC,IAAc;IACpC,MAAM,IAAI,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1D,IAAI,CAAC,IAAI;QAAE,OAAO,SAAS,CAAC;IAC5B,MAAM,QAAQ,GAAG,YAAY,EAAE,CAAC;IAChC,OAAO;QACL,IAAI;QACJ,WAAW,EAAE,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS;QAC3D,UAAU,EAAE,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS;QACzD,SAAS,EAAE,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS;QACvD,QAAQ;QACR,UAAU,EAAE,IAAI,CAAC,QAAQ,EAAE,WAAW,CAAC;QACvC,kBAAkB,EAAE,KAAK;QACzB,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE;KAC1B,CAAC;AACJ,CAAC;AAED,SAAS,QAAQ,CAAC,OAAoB,EAAE,YAAqB;IAC3D,IAAI,OAAO,CAAC,IAAI;QAAE,OAAO,MAAM,CAAC;IAChC,IAAI,OAAO,CAAC,OAAO;QAAE,OAAO,SAAS,CAAC;IACtC,IAAI,YAAY,IAAI,OAAO,CAAC,OAAO;QAAE,OAAO,SAAS,CAAC;IACtD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,QAAQ;IACtB,OAAO,CACL,WAAW,EAAE,CAAC,eAAe,EAAE;QAC/B;;;;;;;;;;EAUF,eAAe,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC;sCACQ,CACnC,CAAC;AACJ,CAAC","sourcesContent":["import { join, resolve } from \"node:path\";\nimport { envSummaryLines } from \"../env-manifest.js\";\nimport { parseSandboxArg } from \"../sandbox/registry.js\";\nimport type { BootPlan } from \"./types.js\";\nimport { cliCommand, nonEmptyValue, stateDirPath } from \"./arg-grammar.js\";\n\nconst SUBCOMMANDS = [\"migrate\", \"office\", \"env\", \"slack\"] as const;\n\ninterface BootOptions {\n sandbox?: string;\n help?: boolean;\n version?: boolean;\n onboard?: boolean;\n}\n\nfunction bootCommand() {\n return cliCommand(\"mikan\")\n .description(\"Multi-platform chat agent daemon\")\n .helpOption(false)\n .argument(\"[working-directory...]\", \"Workspace directory (default: ~/.mikan/workspace)\")\n .option(\"--sandbox <spec>\", \"host | container:<name> | oci | oci:<image[:tag]>\", nonEmptyValue)\n .option(\"--onboard\", \"Interactive first-run setup (also: mikan onboard)\")\n .option(\"-v, --version\", \"Print version\")\n .option(\"-V\", \"Print version\")\n .option(\"-h, --help\", \"Show help\");\n}\n\nexport function resolveBoot(args: string[] = process.argv.slice(2)): BootPlan {\n const routed = subcommandPlan(args);\n if (routed) return routed;\n\n const command = bootCommand();\n command.parse(args, { from: \"user\" });\n const options = command.opts<BootOptions & { V?: boolean }>();\n const onboardFirst = args[0] === \"onboard\";\n const workingDirArg = (onboardFirst ? command.args.slice(1) : command.args).at(-1);\n const sandboxArg = options.sandbox;\n const stateDir = stateDirPath();\n return {\n mode: bootMode({ ...options, version: options.version || options.V }, onboardFirst),\n stateDir,\n workingDir: workingDirArg ? resolve(workingDirArg) : join(stateDir, \"workspace\"),\n workingDirExplicit: workingDirArg !== undefined,\n sandbox: sandboxArg === undefined ? { type: \"host\" } : parseSandboxArg(sandboxArg),\n };\n}\n\nfunction subcommandPlan(args: string[]): BootPlan | undefined {\n const mode = SUBCOMMANDS.find((name) => name === args[0]);\n if (!mode) return undefined;\n const stateDir = stateDirPath();\n return {\n mode,\n migrateArgs: mode === \"migrate\" ? args.slice(1) : undefined,\n officeArgs: mode === \"office\" ? args.slice(1) : undefined,\n slackArgs: mode === \"slack\" ? args.slice(1) : undefined,\n stateDir,\n workingDir: join(stateDir, \"workspace\"),\n workingDirExplicit: false,\n sandbox: { type: \"host\" },\n };\n}\n\nfunction bootMode(options: BootOptions, onboardFirst: boolean): BootPlan[\"mode\"] {\n if (options.help) return \"help\";\n if (options.version) return \"version\";\n if (onboardFirst || options.onboard) return \"onboard\";\n return \"run\";\n}\n\nexport function helpText(): string {\n return (\n bootCommand().helpInformation() +\n `\nCommands:\n mikan migrate --sandbox <spec> [--dry-run] Apply pending state migrations (stop the daemon first).\n mikan office list List office keys with their platform and conversation id.\n mikan env Show environment-variable inventory.\n mikan slack token Store a Slack configuration token; mikan then keeps the Slack app configured.\n mikan slack set --name … Customize the Slack app's name and description.\n mikan onboard Interactive first-run setup.\n\nEnvironment (platform tokens select which chat adapters start):\n${envSummaryLines().join(\"\\n\")}\nRun mikan env for the full inventory.`\n );\n}\n"]}
@@ -1,7 +1,10 @@
1
1
  import type { OnboardIo } from "./types.js";
2
+ import type { SlackAppApi } from "../adapters/slack/types.js";
2
3
  export declare function renderEnvFile(existing: string | undefined, vars: Record<string, string>): string;
3
4
  export declare function runOnboardWizard(stateDir: string, io: OnboardIo, paths?: {
4
5
  envFilePath?: string;
6
+ }, deps?: {
7
+ slackApps?: SlackAppApi;
5
8
  }): Promise<number>;
6
9
  export declare function runOnboardCommand(stateDir: string): Promise<number>;
7
10
  //# sourceMappingURL=onboard.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"onboard.d.ts","sourceRoot":"","sources":["../../src/cli/onboard.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAoI5C,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAUhG;AAUD,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,MAAM,EAChB,EAAE,EAAE,SAAS,EACb,KAAK,CAAC,EAAE;IAAE,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,GAC/B,OAAO,CAAC,MAAM,CAAC,CA2DjB;AAED,wBAAsB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAyBzE"}
1
+ {"version":3,"file":"onboard.d.ts","sourceRoot":"","sources":["../../src/cli/onboard.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAS5C,OAAO,KAAK,EACV,WAAW,EAGZ,MAAM,4BAA4B,CAAC;AAyMpC,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAUhG;AAUD,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,MAAM,EAChB,EAAE,EAAE,SAAS,EACb,KAAK,CAAC,EAAE;IAAE,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,EAChC,IAAI,GAAE;IAAE,SAAS,CAAC,EAAE,WAAW,CAAA;CAAO,GACrC,OAAO,CAAC,MAAM,CAAC,CAwBjB;AA+ED,wBAAsB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAyBzE"}
@@ -8,6 +8,7 @@ import { atomicWritePrivateFile } from "../file-guards.js";
8
8
  import { MINIMAL_SANDBOX_IMAGE, PM2_ECOSYSTEM_FILENAME, renderPm2Ecosystem, } from "./pm2-ecosystem.js";
9
9
  import { PUBLISHED_SANDBOX_SPEC } from "../sandbox/registry.js";
10
10
  import { publishedSandboxImage } from "../sandbox/published-image.js";
11
+ import { createSlackApp, slackAppApi, slackAppCustomizationProblem, slackBotNameProblem, writeConfigTokens, writeSlackAppCustomization, } from "../adapters/slack/app-config.js";
11
12
  class OnboardAborted extends Error {
12
13
  constructor() {
13
14
  super("Onboarding aborted.");
@@ -43,11 +44,54 @@ async function askRequired(io, query, secret = false) {
43
44
  async function askChoice(io, labels, prompt) {
44
45
  return io.select(prompt, labels);
45
46
  }
46
- async function askAdapter(io, env) {
47
+ async function askSlackDisplay(io) {
48
+ for (;;) {
49
+ const name = (await io.ask(" App and bot name [mikan]: ")).trim();
50
+ const description = (await io.ask(" Short description [mikan Slack assistant]: ")).trim();
51
+ const display_information = {
52
+ ...(name ? { name } : {}),
53
+ ...(description ? { description } : {}),
54
+ };
55
+ const customization = Object.keys(display_information).length ? { display_information } : {};
56
+ const problem = slackAppCustomizationProblem(customization);
57
+ if (!problem) {
58
+ const botNameProblem = name ? slackBotNameProblem(name) : undefined;
59
+ if (botNameProblem)
60
+ io.print(` ${botNameProblem}`);
61
+ return customization;
62
+ }
63
+ io.print(` ${problem}`);
64
+ }
65
+ }
66
+ async function createSlackAppInteractively(io, env, apps) {
67
+ io.print(" Open https://api.slack.com/apps, find Your App Configuration Tokens at the bottom, generate a token for your workspace, and copy its Refresh Token. mikan keeps it to update the app when you upgrade.");
68
+ const refreshToken = await askRequired(io, " Configuration refresh token (xoxe-1-…): ", true);
69
+ const customization = await askSlackDisplay(io);
70
+ const name = customization.display_information?.name ?? "mikan";
71
+ if (!(await io.confirm(`Create the Slack app "${name}" now?`)))
72
+ return { cancelled: true };
73
+ const created = await createSlackApp({ apps, refreshToken, customization });
74
+ io.print(` Created Slack app ${created.appId}. Two steps Slack only offers in its web pages:`);
75
+ io.print(` 1. Install it: ${created.installUrl}\n Approve, then copy the Bot User OAuth Token (xoxb-…) from OAuth & Permissions.`);
76
+ io.print(` 2. Create its Socket Mode token: https://api.slack.com/apps/${created.appId}/general\n Under App-Level Tokens, generate a token with the connections:write scope and copy it (xapp-…).`);
77
+ env.SLACK_BOT_TOKEN = await askRequired(io, " SLACK_BOT_TOKEN (xoxb-…): ", true);
78
+ env.SLACK_APP_TOKEN = await askRequired(io, " SLACK_APP_TOKEN (xapp-…): ", true);
79
+ return { slackApp: { appId: created.appId, tokens: created.tokens, customization } };
80
+ }
81
+ async function askAdapter(io, env, apps) {
47
82
  const platforms = ENV_MANIFEST.filter((group) => group.kind === "platform");
48
83
  io.print("\nStep 1/3 — chat adapter");
49
84
  const index = await askChoice(io, platforms.map((g) => g.title), "Platform");
50
85
  const group = platforms[index];
86
+ if (group.key === "slack") {
87
+ const create = await askChoice(io, [
88
+ "Create a new Slack app for me (needs a Slack configuration token)",
89
+ "Use a Slack app I already created",
90
+ ], "Slack app");
91
+ if (create === 0)
92
+ return createSlackAppInteractively(io, env, apps);
93
+ io.print(" Later, `mikan slack token` lets mikan keep this app configured when you upgrade.");
94
+ }
51
95
  for (const spec of group.vars.filter((v) => v.required)) {
52
96
  env[spec.name] = await askRequired(io, ` ${spec.name} (${spec.doc}): `, spec.secret);
53
97
  }
@@ -130,7 +174,7 @@ function rewriteEnvLine(line, pending) {
130
174
  pending.delete(key);
131
175
  return `${key}=${value}`;
132
176
  }
133
- export async function runOnboardWizard(stateDir, io, paths) {
177
+ export async function runOnboardWizard(stateDir, io, paths, deps = {}) {
134
178
  const settingsPath = join(stateDir, "settings.json");
135
179
  if (existsSync(settingsPath)) {
136
180
  io.print(`Global settings already exists at ${settingsPath}.`);
@@ -138,7 +182,32 @@ export async function runOnboardWizard(stateDir, io, paths) {
138
182
  return 1;
139
183
  }
140
184
  const env = {};
141
- const { githubRepos } = await askAdapter(io, env);
185
+ const apps = deps.slackApps ?? slackAppApi();
186
+ const adapter = await askAdapter(io, env, apps);
187
+ if (adapter.cancelled) {
188
+ io.print("Onboarding cancelled; nothing was created or written.");
189
+ return 1;
190
+ }
191
+ const { slackApp } = adapter;
192
+ try {
193
+ const code = await finishOnboarding(stateDir, io, env, adapter, paths);
194
+ if (code !== 0)
195
+ await discardSlackApp(io, apps, slackApp);
196
+ return code;
197
+ }
198
+ catch (error) {
199
+ await discardSlackApp(io, apps, slackApp);
200
+ throw error;
201
+ }
202
+ }
203
+ async function discardSlackApp(io, apps, slackApp) {
204
+ if (!slackApp)
205
+ return;
206
+ await apps.delete(slackApp.tokens.token, slackApp.appId);
207
+ io.print(`Deleted the Slack app ${slackApp.appId} created during onboarding.`);
208
+ }
209
+ async function finishOnboarding(stateDir, io, env, { githubRepos, slackApp }, paths) {
210
+ const settingsPath = join(stateDir, "settings.json");
142
211
  const { llm, modelsJson } = await askLlm(io, env);
143
212
  const sandboxSpec = await askSandboxSpec(io);
144
213
  const modelsPath = join(stateDir, "models.json");
@@ -154,6 +223,13 @@ export async function runOnboardWizard(stateDir, io, paths) {
154
223
  createGlobalSettingsFile(stateDir, { llm, githubRepos });
155
224
  recordAllMigrations(stateDir);
156
225
  io.print(`\nWrote ${settingsPath}`);
226
+ if (slackApp) {
227
+ writeConfigTokens(stateDir, slackApp.tokens);
228
+ if (slackApp.customization.display_information) {
229
+ writeSlackAppCustomization(stateDir, slackApp.customization);
230
+ }
231
+ io.print(`Wrote the Slack configuration token and app settings to ${stateDir}`);
232
+ }
157
233
  if (modelsJson) {
158
234
  atomicWritePrivateFile(modelsPath, `${modelsJson}\n`);
159
235
  io.print(`Wrote ${modelsPath}`);
@@ -1 +1 @@
1
- {"version":3,"file":"onboard.js","sourceRoot":"","sources":["../../src/cli/onboard.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport * as prompts from \"@clack/prompts\";\nimport { ENV_MANIFEST, envSetReport, readEnv } from \"../env-manifest.js\";\nimport { createGlobalSettingsFile } from \"../settings/index.js\";\nimport { recordAllMigrations } from \"../migrations/index.js\";\nimport type { OnboardLlmChoice } from \"../types.js\";\nimport { atomicWritePrivateFile } from \"../file-guards.js\";\nimport {\n MINIMAL_SANDBOX_IMAGE,\n PM2_ECOSYSTEM_FILENAME,\n renderPm2Ecosystem,\n} from \"./pm2-ecosystem.js\";\nimport { PUBLISHED_SANDBOX_SPEC } from \"../sandbox/registry.js\";\nimport { publishedSandboxImage } from \"../sandbox/published-image.js\";\nimport type { OnboardIo } from \"./types.js\";\n\nclass OnboardAborted extends Error {\n constructor() {\n super(\"Onboarding aborted.\");\n }\n}\n\nasync function answer<T>(result: Promise<T>): Promise<Exclude<T, symbol>> {\n const value = await result;\n if (prompts.isCancel(value)) throw new OnboardAborted();\n return value as Exclude<T, symbol>;\n}\n\nfunction terminalIo(): OnboardIo {\n return {\n ask: (message) => answer(prompts.text({ message: message.trim() })),\n askSecret: (message) => answer(prompts.password({ message: message.trim() })),\n select: (message, labels) =>\n answer(\n prompts.select({\n message,\n options: labels.map((label, value) => ({ label, value })),\n }),\n ),\n confirm: (message) => answer(prompts.confirm({ message, initialValue: true })),\n print: (line) => prompts.log.info(line.trim()),\n close: () => {},\n };\n}\n\nasync function askRequired(io: OnboardIo, query: string, secret = false): Promise<string> {\n for (;;) {\n const value = (secret ? await io.askSecret(query) : await io.ask(query)).trim();\n if (value) return value;\n io.print(\" (required)\");\n }\n}\n\nasync function askChoice(io: OnboardIo, labels: string[], prompt: string): Promise<number> {\n return io.select(prompt, labels);\n}\n\nasync function askAdapter(\n io: OnboardIo,\n env: Record<string, string>,\n): Promise<{ githubRepos?: string[] }> {\n const platforms = ENV_MANIFEST.filter((group) => group.kind === \"platform\");\n io.print(\"\\nStep 1/3 — chat adapter\");\n const index = await askChoice(\n io,\n platforms.map((g) => g.title),\n \"Platform\",\n );\n const group = platforms[index]!;\n for (const spec of group.vars.filter((v) => v.required)) {\n env[spec.name] = await askRequired(io, ` ${spec.name} (${spec.doc}): `, spec.secret);\n }\n if (group.key !== \"github\") return {};\n const repos = await askRequired(io, \" Repositories (owner/repo or owner/*, comma-separated): \");\n return {\n githubRepos: repos\n .split(\",\")\n .map((repo) => repo.trim())\n .filter(Boolean),\n };\n}\n\nasync function askLlm(\n io: OnboardIo,\n env: Record<string, string>,\n): Promise<{ llm: OnboardLlmChoice; modelsJson?: string }> {\n io.print(\"\\nStep 2/3 — LLM provider\");\n const index = await askChoice(\n io,\n [\n \"Anthropic (ANTHROPIC_API_KEY)\",\n \"OpenAI (OPENAI_API_KEY)\",\n \"Custom OpenAI-compatible endpoint (vLLM, proxy, …) — writes models.json\",\n ],\n \"Provider\",\n );\n if (index === 0) {\n env.ANTHROPIC_API_KEY = await askRequired(io, \" ANTHROPIC_API_KEY: \", true);\n return { llm: { provider: \"anthropic\", model: \"claude-sonnet-4-6\" } };\n }\n if (index === 1) {\n env.OPENAI_API_KEY = await askRequired(io, \" OPENAI_API_KEY: \", true);\n return { llm: { provider: \"openai\", model: \"gpt-5.2\" } };\n }\n const provider = (await io.ask(\" Provider name [custom]: \")).trim() || \"custom\";\n const baseUrl = await askRequired(io, \" Base URL (e.g. http://host:8080/v1): \");\n const apiKey = (await io.askSecret(\" API key (empty if none): \")).trim();\n const ids = (await askRequired(io, \" Model ids (comma-separated): \"))\n .split(\",\")\n .map((id) => id.trim())\n .filter(Boolean);\n const modelsJson = JSON.stringify(\n {\n providers: {\n [provider]: {\n api: \"openai-completions\",\n baseUrl,\n apiKey: apiKey ? apiKey : undefined,\n models: ids.map((id) => ({ id })),\n },\n },\n },\n null,\n 2,\n );\n return { llm: { provider, model: ids[0]! }, modelsJson };\n}\n\nasync function askSandboxSpec(io: OnboardIo): Promise<string> {\n io.print(\n \"\\nStep 3/3 — sandbox image (one container per conversation; needs nerdctl, Podman, or Docker)\",\n );\n const index = await askChoice(\n io,\n [\n `${publishedSandboxImage()} (recommended: git, gh, gcloud, node, python, browser; follows mikan upgrades)`,\n `${MINIMAL_SANDBOX_IMAGE} (minimal: shell only, no git or package installs)`,\n \"Another image from Docker Hub or a registry…\",\n ],\n \"Sandbox image\",\n );\n if (index === 0) return PUBLISHED_SANDBOX_SPEC;\n if (index === 1) return `oci:${MINIMAL_SANDBOX_IMAGE}`;\n return `oci:${await askRequired(io, \" Image (e.g. registry/name:tag): \")}`;\n}\n\nexport function renderEnvFile(existing: string | undefined, vars: Record<string, string>): string {\n const pending = new Map(Object.entries(vars));\n const lines: string[] = [];\n for (const line of existing ? existing.split(\"\\n\") : []) {\n const rendered = rewriteEnvLine(line, pending);\n if (rendered.trim() || lines.length > 0) lines.push(rendered);\n }\n while (lines.at(-1) === \"\") lines.pop();\n for (const [key, value] of pending) lines.push(`${key}=${value}`);\n return `${lines.join(\"\\n\")}\\n`;\n}\n\nfunction rewriteEnvLine(line: string, pending: Map<string, string>): string {\n const key = /^([A-Za-z_][A-Za-z0-9_]*)=/.exec(line)?.[1];\n if (key === undefined || !pending.has(key)) return line;\n const value = pending.get(key);\n pending.delete(key);\n return `${key}=${value}`;\n}\n\nexport async function runOnboardWizard(\n stateDir: string,\n io: OnboardIo,\n paths?: { envFilePath?: string },\n): Promise<number> {\n const settingsPath = join(stateDir, \"settings.json\");\n if (existsSync(settingsPath)) {\n io.print(`Global settings already exists at ${settingsPath}.`);\n io.print(\"Remove it first to re-run onboarding, or edit it directly.\");\n return 1;\n }\n\n const env: Record<string, string> = {};\n const { githubRepos } = await askAdapter(io, env);\n const { llm, modelsJson } = await askLlm(io, env);\n const sandboxSpec = await askSandboxSpec(io);\n\n const modelsPath = join(stateDir, \"models.json\");\n if (modelsJson && existsSync(modelsPath)) {\n io.print(\n `models.json already exists at ${modelsPath}. Add the provider manually before retrying; nothing was written.`,\n );\n return 1;\n }\n io.print(\n `Review settings\\nProvider: ${llm.provider}\\nModel: ${llm.model}\\nSandbox: ${sandboxSpec}\\nSettings: ${settingsPath}\\nCredentials: ${paths?.envFilePath ?? join(stateDir, \"mikan.env\")}${modelsJson ? `\\nModels: ${modelsPath}` : \"\"}\\nSecrets are hidden.`,\n );\n if (!(await io.confirm(\"Save these settings?\"))) {\n io.print(\"Onboarding cancelled; nothing was written.\");\n return 1;\n }\n\n createGlobalSettingsFile(stateDir, { llm, githubRepos });\n recordAllMigrations(stateDir);\n io.print(`\\nWrote ${settingsPath}`);\n\n if (modelsJson) {\n atomicWritePrivateFile(modelsPath, `${modelsJson}\\n`);\n io.print(`Wrote ${modelsPath}`);\n }\n\n const envFilePath = paths?.envFilePath ?? join(stateDir, \"mikan.env\");\n const existing = existsSync(envFilePath) ? readFileSync(envFilePath, \"utf-8\") : undefined;\n atomicWritePrivateFile(envFilePath, renderEnvFile(existing, env));\n io.print(`Wrote ${envFilePath} (0600)`);\n\n io.print(`\\n${envSetReport((name) => env[name] ?? readEnv(name))}`);\n\n const ecosystemPath = join(stateDir, PM2_ECOSYSTEM_FILENAME);\n if (existsSync(ecosystemPath)) {\n io.print(`Kept existing ${ecosystemPath}`);\n } else {\n atomicWritePrivateFile(ecosystemPath, renderPm2Ecosystem(sandboxSpec));\n io.print(`Wrote ${ecosystemPath}`);\n }\n\n io.print(\"Next steps:\");\n io.print(` pm2 start ${ecosystemPath} && pm2 save`);\n io.print(\n ` Foreground instead: set -a; source ${envFilePath}; set +a; mikan --sandbox=${sandboxSpec}`,\n );\n io.print(\" mikan pulls the sandbox image on start.\");\n return 0;\n}\n\nexport async function runOnboardCommand(stateDir: string): Promise<number> {\n if (!process.stdin.isTTY) {\n const settingsPath = createGlobalSettingsFile(stateDir);\n recordAllMigrations(stateDir);\n console.log(`Created global settings at ${settingsPath}`);\n console.log(\n `Review the file, then start mikan (workspace defaults to ${join(stateDir, \"workspace\")}).`,\n );\n return 0;\n }\n prompts.intro(\"Mikan setup · arrows to choose · Esc / Ctrl+C to cancel\");\n const io = terminalIo();\n try {\n const code = await runOnboardWizard(stateDir, io);\n prompts.outro(code === 0 ? \"Setup complete\" : \"Setup not saved\");\n return code;\n } catch (err) {\n if (err instanceof OnboardAborted) {\n prompts.cancel(\"Onboarding aborted; nothing was written.\");\n return 1;\n }\n throw err;\n } finally {\n io.close();\n }\n}\n"]}
1
+ {"version":3,"file":"onboard.js","sourceRoot":"","sources":["../../src/cli/onboard.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport * as prompts from \"@clack/prompts\";\nimport { ENV_MANIFEST, envSetReport, readEnv } from \"../env-manifest.js\";\nimport { createGlobalSettingsFile } from \"../settings/index.js\";\nimport { recordAllMigrations } from \"../migrations/index.js\";\nimport type { OnboardLlmChoice } from \"../types.js\";\nimport { atomicWritePrivateFile } from \"../file-guards.js\";\nimport {\n MINIMAL_SANDBOX_IMAGE,\n PM2_ECOSYSTEM_FILENAME,\n renderPm2Ecosystem,\n} from \"./pm2-ecosystem.js\";\nimport { PUBLISHED_SANDBOX_SPEC } from \"../sandbox/registry.js\";\nimport { publishedSandboxImage } from \"../sandbox/published-image.js\";\nimport type { OnboardIo } from \"./types.js\";\nimport {\n createSlackApp,\n slackAppApi,\n slackAppCustomizationProblem,\n slackBotNameProblem,\n writeConfigTokens,\n writeSlackAppCustomization,\n} from \"../adapters/slack/app-config.js\";\nimport type {\n SlackAppApi,\n SlackAppCustomization,\n SlackConfigTokens,\n} from \"../adapters/slack/types.js\";\n\ninterface CreatedSlackApp {\n appId: string;\n tokens: SlackConfigTokens;\n customization: SlackAppCustomization;\n}\n\ninterface AdapterAnswers {\n githubRepos?: string[];\n slackApp?: CreatedSlackApp;\n cancelled?: boolean;\n}\n\nclass OnboardAborted extends Error {\n constructor() {\n super(\"Onboarding aborted.\");\n }\n}\n\nasync function answer<T>(result: Promise<T>): Promise<Exclude<T, symbol>> {\n const value = await result;\n if (prompts.isCancel(value)) throw new OnboardAborted();\n return value as Exclude<T, symbol>;\n}\n\nfunction terminalIo(): OnboardIo {\n return {\n ask: (message) => answer(prompts.text({ message: message.trim() })),\n askSecret: (message) => answer(prompts.password({ message: message.trim() })),\n select: (message, labels) =>\n answer(\n prompts.select({\n message,\n options: labels.map((label, value) => ({ label, value })),\n }),\n ),\n confirm: (message) => answer(prompts.confirm({ message, initialValue: true })),\n print: (line) => prompts.log.info(line.trim()),\n close: () => {},\n };\n}\n\nasync function askRequired(io: OnboardIo, query: string, secret = false): Promise<string> {\n for (;;) {\n const value = (secret ? await io.askSecret(query) : await io.ask(query)).trim();\n if (value) return value;\n io.print(\" (required)\");\n }\n}\n\nasync function askChoice(io: OnboardIo, labels: string[], prompt: string): Promise<number> {\n return io.select(prompt, labels);\n}\n\nasync function askSlackDisplay(io: OnboardIo): Promise<SlackAppCustomization> {\n for (;;) {\n const name = (await io.ask(\" App and bot name [mikan]: \")).trim();\n const description = (await io.ask(\" Short description [mikan Slack assistant]: \")).trim();\n const display_information = {\n ...(name ? { name } : {}),\n ...(description ? { description } : {}),\n };\n const customization = Object.keys(display_information).length ? { display_information } : {};\n const problem = slackAppCustomizationProblem(customization);\n if (!problem) {\n const botNameProblem = name ? slackBotNameProblem(name) : undefined;\n if (botNameProblem) io.print(` ${botNameProblem}`);\n return customization;\n }\n io.print(` ${problem}`);\n }\n}\n\nasync function createSlackAppInteractively(\n io: OnboardIo,\n env: Record<string, string>,\n apps: SlackAppApi,\n): Promise<AdapterAnswers> {\n io.print(\n \" Open https://api.slack.com/apps, find Your App Configuration Tokens at the bottom, generate a token for your workspace, and copy its Refresh Token. mikan keeps it to update the app when you upgrade.\",\n );\n const refreshToken = await askRequired(io, \" Configuration refresh token (xoxe-1-…): \", true);\n const customization = await askSlackDisplay(io);\n const name = customization.display_information?.name ?? \"mikan\";\n if (!(await io.confirm(`Create the Slack app \"${name}\" now?`))) return { cancelled: true };\n const created = await createSlackApp({ apps, refreshToken, customization });\n io.print(` Created Slack app ${created.appId}. Two steps Slack only offers in its web pages:`);\n io.print(\n ` 1. Install it: ${created.installUrl}\\n Approve, then copy the Bot User OAuth Token (xoxb-…) from OAuth & Permissions.`,\n );\n io.print(\n ` 2. Create its Socket Mode token: https://api.slack.com/apps/${created.appId}/general\\n Under App-Level Tokens, generate a token with the connections:write scope and copy it (xapp-…).`,\n );\n env.SLACK_BOT_TOKEN = await askRequired(io, \" SLACK_BOT_TOKEN (xoxb-…): \", true);\n env.SLACK_APP_TOKEN = await askRequired(io, \" SLACK_APP_TOKEN (xapp-…): \", true);\n return { slackApp: { appId: created.appId, tokens: created.tokens, customization } };\n}\n\nasync function askAdapter(\n io: OnboardIo,\n env: Record<string, string>,\n apps: SlackAppApi,\n): Promise<AdapterAnswers> {\n const platforms = ENV_MANIFEST.filter((group) => group.kind === \"platform\");\n io.print(\"\\nStep 1/3 — chat adapter\");\n const index = await askChoice(\n io,\n platforms.map((g) => g.title),\n \"Platform\",\n );\n const group = platforms[index]!;\n if (group.key === \"slack\") {\n const create = await askChoice(\n io,\n [\n \"Create a new Slack app for me (needs a Slack configuration token)\",\n \"Use a Slack app I already created\",\n ],\n \"Slack app\",\n );\n if (create === 0) return createSlackAppInteractively(io, env, apps);\n io.print(\" Later, `mikan slack token` lets mikan keep this app configured when you upgrade.\");\n }\n for (const spec of group.vars.filter((v) => v.required)) {\n env[spec.name] = await askRequired(io, ` ${spec.name} (${spec.doc}): `, spec.secret);\n }\n if (group.key !== \"github\") return {};\n const repos = await askRequired(io, \" Repositories (owner/repo or owner/*, comma-separated): \");\n return {\n githubRepos: repos\n .split(\",\")\n .map((repo) => repo.trim())\n .filter(Boolean),\n };\n}\n\nasync function askLlm(\n io: OnboardIo,\n env: Record<string, string>,\n): Promise<{ llm: OnboardLlmChoice; modelsJson?: string }> {\n io.print(\"\\nStep 2/3 — LLM provider\");\n const index = await askChoice(\n io,\n [\n \"Anthropic (ANTHROPIC_API_KEY)\",\n \"OpenAI (OPENAI_API_KEY)\",\n \"Custom OpenAI-compatible endpoint (vLLM, proxy, …) — writes models.json\",\n ],\n \"Provider\",\n );\n if (index === 0) {\n env.ANTHROPIC_API_KEY = await askRequired(io, \" ANTHROPIC_API_KEY: \", true);\n return { llm: { provider: \"anthropic\", model: \"claude-sonnet-4-6\" } };\n }\n if (index === 1) {\n env.OPENAI_API_KEY = await askRequired(io, \" OPENAI_API_KEY: \", true);\n return { llm: { provider: \"openai\", model: \"gpt-5.2\" } };\n }\n const provider = (await io.ask(\" Provider name [custom]: \")).trim() || \"custom\";\n const baseUrl = await askRequired(io, \" Base URL (e.g. http://host:8080/v1): \");\n const apiKey = (await io.askSecret(\" API key (empty if none): \")).trim();\n const ids = (await askRequired(io, \" Model ids (comma-separated): \"))\n .split(\",\")\n .map((id) => id.trim())\n .filter(Boolean);\n const modelsJson = JSON.stringify(\n {\n providers: {\n [provider]: {\n api: \"openai-completions\",\n baseUrl,\n apiKey: apiKey ? apiKey : undefined,\n models: ids.map((id) => ({ id })),\n },\n },\n },\n null,\n 2,\n );\n return { llm: { provider, model: ids[0]! }, modelsJson };\n}\n\nasync function askSandboxSpec(io: OnboardIo): Promise<string> {\n io.print(\n \"\\nStep 3/3 — sandbox image (one container per conversation; needs nerdctl, Podman, or Docker)\",\n );\n const index = await askChoice(\n io,\n [\n `${publishedSandboxImage()} (recommended: git, gh, gcloud, node, python, browser; follows mikan upgrades)`,\n `${MINIMAL_SANDBOX_IMAGE} (minimal: shell only, no git or package installs)`,\n \"Another image from Docker Hub or a registry…\",\n ],\n \"Sandbox image\",\n );\n if (index === 0) return PUBLISHED_SANDBOX_SPEC;\n if (index === 1) return `oci:${MINIMAL_SANDBOX_IMAGE}`;\n return `oci:${await askRequired(io, \" Image (e.g. registry/name:tag): \")}`;\n}\n\nexport function renderEnvFile(existing: string | undefined, vars: Record<string, string>): string {\n const pending = new Map(Object.entries(vars));\n const lines: string[] = [];\n for (const line of existing ? existing.split(\"\\n\") : []) {\n const rendered = rewriteEnvLine(line, pending);\n if (rendered.trim() || lines.length > 0) lines.push(rendered);\n }\n while (lines.at(-1) === \"\") lines.pop();\n for (const [key, value] of pending) lines.push(`${key}=${value}`);\n return `${lines.join(\"\\n\")}\\n`;\n}\n\nfunction rewriteEnvLine(line: string, pending: Map<string, string>): string {\n const key = /^([A-Za-z_][A-Za-z0-9_]*)=/.exec(line)?.[1];\n if (key === undefined || !pending.has(key)) return line;\n const value = pending.get(key);\n pending.delete(key);\n return `${key}=${value}`;\n}\n\nexport async function runOnboardWizard(\n stateDir: string,\n io: OnboardIo,\n paths?: { envFilePath?: string },\n deps: { slackApps?: SlackAppApi } = {},\n): Promise<number> {\n const settingsPath = join(stateDir, \"settings.json\");\n if (existsSync(settingsPath)) {\n io.print(`Global settings already exists at ${settingsPath}.`);\n io.print(\"Remove it first to re-run onboarding, or edit it directly.\");\n return 1;\n }\n\n const env: Record<string, string> = {};\n const apps = deps.slackApps ?? slackAppApi();\n const adapter = await askAdapter(io, env, apps);\n if (adapter.cancelled) {\n io.print(\"Onboarding cancelled; nothing was created or written.\");\n return 1;\n }\n const { slackApp } = adapter;\n try {\n const code = await finishOnboarding(stateDir, io, env, adapter, paths);\n if (code !== 0) await discardSlackApp(io, apps, slackApp);\n return code;\n } catch (error) {\n await discardSlackApp(io, apps, slackApp);\n throw error;\n }\n}\n\nasync function discardSlackApp(\n io: OnboardIo,\n apps: SlackAppApi,\n slackApp: CreatedSlackApp | undefined,\n): Promise<void> {\n if (!slackApp) return;\n await apps.delete(slackApp.tokens.token, slackApp.appId);\n io.print(`Deleted the Slack app ${slackApp.appId} created during onboarding.`);\n}\n\nasync function finishOnboarding(\n stateDir: string,\n io: OnboardIo,\n env: Record<string, string>,\n { githubRepos, slackApp }: AdapterAnswers,\n paths?: { envFilePath?: string },\n): Promise<number> {\n const settingsPath = join(stateDir, \"settings.json\");\n const { llm, modelsJson } = await askLlm(io, env);\n const sandboxSpec = await askSandboxSpec(io);\n\n const modelsPath = join(stateDir, \"models.json\");\n if (modelsJson && existsSync(modelsPath)) {\n io.print(\n `models.json already exists at ${modelsPath}. Add the provider manually before retrying; nothing was written.`,\n );\n return 1;\n }\n io.print(\n `Review settings\\nProvider: ${llm.provider}\\nModel: ${llm.model}\\nSandbox: ${sandboxSpec}\\nSettings: ${settingsPath}\\nCredentials: ${paths?.envFilePath ?? join(stateDir, \"mikan.env\")}${modelsJson ? `\\nModels: ${modelsPath}` : \"\"}\\nSecrets are hidden.`,\n );\n if (!(await io.confirm(\"Save these settings?\"))) {\n io.print(\"Onboarding cancelled; nothing was written.\");\n return 1;\n }\n\n createGlobalSettingsFile(stateDir, { llm, githubRepos });\n recordAllMigrations(stateDir);\n io.print(`\\nWrote ${settingsPath}`);\n\n if (slackApp) {\n writeConfigTokens(stateDir, slackApp.tokens);\n if (slackApp.customization.display_information) {\n writeSlackAppCustomization(stateDir, slackApp.customization);\n }\n io.print(`Wrote the Slack configuration token and app settings to ${stateDir}`);\n }\n\n if (modelsJson) {\n atomicWritePrivateFile(modelsPath, `${modelsJson}\\n`);\n io.print(`Wrote ${modelsPath}`);\n }\n\n const envFilePath = paths?.envFilePath ?? join(stateDir, \"mikan.env\");\n const existing = existsSync(envFilePath) ? readFileSync(envFilePath, \"utf-8\") : undefined;\n atomicWritePrivateFile(envFilePath, renderEnvFile(existing, env));\n io.print(`Wrote ${envFilePath} (0600)`);\n\n io.print(`\\n${envSetReport((name) => env[name] ?? readEnv(name))}`);\n\n const ecosystemPath = join(stateDir, PM2_ECOSYSTEM_FILENAME);\n if (existsSync(ecosystemPath)) {\n io.print(`Kept existing ${ecosystemPath}`);\n } else {\n atomicWritePrivateFile(ecosystemPath, renderPm2Ecosystem(sandboxSpec));\n io.print(`Wrote ${ecosystemPath}`);\n }\n\n io.print(\"Next steps:\");\n io.print(` pm2 start ${ecosystemPath} && pm2 save`);\n io.print(\n ` Foreground instead: set -a; source ${envFilePath}; set +a; mikan --sandbox=${sandboxSpec}`,\n );\n io.print(\" mikan pulls the sandbox image on start.\");\n return 0;\n}\n\nexport async function runOnboardCommand(stateDir: string): Promise<number> {\n if (!process.stdin.isTTY) {\n const settingsPath = createGlobalSettingsFile(stateDir);\n recordAllMigrations(stateDir);\n console.log(`Created global settings at ${settingsPath}`);\n console.log(\n `Review the file, then start mikan (workspace defaults to ${join(stateDir, \"workspace\")}).`,\n );\n return 0;\n }\n prompts.intro(\"Mikan setup · arrows to choose · Esc / Ctrl+C to cancel\");\n const io = terminalIo();\n try {\n const code = await runOnboardWizard(stateDir, io);\n prompts.outro(code === 0 ? \"Setup complete\" : \"Setup not saved\");\n return code;\n } catch (err) {\n if (err instanceof OnboardAborted) {\n prompts.cancel(\"Onboarding aborted; nothing was written.\");\n return 1;\n }\n throw err;\n } finally {\n io.close();\n }\n}\n"]}
@@ -0,0 +1,9 @@
1
+ import type { SlackAppApi } from "../adapters/slack/types.js";
2
+ interface SlackCommandDeps {
3
+ stateDir: string;
4
+ apps: SlackAppApi;
5
+ readSecret: (message: string) => Promise<string>;
6
+ }
7
+ export declare function runSlackCommand(argv: string[], overrides?: Partial<SlackCommandDeps>): Promise<number>;
8
+ export {};
9
+ //# sourceMappingURL=slack.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slack.d.ts","sourceRoot":"","sources":["../../src/cli/slack.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,WAAW,EAAyB,MAAM,4BAA4B,CAAC;AAIrF,UAAU,gBAAgB;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,WAAW,CAAC;IAClB,UAAU,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;CAClD;AAuED,wBAAsB,eAAe,CACnC,IAAI,EAAE,MAAM,EAAE,EACd,SAAS,GAAE,OAAO,CAAC,gBAAgB,CAAM,GACxC,OAAO,CAAC,MAAM,CAAC,CAgCjB"}
@@ -0,0 +1,96 @@
1
+ import * as prompts from "@clack/prompts";
2
+ import { readSlackAppCustomization, slackAppApi, slackBotNameProblem, writeConfigTokens, writeSlackAppCustomization, } from "../adapters/slack/app-config.js";
3
+ import { errorMessage } from "../unknown-values.js";
4
+ import { cliCommand, commandExitCode, stateDirPath } from "./arg-grammar.js";
5
+ const REFRESH_TOKEN_PROMPT = "Refresh token from api.slack.com/apps > Your App Configuration Tokens (xoxe-1-…)";
6
+ async function readSecretLine(message) {
7
+ if (process.stdin.isTTY) {
8
+ const value = await prompts.password({ message });
9
+ return prompts.isCancel(value) ? "" : value;
10
+ }
11
+ let input = "";
12
+ for await (const chunk of process.stdin)
13
+ input += String(chunk);
14
+ return (input
15
+ .split("\n")
16
+ .find((line) => line.trim())
17
+ ?.trim() ?? "");
18
+ }
19
+ async function storeToken(deps) {
20
+ const refreshToken = (await deps.readSecret(REFRESH_TOKEN_PROMPT)).trim();
21
+ if (!refreshToken) {
22
+ console.error("No refresh token given; nothing was stored.");
23
+ return 1;
24
+ }
25
+ try {
26
+ writeConfigTokens(deps.stateDir, await deps.apps.rotate(refreshToken));
27
+ }
28
+ catch (error) {
29
+ console.error(`Slack refused the refresh token (${errorMessage(error)}); nothing was stored.`);
30
+ return 1;
31
+ }
32
+ console.log("Stored. mikan applies its Slack app configuration on its next start.");
33
+ return 0;
34
+ }
35
+ function setDisplay(stateDir, options) {
36
+ const current = readSlackAppCustomization(stateDir);
37
+ const next = {
38
+ ...current,
39
+ display_information: {
40
+ ...current.display_information,
41
+ ...(options.name === undefined ? {} : { name: options.name }),
42
+ ...(options.description === undefined ? {} : { description: options.description }),
43
+ ...(options.longDescription === undefined
44
+ ? {}
45
+ : { long_description: options.longDescription }),
46
+ ...(options.backgroundColor === undefined
47
+ ? {}
48
+ : { background_color: options.backgroundColor }),
49
+ },
50
+ };
51
+ try {
52
+ writeSlackAppCustomization(stateDir, next);
53
+ }
54
+ catch (error) {
55
+ console.error(errorMessage(error));
56
+ return 1;
57
+ }
58
+ const botNameProblem = options.name === undefined ? undefined : slackBotNameProblem(options.name);
59
+ if (botNameProblem)
60
+ console.log(botNameProblem);
61
+ console.log("Saved slack.json. mikan applies it to the Slack app on its next start.");
62
+ return 0;
63
+ }
64
+ export async function runSlackCommand(argv, overrides = {}) {
65
+ const deps = {
66
+ stateDir: overrides.stateDir ?? stateDirPath(),
67
+ apps: overrides.apps ?? slackAppApi(),
68
+ readSecret: overrides.readSecret ?? readSecretLine,
69
+ };
70
+ const command = cliCommand("mikan slack").description("Configure the Slack app that mikan keeps in sync on start");
71
+ let result = 1;
72
+ command
73
+ .command("token")
74
+ .description("Store a Slack app configuration token so mikan can update the app")
75
+ .action(async () => {
76
+ result = await storeToken(deps);
77
+ });
78
+ command
79
+ .command("set")
80
+ .description("Customize the app's name and description (saved in slack.json)")
81
+ .option("--name <name>", "App and bot name, up to 35 characters")
82
+ .option("--description <text>", "Short description, up to 140 characters")
83
+ .option("--long-description <text>", "Long description, up to 4000 characters")
84
+ .option("--background-color <hex>", "Background color such as #4d5673")
85
+ .action((options) => {
86
+ result = setDisplay(deps.stateDir, options);
87
+ });
88
+ try {
89
+ await command.parseAsync(argv, { from: "user" });
90
+ return result;
91
+ }
92
+ catch (error) {
93
+ return commandExitCode(error, command);
94
+ }
95
+ }
96
+ //# sourceMappingURL=slack.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slack.js","sourceRoot":"","sources":["../../src/cli/slack.ts"],"names":[],"mappings":"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","sourcesContent":["import * as prompts from \"@clack/prompts\";\nimport {\n readSlackAppCustomization,\n slackAppApi,\n slackBotNameProblem,\n writeConfigTokens,\n writeSlackAppCustomization,\n} from \"../adapters/slack/app-config.js\";\nimport type { SlackAppApi, SlackAppCustomization } from \"../adapters/slack/types.js\";\nimport { errorMessage } from \"../unknown-values.js\";\nimport { cliCommand, commandExitCode, stateDirPath } from \"./arg-grammar.js\";\n\ninterface SlackCommandDeps {\n stateDir: string;\n apps: SlackAppApi;\n readSecret: (message: string) => Promise<string>;\n}\n\ninterface SetOptions {\n name?: string;\n description?: string;\n longDescription?: string;\n backgroundColor?: string;\n}\n\nconst REFRESH_TOKEN_PROMPT =\n \"Refresh token from api.slack.com/apps > Your App Configuration Tokens (xoxe-1-…)\";\n\nasync function readSecretLine(message: string): Promise<string> {\n if (process.stdin.isTTY) {\n const value = await prompts.password({ message });\n return prompts.isCancel(value) ? \"\" : value;\n }\n let input = \"\";\n for await (const chunk of process.stdin) input += String(chunk);\n return (\n input\n .split(\"\\n\")\n .find((line) => line.trim())\n ?.trim() ?? \"\"\n );\n}\n\nasync function storeToken(deps: SlackCommandDeps): Promise<number> {\n const refreshToken = (await deps.readSecret(REFRESH_TOKEN_PROMPT)).trim();\n if (!refreshToken) {\n console.error(\"No refresh token given; nothing was stored.\");\n return 1;\n }\n try {\n writeConfigTokens(deps.stateDir, await deps.apps.rotate(refreshToken));\n } catch (error) {\n console.error(`Slack refused the refresh token (${errorMessage(error)}); nothing was stored.`);\n return 1;\n }\n console.log(\"Stored. mikan applies its Slack app configuration on its next start.\");\n return 0;\n}\n\nfunction setDisplay(stateDir: string, options: SetOptions): number {\n const current = readSlackAppCustomization(stateDir);\n const next: SlackAppCustomization = {\n ...current,\n display_information: {\n ...current.display_information,\n ...(options.name === undefined ? {} : { name: options.name }),\n ...(options.description === undefined ? {} : { description: options.description }),\n ...(options.longDescription === undefined\n ? {}\n : { long_description: options.longDescription }),\n ...(options.backgroundColor === undefined\n ? {}\n : { background_color: options.backgroundColor }),\n },\n };\n try {\n writeSlackAppCustomization(stateDir, next);\n } catch (error) {\n console.error(errorMessage(error));\n return 1;\n }\n const botNameProblem = options.name === undefined ? undefined : slackBotNameProblem(options.name);\n if (botNameProblem) console.log(botNameProblem);\n console.log(\"Saved slack.json. mikan applies it to the Slack app on its next start.\");\n return 0;\n}\n\nexport async function runSlackCommand(\n argv: string[],\n overrides: Partial<SlackCommandDeps> = {},\n): Promise<number> {\n const deps: SlackCommandDeps = {\n stateDir: overrides.stateDir ?? stateDirPath(),\n apps: overrides.apps ?? slackAppApi(),\n readSecret: overrides.readSecret ?? readSecretLine,\n };\n const command = cliCommand(\"mikan slack\").description(\n \"Configure the Slack app that mikan keeps in sync on start\",\n );\n let result = 1;\n command\n .command(\"token\")\n .description(\"Store a Slack app configuration token so mikan can update the app\")\n .action(async () => {\n result = await storeToken(deps);\n });\n command\n .command(\"set\")\n .description(\"Customize the app's name and description (saved in slack.json)\")\n .option(\"--name <name>\", \"App and bot name, up to 35 characters\")\n .option(\"--description <text>\", \"Short description, up to 140 characters\")\n .option(\"--long-description <text>\", \"Long description, up to 4000 characters\")\n .option(\"--background-color <hex>\", \"Background color such as #4d5673\")\n .action((options: SetOptions) => {\n result = setDisplay(deps.stateDir, options);\n });\n try {\n await command.parseAsync(argv, { from: \"user\" });\n return result;\n } catch (error) {\n return commandExitCode(error, command);\n }\n}\n"]}
@@ -8,9 +8,10 @@ export interface OnboardIo {
8
8
  close(): void;
9
9
  }
10
10
  export interface BootPlan {
11
- mode: "migrate" | "office" | "env" | "help" | "version" | "onboard" | "run";
11
+ mode: "migrate" | "office" | "env" | "slack" | "help" | "version" | "onboard" | "run";
12
12
  migrateArgs?: string[];
13
13
  officeArgs?: string[];
14
+ slackArgs?: string[];
14
15
  stateDir: string;
15
16
  workingDir: string;
16
17
  workingDirExplicit: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/cli/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD,MAAM,WAAW,SAAS;IACxB,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACpC,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC1C,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACzD,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACzC,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,KAAK,IAAI,IAAI,CAAC;CACf;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,SAAS,GAAG,QAAQ,GAAG,KAAK,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,KAAK,CAAC;IAC5E,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,kBAAkB,EAAE,OAAO,CAAC;IAC5B,OAAO,EAAE,aAAa,CAAC;CACxB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/cli/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD,MAAM,WAAW,SAAS;IACxB,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACpC,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC1C,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACzD,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACzC,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,KAAK,IAAI,IAAI,CAAC;CACf;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,SAAS,GAAG,QAAQ,GAAG,KAAK,GAAG,OAAO,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,KAAK,CAAC;IACtF,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,kBAAkB,EAAE,OAAO,CAAC;IAC5B,OAAO,EAAE,aAAa,CAAC;CACxB"}
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/cli/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { SandboxConfig } from \"../sandbox/types.js\";\n\nexport interface OnboardIo {\n ask(query: string): Promise<string>;\n askSecret(query: string): Promise<string>;\n select(query: string, labels: string[]): Promise<number>;\n confirm(query: string): Promise<boolean>;\n print(line: string): void;\n close(): void;\n}\n\nexport interface BootPlan {\n mode: \"migrate\" | \"office\" | \"env\" | \"help\" | \"version\" | \"onboard\" | \"run\";\n migrateArgs?: string[];\n officeArgs?: string[];\n stateDir: string;\n workingDir: string;\n workingDirExplicit: boolean;\n sandbox: SandboxConfig;\n}\n"]}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/cli/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { SandboxConfig } from \"../sandbox/types.js\";\n\nexport interface OnboardIo {\n ask(query: string): Promise<string>;\n askSecret(query: string): Promise<string>;\n select(query: string, labels: string[]): Promise<number>;\n confirm(query: string): Promise<boolean>;\n print(line: string): void;\n close(): void;\n}\n\nexport interface BootPlan {\n mode: \"migrate\" | \"office\" | \"env\" | \"slack\" | \"help\" | \"version\" | \"onboard\" | \"run\";\n migrateArgs?: string[];\n officeArgs?: string[];\n slackArgs?: string[];\n stateDir: string;\n workingDir: string;\n workingDirExplicit: boolean;\n sandbox: SandboxConfig;\n}\n"]}
@@ -0,0 +1,16 @@
1
+ import type { OfficeDesktop } from "../sandbox/desktop.js";
2
+ import type { DockerContainerManager } from "../sandbox/provisioner.js";
3
+ import type { SandboxConfig } from "../sandbox/types.js";
4
+ import type { Workspace } from "../office/types.js";
5
+ import type { OpenDesktop } from "../types.js";
6
+ import type { VaultManager } from "../vault/types.js";
7
+ interface DesktopOpenerOptions {
8
+ sandbox: SandboxConfig;
9
+ vaultManager: VaultManager;
10
+ provisioner: DockerContainerManager;
11
+ workspace: Workspace;
12
+ desktop: Pick<OfficeDesktop, "start">;
13
+ }
14
+ export declare function createDesktopOpener(options: DesktopOpenerOptions): OpenDesktop;
15
+ export {};
16
+ //# sourceMappingURL=desktop.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"desktop.d.ts","sourceRoot":"","sources":["../../src/harness/desktop.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AACxE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAGtD,UAAU,oBAAoB;IAC5B,OAAO,EAAE,aAAa,CAAC;IACvB,YAAY,EAAE,YAAY,CAAC;IAC3B,WAAW,EAAE,sBAAsB,CAAC;IACpC,SAAS,EAAE,SAAS,CAAC;IACrB,OAAO,EAAE,IAAI,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;CACvC;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,oBAAoB,GAAG,WAAW,CAQ9E"}
@@ -0,0 +1,6 @@
1
+ import { ActorExecutionResolver } from "./execution-resolver.js";
2
+ export function createDesktopOpener(options) {
3
+ const resolver = new ActorExecutionResolver(options.sandbox, options.vaultManager, options.provisioner, options.workspace);
4
+ return async (actor) => options.desktop.start(await resolver.prepare(actor));
5
+ }
6
+ //# sourceMappingURL=desktop.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"desktop.js","sourceRoot":"","sources":["../../src/harness/desktop.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AAUjE,MAAM,UAAU,mBAAmB,CAAC,OAA6B;IAC/D,MAAM,QAAQ,GAAG,IAAI,sBAAsB,CACzC,OAAO,CAAC,OAAO,EACf,OAAO,CAAC,YAAY,EACpB,OAAO,CAAC,WAAW,EACnB,OAAO,CAAC,SAAS,CAClB,CAAC;IACF,OAAO,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;AAC/E,CAAC","sourcesContent":["import type { OfficeDesktop } from \"../sandbox/desktop.js\";\nimport type { DockerContainerManager } from \"../sandbox/provisioner.js\";\nimport type { SandboxConfig } from \"../sandbox/types.js\";\nimport type { Workspace } from \"../office/types.js\";\nimport type { OpenDesktop } from \"../types.js\";\nimport type { VaultManager } from \"../vault/types.js\";\nimport { ActorExecutionResolver } from \"./execution-resolver.js\";\n\ninterface DesktopOpenerOptions {\n sandbox: SandboxConfig;\n vaultManager: VaultManager;\n provisioner: DockerContainerManager;\n workspace: Workspace;\n desktop: Pick<OfficeDesktop, \"start\">;\n}\n\nexport function createDesktopOpener(options: DesktopOpenerOptions): OpenDesktop {\n const resolver = new ActorExecutionResolver(\n options.sandbox,\n options.vaultManager,\n options.provisioner,\n options.workspace,\n );\n return async (actor) => options.desktop.start(await resolver.prepare(actor));\n}\n"]}
@@ -15,6 +15,7 @@ export declare class ActorExecutionResolver {
15
15
  pathContext: import("../sandbox/types.js").RuntimePathContext;
16
16
  projection: WorkspaceProjection;
17
17
  }>;
18
+ prepare(context: ActorContext): Promise<string>;
18
19
  private resolvePlan;
19
20
  private ensureDefaultSharedVault;
20
21
  private resolveSandboxConfig;
@@ -1 +1 @@
1
- {"version":3,"file":"execution-resolver.d.ts","sourceRoot":"","sources":["../../src/harness/execution-resolver.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AACnE,OAAO,KAAK,EAAkB,YAAY,EAAiB,MAAM,aAAa,CAAC;AAM/E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAGzD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAItD,OAAO,KAAK,EAAE,mBAAmB,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAEzE,qBAAa,sBAAsB;IAE/B,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,YAAY;IACpB,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,SAAS;IAJnB,YACU,UAAU,EAAE,aAAa,EACzB,YAAY,EAAE,IAAI,CAAC,YAAY,EAAE,UAAU,GAAG,SAAS,GAAG,mBAAmB,CAAC,EAC9E,WAAW,EAAE,IAAI,CAAC,sBAAsB,EAAE,WAAW,GAAG,UAAU,CAAC,GAAG,SAAS,EAC/E,SAAS,EAAE,SAAS,EAC1B;IAEE,OAAO,CAAC,OAAO,EAAE,YAAY;;;;;OAUlC;IAED,OAAO,CAAC,WAAW;IAmCnB,OAAO,CAAC,wBAAwB;IAiBhC,OAAO,CAAC,oBAAoB;IAQ5B,OAAO,CAAC,wBAAwB;IA0ChC,OAAO,CAAC,aAAa;CA4BtB"}
1
+ {"version":3,"file":"execution-resolver.d.ts","sourceRoot":"","sources":["../../src/harness/execution-resolver.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AACnE,OAAO,KAAK,EAAkB,YAAY,EAAiB,MAAM,aAAa,CAAC;AAM/E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAGzD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAItD,OAAO,KAAK,EAAE,mBAAmB,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAEzE,qBAAa,sBAAsB;IAE/B,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,YAAY;IACpB,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,SAAS;IAJnB,YACU,UAAU,EAAE,aAAa,EACzB,YAAY,EAAE,IAAI,CAAC,YAAY,EAAE,UAAU,GAAG,SAAS,GAAG,mBAAmB,CAAC,EAC9E,WAAW,EAAE,IAAI,CAAC,sBAAsB,EAAE,WAAW,GAAG,UAAU,CAAC,GAAG,SAAS,EAC/E,SAAS,EAAE,SAAS,EAC1B;IAEE,OAAO,CAAC,OAAO,EAAE,YAAY;;;;;OAUlC;IAEK,OAAO,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,CAIpD;IAED,OAAO,CAAC,WAAW;IAmCnB,OAAO,CAAC,wBAAwB;IAiBhC,OAAO,CAAC,oBAAoB;IAQ5B,OAAO,CAAC,wBAAwB;IA0ChC,OAAO,CAAC,aAAa;CA4BtB"}
@@ -25,6 +25,11 @@ export class ActorExecutionResolver {
25
25
  });
26
26
  return { env, sandboxConfig: plan.sandboxConfig, pathContext, projection };
27
27
  }
28
+ async prepare(context) {
29
+ const { plan } = this.resolvePlan(context);
30
+ await this.buildEnsureReadyCallback(plan, context.address.conversationId)?.();
31
+ return plan.resourceKey;
32
+ }
28
33
  resolvePlan(context) {
29
34
  const scope = { userId: context.userId, address: context.address };
30
35
  const credentialKey = credentialAuthorizationKey(this.baseConfig, scope);