@geminixiang/mikan 1.4.0 → 1.5.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.
- package/CHANGELOG.md +36 -0
- package/dist/adapters/commands/desktop.d.ts +5 -0
- package/dist/adapters/commands/desktop.d.ts.map +1 -0
- package/dist/adapters/commands/desktop.js +58 -0
- package/dist/adapters/commands/desktop.js.map +1 -0
- package/dist/adapters/commands/manifest.d.ts.map +1 -1
- package/dist/adapters/commands/manifest.js +8 -0
- package/dist/adapters/commands/manifest.js.map +1 -1
- package/dist/adapters/commands/registry.d.ts.map +1 -1
- package/dist/adapters/commands/registry.js +2 -0
- package/dist/adapters/commands/registry.js.map +1 -1
- package/dist/adapters/commands/types.d.ts +3 -1
- package/dist/adapters/commands/types.d.ts.map +1 -1
- package/dist/adapters/commands/types.js.map +1 -1
- package/dist/adapters/messages.d.ts +0 -1
- package/dist/adapters/messages.d.ts.map +1 -1
- package/dist/adapters/messages.js +0 -3
- package/dist/adapters/messages.js.map +1 -1
- package/dist/adapters/slack/app-config.d.ts +27 -0
- package/dist/adapters/slack/app-config.d.ts.map +1 -0
- package/dist/adapters/slack/app-config.js +241 -0
- package/dist/adapters/slack/app-config.js.map +1 -0
- package/dist/adapters/slack/bot.d.ts +0 -3
- package/dist/adapters/slack/bot.d.ts.map +1 -1
- package/dist/adapters/slack/bot.js +4 -163
- package/dist/adapters/slack/bot.js.map +1 -1
- package/dist/adapters/slack/types.d.ts +46 -2
- package/dist/adapters/slack/types.d.ts.map +1 -1
- package/dist/adapters/slack/types.js.map +1 -1
- package/dist/adapters/web/desktop/index.d.ts +16 -0
- package/dist/adapters/web/desktop/index.d.ts.map +1 -0
- package/dist/adapters/web/desktop/index.js +163 -0
- package/dist/adapters/web/desktop/index.js.map +1 -0
- package/dist/adapters/web/desktop/page.d.ts +2 -0
- package/dist/adapters/web/desktop/page.d.ts.map +1 -0
- package/dist/adapters/web/desktop/page.js +83 -0
- package/dist/adapters/web/desktop/page.js.map +1 -0
- package/dist/adapters/web/desktop/types.d.ts +8 -0
- package/dist/adapters/web/desktop/types.d.ts.map +1 -0
- package/dist/adapters/web/desktop/types.js +2 -0
- package/dist/adapters/web/desktop/types.js.map +1 -0
- package/dist/adapters/web/server.d.ts +2 -0
- package/dist/adapters/web/server.d.ts.map +1 -1
- package/dist/adapters/web/server.js +19 -0
- package/dist/adapters/web/server.js.map +1 -1
- package/dist/cli/boot.d.ts.map +1 -1
- package/dist/cli/boot.js +4 -1
- package/dist/cli/boot.js.map +1 -1
- package/dist/cli/onboard.d.ts +3 -0
- package/dist/cli/onboard.d.ts.map +1 -1
- package/dist/cli/onboard.js +79 -3
- package/dist/cli/onboard.js.map +1 -1
- package/dist/cli/slack.d.ts +9 -0
- package/dist/cli/slack.d.ts.map +1 -0
- package/dist/cli/slack.js +96 -0
- package/dist/cli/slack.js.map +1 -0
- package/dist/cli/types.d.ts +2 -1
- package/dist/cli/types.d.ts.map +1 -1
- package/dist/cli/types.js.map +1 -1
- package/dist/harness/desktop.d.ts +16 -0
- package/dist/harness/desktop.d.ts.map +1 -0
- package/dist/harness/desktop.js +6 -0
- package/dist/harness/desktop.js.map +1 -0
- package/dist/harness/execution-resolver.d.ts +1 -0
- package/dist/harness/execution-resolver.d.ts.map +1 -1
- package/dist/harness/execution-resolver.js +5 -0
- package/dist/harness/execution-resolver.js.map +1 -1
- package/dist/harness/presenter.d.ts.map +1 -1
- package/dist/harness/presenter.js +6 -1
- package/dist/harness/presenter.js.map +1 -1
- package/dist/harness/runner.d.ts.map +1 -1
- package/dist/harness/runner.js +22 -1
- package/dist/harness/runner.js.map +1 -1
- package/dist/harness/session.d.ts +1 -1
- package/dist/harness/session.d.ts.map +1 -1
- package/dist/harness/session.js +30 -9
- package/dist/harness/session.js.map +1 -1
- package/dist/harness/tools/codemode.d.ts.map +1 -1
- package/dist/harness/tools/codemode.js +2 -2
- package/dist/harness/tools/codemode.js.map +1 -1
- package/dist/harness/tools/index.d.ts +2 -2
- package/dist/harness/tools/index.d.ts.map +1 -1
- package/dist/harness/tools/index.js +10 -2
- package/dist/harness/tools/index.js.map +1 -1
- package/dist/harness/tools/jev-browser.d.ts +12 -1
- package/dist/harness/tools/jev-browser.d.ts.map +1 -1
- package/dist/harness/tools/jev-browser.js +189 -30
- package/dist/harness/tools/jev-browser.js.map +1 -1
- package/dist/harness/tools/pi-tools.d.ts.map +1 -1
- package/dist/harness/tools/pi-tools.js +2 -1
- package/dist/harness/tools/pi-tools.js.map +1 -1
- package/dist/harness/tools/types.d.ts +4 -0
- package/dist/harness/tools/types.d.ts.map +1 -1
- package/dist/harness/tools/types.js.map +1 -1
- package/dist/harness/types.d.ts +2 -1
- package/dist/harness/types.d.ts.map +1 -1
- package/dist/harness/types.js.map +1 -1
- package/dist/main.js +29 -0
- package/dist/main.js.map +1 -1
- package/dist/runtime/conversation-runtime.js +7 -0
- package/dist/runtime/conversation-runtime.js.map +1 -1
- package/dist/sandbox/desktop.d.ts +30 -0
- package/dist/sandbox/desktop.d.ts.map +1 -0
- package/dist/sandbox/desktop.js +112 -0
- package/dist/sandbox/desktop.js.map +1 -0
- package/dist/sandbox/provisioner.d.ts +4 -1
- package/dist/sandbox/provisioner.d.ts.map +1 -1
- package/dist/sandbox/provisioner.js +21 -0
- package/dist/sandbox/provisioner.js.map +1 -1
- package/dist/sandbox/types.d.ts +19 -0
- package/dist/sandbox/types.d.ts.map +1 -1
- package/dist/sandbox/types.js.map +1 -1
- package/dist/types.d.ts +17 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +9 -8
package/dist/cli/boot.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
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,CAAU,CAAC;
|
|
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\", \"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"]}
|
package/dist/cli/onboard.d.ts
CHANGED
|
@@ -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;
|
|
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"}
|
package/dist/cli/onboard.js
CHANGED
|
@@ -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
|
|
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
|
|
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}`);
|
package/dist/cli/onboard.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"onboard.js","sourceRoot":"","sources":["../../src/cli/onboard.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AACzE,OAAO,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAE7D,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EACL,qBAAqB,EACrB,sBAAsB,EACtB,kBAAkB,GACnB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAChE,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AAGtE,MAAM,cAAe,SAAQ,KAAK;IAChC;QACE,KAAK,CAAC,qBAAqB,CAAC,CAAC;IAC/B,CAAC;CACF;AAED,KAAK,UAAU,MAAM,CAAI,MAAkB;IACzC,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC;IAC3B,IAAI,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,MAAM,IAAI,cAAc,EAAE,CAAC;IACxD,OAAO,KAA2B,CAAC;AACrC,CAAC;AAED,SAAS,UAAU;IACjB,OAAO;QACL,GAAG,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACnE,SAAS,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAC7E,MAAM,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,CAC1B,MAAM,CACJ,OAAO,CAAC,MAAM,CAAC;YACb,OAAO;YACP,OAAO,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;SAC1D,CAAC,CACH;QACH,OAAO,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,CAAC;QAC9E,KAAK,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QAC9C,KAAK,EAAE,GAAG,EAAE,GAAE,CAAC;KAChB,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,WAAW,CAAC,EAAa,EAAE,KAAa,EAAE,MAAM,GAAG,KAAK;IACrE,SAAS,CAAC;QACR,MAAM,KAAK,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAChF,IAAI,KAAK;YAAE,OAAO,KAAK,CAAC;QACxB,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;IAC3B,CAAC;AACH,CAAC;AAED,KAAK,UAAU,SAAS,CAAC,EAAa,EAAE,MAAgB,EAAE,MAAc;IACtE,OAAO,EAAE,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AACnC,CAAC;AAED,KAAK,UAAU,UAAU,CACvB,EAAa,EACb,GAA2B;IAE3B,MAAM,SAAS,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC;IAC5E,EAAE,CAAC,KAAK,CAAC,2BAA2B,CAAC,CAAC;IACtC,MAAM,KAAK,GAAG,MAAM,SAAS,CAC3B,EAAE,EACF,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,EAC7B,UAAU,CACX,CAAC;IACF,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAE,CAAC;IAChC,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC;QACxD,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,MAAM,WAAW,CAAC,EAAE,EAAE,KAAK,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,GAAG,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IACxF,CAAC;IACD,IAAI,KAAK,CAAC,GAAG,KAAK,QAAQ;QAAE,OAAO,EAAE,CAAC;IACtC,MAAM,KAAK,GAAG,MAAM,WAAW,CAAC,EAAE,EAAE,2DAA2D,CAAC,CAAC;IACjG,OAAO;QACL,WAAW,EAAE,KAAK;aACf,KAAK,CAAC,GAAG,CAAC;aACV,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;aAC1B,MAAM,CAAC,OAAO,CAAC;KACnB,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,MAAM,CACnB,EAAa,EACb,GAA2B;IAE3B,EAAE,CAAC,KAAK,CAAC,2BAA2B,CAAC,CAAC;IACtC,MAAM,KAAK,GAAG,MAAM,SAAS,CAC3B,EAAE,EACF;QACE,+BAA+B;QAC/B,yBAAyB;QACzB,yEAAyE;KAC1E,EACD,UAAU,CACX,CAAC;IACF,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC;QAChB,GAAG,CAAC,iBAAiB,GAAG,MAAM,WAAW,CAAC,EAAE,EAAE,uBAAuB,EAAE,IAAI,CAAC,CAAC;QAC7E,OAAO,EAAE,GAAG,EAAE,EAAE,QAAQ,EAAE,WAAW,EAAE,KAAK,EAAE,mBAAmB,EAAE,EAAE,CAAC;IACxE,CAAC;IACD,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC;QAChB,GAAG,CAAC,cAAc,GAAG,MAAM,WAAW,CAAC,EAAE,EAAE,oBAAoB,EAAE,IAAI,CAAC,CAAC;QACvE,OAAO,EAAE,GAAG,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,CAAC;IAC3D,CAAC;IACD,MAAM,QAAQ,GAAG,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,QAAQ,CAAC;IACjF,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,EAAE,EAAE,yCAAyC,CAAC,CAAC;IACjF,MAAM,MAAM,GAAG,CAAC,MAAM,EAAE,CAAC,SAAS,CAAC,6BAA6B,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAC1E,MAAM,GAAG,GAAG,CAAC,MAAM,WAAW,CAAC,EAAE,EAAE,iCAAiC,CAAC,CAAC;SACnE,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC;SACtB,MAAM,CAAC,OAAO,CAAC,CAAC;IACnB,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAC/B;QACE,SAAS,EAAE;YACT,CAAC,QAAQ,CAAC,EAAE;gBACV,GAAG,EAAE,oBAAoB;gBACzB,OAAO;gBACP,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS;gBACnC,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;aAClC;SACF;KACF,EACD,IAAI,EACJ,CAAC,CACF,CAAC;IACF,OAAO,EAAE,GAAG,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC,CAAE,EAAE,EAAE,UAAU,EAAE,CAAC;AAC3D,CAAC;AAED,KAAK,UAAU,cAAc,CAAC,EAAa;IACzC,EAAE,CAAC,KAAK,CACN,+FAA+F,CAChG,CAAC;IACF,MAAM,KAAK,GAAG,MAAM,SAAS,CAC3B,EAAE,EACF;QACE,GAAG,qBAAqB,EAAE,gFAAgF;QAC1G,GAAG,qBAAqB,oDAAoD;QAC5E,8CAA8C;KAC/C,EACD,eAAe,CAChB,CAAC;IACF,IAAI,KAAK,KAAK,CAAC;QAAE,OAAO,sBAAsB,CAAC;IAC/C,IAAI,KAAK,KAAK,CAAC;QAAE,OAAO,OAAO,qBAAqB,EAAE,CAAC;IACvD,OAAO,OAAO,MAAM,WAAW,CAAC,EAAE,EAAE,oCAAoC,CAAC,EAAE,CAAC;AAC9E,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,QAA4B,EAAE,IAA4B;IACtF,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IAC9C,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;QACxD,MAAM,QAAQ,GAAG,cAAc,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAC/C,IAAI,QAAQ,CAAC,IAAI,EAAE,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;YAAE,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAChE,CAAC;IACD,OAAO,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE;QAAE,KAAK,CAAC,GAAG,EAAE,CAAC;IACxC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,OAAO;QAAE,KAAK,CAAC,IAAI,CAAC,GAAG,GAAG,IAAI,KAAK,EAAE,CAAC,CAAC;IAClE,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;AACjC,CAAC;AAED,SAAS,cAAc,CAAC,IAAY,EAAE,OAA4B;IAChE,MAAM,GAAG,GAAG,4BAA4B,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IACzD,IAAI,GAAG,KAAK,SAAS,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IACxD,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC/B,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACpB,OAAO,GAAG,GAAG,IAAI,KAAK,EAAE,CAAC;AAC3B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,QAAgB,EAChB,EAAa,EACb,KAAgC;IAEhC,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC;IACrD,IAAI,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QAC7B,EAAE,CAAC,KAAK,CAAC,qCAAqC,YAAY,GAAG,CAAC,CAAC;QAC/D,EAAE,CAAC,KAAK,CAAC,4DAA4D,CAAC,CAAC;QACvE,OAAO,CAAC,CAAC;IACX,CAAC;IAED,MAAM,GAAG,GAA2B,EAAE,CAAC;IACvC,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,UAAU,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;IAClD,MAAM,EAAE,GAAG,EAAE,UAAU,EAAE,GAAG,MAAM,MAAM,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;IAClD,MAAM,WAAW,GAAG,MAAM,cAAc,CAAC,EAAE,CAAC,CAAC;IAE7C,MAAM,UAAU,GAAG,IAAI,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;IACjD,IAAI,UAAU,IAAI,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QACzC,EAAE,CAAC,KAAK,CACN,iCAAiC,UAAU,mEAAmE,CAC/G,CAAC;QACF,OAAO,CAAC,CAAC;IACX,CAAC;IACD,EAAE,CAAC,KAAK,CACN,8BAA8B,GAAG,CAAC,QAAQ,YAAY,GAAG,CAAC,KAAK,cAAc,WAAW,eAAe,YAAY,kBAAkB,KAAK,EAAE,WAAW,IAAI,IAAI,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,aAAa,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,uBAAuB,CAC5P,CAAC;IACF,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,sBAAsB,CAAC,CAAC,EAAE,CAAC;QAChD,EAAE,CAAC,KAAK,CAAC,4CAA4C,CAAC,CAAC;QACvD,OAAO,CAAC,CAAC;IACX,CAAC;IAED,wBAAwB,CAAC,QAAQ,EAAE,EAAE,GAAG,EAAE,WAAW,EAAE,CAAC,CAAC;IACzD,mBAAmB,CAAC,QAAQ,CAAC,CAAC;IAC9B,EAAE,CAAC,KAAK,CAAC,WAAW,YAAY,EAAE,CAAC,CAAC;IAEpC,IAAI,UAAU,EAAE,CAAC;QACf,sBAAsB,CAAC,UAAU,EAAE,GAAG,UAAU,IAAI,CAAC,CAAC;QACtD,EAAE,CAAC,KAAK,CAAC,SAAS,UAAU,EAAE,CAAC,CAAC;IAClC,CAAC;IAED,MAAM,WAAW,GAAG,KAAK,EAAE,WAAW,IAAI,IAAI,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;IACtE,MAAM,QAAQ,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC1F,sBAAsB,CAAC,WAAW,EAAE,aAAa,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC;IAClE,EAAE,CAAC,KAAK,CAAC,SAAS,WAAW,SAAS,CAAC,CAAC;IAExC,EAAE,CAAC,KAAK,CAAC,KAAK,YAAY,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC;IAEpE,MAAM,aAAa,GAAG,IAAI,CAAC,QAAQ,EAAE,sBAAsB,CAAC,CAAC;IAC7D,IAAI,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;QAC9B,EAAE,CAAC,KAAK,CAAC,iBAAiB,aAAa,EAAE,CAAC,CAAC;IAC7C,CAAC;SAAM,CAAC;QACN,sBAAsB,CAAC,aAAa,EAAE,kBAAkB,CAAC,WAAW,CAAC,CAAC,CAAC;QACvE,EAAE,CAAC,KAAK,CAAC,SAAS,aAAa,EAAE,CAAC,CAAC;IACrC,CAAC;IAED,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;IACxB,EAAE,CAAC,KAAK,CAAC,eAAe,aAAa,cAAc,CAAC,CAAC;IACrD,EAAE,CAAC,KAAK,CACN,wCAAwC,WAAW,6BAA6B,WAAW,EAAE,CAC9F,CAAC;IACF,EAAE,CAAC,KAAK,CAAC,2CAA2C,CAAC,CAAC;IACtD,OAAO,CAAC,CAAC;AACX,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,QAAgB;IACtD,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QACzB,MAAM,YAAY,GAAG,wBAAwB,CAAC,QAAQ,CAAC,CAAC;QACxD,mBAAmB,CAAC,QAAQ,CAAC,CAAC;QAC9B,OAAO,CAAC,GAAG,CAAC,8BAA8B,YAAY,EAAE,CAAC,CAAC;QAC1D,OAAO,CAAC,GAAG,CACT,4DAA4D,IAAI,CAAC,QAAQ,EAAE,WAAW,CAAC,IAAI,CAC5F,CAAC;QACF,OAAO,CAAC,CAAC;IACX,CAAC;IACD,OAAO,CAAC,KAAK,CAAC,yDAAyD,CAAC,CAAC;IACzE,MAAM,EAAE,GAAG,UAAU,EAAE,CAAC;IACxB,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,gBAAgB,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QAClD,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC;QACjE,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,cAAc,EAAE,CAAC;YAClC,OAAO,CAAC,MAAM,CAAC,0CAA0C,CAAC,CAAC;YAC3D,OAAO,CAAC,CAAC;QACX,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;YAAS,CAAC;QACT,EAAE,CAAC,KAAK,EAAE,CAAC;IACb,CAAC;AACH,CAAC","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"]}
|
package/dist/cli/types.d.ts
CHANGED
|
@@ -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;
|
package/dist/cli/types.d.ts.map
CHANGED
|
@@ -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;
|
|
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"}
|
package/dist/cli/types.js.map
CHANGED
|
@@ -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);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"execution-resolver.js","sourceRoot":"","sources":["../../src/harness/execution-resolver.ts"],"names":[],"mappings":"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","sourcesContent":["import { posix } from \"node:path\";\n\nimport { loadGlobalSettings } from \"../settings/index.js\";\nimport { DockerContainerManager } from \"../sandbox/provisioner.js\";\nimport type { ContainerMount, ActorContext, ExecutionPlan } from \"../types.js\";\nimport {\n createSandboxEnv,\n getSandboxCredentialCapabilities,\n getSandboxPathContext,\n} from \"../sandbox/registry.js\";\nimport type { SandboxConfig } from \"../sandbox/types.js\";\nimport { reportUserFacingError } from \"../observability/index.js\";\nimport { normalizeSharedVaultName } from \"../vault/index.js\";\nimport type { VaultManager } from \"../vault/types.js\";\nimport { allowsAmbientDefaultSharedVault, resolveVaultInjection } from \"../vault/index.js\";\nimport { credentialAuthorizationKey, runtimeResourceKey } from \"../sandbox/identity.js\";\nimport { resolveWorkspaceProjection } from \"../office/projection.js\";\nimport type { WorkspaceProjection, Workspace } from \"../office/types.js\";\n\nexport class ActorExecutionResolver {\n constructor(\n private baseConfig: SandboxConfig,\n private vaultManager: Pick<VaultManager, \"hasEntry\" | \"resolve\" | \"copySharedVaultTo\">,\n private provisioner: Pick<DockerContainerManager, \"provision\" | \"markUsed\"> | undefined,\n private workspace: Workspace,\n ) {}\n\n async resolve(context: ActorContext) {\n const { plan, projection } = this.resolvePlan(context);\n const pathContext = getSandboxPathContext(plan.sandboxConfig, this.workspace.root);\n const env = createSandboxEnv(plan.sandboxConfig, {\n cwd: pathContext.runtimeWorkspaceRoot,\n env: plan.env,\n ensureReady: this.buildEnsureReadyCallback(plan, context.address.conversationId),\n markUsed: () => this.provisioner?.markUsed(plan.resourceKey),\n });\n return { env, sandboxConfig: plan.sandboxConfig, pathContext, projection };\n }\n\n private resolvePlan(context: ActorContext): {\n plan: ExecutionPlan;\n projection: WorkspaceProjection;\n } {\n const scope = { userId: context.userId, address: context.address };\n const credentialKey = credentialAuthorizationKey(this.baseConfig, scope);\n const resourceKey = runtimeResourceKey(this.baseConfig, {\n userId: context.userId,\n address: context.address,\n });\n this.ensureDefaultSharedVault(credentialKey, context.trustModel);\n\n const vault = this.vaultManager.resolve(credentialKey);\n const capabilities = getSandboxCredentialCapabilities(this.baseConfig.type);\n const office = this.workspace.office(context.address);\n const projection = resolveWorkspaceProjection(office);\n const injection = resolveVaultInjection({\n vault,\n capabilities,\n sandboxType: this.baseConfig.type,\n address: office.address,\n });\n const mounts = this.resolveMounts(injection.mounts, projection);\n return {\n plan: {\n credentialKey,\n resourceKey,\n sandboxConfig: this.resolveSandboxConfig(resourceKey),\n env: injection.env,\n mounts,\n },\n projection,\n };\n }\n\n private ensureDefaultSharedVault(\n credentialKey: string,\n trustModel: ActorContext[\"trustModel\"],\n ): void {\n if (!allowsAmbientDefaultSharedVault({ trustModel, sandboxType: this.baseConfig.type })) return;\n if (this.vaultManager.hasEntry(credentialKey)) return;\n\n let profile: string | undefined;\n try {\n profile = loadGlobalSettings(this.workspace.stateDir).sandbox?.defaultSharedVault;\n } catch {\n return;\n }\n if (!profile || normalizeSharedVaultName(profile) !== profile) return;\n this.vaultManager.copySharedVaultTo(profile, credentialKey);\n }\n\n private resolveSandboxConfig(resourceKey: string): SandboxConfig {\n if (this.baseConfig.type !== \"oci\") return this.baseConfig;\n return {\n type: \"container\",\n container: DockerContainerManager.containerName(resourceKey),\n };\n }\n\n private buildEnsureReadyCallback(\n plan: ExecutionPlan,\n conversationId: string,\n ): (() => Promise<void>) | undefined {\n if (this.baseConfig.type !== \"oci\" || plan.sandboxConfig.type !== \"container\") {\n return undefined;\n }\n\n return async () => {\n const expected = plan.sandboxConfig.type === \"container\" ? plan.sandboxConfig.container : \"\";\n let actual: string | undefined;\n try {\n actual = await this.provisioner?.provision(plan.resourceKey, {\n containerName: expected,\n mounts: plan.mounts,\n conversationId,\n });\n } catch (err) {\n reportUserFacingError(err, {\n domain: \"sandbox\",\n surface: \"sandbox_provision\",\n operation: \"ensure_image_container_ready\",\n severity: \"error\",\n context: {\n sandboxType: \"oci\",\n conversationId,\n credentialKey: plan.credentialKey,\n resourceKey: plan.resourceKey,\n expectedContainer: expected,\n hasVault: Boolean(plan.env || plan.mounts.length > 0),\n },\n });\n throw err;\n }\n if (actual && actual !== expected) {\n throw new Error(\n `Provisioner returned container \"${actual}\" for resource key \"${plan.resourceKey}\", expected \"${expected}\"`,\n );\n }\n };\n }\n\n private resolveMounts(\n vaultMounts: ContainerMount[],\n projection: WorkspaceProjection,\n ): ContainerMount[] {\n const protectedMounts = projection.mounts;\n for (let index = 0; index < vaultMounts.length; index += 1) {\n const vaultMount = vaultMounts[index];\n if (vaultMount === undefined) continue;\n const workspaceCollision = protectedMounts.find((protectedMount) =>\n targetsOverlap(protectedMount.target, vaultMount.target),\n );\n if (workspaceCollision) {\n throw new Error(\n `Vault mount target \"${vaultMount.target}\" overlaps protected workspace target \"${workspaceCollision.target}\"`,\n );\n }\n\n const vaultCollision = vaultMounts\n .slice(0, index)\n .find((other) => targetsOverlap(other.target, vaultMount.target));\n if (vaultCollision) {\n throw new Error(\n `Vault mount target \"${vaultMount.target}\" overlaps vault target \"${vaultCollision.target}\"`,\n );\n }\n }\n return [...protectedMounts, ...vaultMounts];\n }\n}\n\nfunction targetsOverlap(left: string, right: string): boolean {\n const a = normalizeMountTarget(left);\n const b = normalizeMountTarget(right);\n return a === b || a.startsWith(`${b}/`) || b.startsWith(`${a}/`);\n}\n\nfunction normalizeMountTarget(value: string): string {\n const normalized = posix.normalize(value);\n return normalized.replace(/\\/+$/, \"\") || \"/\";\n}\n"]}
|
|
1
|
+
{"version":3,"file":"execution-resolver.js","sourceRoot":"","sources":["../../src/harness/execution-resolver.ts"],"names":[],"mappings":"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","sourcesContent":["import { posix } from \"node:path\";\n\nimport { loadGlobalSettings } from \"../settings/index.js\";\nimport { DockerContainerManager } from \"../sandbox/provisioner.js\";\nimport type { ContainerMount, ActorContext, ExecutionPlan } from \"../types.js\";\nimport {\n createSandboxEnv,\n getSandboxCredentialCapabilities,\n getSandboxPathContext,\n} from \"../sandbox/registry.js\";\nimport type { SandboxConfig } from \"../sandbox/types.js\";\nimport { reportUserFacingError } from \"../observability/index.js\";\nimport { normalizeSharedVaultName } from \"../vault/index.js\";\nimport type { VaultManager } from \"../vault/types.js\";\nimport { allowsAmbientDefaultSharedVault, resolveVaultInjection } from \"../vault/index.js\";\nimport { credentialAuthorizationKey, runtimeResourceKey } from \"../sandbox/identity.js\";\nimport { resolveWorkspaceProjection } from \"../office/projection.js\";\nimport type { WorkspaceProjection, Workspace } from \"../office/types.js\";\n\nexport class ActorExecutionResolver {\n constructor(\n private baseConfig: SandboxConfig,\n private vaultManager: Pick<VaultManager, \"hasEntry\" | \"resolve\" | \"copySharedVaultTo\">,\n private provisioner: Pick<DockerContainerManager, \"provision\" | \"markUsed\"> | undefined,\n private workspace: Workspace,\n ) {}\n\n async resolve(context: ActorContext) {\n const { plan, projection } = this.resolvePlan(context);\n const pathContext = getSandboxPathContext(plan.sandboxConfig, this.workspace.root);\n const env = createSandboxEnv(plan.sandboxConfig, {\n cwd: pathContext.runtimeWorkspaceRoot,\n env: plan.env,\n ensureReady: this.buildEnsureReadyCallback(plan, context.address.conversationId),\n markUsed: () => this.provisioner?.markUsed(plan.resourceKey),\n });\n return { env, sandboxConfig: plan.sandboxConfig, pathContext, projection };\n }\n\n async prepare(context: ActorContext): Promise<string> {\n const { plan } = this.resolvePlan(context);\n await this.buildEnsureReadyCallback(plan, context.address.conversationId)?.();\n return plan.resourceKey;\n }\n\n private resolvePlan(context: ActorContext): {\n plan: ExecutionPlan;\n projection: WorkspaceProjection;\n } {\n const scope = { userId: context.userId, address: context.address };\n const credentialKey = credentialAuthorizationKey(this.baseConfig, scope);\n const resourceKey = runtimeResourceKey(this.baseConfig, {\n userId: context.userId,\n address: context.address,\n });\n this.ensureDefaultSharedVault(credentialKey, context.trustModel);\n\n const vault = this.vaultManager.resolve(credentialKey);\n const capabilities = getSandboxCredentialCapabilities(this.baseConfig.type);\n const office = this.workspace.office(context.address);\n const projection = resolveWorkspaceProjection(office);\n const injection = resolveVaultInjection({\n vault,\n capabilities,\n sandboxType: this.baseConfig.type,\n address: office.address,\n });\n const mounts = this.resolveMounts(injection.mounts, projection);\n return {\n plan: {\n credentialKey,\n resourceKey,\n sandboxConfig: this.resolveSandboxConfig(resourceKey),\n env: injection.env,\n mounts,\n },\n projection,\n };\n }\n\n private ensureDefaultSharedVault(\n credentialKey: string,\n trustModel: ActorContext[\"trustModel\"],\n ): void {\n if (!allowsAmbientDefaultSharedVault({ trustModel, sandboxType: this.baseConfig.type })) return;\n if (this.vaultManager.hasEntry(credentialKey)) return;\n\n let profile: string | undefined;\n try {\n profile = loadGlobalSettings(this.workspace.stateDir).sandbox?.defaultSharedVault;\n } catch {\n return;\n }\n if (!profile || normalizeSharedVaultName(profile) !== profile) return;\n this.vaultManager.copySharedVaultTo(profile, credentialKey);\n }\n\n private resolveSandboxConfig(resourceKey: string): SandboxConfig {\n if (this.baseConfig.type !== \"oci\") return this.baseConfig;\n return {\n type: \"container\",\n container: DockerContainerManager.containerName(resourceKey),\n };\n }\n\n private buildEnsureReadyCallback(\n plan: ExecutionPlan,\n conversationId: string,\n ): (() => Promise<void>) | undefined {\n if (this.baseConfig.type !== \"oci\" || plan.sandboxConfig.type !== \"container\") {\n return undefined;\n }\n\n return async () => {\n const expected = plan.sandboxConfig.type === \"container\" ? plan.sandboxConfig.container : \"\";\n let actual: string | undefined;\n try {\n actual = await this.provisioner?.provision(plan.resourceKey, {\n containerName: expected,\n mounts: plan.mounts,\n conversationId,\n });\n } catch (err) {\n reportUserFacingError(err, {\n domain: \"sandbox\",\n surface: \"sandbox_provision\",\n operation: \"ensure_image_container_ready\",\n severity: \"error\",\n context: {\n sandboxType: \"oci\",\n conversationId,\n credentialKey: plan.credentialKey,\n resourceKey: plan.resourceKey,\n expectedContainer: expected,\n hasVault: Boolean(plan.env || plan.mounts.length > 0),\n },\n });\n throw err;\n }\n if (actual && actual !== expected) {\n throw new Error(\n `Provisioner returned container \"${actual}\" for resource key \"${plan.resourceKey}\", expected \"${expected}\"`,\n );\n }\n };\n }\n\n private resolveMounts(\n vaultMounts: ContainerMount[],\n projection: WorkspaceProjection,\n ): ContainerMount[] {\n const protectedMounts = projection.mounts;\n for (let index = 0; index < vaultMounts.length; index += 1) {\n const vaultMount = vaultMounts[index];\n if (vaultMount === undefined) continue;\n const workspaceCollision = protectedMounts.find((protectedMount) =>\n targetsOverlap(protectedMount.target, vaultMount.target),\n );\n if (workspaceCollision) {\n throw new Error(\n `Vault mount target \"${vaultMount.target}\" overlaps protected workspace target \"${workspaceCollision.target}\"`,\n );\n }\n\n const vaultCollision = vaultMounts\n .slice(0, index)\n .find((other) => targetsOverlap(other.target, vaultMount.target));\n if (vaultCollision) {\n throw new Error(\n `Vault mount target \"${vaultMount.target}\" overlaps vault target \"${vaultCollision.target}\"`,\n );\n }\n }\n return [...protectedMounts, ...vaultMounts];\n }\n}\n\nfunction targetsOverlap(left: string, right: string): boolean {\n const a = normalizeMountTarget(left);\n const b = normalizeMountTarget(right);\n return a === b || a.startsWith(`${b}/`) || b.startsWith(`${a}/`);\n}\n\nfunction normalizeMountTarget(value: string): string {\n const normalized = posix.normalize(value);\n return normalized.replace(/\\/+$/, \"\") || \"/\";\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"presenter.d.ts","sourceRoot":"","sources":["../../src/harness/presenter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,0BAA0B,EAG1B,eAAe,EACf,sBAAsB,EAEtB,kBAAkB,EAClB,yBAAyB,EAEzB,kBAAkB,EACnB,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAMtD,OAAO,KAAK,EACV,qBAAqB,EAGtB,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"presenter.d.ts","sourceRoot":"","sources":["../../src/harness/presenter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,0BAA0B,EAG1B,eAAe,EACf,sBAAsB,EAEtB,kBAAkB,EAClB,yBAAyB,EAEzB,kBAAkB,EACnB,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAMtD,OAAO,KAAK,EACV,qBAAqB,EAGtB,MAAM,aAAa,CAAC;AAoGrB,wBAAgB,cAAc,IAAI,kBAAkB,CAEnD;AAED,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,kBAAkB,EAC5B,OAAO,EAAE,sBAAsB,GAC9B,eAAe,CA6CjB;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,iBAAiB,GAAG,MAAM,CAGxE;AAED,wBAAgB,yBAAyB,CAAC,kBAAkB,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAEzF;AAwID,wBAAsB,mBAAmB,CACvC,SAAS,EAAE,qBAAqB,EAChC,OAAO,EAAE,iBAAiB,EAC1B,QAAQ,EAAE,kBAAkB,EAC5B,OAAO,CAAC,EAAE,0BAA0B,GACnC,OAAO,CAAC,IAAI,CAAC,CAkBf;AAiED,wBAAsB,kBAAkB,CAAC,GAAG,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAwF/E;AA0fD,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,yBAAyB,GAAG,IAAI,CAyBlF"}
|
|
@@ -3,6 +3,7 @@ import { mergeSubagentProgress, renderSubagentDashboard, settleSubagentProgress,
|
|
|
3
3
|
import { addLifecycleEvent, metricAttributes, recordCounter, recordDistribution, recordGauge, reportUserFacingError, startOperationSpan, updateActiveSpanAttribution, } from "../observability/index.js";
|
|
4
4
|
import { appendTriggerAttribution } from "./prompt.js";
|
|
5
5
|
import { START_TASK_TOOL, TASK_STATUS_TOOL } from "./tools/task.js";
|
|
6
|
+
import { JEV_BROWSER_TOOL } from "./tools/jev-browser.js";
|
|
6
7
|
import { toRunEvent, toolResultText } from "./run-events.js";
|
|
7
8
|
import { REACT_TOOL } from "./tools/react.js";
|
|
8
9
|
import * as log from "../log.js";
|
|
@@ -511,10 +512,14 @@ function observeToolEnd(event, context) {
|
|
|
511
512
|
return;
|
|
512
513
|
}
|
|
513
514
|
log.logToolSuccess(logCtx, event.toolName, durationMs, resultStr);
|
|
514
|
-
if (context.platformToolRoles.finalResponseTools.has(event.toolName)
|
|
515
|
+
if (context.platformToolRoles.finalResponseTools.has(event.toolName) ||
|
|
516
|
+
(event.toolName === JEV_BROWSER_TOOL && handedBrowserToPerson(event.result))) {
|
|
515
517
|
runState.finalResponseHandledByTool = true;
|
|
516
518
|
}
|
|
517
519
|
}
|
|
520
|
+
function handedBrowserToPerson(result) {
|
|
521
|
+
return isRecord(result) && isRecord(result.details) && result.details.handedOff === true;
|
|
522
|
+
}
|
|
518
523
|
function observeMessageStart(event, context) {
|
|
519
524
|
if (event.message.role !== "assistant")
|
|
520
525
|
return;
|