@geminixiang/mikan 0.5.3 → 1.0.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.
- package/CHANGELOG.md +16 -0
- package/README.md +2 -2
- package/dist/adapter.d.ts +1 -1
- package/dist/adapter.d.ts.map +1 -1
- package/dist/adapter.js.map +1 -1
- package/dist/agent.d.ts +10 -1
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +153 -95
- package/dist/agent.js.map +1 -1
- package/dist/commands/model.d.ts +2 -2
- package/dist/commands/model.d.ts.map +1 -1
- package/dist/commands/model.js.map +1 -1
- package/dist/commands/registry.d.ts.map +1 -1
- package/dist/commands/registry.js +2 -5
- package/dist/commands/registry.js.map +1 -1
- package/dist/config.d.ts +33 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +83 -5
- package/dist/config.js.map +1 -1
- package/dist/execution-resolver.d.ts.map +1 -1
- package/dist/execution-resolver.js +2 -3
- package/dist/execution-resolver.js.map +1 -1
- package/dist/harness/auth.d.ts +16 -0
- package/dist/harness/auth.d.ts.map +1 -0
- package/dist/harness/auth.js +86 -0
- package/dist/harness/auth.js.map +1 -0
- package/dist/harness/extensions/loader.d.ts +43 -0
- package/dist/harness/extensions/loader.d.ts.map +1 -0
- package/dist/harness/extensions/loader.js +325 -0
- package/dist/harness/extensions/loader.js.map +1 -0
- package/dist/harness/extensions/registry.d.ts +23 -0
- package/dist/harness/extensions/registry.d.ts.map +1 -0
- package/dist/harness/extensions/registry.js +45 -0
- package/dist/harness/extensions/registry.js.map +1 -0
- package/dist/harness/extensions/types.d.ts +225 -0
- package/dist/harness/extensions/types.d.ts.map +1 -0
- package/dist/harness/extensions/types.js +2 -0
- package/dist/harness/extensions/types.js.map +1 -0
- package/dist/harness/http.d.ts +16 -0
- package/dist/harness/http.d.ts.map +1 -0
- package/dist/harness/http.js +71 -0
- package/dist/harness/http.js.map +1 -0
- package/dist/harness/index.d.ts +19 -0
- package/dist/harness/index.d.ts.map +1 -0
- package/dist/harness/index.js +18 -0
- package/dist/harness/index.js.map +1 -0
- package/dist/harness/models.d.ts +34 -0
- package/dist/harness/models.d.ts.map +1 -0
- package/dist/harness/models.js +248 -0
- package/dist/harness/models.js.map +1 -0
- package/dist/harness/runner.d.ts +124 -0
- package/dist/harness/runner.d.ts.map +1 -0
- package/dist/harness/runner.js +436 -0
- package/dist/harness/runner.js.map +1 -0
- package/dist/harness/session-store.d.ts +77 -0
- package/dist/harness/session-store.d.ts.map +1 -0
- package/dist/harness/session-store.js +248 -0
- package/dist/harness/session-store.js.map +1 -0
- package/dist/harness/settings.d.ts +47 -0
- package/dist/harness/settings.d.ts.map +1 -0
- package/dist/harness/settings.js +29 -0
- package/dist/harness/settings.js.map +1 -0
- package/dist/harness/skills.d.ts +54 -0
- package/dist/harness/skills.d.ts.map +1 -0
- package/dist/harness/skills.js +203 -0
- package/dist/harness/skills.js.map +1 -0
- package/dist/harness/types.d.ts +32 -0
- package/dist/harness/types.d.ts.map +1 -0
- package/dist/harness/types.js +2 -0
- package/dist/harness/types.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/main.js +65 -3
- package/dist/main.js.map +1 -1
- package/dist/model-registry.d.ts +2 -2
- package/dist/model-registry.d.ts.map +1 -1
- package/dist/model-registry.js.map +1 -1
- package/dist/runtime/conversation-runtime.js +1 -1
- package/dist/runtime/conversation-runtime.js.map +1 -1
- package/dist/runtime/types.d.ts +3 -1
- package/dist/runtime/types.d.ts.map +1 -1
- package/dist/runtime/types.js.map +1 -1
- package/dist/sessions/agent-memory-file-manager.d.ts.map +1 -1
- package/dist/sessions/agent-memory-file-manager.js +8 -8
- package/dist/sessions/agent-memory-file-manager.js.map +1 -1
- package/dist/sessions/metadata.js +2 -2
- package/dist/sessions/metadata.js.map +1 -1
- package/dist/sessions/store.d.ts +3 -3
- package/dist/sessions/store.d.ts.map +1 -1
- package/dist/sessions/store.js +4 -4
- package/dist/sessions/store.js.map +1 -1
- package/dist/sessions/types.d.ts +1 -1
- package/dist/sessions/types.d.ts.map +1 -1
- package/dist/sessions/types.js.map +1 -1
- package/dist/trigger.d.ts.map +1 -1
- package/dist/trigger.js +5 -13
- package/dist/trigger.js.map +1 -1
- package/dist/types.d.ts +6 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/vault/index.d.ts.map +1 -1
- package/dist/vault/index.js +7 -1
- package/dist/vault/index.js.map +1 -1
- package/dist/web/admin/portal.d.ts.map +1 -1
- package/dist/web/admin/portal.js +328 -9
- package/dist/web/admin/portal.js.map +1 -1
- package/dist/web/admin/provider-models.d.ts +2 -2
- package/dist/web/admin/provider-models.d.ts.map +1 -1
- package/dist/web/admin/provider-models.js.map +1 -1
- package/dist/web/session-view/service.js +5 -5
- package/dist/web/session-view/service.js.map +1 -1
- package/package.json +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/commands/registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/commands/registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAC1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAC;AAG9D,MAAM,UAAU,sBAAsB;IACpC,MAAM,aAAa,GAAG,WAAW,CAAC,MAAM,EAAE,CAAC;IAC3C,OAAO;QACL,IAAI,mBAAmB,EAAE;QACzB,IAAI,mBAAmB,EAAE;QACzB,IAAI,yBAAyB,EAAE;QAC/B,IAAI,uBAAuB,EAAE;QAC7B,IAAI,mBAAmB,CAAC,aAAa,CAAC;QACtC,IAAI,qBAAqB,EAAE;QAC3B,IAAI,iBAAiB,EAAE;KACxB,CAAC;AACJ,CAAC;AAED,gFAAgF;AAChF,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,QAAmC,EACnC,OAAuB;IAEvB,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,IAAI,MAAM,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC;YAAE,OAAO,IAAI,CAAC;IACpD,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC","sourcesContent":["import { MikanModels } from \"../harness/index.js\";\nimport { AdminCommandHandler } from \"./admin.js\";\nimport { AutoReplyCommandHandler } from \"./auto-reply.js\";\nimport { LoginCommandHandler } from \"./login.js\";\nimport { ModelCommandHandler } from \"./model.js\";\nimport { NewCommandHandler } from \"./new.js\";\nimport { SandboxCommandHandler } from \"./sandbox.js\";\nimport { SessionViewCommandHandler } from \"./session-view.js\";\nimport type { CommandContext, CommandHandler } from \"./types.js\";\n\nexport function defaultCommandHandlers(): CommandHandler[] {\n const modelRegistry = MikanModels.create();\n return [\n new AdminCommandHandler(),\n new LoginCommandHandler(),\n new SessionViewCommandHandler(),\n new AutoReplyCommandHandler(),\n new ModelCommandHandler(modelRegistry),\n new SandboxCommandHandler(),\n new NewCommandHandler(),\n ];\n}\n\n/** Run handlers in order, returning true as soon as one accepts the command. */\nexport async function dispatchCommand(\n handlers: readonly CommandHandler[],\n context: CommandContext,\n): Promise<boolean> {\n for (const handler of handlers) {\n if (await handler.tryHandle(context)) return true;\n }\n return false;\n}\n"]}
|
package/dist/config.d.ts
CHANGED
|
@@ -5,6 +5,24 @@ export declare class MissingGlobalSettingsError extends Error {
|
|
|
5
5
|
export type { AgentConfig, AutoReplyConfig, JudgeModelConfig } from "./types.js";
|
|
6
6
|
import type { AgentConfig, AutoReplyConfig, JudgeModelConfig } from "./types.js";
|
|
7
7
|
export declare function loadGlobalSettings(): AgentConfig;
|
|
8
|
+
/**
|
|
9
|
+
* Host-authoritative location of a conversation's settings file:
|
|
10
|
+
* `<stateDir>/conversations/<conversationId>/settings.json`.
|
|
11
|
+
*
|
|
12
|
+
* Conversation settings used to live at `<conversationDir>/settings.json`,
|
|
13
|
+
* but conversation dirs are bind-mounted read-write into sandbox containers
|
|
14
|
+
* in image mode — code inside the sandbox could edit its own settings.json
|
|
15
|
+
* and flip `sandbox.image.workspaceMount` to "full", remounting the entire
|
|
16
|
+
* workspace into its container (cross-conversation access). Settings are an
|
|
17
|
+
* administrator surface, so they live under the host-only state dir.
|
|
18
|
+
*
|
|
19
|
+
* Migration: on first access per conversation, a legacy
|
|
20
|
+
* `<conversationDir>/settings.json` is moved here. The new file's existence
|
|
21
|
+
* (an empty `{}` is written when there is nothing to migrate) is the
|
|
22
|
+
* migration marker — a legacy file (re)appearing later, e.g. planted from
|
|
23
|
+
* inside the sandbox, is never read again.
|
|
24
|
+
*/
|
|
25
|
+
export declare function conversationSettingsPath(conversationDir: string): string;
|
|
8
26
|
export declare function resolveConversationSettings(conversationDir: string): AgentConfig;
|
|
9
27
|
/**
|
|
10
28
|
* Resolve the model used to judge auto-reply rules. Falls back to the main
|
|
@@ -32,6 +50,21 @@ export declare function loadConversationAutoReplyConfig(conversationDir: string)
|
|
|
32
50
|
export declare function saveConversationAutoReplyConfig(conversationDir: string, config: AutoReplyConfig): void;
|
|
33
51
|
export declare function resolveWorkspaceDirFromArgv(args?: string[]): string | undefined;
|
|
34
52
|
export declare function resolveStateDirFromArgv(args?: string[]): string;
|
|
53
|
+
/**
|
|
54
|
+
* True when `child` is `parent` or a path inside it. Purely lexical (no
|
|
55
|
+
* symlink resolution) — used for configuration sanity checks, not as the
|
|
56
|
+
* final security boundary.
|
|
57
|
+
*/
|
|
58
|
+
export declare function isPathInside(child: string, parent: string): boolean;
|
|
59
|
+
/**
|
|
60
|
+
* The state dir (extensions code, extension data, vaults, auth.json) must
|
|
61
|
+
* never live inside the working dir: conversation opt-in "full" mode mounts
|
|
62
|
+
* the entire working dir read-write into sandbox containers, and a mounted
|
|
63
|
+
* state dir would let sandboxed code plant extension modules that the host
|
|
64
|
+
* process later imports — a sandbox escape. Fatal under sandboxed modes;
|
|
65
|
+
* host mode has no mounts, so only warn about the bad hygiene.
|
|
66
|
+
*/
|
|
67
|
+
export declare function assertStateDirOutsideWorkspace(stateDir: string, workingDir: string, sandboxType: string): void;
|
|
35
68
|
export declare function resolveSentryDsn(): string | undefined;
|
|
36
69
|
export declare function createGlobalSettingsFile(stateDir: string): string;
|
|
37
70
|
/**
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAUA,qBAAa,0BAA2B,SAAQ,KAAK;aACvB,YAAY,EAAE,MAAM;IAAhD,YAA4B,YAAY,EAAE,MAAM,EAG/C;CACF;AAED,YAAY,EAAE,WAAW,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AACjF,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AA2LjF,wBAAgB,kBAAkB,IAAI,WAAW,CAEhD;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,wBAAwB,CAAC,eAAe,EAAE,MAAM,GAAG,MAAM,CA2BxE;AAED,wBAAgB,2BAA2B,CAAC,eAAe,EAAE,MAAM,GAAG,WAAW,CAMhF;AAED;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CAAC,eAAe,CAAC,EAAE,MAAM,GAAG,gBAAgB,CAUlF;AAUD;;;;;;;;GAQG;AACH,wBAAgB,+BAA+B,CAAC,eAAe,EAAE,MAAM,GAAG,eAAe,CAYxF;AAED;;;;GAIG;AACH,wBAAgB,+BAA+B,CAC7C,eAAe,EAAE,MAAM,EACvB,MAAM,EAAE,eAAe,GACtB,IAAI,CAaN;AAED,wBAAgB,2BAA2B,CAAC,IAAI,WAAwB,GAAG,MAAM,GAAG,SAAS,CA2B5F;AAED,wBAAgB,uBAAuB,CAAC,IAAI,WAAwB,GAAG,MAAM,CAY5E;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAInE;AAED;;;;;;;GAOG;AACH,wBAAgB,8BAA8B,CAC5C,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,GAClB,IAAI,CAWN;AAED,wBAAgB,gBAAgB,IAAI,MAAM,GAAG,SAAS,CAOrD;AAED,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAQjE;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,GAAG,SAAS,CAIvD;AA4FD,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,CAAC,WAAW,CAAC,GAAG,IAAI,CAEtE;AAED,wBAAgB,0BAA0B,CACxC,eAAe,EAAE,MAAM,EACvB,KAAK,EAAE,OAAO,CAAC,WAAW,CAAC,GAC1B,IAAI,CAEN"}
|
package/dist/config.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { Type } from "@sinclair/typebox";
|
|
2
|
-
import { existsSync, readFileSync, renameSync } from "fs";
|
|
2
|
+
import { existsSync, readFileSync, renameSync, rmSync } from "fs";
|
|
3
3
|
import { homedir } from "os";
|
|
4
|
-
import { dirname, join, resolve } from "path";
|
|
4
|
+
import { basename, dirname, join, resolve } from "path";
|
|
5
5
|
import { readEnv } from "./utils/env.js";
|
|
6
6
|
import { ensureDirExists, readJsonSchemaFileIfExists } from "./utils/file-guards.js";
|
|
7
7
|
import { atomicWritePrivateFile } from "./utils/fs-atomic.js";
|
|
8
|
+
import * as log from "./log.js";
|
|
8
9
|
export class MissingGlobalSettingsError extends Error {
|
|
9
10
|
constructor(settingsPath) {
|
|
10
11
|
super(`Missing global settings file at ${settingsPath}`);
|
|
@@ -162,9 +163,56 @@ function loadRawGlobalSettings() {
|
|
|
162
163
|
export function loadGlobalSettings() {
|
|
163
164
|
return toAgentConfig(loadRawGlobalSettings());
|
|
164
165
|
}
|
|
166
|
+
/**
|
|
167
|
+
* Host-authoritative location of a conversation's settings file:
|
|
168
|
+
* `<stateDir>/conversations/<conversationId>/settings.json`.
|
|
169
|
+
*
|
|
170
|
+
* Conversation settings used to live at `<conversationDir>/settings.json`,
|
|
171
|
+
* but conversation dirs are bind-mounted read-write into sandbox containers
|
|
172
|
+
* in image mode — code inside the sandbox could edit its own settings.json
|
|
173
|
+
* and flip `sandbox.image.workspaceMount` to "full", remounting the entire
|
|
174
|
+
* workspace into its container (cross-conversation access). Settings are an
|
|
175
|
+
* administrator surface, so they live under the host-only state dir.
|
|
176
|
+
*
|
|
177
|
+
* Migration: on first access per conversation, a legacy
|
|
178
|
+
* `<conversationDir>/settings.json` is moved here. The new file's existence
|
|
179
|
+
* (an empty `{}` is written when there is nothing to migrate) is the
|
|
180
|
+
* migration marker — a legacy file (re)appearing later, e.g. planted from
|
|
181
|
+
* inside the sandbox, is never read again.
|
|
182
|
+
*/
|
|
183
|
+
export function conversationSettingsPath(conversationDir) {
|
|
184
|
+
const conversationId = basename(resolve(conversationDir));
|
|
185
|
+
const hostPath = join(getStateDir(), "conversations", conversationId, "settings.json");
|
|
186
|
+
if (existsSync(hostPath))
|
|
187
|
+
return hostPath;
|
|
188
|
+
ensureDirExists(dirname(hostPath));
|
|
189
|
+
const legacyPath = join(conversationDir, "settings.json");
|
|
190
|
+
let content = "{}\n";
|
|
191
|
+
let migrated = false;
|
|
192
|
+
if (existsSync(legacyPath)) {
|
|
193
|
+
try {
|
|
194
|
+
content = readFileSync(legacyPath, "utf-8");
|
|
195
|
+
migrated = true;
|
|
196
|
+
}
|
|
197
|
+
catch (err) {
|
|
198
|
+
log.logWarning(`Could not read legacy conversation settings: ${legacyPath}`, String(err));
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
atomicWritePrivateFile(hostPath, content);
|
|
202
|
+
if (migrated) {
|
|
203
|
+
try {
|
|
204
|
+
rmSync(legacyPath);
|
|
205
|
+
}
|
|
206
|
+
catch (err) {
|
|
207
|
+
log.logWarning(`Could not remove legacy conversation settings: ${legacyPath}`, String(err));
|
|
208
|
+
}
|
|
209
|
+
log.logInfo(`Migrated conversation settings to host-only path: ${hostPath}`);
|
|
210
|
+
}
|
|
211
|
+
return hostPath;
|
|
212
|
+
}
|
|
165
213
|
export function resolveConversationSettings(conversationDir) {
|
|
166
214
|
const globalConfig = loadRawGlobalSettings();
|
|
167
|
-
const conversationConfig = normalizeSettingsConfig(loadSettingsFile(
|
|
215
|
+
const conversationConfig = normalizeSettingsConfig(loadSettingsFile(conversationSettingsPath(conversationDir)) ?? {});
|
|
168
216
|
return toAgentConfig({ ...globalConfig, ...conversationConfig });
|
|
169
217
|
}
|
|
170
218
|
/**
|
|
@@ -177,7 +225,7 @@ export function resolveConversationSettings(conversationDir) {
|
|
|
177
225
|
export function loadAutoReplyJudgeModel(conversationDir) {
|
|
178
226
|
const global = requireGlobalSettings();
|
|
179
227
|
const local = conversationDir
|
|
180
|
-
? (loadSettingsFile(
|
|
228
|
+
? (loadSettingsFile(conversationSettingsPath(conversationDir)) ?? {})
|
|
181
229
|
: {};
|
|
182
230
|
const merged = { ...global.llm, ...local.llm };
|
|
183
231
|
const judge = { ...global.llm?.autoReply, ...local.llm?.autoReply };
|
|
@@ -260,6 +308,36 @@ export function resolveStateDirFromArgv(args = process.argv.slice(2)) {
|
|
|
260
308
|
}
|
|
261
309
|
return join(homedir(), ".mikan");
|
|
262
310
|
}
|
|
311
|
+
/**
|
|
312
|
+
* True when `child` is `parent` or a path inside it. Purely lexical (no
|
|
313
|
+
* symlink resolution) — used for configuration sanity checks, not as the
|
|
314
|
+
* final security boundary.
|
|
315
|
+
*/
|
|
316
|
+
export function isPathInside(child, parent) {
|
|
317
|
+
const parentPath = resolve(parent);
|
|
318
|
+
const childPath = resolve(child);
|
|
319
|
+
return childPath === parentPath || childPath.startsWith(parentPath + "/");
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* The state dir (extensions code, extension data, vaults, auth.json) must
|
|
323
|
+
* never live inside the working dir: conversation opt-in "full" mode mounts
|
|
324
|
+
* the entire working dir read-write into sandbox containers, and a mounted
|
|
325
|
+
* state dir would let sandboxed code plant extension modules that the host
|
|
326
|
+
* process later imports — a sandbox escape. Fatal under sandboxed modes;
|
|
327
|
+
* host mode has no mounts, so only warn about the bad hygiene.
|
|
328
|
+
*/
|
|
329
|
+
export function assertStateDirOutsideWorkspace(stateDir, workingDir, sandboxType) {
|
|
330
|
+
if (!isPathInside(stateDir, workingDir))
|
|
331
|
+
return;
|
|
332
|
+
const message = `--state-dir (${stateDir}) must not be inside the working directory (${workingDir}): ` +
|
|
333
|
+
`sandbox containers mount the working directory, and a mounted state dir ` +
|
|
334
|
+
`would expose extensions, vaults, and credentials to sandboxed code.`;
|
|
335
|
+
if (sandboxType === "host") {
|
|
336
|
+
log.logWarning("Insecure state dir location", message);
|
|
337
|
+
return;
|
|
338
|
+
}
|
|
339
|
+
throw new Error(message);
|
|
340
|
+
}
|
|
263
341
|
export function resolveSentryDsn() {
|
|
264
342
|
const fromFile = normalizeSettingsConfig(loadSettingsFile(getSettingsPath()) ?? {});
|
|
265
343
|
if (fromFile.sentryDsn) {
|
|
@@ -367,6 +445,6 @@ export function updateGlobalSettings(patch) {
|
|
|
367
445
|
updateSettingsFile(join(getStateDir(), "settings.json"), patch, ONBOARD_SETTINGS);
|
|
368
446
|
}
|
|
369
447
|
export function updateConversationSettings(conversationDir, patch) {
|
|
370
|
-
updateSettingsFile(
|
|
448
|
+
updateSettingsFile(conversationSettingsPath(conversationDir), patch, {});
|
|
371
449
|
}
|
|
372
450
|
//# sourceMappingURL=config.js.map
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ThinkingLevel } from \"@earendil-works/pi-agent-core\";\nimport { Type, type Static } from \"@sinclair/typebox\";\nimport { existsSync, readFileSync, renameSync } from \"fs\";\nimport { homedir } from \"os\";\nimport { dirname, join, resolve } from \"path\";\nimport { readEnv } from \"./utils/env.js\";\nimport { ensureDirExists, readJsonSchemaFileIfExists } from \"./utils/file-guards.js\";\nimport { atomicWritePrivateFile } from \"./utils/fs-atomic.js\";\n\nexport class MissingGlobalSettingsError extends Error {\n constructor(public readonly settingsPath: string) {\n super(`Missing global settings file at ${settingsPath}`);\n this.name = \"MissingGlobalSettingsError\";\n }\n}\n\nexport type { AgentConfig, AutoReplyConfig, JudgeModelConfig } from \"./types.js\";\nimport type { AgentConfig, AutoReplyConfig, JudgeModelConfig } from \"./types.js\";\n\nconst ONBOARD_SETTINGS: SettingsFileConfig = {\n llm: {\n provider: \"anthropic\",\n model: \"claude-sonnet-4-6\",\n thinkingLevel: \"off\",\n autoReply: {\n provider: \"anthropic\",\n model: \"claude-haiku-4-5\",\n },\n },\n slack: {\n replyMode: \"top-level\",\n },\n sandbox: {\n cpus: \"0.5\",\n memory: \"1g\",\n boost: {\n cpus: \"2\",\n memory: \"4g\",\n },\n image: {\n workspaceMount: \"private\",\n },\n defaultSharedVault: \"\",\n },\n};\n\nconst SettingsFileSchema = Type.Object({\n llm: Type.Optional(\n Type.Object({\n provider: Type.Optional(Type.String()),\n model: Type.Optional(Type.String()),\n thinkingLevel: Type.Optional(\n Type.Union([\n Type.Literal(\"off\"),\n Type.Literal(\"minimal\"),\n Type.Literal(\"low\"),\n Type.Literal(\"medium\"),\n Type.Literal(\"high\"),\n Type.Literal(\"xhigh\"),\n ]),\n ),\n autoReply: Type.Optional(\n Type.Object({\n provider: Type.Optional(Type.String()),\n model: Type.Optional(Type.String()),\n }),\n ),\n }),\n ),\n sentry: Type.Optional(\n Type.Object({\n dsn: Type.Optional(Type.String()),\n }),\n ),\n slack: Type.Optional(\n Type.Object({\n replyMode: Type.Optional(Type.Union([Type.Literal(\"top-level\"), Type.Literal(\"thread\")])),\n }),\n ),\n sandbox: Type.Optional(\n Type.Object({\n cpus: Type.Optional(Type.String()),\n memory: Type.Optional(Type.String()),\n boost: Type.Optional(\n Type.Object({\n cpus: Type.Optional(Type.String()),\n memory: Type.Optional(Type.String()),\n }),\n ),\n image: Type.Optional(\n Type.Object({\n workspaceMount: Type.Optional(\n Type.Union([Type.Literal(\"private\"), Type.Literal(\"full\")]),\n ),\n }),\n ),\n defaultSharedVault: Type.Optional(Type.String()),\n }),\n ),\n autoReply: Type.Optional(\n Type.Object({\n enabled: Type.Optional(Type.Boolean()),\n rules: Type.Optional(Type.Array(Type.String())),\n }),\n ),\n});\n\ntype SettingsFileConfig = Static<typeof SettingsFileSchema>;\n\nfunction loadSettingsFile(settingsPath: string): SettingsFileConfig | undefined {\n return readJsonSchemaFileIfExists(settingsPath, SettingsFileSchema, (detail) =>\n detail === \"unexpected JSON shape\"\n ? `Malformed settings file at ${settingsPath}: expected a JSON object at the top level`\n : `Malformed settings file at ${settingsPath}: ${detail}`,\n );\n}\n\nfunction getStateDir(): string {\n const raw = readEnv(\"STATE_DIR\");\n return raw ? resolve(raw) : join(homedir(), \".mikan\");\n}\n\nfunction normalizeSettingsConfig(config: SettingsFileConfig): Partial<AgentConfig> {\n return {\n ...(config.llm?.provider !== undefined ? { provider: config.llm.provider } : {}),\n ...(config.llm?.model !== undefined ? { model: config.llm.model } : {}),\n ...(config.llm?.thinkingLevel !== undefined ? { thinkingLevel: config.llm.thinkingLevel } : {}),\n ...(config.sentry?.dsn !== undefined ? { sentryDsn: config.sentry.dsn } : {}),\n ...(config.sandbox?.cpus !== undefined ? { sandboxCpus: config.sandbox.cpus } : {}),\n ...(config.sandbox?.memory !== undefined ? { sandboxMemory: config.sandbox.memory } : {}),\n ...(config.sandbox?.boost?.cpus !== undefined\n ? { sandboxBoostCpus: config.sandbox.boost.cpus }\n : {}),\n ...(config.sandbox?.boost?.memory !== undefined\n ? { sandboxBoostMemory: config.sandbox.boost.memory }\n : {}),\n ...(config.sandbox?.image?.workspaceMount !== undefined\n ? { sandboxImageWorkspaceMount: config.sandbox.image.workspaceMount }\n : {}),\n ...(config.sandbox?.defaultSharedVault?.trim()\n ? { defaultSharedVault: config.sandbox.defaultSharedVault.trim() }\n : {}),\n ...(config.slack !== undefined ? { slack: config.slack } : {}),\n };\n}\n\nfunction getSettingsPath(): string {\n return join(getStateDir(), \"settings.json\");\n}\n\nfunction requireGlobalSettings(): SettingsFileConfig {\n const settingsPath = getSettingsPath();\n const config = loadSettingsFile(settingsPath);\n if (!config) {\n throw new MissingGlobalSettingsError(settingsPath);\n }\n return config;\n}\n\nfunction requireString(value: string | undefined, path: string): string {\n if (!value) {\n throw new Error(\n `Missing required global setting: ${path}. Run \\`mikan --onboard\\` to create settings.json.`,\n );\n }\n return value;\n}\n\nfunction requireThinkingLevel(value: ThinkingLevel | undefined): ThinkingLevel {\n return requireString(value, \"llm.thinkingLevel\") as ThinkingLevel;\n}\n\nfunction toAgentConfig(fromFile: Partial<AgentConfig>): AgentConfig {\n const provider = requireString(fromFile.provider, \"llm.provider\");\n const model = requireString(fromFile.model, \"llm.model\");\n const thinkingLevel = requireThinkingLevel(fromFile.thinkingLevel);\n const sentryDsn = fromFile.sentryDsn ?? process.env.SENTRY_DSN;\n const sandboxCpus = fromFile.sandboxCpus;\n const sandboxMemory = fromFile.sandboxMemory;\n const sandboxBoostCpus = fromFile.sandboxBoostCpus;\n const sandboxBoostMemory = fromFile.sandboxBoostMemory;\n const sandboxImageWorkspaceMount = fromFile.sandboxImageWorkspaceMount;\n const defaultSharedVault = fromFile.defaultSharedVault;\n const slack = fromFile.slack;\n\n return {\n provider,\n model,\n thinkingLevel,\n sentryDsn,\n sandboxCpus,\n sandboxMemory,\n sandboxBoostCpus,\n sandboxBoostMemory,\n sandboxImageWorkspaceMount,\n defaultSharedVault,\n slack,\n };\n}\n\nfunction loadRawGlobalSettings(): Partial<AgentConfig> {\n return normalizeSettingsConfig(requireGlobalSettings());\n}\n\nexport function loadGlobalSettings(): AgentConfig {\n return toAgentConfig(loadRawGlobalSettings());\n}\n\nexport function resolveConversationSettings(conversationDir: string): AgentConfig {\n const globalConfig = loadRawGlobalSettings();\n const conversationConfig = normalizeSettingsConfig(\n loadSettingsFile(join(conversationDir, \"settings.json\")) ?? {},\n );\n return toAgentConfig({ ...globalConfig, ...conversationConfig });\n}\n\n/**\n * Resolve the model used to judge auto-reply rules. Falls back to the main\n * llm.{provider,model} when llm.autoReply is not set, so a missing override\n * keeps current behavior.\n *\n * @deprecated Auto-reply is kept for compatibility while its future is undecided.\n */\nexport function loadAutoReplyJudgeModel(conversationDir?: string): JudgeModelConfig {\n const global = requireGlobalSettings();\n const local = conversationDir\n ? (loadSettingsFile(join(conversationDir, \"settings.json\")) ?? {})\n : {};\n const merged: SettingsFileConfig[\"llm\"] = { ...global.llm, ...local.llm };\n const judge = { ...global.llm?.autoReply, ...local.llm?.autoReply };\n const provider = requireString(judge.provider ?? merged?.provider, \"llm.autoReply.provider\");\n const model = requireString(judge.model ?? merged?.model, \"llm.autoReply.model\");\n return { provider, model };\n}\n\nconst AUTO_REPLY_FILE = \"auto-reply\";\nconst AUTO_REPLY_DISABLED_FILE = \"auto-reply.disabled\";\n\nfunction readAutoReplyRulesFile(path: string): string[] {\n const text = readFileSync(path, \"utf-8\").trim();\n return text ? [text] : [];\n}\n\n/**\n * Load the mom-compatible auto-reply marker file state for a conversation.\n *\n * - `auto-reply` exists: enabled; empty file means reply to any top-level message.\n * - `auto-reply.disabled` exists: disabled, preserving any rules text for re-enable.\n * - neither exists: disabled.\n *\n * @deprecated Auto-reply is kept for compatibility while its future is undecided.\n */\nexport function loadConversationAutoReplyConfig(conversationDir: string): AutoReplyConfig {\n const enabledPath = join(conversationDir, AUTO_REPLY_FILE);\n if (existsSync(enabledPath)) {\n return { enabled: true, rules: readAutoReplyRulesFile(enabledPath) };\n }\n\n const disabledPath = join(conversationDir, AUTO_REPLY_DISABLED_FILE);\n if (existsSync(disabledPath)) {\n return { enabled: false, rules: readAutoReplyRulesFile(disabledPath) };\n }\n\n return { enabled: false, rules: [] };\n}\n\n/**\n * Save auto-reply state using mom-compatible marker files.\n *\n * @deprecated Auto-reply is kept for compatibility while its future is undecided.\n */\nexport function saveConversationAutoReplyConfig(\n conversationDir: string,\n config: AutoReplyConfig,\n): void {\n ensureDirExists(conversationDir);\n\n const enabledPath = join(conversationDir, AUTO_REPLY_FILE);\n const disabledPath = join(conversationDir, AUTO_REPLY_DISABLED_FILE);\n const targetPath = config.enabled ? enabledPath : disabledPath;\n const otherPath = config.enabled ? disabledPath : enabledPath;\n\n if (existsSync(otherPath)) {\n renameSync(otherPath, targetPath);\n }\n\n atomicWritePrivateFile(targetPath, config.rules.join(\"\\n\"));\n}\n\nexport function resolveWorkspaceDirFromArgv(args = process.argv.slice(2)): string | undefined {\n for (let i = 0; i < args.length; i++) {\n const arg = args[i];\n\n if (arg === \"--sandbox\" || arg === \"--download\" || arg === \"--state-dir\") {\n i += 1;\n continue;\n }\n\n if (arg === \"--version\" || arg === \"-v\" || arg === \"-V\" || arg === \"--onboard\") {\n continue;\n }\n\n if (\n arg.startsWith(\"--sandbox=\") ||\n arg.startsWith(\"--download=\") ||\n arg.startsWith(\"--state-dir=\")\n ) {\n continue;\n }\n\n if (!arg.startsWith(\"-\")) {\n return arg;\n }\n }\n\n return undefined;\n}\n\nexport function resolveStateDirFromArgv(args = process.argv.slice(2)): string {\n for (let i = 0; i < args.length; i++) {\n const arg = args[i];\n if (arg.startsWith(\"--state-dir=\")) {\n return resolve(arg.slice(\"--state-dir=\".length));\n }\n if (arg === \"--state-dir\") {\n return resolve(args[++i] || \"\");\n }\n }\n\n return join(homedir(), \".mikan\");\n}\n\nexport function resolveSentryDsn(): string | undefined {\n const fromFile = normalizeSettingsConfig(loadSettingsFile(getSettingsPath()) ?? {});\n if (fromFile.sentryDsn) {\n return fromFile.sentryDsn;\n }\n\n return process.env.SENTRY_DSN;\n}\n\nexport function createGlobalSettingsFile(stateDir: string): string {\n const settingsPath = join(stateDir, \"settings.json\");\n if (existsSync(settingsPath)) {\n throw new Error(`Global settings already exists at ${settingsPath}`);\n }\n ensureDirExists(stateDir);\n atomicWritePrivateFile(settingsPath, JSON.stringify(ONBOARD_SETTINGS, null, 2));\n return settingsPath;\n}\n\n/**\n * Externally-visible base URL of the link/OAuth server, e.g.\n * `https://mikan.example.com` (no trailing slash). Read from `LINK_URL` or\n * `MIKAN_LINK_URL`, the same env var the bot uses to build credential onboarding links.\n */\nexport function resolveLinkBaseUrl(): string | undefined {\n const raw = readEnv(\"LINK_URL\");\n if (!raw) return undefined;\n return raw.replace(/\\/+$/, \"\");\n}\n\nfunction hasDefinedValue(values: Record<string, unknown> | undefined): boolean {\n return values !== undefined && Object.values(values).some((value) => value !== undefined);\n}\n\nfunction compactSettingsConfig(config: SettingsFileConfig): SettingsFileConfig {\n return {\n ...(hasDefinedValue(config.llm) ? { llm: config.llm } : {}),\n ...(hasDefinedValue(config.sentry) ? { sentry: config.sentry } : {}),\n ...(hasDefinedValue(config.sandbox) ? { sandbox: config.sandbox } : {}),\n ...(hasDefinedValue(config.autoReply) ? { autoReply: config.autoReply } : {}),\n ...(hasDefinedValue(config.slack) ? { slack: config.slack } : {}),\n };\n}\n\nfunction patchSettingsConfig(\n existing: SettingsFileConfig,\n config: Partial<AgentConfig>,\n): SettingsFileConfig {\n const patched: SettingsFileConfig = {\n ...existing,\n llm: {\n ...existing.llm,\n ...(config.provider !== undefined ? { provider: config.provider } : {}),\n ...(config.model !== undefined ? { model: config.model } : {}),\n ...(config.thinkingLevel !== undefined ? { thinkingLevel: config.thinkingLevel } : {}),\n },\n sentry: {\n ...existing.sentry,\n ...(config.sentryDsn !== undefined ? { dsn: config.sentryDsn } : {}),\n },\n sandbox: {\n ...existing.sandbox,\n ...(config.sandboxCpus !== undefined ? { cpus: config.sandboxCpus } : {}),\n ...(config.sandboxMemory !== undefined ? { memory: config.sandboxMemory } : {}),\n ...(config.sandboxBoostCpus !== undefined || config.sandboxBoostMemory !== undefined\n ? {\n boost: {\n ...existing.sandbox?.boost,\n ...(config.sandboxBoostCpus !== undefined ? { cpus: config.sandboxBoostCpus } : {}),\n ...(config.sandboxBoostMemory !== undefined\n ? { memory: config.sandboxBoostMemory }\n : {}),\n },\n }\n : {}),\n ...(config.sandboxImageWorkspaceMount !== undefined\n ? {\n image: {\n ...existing.sandbox?.image,\n workspaceMount: config.sandboxImageWorkspaceMount,\n },\n }\n : {}),\n ...(config.defaultSharedVault !== undefined\n ? { defaultSharedVault: config.defaultSharedVault }\n : {}),\n },\n slack: {\n ...existing.slack,\n ...config.slack,\n },\n };\n return compactSettingsConfig(patched);\n}\n\nfunction updateSettingsFile(\n settingsPath: string,\n patch: Partial<AgentConfig>,\n defaultSettings: SettingsFileConfig,\n): void {\n let existing = defaultSettings;\n if (existsSync(settingsPath)) {\n try {\n existing = loadSettingsFile(settingsPath) ?? {};\n } catch (err) {\n const detail = err instanceof Error ? err.message : String(err);\n const message = detail.startsWith(\"Malformed settings file\")\n ? detail.replace(\"Malformed settings file\", \"Refusing to overwrite malformed settings file\")\n : detail;\n throw new Error(message, { cause: err });\n }\n }\n\n ensureDirExists(dirname(settingsPath));\n atomicWritePrivateFile(\n settingsPath,\n JSON.stringify(patchSettingsConfig(existing, patch), null, 2),\n );\n}\n\nexport function updateGlobalSettings(patch: Partial<AgentConfig>): void {\n updateSettingsFile(join(getStateDir(), \"settings.json\"), patch, ONBOARD_SETTINGS);\n}\n\nexport function updateConversationSettings(\n conversationDir: string,\n patch: Partial<AgentConfig>,\n): void {\n updateSettingsFile(join(conversationDir, \"settings.json\"), patch, {});\n}\n"]}
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAe,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,IAAI,CAAC;AAClE,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACxD,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AACzC,OAAO,EAAE,eAAe,EAAE,0BAA0B,EAAE,MAAM,wBAAwB,CAAC;AACrF,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,KAAK,GAAG,MAAM,UAAU,CAAC;AAEhC,MAAM,OAAO,0BAA2B,SAAQ,KAAK;IACnD,YAA4B,YAAoB;QAC9C,KAAK,CAAC,mCAAmC,YAAY,EAAE,CAAC,CAAC;4BAD/B,YAAY;QAEtC,IAAI,CAAC,IAAI,GAAG,4BAA4B,CAAC;IAC3C,CAAC;CACF;AAKD,MAAM,gBAAgB,GAAuB;IAC3C,GAAG,EAAE;QACH,QAAQ,EAAE,WAAW;QACrB,KAAK,EAAE,mBAAmB;QAC1B,aAAa,EAAE,KAAK;QACpB,SAAS,EAAE;YACT,QAAQ,EAAE,WAAW;YACrB,KAAK,EAAE,kBAAkB;SAC1B;KACF;IACD,KAAK,EAAE;QACL,SAAS,EAAE,WAAW;KACvB;IACD,OAAO,EAAE;QACP,IAAI,EAAE,KAAK;QACX,MAAM,EAAE,IAAI;QACZ,KAAK,EAAE;YACL,IAAI,EAAE,GAAG;YACT,MAAM,EAAE,IAAI;SACb;QACD,KAAK,EAAE;YACL,cAAc,EAAE,SAAS;SAC1B;QACD,kBAAkB,EAAE,EAAE;KACvB;CACF,CAAC;AAEF,MAAM,kBAAkB,GAAG,IAAI,CAAC,MAAM,CAAC;IACrC,GAAG,EAAE,IAAI,CAAC,QAAQ,CAChB,IAAI,CAAC,MAAM,CAAC;QACV,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;QACtC,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;QACnC,aAAa,EAAE,IAAI,CAAC,QAAQ,CAC1B,IAAI,CAAC,KAAK,CAAC;YACT,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;YACnB,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC;YACvB,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;YACnB,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC;YACtB,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;YACpB,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC;SACtB,CAAC,CACH;QACD,SAAS,EAAE,IAAI,CAAC,QAAQ,CACtB,IAAI,CAAC,MAAM,CAAC;YACV,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACtC,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;SACpC,CAAC,CACH;KACF,CAAC,CACH;IACD,MAAM,EAAE,IAAI,CAAC,QAAQ,CACnB,IAAI,CAAC,MAAM,CAAC;QACV,GAAG,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;KAClC,CAAC,CACH;IACD,KAAK,EAAE,IAAI,CAAC,QAAQ,CAClB,IAAI,CAAC,MAAM,CAAC;QACV,SAAS,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;KAC1F,CAAC,CACH;IACD,OAAO,EAAE,IAAI,CAAC,QAAQ,CACpB,IAAI,CAAC,MAAM,CAAC;QACV,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;QAClC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;QACpC,KAAK,EAAE,IAAI,CAAC,QAAQ,CAClB,IAAI,CAAC,MAAM,CAAC;YACV,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YAClC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;SACrC,CAAC,CACH;QACD,KAAK,EAAE,IAAI,CAAC,QAAQ,CAClB,IAAI,CAAC,MAAM,CAAC;YACV,cAAc,EAAE,IAAI,CAAC,QAAQ,CAC3B,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAC5D;SACF,CAAC,CACH;QACD,kBAAkB,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;KACjD,CAAC,CACH;IACD,SAAS,EAAE,IAAI,CAAC,QAAQ,CACtB,IAAI,CAAC,MAAM,CAAC;QACV,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;QACtC,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;KAChD,CAAC,CACH;CACF,CAAC,CAAC;AAIH,SAAS,gBAAgB,CAAC,YAAoB;IAC5C,OAAO,0BAA0B,CAAC,YAAY,EAAE,kBAAkB,EAAE,CAAC,MAAM,EAAE,EAAE,CAC7E,MAAM,KAAK,uBAAuB;QAChC,CAAC,CAAC,8BAA8B,YAAY,2CAA2C;QACvF,CAAC,CAAC,8BAA8B,YAAY,KAAK,MAAM,EAAE,CAC5D,CAAC;AACJ,CAAC;AAED,SAAS,WAAW;IAClB,MAAM,GAAG,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IACjC,OAAO,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,QAAQ,CAAC,CAAC;AACxD,CAAC;AAED,SAAS,uBAAuB,CAAC,MAA0B;IACzD,OAAO;QACL,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAChF,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACvE,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,MAAM,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/F,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7E,GAAG,CAAC,MAAM,CAAC,OAAO,EAAE,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACnF,GAAG,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACzF,GAAG,CAAC,MAAM,CAAC,OAAO,EAAE,KAAK,EAAE,IAAI,KAAK,SAAS;YAC3C,CAAC,CAAC,EAAE,gBAAgB,EAAE,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE;YACjD,CAAC,CAAC,EAAE,CAAC;QACP,GAAG,CAAC,MAAM,CAAC,OAAO,EAAE,KAAK,EAAE,MAAM,KAAK,SAAS;YAC7C,CAAC,CAAC,EAAE,kBAAkB,EAAE,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE;YACrD,CAAC,CAAC,EAAE,CAAC;QACP,GAAG,CAAC,MAAM,CAAC,OAAO,EAAE,KAAK,EAAE,cAAc,KAAK,SAAS;YACrD,CAAC,CAAC,EAAE,0BAA0B,EAAE,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE;YACrE,CAAC,CAAC,EAAE,CAAC;QACP,GAAG,CAAC,MAAM,CAAC,OAAO,EAAE,kBAAkB,EAAE,IAAI,EAAE;YAC5C,CAAC,CAAC,EAAE,kBAAkB,EAAE,MAAM,CAAC,OAAO,CAAC,kBAAkB,CAAC,IAAI,EAAE,EAAE;YAClE,CAAC,CAAC,EAAE,CAAC;QACP,GAAG,CAAC,MAAM,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC/D,CAAC;AACJ,CAAC;AAED,SAAS,eAAe;IACtB,OAAO,IAAI,CAAC,WAAW,EAAE,EAAE,eAAe,CAAC,CAAC;AAC9C,CAAC;AAED,SAAS,qBAAqB;IAC5B,MAAM,YAAY,GAAG,eAAe,EAAE,CAAC;IACvC,MAAM,MAAM,GAAG,gBAAgB,CAAC,YAAY,CAAC,CAAC;IAC9C,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,0BAA0B,CAAC,YAAY,CAAC,CAAC;IACrD,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,aAAa,CAAC,KAAyB,EAAE,IAAY;IAC5D,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CACb,oCAAoC,IAAI,oDAAoD,CAC7F,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,oBAAoB,CAAC,KAAgC;IAC5D,OAAO,aAAa,CAAC,KAAK,EAAE,mBAAmB,CAAkB,CAAC;AACpE,CAAC;AAED,SAAS,aAAa,CAAC,QAA8B;IACnD,MAAM,QAAQ,GAAG,aAAa,CAAC,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;IAClE,MAAM,KAAK,GAAG,aAAa,CAAC,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;IACzD,MAAM,aAAa,GAAG,oBAAoB,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;IACnE,MAAM,SAAS,GAAG,QAAQ,CAAC,SAAS,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC;IAC/D,MAAM,WAAW,GAAG,QAAQ,CAAC,WAAW,CAAC;IACzC,MAAM,aAAa,GAAG,QAAQ,CAAC,aAAa,CAAC;IAC7C,MAAM,gBAAgB,GAAG,QAAQ,CAAC,gBAAgB,CAAC;IACnD,MAAM,kBAAkB,GAAG,QAAQ,CAAC,kBAAkB,CAAC;IACvD,MAAM,0BAA0B,GAAG,QAAQ,CAAC,0BAA0B,CAAC;IACvE,MAAM,kBAAkB,GAAG,QAAQ,CAAC,kBAAkB,CAAC;IACvD,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC;IAE7B,OAAO;QACL,QAAQ;QACR,KAAK;QACL,aAAa;QACb,SAAS;QACT,WAAW;QACX,aAAa;QACb,gBAAgB;QAChB,kBAAkB;QAClB,0BAA0B;QAC1B,kBAAkB;QAClB,KAAK;KACN,CAAC;AACJ,CAAC;AAED,SAAS,qBAAqB;IAC5B,OAAO,uBAAuB,CAAC,qBAAqB,EAAE,CAAC,CAAC;AAC1D,CAAC;AAED,MAAM,UAAU,kBAAkB;IAChC,OAAO,aAAa,CAAC,qBAAqB,EAAE,CAAC,CAAC;AAChD,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,wBAAwB,CAAC,eAAuB;IAC9D,MAAM,cAAc,GAAG,QAAQ,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC;IAC1D,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE,EAAE,eAAe,EAAE,cAAc,EAAE,eAAe,CAAC,CAAC;IACvF,IAAI,UAAU,CAAC,QAAQ,CAAC;QAAE,OAAO,QAAQ,CAAC;IAE1C,eAAe,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;IACnC,MAAM,UAAU,GAAG,IAAI,CAAC,eAAe,EAAE,eAAe,CAAC,CAAC;IAC1D,IAAI,OAAO,GAAG,MAAM,CAAC;IACrB,IAAI,QAAQ,GAAG,KAAK,CAAC;IACrB,IAAI,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC3B,IAAI,CAAC;YACH,OAAO,GAAG,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;YAC5C,QAAQ,GAAG,IAAI,CAAC;QAClB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,GAAG,CAAC,UAAU,CAAC,gDAAgD,UAAU,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QAC5F,CAAC;IACH,CAAC;IACD,sBAAsB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC1C,IAAI,QAAQ,EAAE,CAAC;QACb,IAAI,CAAC;YACH,MAAM,CAAC,UAAU,CAAC,CAAC;QACrB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,GAAG,CAAC,UAAU,CAAC,kDAAkD,UAAU,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QAC9F,CAAC;QACD,GAAG,CAAC,OAAO,CAAC,qDAAqD,QAAQ,EAAE,CAAC,CAAC;IAC/E,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,2BAA2B,CAAC,eAAuB;IACjE,MAAM,YAAY,GAAG,qBAAqB,EAAE,CAAC;IAC7C,MAAM,kBAAkB,GAAG,uBAAuB,CAChD,gBAAgB,CAAC,wBAAwB,CAAC,eAAe,CAAC,CAAC,IAAI,EAAE,CAClE,CAAC;IACF,OAAO,aAAa,CAAC,EAAE,GAAG,YAAY,EAAE,GAAG,kBAAkB,EAAE,CAAC,CAAC;AACnE,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,uBAAuB,CAAC,eAAwB;IAC9D,MAAM,MAAM,GAAG,qBAAqB,EAAE,CAAC;IACvC,MAAM,KAAK,GAAG,eAAe;QAC3B,CAAC,CAAC,CAAC,gBAAgB,CAAC,wBAAwB,CAAC,eAAe,CAAC,CAAC,IAAI,EAAE,CAAC;QACrE,CAAC,CAAC,EAAE,CAAC;IACP,MAAM,MAAM,GAA8B,EAAE,GAAG,MAAM,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,GAAG,EAAE,CAAC;IAC1E,MAAM,KAAK,GAAG,EAAE,GAAG,MAAM,CAAC,GAAG,EAAE,SAAS,EAAE,GAAG,KAAK,CAAC,GAAG,EAAE,SAAS,EAAE,CAAC;IACpE,MAAM,QAAQ,GAAG,aAAa,CAAC,KAAK,CAAC,QAAQ,IAAI,MAAM,EAAE,QAAQ,EAAE,wBAAwB,CAAC,CAAC;IAC7F,MAAM,KAAK,GAAG,aAAa,CAAC,KAAK,CAAC,KAAK,IAAI,MAAM,EAAE,KAAK,EAAE,qBAAqB,CAAC,CAAC;IACjF,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;AAC7B,CAAC;AAED,MAAM,eAAe,GAAG,YAAY,CAAC;AACrC,MAAM,wBAAwB,GAAG,qBAAqB,CAAC;AAEvD,SAAS,sBAAsB,CAAC,IAAY;IAC1C,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;IAChD,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AAC5B,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,+BAA+B,CAAC,eAAuB;IACrE,MAAM,WAAW,GAAG,IAAI,CAAC,eAAe,EAAE,eAAe,CAAC,CAAC;IAC3D,IAAI,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAC5B,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,sBAAsB,CAAC,WAAW,CAAC,EAAE,CAAC;IACvE,CAAC;IAED,MAAM,YAAY,GAAG,IAAI,CAAC,eAAe,EAAE,wBAAwB,CAAC,CAAC;IACrE,IAAI,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QAC7B,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,sBAAsB,CAAC,YAAY,CAAC,EAAE,CAAC;IACzE,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;AACvC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,+BAA+B,CAC7C,eAAuB,EACvB,MAAuB;IAEvB,eAAe,CAAC,eAAe,CAAC,CAAC;IAEjC,MAAM,WAAW,GAAG,IAAI,CAAC,eAAe,EAAE,eAAe,CAAC,CAAC;IAC3D,MAAM,YAAY,GAAG,IAAI,CAAC,eAAe,EAAE,wBAAwB,CAAC,CAAC;IACrE,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,YAAY,CAAC;IAC/D,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,WAAW,CAAC;IAE9D,IAAI,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC1B,UAAU,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;IACpC,CAAC;IAED,sBAAsB,CAAC,UAAU,EAAE,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;AAC9D,CAAC;AAED,MAAM,UAAU,2BAA2B,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IACtE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAEpB,IAAI,GAAG,KAAK,WAAW,IAAI,GAAG,KAAK,YAAY,IAAI,GAAG,KAAK,aAAa,EAAE,CAAC;YACzE,CAAC,IAAI,CAAC,CAAC;YACP,SAAS;QACX,CAAC;QAED,IAAI,GAAG,KAAK,WAAW,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,KAAK,WAAW,EAAE,CAAC;YAC/E,SAAS;QACX,CAAC;QAED,IACE,GAAG,CAAC,UAAU,CAAC,YAAY,CAAC;YAC5B,GAAG,CAAC,UAAU,CAAC,aAAa,CAAC;YAC7B,GAAG,CAAC,UAAU,CAAC,cAAc,CAAC,EAC9B,CAAC;YACD,SAAS;QACX,CAAC;QAED,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACzB,OAAO,GAAG,CAAC;QACb,CAAC;IACH,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IAClE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACpB,IAAI,GAAG,CAAC,UAAU,CAAC,cAAc,CAAC,EAAE,CAAC;YACnC,OAAO,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC;QACnD,CAAC;QACD,IAAI,GAAG,KAAK,aAAa,EAAE,CAAC;YAC1B,OAAO,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QAClC,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,QAAQ,CAAC,CAAC;AACnC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,KAAa,EAAE,MAAc;IACxD,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACnC,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;IACjC,OAAO,SAAS,KAAK,UAAU,IAAI,SAAS,CAAC,UAAU,CAAC,UAAU,GAAG,GAAG,CAAC,CAAC;AAC5E,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,8BAA8B,CAC5C,QAAgB,EAChB,UAAkB,EAClB,WAAmB;IAEnB,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,UAAU,CAAC;QAAE,OAAO;IAChD,MAAM,OAAO,GACX,gBAAgB,QAAQ,+CAA+C,UAAU,KAAK;QACtF,0EAA0E;QAC1E,qEAAqE,CAAC;IACxE,IAAI,WAAW,KAAK,MAAM,EAAE,CAAC;QAC3B,GAAG,CAAC,UAAU,CAAC,6BAA6B,EAAE,OAAO,CAAC,CAAC;QACvD,OAAO;IACT,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC;AAC3B,CAAC;AAED,MAAM,UAAU,gBAAgB;IAC9B,MAAM,QAAQ,GAAG,uBAAuB,CAAC,gBAAgB,CAAC,eAAe,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC;IACpF,IAAI,QAAQ,CAAC,SAAS,EAAE,CAAC;QACvB,OAAO,QAAQ,CAAC,SAAS,CAAC;IAC5B,CAAC;IAED,OAAO,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC;AAChC,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,QAAgB;IACvD,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC;IACrD,IAAI,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CAAC,qCAAqC,YAAY,EAAE,CAAC,CAAC;IACvE,CAAC;IACD,eAAe,CAAC,QAAQ,CAAC,CAAC;IAC1B,sBAAsB,CAAC,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,gBAAgB,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAChF,OAAO,YAAY,CAAC;AACtB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,kBAAkB;IAChC,MAAM,GAAG,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IAChC,IAAI,CAAC,GAAG;QAAE,OAAO,SAAS,CAAC;IAC3B,OAAO,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AACjC,CAAC;AAED,SAAS,eAAe,CAAC,MAA2C;IAClE,OAAO,MAAM,KAAK,SAAS,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC;AAC5F,CAAC;AAED,SAAS,qBAAqB,CAAC,MAA0B;IACvD,OAAO;QACL,GAAG,CAAC,eAAe,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3D,GAAG,CAAC,eAAe,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACpE,GAAG,CAAC,eAAe,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACvE,GAAG,CAAC,eAAe,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7E,GAAG,CAAC,eAAe,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAClE,CAAC;AACJ,CAAC;AAED,SAAS,mBAAmB,CAC1B,QAA4B,EAC5B,MAA4B;IAE5B,MAAM,OAAO,GAAuB;QAClC,GAAG,QAAQ;QACX,GAAG,EAAE;YACH,GAAG,QAAQ,CAAC,GAAG;YACf,GAAG,CAAC,MAAM,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACvE,GAAG,CAAC,MAAM,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC9D,GAAG,CAAC,MAAM,CAAC,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACvF;QACD,MAAM,EAAE;YACN,GAAG,QAAQ,CAAC,MAAM;YAClB,GAAG,CAAC,MAAM,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACrE;QACD,OAAO,EAAE;YACP,GAAG,QAAQ,CAAC,OAAO;YACnB,GAAG,CAAC,MAAM,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACzE,GAAG,CAAC,MAAM,CAAC,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC/E,GAAG,CAAC,MAAM,CAAC,gBAAgB,KAAK,SAAS,IAAI,MAAM,CAAC,kBAAkB,KAAK,SAAS;gBAClF,CAAC,CAAC;oBACE,KAAK,EAAE;wBACL,GAAG,QAAQ,CAAC,OAAO,EAAE,KAAK;wBAC1B,GAAG,CAAC,MAAM,CAAC,gBAAgB,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;wBACnF,GAAG,CAAC,MAAM,CAAC,kBAAkB,KAAK,SAAS;4BACzC,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,kBAAkB,EAAE;4BACvC,CAAC,CAAC,EAAE,CAAC;qBACR;iBACF;gBACH,CAAC,CAAC,EAAE,CAAC;YACP,GAAG,CAAC,MAAM,CAAC,0BAA0B,KAAK,SAAS;gBACjD,CAAC,CAAC;oBACE,KAAK,EAAE;wBACL,GAAG,QAAQ,CAAC,OAAO,EAAE,KAAK;wBAC1B,cAAc,EAAE,MAAM,CAAC,0BAA0B;qBAClD;iBACF;gBACH,CAAC,CAAC,EAAE,CAAC;YACP,GAAG,CAAC,MAAM,CAAC,kBAAkB,KAAK,SAAS;gBACzC,CAAC,CAAC,EAAE,kBAAkB,EAAE,MAAM,CAAC,kBAAkB,EAAE;gBACnD,CAAC,CAAC,EAAE,CAAC;SACR;QACD,KAAK,EAAE;YACL,GAAG,QAAQ,CAAC,KAAK;YACjB,GAAG,MAAM,CAAC,KAAK;SAChB;KACF,CAAC;IACF,OAAO,qBAAqB,CAAC,OAAO,CAAC,CAAC;AACxC,CAAC;AAED,SAAS,kBAAkB,CACzB,YAAoB,EACpB,KAA2B,EAC3B,eAAmC;IAEnC,IAAI,QAAQ,GAAG,eAAe,CAAC;IAC/B,IAAI,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QAC7B,IAAI,CAAC;YACH,QAAQ,GAAG,gBAAgB,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC;QAClD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,MAAM,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAChE,MAAM,OAAO,GAAG,MAAM,CAAC,UAAU,CAAC,yBAAyB,CAAC;gBAC1D,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,yBAAyB,EAAE,+CAA+C,CAAC;gBAC5F,CAAC,CAAC,MAAM,CAAC;YACX,MAAM,IAAI,KAAK,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;QAC3C,CAAC;IACH,CAAC;IAED,eAAe,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC;IACvC,sBAAsB,CACpB,YAAY,EACZ,IAAI,CAAC,SAAS,CAAC,mBAAmB,CAAC,QAAQ,EAAE,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAC9D,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,KAA2B;IAC9D,kBAAkB,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,eAAe,CAAC,EAAE,KAAK,EAAE,gBAAgB,CAAC,CAAC;AACpF,CAAC;AAED,MAAM,UAAU,0BAA0B,CACxC,eAAuB,EACvB,KAA2B;IAE3B,kBAAkB,CAAC,wBAAwB,CAAC,eAAe,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;AAC3E,CAAC","sourcesContent":["import type { ThinkingLevel } from \"@earendil-works/pi-agent-core\";\nimport { Type, type Static } from \"@sinclair/typebox\";\nimport { existsSync, readFileSync, renameSync, rmSync } from \"fs\";\nimport { homedir } from \"os\";\nimport { basename, dirname, join, resolve } from \"path\";\nimport { readEnv } from \"./utils/env.js\";\nimport { ensureDirExists, readJsonSchemaFileIfExists } from \"./utils/file-guards.js\";\nimport { atomicWritePrivateFile } from \"./utils/fs-atomic.js\";\nimport * as log from \"./log.js\";\n\nexport class MissingGlobalSettingsError extends Error {\n constructor(public readonly settingsPath: string) {\n super(`Missing global settings file at ${settingsPath}`);\n this.name = \"MissingGlobalSettingsError\";\n }\n}\n\nexport type { AgentConfig, AutoReplyConfig, JudgeModelConfig } from \"./types.js\";\nimport type { AgentConfig, AutoReplyConfig, JudgeModelConfig } from \"./types.js\";\n\nconst ONBOARD_SETTINGS: SettingsFileConfig = {\n llm: {\n provider: \"anthropic\",\n model: \"claude-sonnet-4-6\",\n thinkingLevel: \"off\",\n autoReply: {\n provider: \"anthropic\",\n model: \"claude-haiku-4-5\",\n },\n },\n slack: {\n replyMode: \"top-level\",\n },\n sandbox: {\n cpus: \"0.5\",\n memory: \"1g\",\n boost: {\n cpus: \"2\",\n memory: \"4g\",\n },\n image: {\n workspaceMount: \"private\",\n },\n defaultSharedVault: \"\",\n },\n};\n\nconst SettingsFileSchema = Type.Object({\n llm: Type.Optional(\n Type.Object({\n provider: Type.Optional(Type.String()),\n model: Type.Optional(Type.String()),\n thinkingLevel: Type.Optional(\n Type.Union([\n Type.Literal(\"off\"),\n Type.Literal(\"minimal\"),\n Type.Literal(\"low\"),\n Type.Literal(\"medium\"),\n Type.Literal(\"high\"),\n Type.Literal(\"xhigh\"),\n ]),\n ),\n autoReply: Type.Optional(\n Type.Object({\n provider: Type.Optional(Type.String()),\n model: Type.Optional(Type.String()),\n }),\n ),\n }),\n ),\n sentry: Type.Optional(\n Type.Object({\n dsn: Type.Optional(Type.String()),\n }),\n ),\n slack: Type.Optional(\n Type.Object({\n replyMode: Type.Optional(Type.Union([Type.Literal(\"top-level\"), Type.Literal(\"thread\")])),\n }),\n ),\n sandbox: Type.Optional(\n Type.Object({\n cpus: Type.Optional(Type.String()),\n memory: Type.Optional(Type.String()),\n boost: Type.Optional(\n Type.Object({\n cpus: Type.Optional(Type.String()),\n memory: Type.Optional(Type.String()),\n }),\n ),\n image: Type.Optional(\n Type.Object({\n workspaceMount: Type.Optional(\n Type.Union([Type.Literal(\"private\"), Type.Literal(\"full\")]),\n ),\n }),\n ),\n defaultSharedVault: Type.Optional(Type.String()),\n }),\n ),\n autoReply: Type.Optional(\n Type.Object({\n enabled: Type.Optional(Type.Boolean()),\n rules: Type.Optional(Type.Array(Type.String())),\n }),\n ),\n});\n\ntype SettingsFileConfig = Static<typeof SettingsFileSchema>;\n\nfunction loadSettingsFile(settingsPath: string): SettingsFileConfig | undefined {\n return readJsonSchemaFileIfExists(settingsPath, SettingsFileSchema, (detail) =>\n detail === \"unexpected JSON shape\"\n ? `Malformed settings file at ${settingsPath}: expected a JSON object at the top level`\n : `Malformed settings file at ${settingsPath}: ${detail}`,\n );\n}\n\nfunction getStateDir(): string {\n const raw = readEnv(\"STATE_DIR\");\n return raw ? resolve(raw) : join(homedir(), \".mikan\");\n}\n\nfunction normalizeSettingsConfig(config: SettingsFileConfig): Partial<AgentConfig> {\n return {\n ...(config.llm?.provider !== undefined ? { provider: config.llm.provider } : {}),\n ...(config.llm?.model !== undefined ? { model: config.llm.model } : {}),\n ...(config.llm?.thinkingLevel !== undefined ? { thinkingLevel: config.llm.thinkingLevel } : {}),\n ...(config.sentry?.dsn !== undefined ? { sentryDsn: config.sentry.dsn } : {}),\n ...(config.sandbox?.cpus !== undefined ? { sandboxCpus: config.sandbox.cpus } : {}),\n ...(config.sandbox?.memory !== undefined ? { sandboxMemory: config.sandbox.memory } : {}),\n ...(config.sandbox?.boost?.cpus !== undefined\n ? { sandboxBoostCpus: config.sandbox.boost.cpus }\n : {}),\n ...(config.sandbox?.boost?.memory !== undefined\n ? { sandboxBoostMemory: config.sandbox.boost.memory }\n : {}),\n ...(config.sandbox?.image?.workspaceMount !== undefined\n ? { sandboxImageWorkspaceMount: config.sandbox.image.workspaceMount }\n : {}),\n ...(config.sandbox?.defaultSharedVault?.trim()\n ? { defaultSharedVault: config.sandbox.defaultSharedVault.trim() }\n : {}),\n ...(config.slack !== undefined ? { slack: config.slack } : {}),\n };\n}\n\nfunction getSettingsPath(): string {\n return join(getStateDir(), \"settings.json\");\n}\n\nfunction requireGlobalSettings(): SettingsFileConfig {\n const settingsPath = getSettingsPath();\n const config = loadSettingsFile(settingsPath);\n if (!config) {\n throw new MissingGlobalSettingsError(settingsPath);\n }\n return config;\n}\n\nfunction requireString(value: string | undefined, path: string): string {\n if (!value) {\n throw new Error(\n `Missing required global setting: ${path}. Run \\`mikan --onboard\\` to create settings.json.`,\n );\n }\n return value;\n}\n\nfunction requireThinkingLevel(value: ThinkingLevel | undefined): ThinkingLevel {\n return requireString(value, \"llm.thinkingLevel\") as ThinkingLevel;\n}\n\nfunction toAgentConfig(fromFile: Partial<AgentConfig>): AgentConfig {\n const provider = requireString(fromFile.provider, \"llm.provider\");\n const model = requireString(fromFile.model, \"llm.model\");\n const thinkingLevel = requireThinkingLevel(fromFile.thinkingLevel);\n const sentryDsn = fromFile.sentryDsn ?? process.env.SENTRY_DSN;\n const sandboxCpus = fromFile.sandboxCpus;\n const sandboxMemory = fromFile.sandboxMemory;\n const sandboxBoostCpus = fromFile.sandboxBoostCpus;\n const sandboxBoostMemory = fromFile.sandboxBoostMemory;\n const sandboxImageWorkspaceMount = fromFile.sandboxImageWorkspaceMount;\n const defaultSharedVault = fromFile.defaultSharedVault;\n const slack = fromFile.slack;\n\n return {\n provider,\n model,\n thinkingLevel,\n sentryDsn,\n sandboxCpus,\n sandboxMemory,\n sandboxBoostCpus,\n sandboxBoostMemory,\n sandboxImageWorkspaceMount,\n defaultSharedVault,\n slack,\n };\n}\n\nfunction loadRawGlobalSettings(): Partial<AgentConfig> {\n return normalizeSettingsConfig(requireGlobalSettings());\n}\n\nexport function loadGlobalSettings(): AgentConfig {\n return toAgentConfig(loadRawGlobalSettings());\n}\n\n/**\n * Host-authoritative location of a conversation's settings file:\n * `<stateDir>/conversations/<conversationId>/settings.json`.\n *\n * Conversation settings used to live at `<conversationDir>/settings.json`,\n * but conversation dirs are bind-mounted read-write into sandbox containers\n * in image mode — code inside the sandbox could edit its own settings.json\n * and flip `sandbox.image.workspaceMount` to \"full\", remounting the entire\n * workspace into its container (cross-conversation access). Settings are an\n * administrator surface, so they live under the host-only state dir.\n *\n * Migration: on first access per conversation, a legacy\n * `<conversationDir>/settings.json` is moved here. The new file's existence\n * (an empty `{}` is written when there is nothing to migrate) is the\n * migration marker — a legacy file (re)appearing later, e.g. planted from\n * inside the sandbox, is never read again.\n */\nexport function conversationSettingsPath(conversationDir: string): string {\n const conversationId = basename(resolve(conversationDir));\n const hostPath = join(getStateDir(), \"conversations\", conversationId, \"settings.json\");\n if (existsSync(hostPath)) return hostPath;\n\n ensureDirExists(dirname(hostPath));\n const legacyPath = join(conversationDir, \"settings.json\");\n let content = \"{}\\n\";\n let migrated = false;\n if (existsSync(legacyPath)) {\n try {\n content = readFileSync(legacyPath, \"utf-8\");\n migrated = true;\n } catch (err) {\n log.logWarning(`Could not read legacy conversation settings: ${legacyPath}`, String(err));\n }\n }\n atomicWritePrivateFile(hostPath, content);\n if (migrated) {\n try {\n rmSync(legacyPath);\n } catch (err) {\n log.logWarning(`Could not remove legacy conversation settings: ${legacyPath}`, String(err));\n }\n log.logInfo(`Migrated conversation settings to host-only path: ${hostPath}`);\n }\n return hostPath;\n}\n\nexport function resolveConversationSettings(conversationDir: string): AgentConfig {\n const globalConfig = loadRawGlobalSettings();\n const conversationConfig = normalizeSettingsConfig(\n loadSettingsFile(conversationSettingsPath(conversationDir)) ?? {},\n );\n return toAgentConfig({ ...globalConfig, ...conversationConfig });\n}\n\n/**\n * Resolve the model used to judge auto-reply rules. Falls back to the main\n * llm.{provider,model} when llm.autoReply is not set, so a missing override\n * keeps current behavior.\n *\n * @deprecated Auto-reply is kept for compatibility while its future is undecided.\n */\nexport function loadAutoReplyJudgeModel(conversationDir?: string): JudgeModelConfig {\n const global = requireGlobalSettings();\n const local = conversationDir\n ? (loadSettingsFile(conversationSettingsPath(conversationDir)) ?? {})\n : {};\n const merged: SettingsFileConfig[\"llm\"] = { ...global.llm, ...local.llm };\n const judge = { ...global.llm?.autoReply, ...local.llm?.autoReply };\n const provider = requireString(judge.provider ?? merged?.provider, \"llm.autoReply.provider\");\n const model = requireString(judge.model ?? merged?.model, \"llm.autoReply.model\");\n return { provider, model };\n}\n\nconst AUTO_REPLY_FILE = \"auto-reply\";\nconst AUTO_REPLY_DISABLED_FILE = \"auto-reply.disabled\";\n\nfunction readAutoReplyRulesFile(path: string): string[] {\n const text = readFileSync(path, \"utf-8\").trim();\n return text ? [text] : [];\n}\n\n/**\n * Load the mom-compatible auto-reply marker file state for a conversation.\n *\n * - `auto-reply` exists: enabled; empty file means reply to any top-level message.\n * - `auto-reply.disabled` exists: disabled, preserving any rules text for re-enable.\n * - neither exists: disabled.\n *\n * @deprecated Auto-reply is kept for compatibility while its future is undecided.\n */\nexport function loadConversationAutoReplyConfig(conversationDir: string): AutoReplyConfig {\n const enabledPath = join(conversationDir, AUTO_REPLY_FILE);\n if (existsSync(enabledPath)) {\n return { enabled: true, rules: readAutoReplyRulesFile(enabledPath) };\n }\n\n const disabledPath = join(conversationDir, AUTO_REPLY_DISABLED_FILE);\n if (existsSync(disabledPath)) {\n return { enabled: false, rules: readAutoReplyRulesFile(disabledPath) };\n }\n\n return { enabled: false, rules: [] };\n}\n\n/**\n * Save auto-reply state using mom-compatible marker files.\n *\n * @deprecated Auto-reply is kept for compatibility while its future is undecided.\n */\nexport function saveConversationAutoReplyConfig(\n conversationDir: string,\n config: AutoReplyConfig,\n): void {\n ensureDirExists(conversationDir);\n\n const enabledPath = join(conversationDir, AUTO_REPLY_FILE);\n const disabledPath = join(conversationDir, AUTO_REPLY_DISABLED_FILE);\n const targetPath = config.enabled ? enabledPath : disabledPath;\n const otherPath = config.enabled ? disabledPath : enabledPath;\n\n if (existsSync(otherPath)) {\n renameSync(otherPath, targetPath);\n }\n\n atomicWritePrivateFile(targetPath, config.rules.join(\"\\n\"));\n}\n\nexport function resolveWorkspaceDirFromArgv(args = process.argv.slice(2)): string | undefined {\n for (let i = 0; i < args.length; i++) {\n const arg = args[i];\n\n if (arg === \"--sandbox\" || arg === \"--download\" || arg === \"--state-dir\") {\n i += 1;\n continue;\n }\n\n if (arg === \"--version\" || arg === \"-v\" || arg === \"-V\" || arg === \"--onboard\") {\n continue;\n }\n\n if (\n arg.startsWith(\"--sandbox=\") ||\n arg.startsWith(\"--download=\") ||\n arg.startsWith(\"--state-dir=\")\n ) {\n continue;\n }\n\n if (!arg.startsWith(\"-\")) {\n return arg;\n }\n }\n\n return undefined;\n}\n\nexport function resolveStateDirFromArgv(args = process.argv.slice(2)): string {\n for (let i = 0; i < args.length; i++) {\n const arg = args[i];\n if (arg.startsWith(\"--state-dir=\")) {\n return resolve(arg.slice(\"--state-dir=\".length));\n }\n if (arg === \"--state-dir\") {\n return resolve(args[++i] || \"\");\n }\n }\n\n return join(homedir(), \".mikan\");\n}\n\n/**\n * True when `child` is `parent` or a path inside it. Purely lexical (no\n * symlink resolution) — used for configuration sanity checks, not as the\n * final security boundary.\n */\nexport function isPathInside(child: string, parent: string): boolean {\n const parentPath = resolve(parent);\n const childPath = resolve(child);\n return childPath === parentPath || childPath.startsWith(parentPath + \"/\");\n}\n\n/**\n * The state dir (extensions code, extension data, vaults, auth.json) must\n * never live inside the working dir: conversation opt-in \"full\" mode mounts\n * the entire working dir read-write into sandbox containers, and a mounted\n * state dir would let sandboxed code plant extension modules that the host\n * process later imports — a sandbox escape. Fatal under sandboxed modes;\n * host mode has no mounts, so only warn about the bad hygiene.\n */\nexport function assertStateDirOutsideWorkspace(\n stateDir: string,\n workingDir: string,\n sandboxType: string,\n): void {\n if (!isPathInside(stateDir, workingDir)) return;\n const message =\n `--state-dir (${stateDir}) must not be inside the working directory (${workingDir}): ` +\n `sandbox containers mount the working directory, and a mounted state dir ` +\n `would expose extensions, vaults, and credentials to sandboxed code.`;\n if (sandboxType === \"host\") {\n log.logWarning(\"Insecure state dir location\", message);\n return;\n }\n throw new Error(message);\n}\n\nexport function resolveSentryDsn(): string | undefined {\n const fromFile = normalizeSettingsConfig(loadSettingsFile(getSettingsPath()) ?? {});\n if (fromFile.sentryDsn) {\n return fromFile.sentryDsn;\n }\n\n return process.env.SENTRY_DSN;\n}\n\nexport function createGlobalSettingsFile(stateDir: string): string {\n const settingsPath = join(stateDir, \"settings.json\");\n if (existsSync(settingsPath)) {\n throw new Error(`Global settings already exists at ${settingsPath}`);\n }\n ensureDirExists(stateDir);\n atomicWritePrivateFile(settingsPath, JSON.stringify(ONBOARD_SETTINGS, null, 2));\n return settingsPath;\n}\n\n/**\n * Externally-visible base URL of the link/OAuth server, e.g.\n * `https://mikan.example.com` (no trailing slash). Read from `LINK_URL` or\n * `MIKAN_LINK_URL`, the same env var the bot uses to build credential onboarding links.\n */\nexport function resolveLinkBaseUrl(): string | undefined {\n const raw = readEnv(\"LINK_URL\");\n if (!raw) return undefined;\n return raw.replace(/\\/+$/, \"\");\n}\n\nfunction hasDefinedValue(values: Record<string, unknown> | undefined): boolean {\n return values !== undefined && Object.values(values).some((value) => value !== undefined);\n}\n\nfunction compactSettingsConfig(config: SettingsFileConfig): SettingsFileConfig {\n return {\n ...(hasDefinedValue(config.llm) ? { llm: config.llm } : {}),\n ...(hasDefinedValue(config.sentry) ? { sentry: config.sentry } : {}),\n ...(hasDefinedValue(config.sandbox) ? { sandbox: config.sandbox } : {}),\n ...(hasDefinedValue(config.autoReply) ? { autoReply: config.autoReply } : {}),\n ...(hasDefinedValue(config.slack) ? { slack: config.slack } : {}),\n };\n}\n\nfunction patchSettingsConfig(\n existing: SettingsFileConfig,\n config: Partial<AgentConfig>,\n): SettingsFileConfig {\n const patched: SettingsFileConfig = {\n ...existing,\n llm: {\n ...existing.llm,\n ...(config.provider !== undefined ? { provider: config.provider } : {}),\n ...(config.model !== undefined ? { model: config.model } : {}),\n ...(config.thinkingLevel !== undefined ? { thinkingLevel: config.thinkingLevel } : {}),\n },\n sentry: {\n ...existing.sentry,\n ...(config.sentryDsn !== undefined ? { dsn: config.sentryDsn } : {}),\n },\n sandbox: {\n ...existing.sandbox,\n ...(config.sandboxCpus !== undefined ? { cpus: config.sandboxCpus } : {}),\n ...(config.sandboxMemory !== undefined ? { memory: config.sandboxMemory } : {}),\n ...(config.sandboxBoostCpus !== undefined || config.sandboxBoostMemory !== undefined\n ? {\n boost: {\n ...existing.sandbox?.boost,\n ...(config.sandboxBoostCpus !== undefined ? { cpus: config.sandboxBoostCpus } : {}),\n ...(config.sandboxBoostMemory !== undefined\n ? { memory: config.sandboxBoostMemory }\n : {}),\n },\n }\n : {}),\n ...(config.sandboxImageWorkspaceMount !== undefined\n ? {\n image: {\n ...existing.sandbox?.image,\n workspaceMount: config.sandboxImageWorkspaceMount,\n },\n }\n : {}),\n ...(config.defaultSharedVault !== undefined\n ? { defaultSharedVault: config.defaultSharedVault }\n : {}),\n },\n slack: {\n ...existing.slack,\n ...config.slack,\n },\n };\n return compactSettingsConfig(patched);\n}\n\nfunction updateSettingsFile(\n settingsPath: string,\n patch: Partial<AgentConfig>,\n defaultSettings: SettingsFileConfig,\n): void {\n let existing = defaultSettings;\n if (existsSync(settingsPath)) {\n try {\n existing = loadSettingsFile(settingsPath) ?? {};\n } catch (err) {\n const detail = err instanceof Error ? err.message : String(err);\n const message = detail.startsWith(\"Malformed settings file\")\n ? detail.replace(\"Malformed settings file\", \"Refusing to overwrite malformed settings file\")\n : detail;\n throw new Error(message, { cause: err });\n }\n }\n\n ensureDirExists(dirname(settingsPath));\n atomicWritePrivateFile(\n settingsPath,\n JSON.stringify(patchSettingsConfig(existing, patch), null, 2),\n );\n}\n\nexport function updateGlobalSettings(patch: Partial<AgentConfig>): void {\n updateSettingsFile(join(getStateDir(), \"settings.json\"), patch, ONBOARD_SETTINGS);\n}\n\nexport function updateConversationSettings(\n conversationDir: string,\n patch: Partial<AgentConfig>,\n): void {\n updateSettingsFile(conversationSettingsPath(conversationDir), patch, {});\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"execution-resolver.d.ts","sourceRoot":"","sources":["../src/execution-resolver.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"execution-resolver.d.ts","sourceRoot":"","sources":["../src/execution-resolver.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,sBAAsB,EAAuB,MAAM,kBAAkB,CAAC;AAC/E,OAAO,EAAkB,KAAK,QAAQ,EAAE,KAAK,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEvF,OAAO,EAAgD,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAInG,YAAY,EAAE,YAAY,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AACxE,OAAO,KAAK,EAAE,YAAY,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAExE,wBAAgB,kCAAkC,CAChD,YAAY,EAAE,MAAM,GAAG,SAAS,EAChC,cAAc,EAAE,MAAM,GACrB,uBAAuB,CAiBzB;AAiCD,qBAAa,sBAAsB;IAI/B,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,YAAY;IACpB,OAAO,CAAC,WAAW,CAAC;IACpB,OAAO,CAAC,YAAY,CAAC;IANvB,OAAO,CAAC,QAAQ,CAAC,uBAAuB,CAAqB;IAE7D,YACU,UAAU,EAAE,aAAa,EACzB,YAAY,EAAE,YAAY,EAC1B,WAAW,CAAC,EAAE,sBAAsB,YAAA,EACpC,YAAY,CAAC,EAAE,MAAM,YAAA,EAC3B;IAEE,OAAO,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,QAAQ,CAAC,CAatD;IAED,OAAO,CAAC,wBAAwB;IAehC,OAAO,CAAC,oBAAoB;IAgB5B,OAAO,CAAC,wBAAwB;IA4ChC,OAAO,CAAC,aAAa;IA0BrB,OAAO,CAAC,uBAAuB;CAsBhC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { existsSync } from "fs";
|
|
2
2
|
import { join } from "path";
|
|
3
|
-
import { loadGlobalSettings, resolveConversationSettings } from "./config.js";
|
|
3
|
+
import { conversationSettingsPath, loadGlobalSettings, resolveConversationSettings, } from "./config.js";
|
|
4
4
|
import { ensureDirExists, isRecord, readJsonFileIfExists } from "./utils/file-guards.js";
|
|
5
5
|
import { DockerContainerManager } from "./provisioner.js";
|
|
6
6
|
import { createExecutor } from "./sandbox/index.js";
|
|
@@ -19,8 +19,7 @@ export function readConversationWorkspaceMountMode(workspaceDir, conversationId)
|
|
|
19
19
|
}
|
|
20
20
|
catch (err) {
|
|
21
21
|
log.logWarning("Falling back while resolving conversation workspace mount", err instanceof Error ? err.message : String(err));
|
|
22
|
-
const
|
|
23
|
-
const raw = readConversationSettingsFallback(conversationSettingsPath);
|
|
22
|
+
const raw = readConversationSettingsFallback(conversationSettingsPath(conversationDir));
|
|
24
23
|
return raw?.sandbox?.image?.workspaceMount ?? globalDefault;
|
|
25
24
|
}
|
|
26
25
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"execution-resolver.js","sourceRoot":"","sources":["../src/execution-resolver.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync } from \"fs\";\nimport { join } from \"path\";\nimport { loadGlobalSettings, resolveConversationSettings } from \"./config.js\";\nimport { ensureDirExists, isRecord, readJsonFileIfExists } from \"./utils/file-guards.js\";\nimport { DockerContainerManager, type ContainerMount } from \"./provisioner.js\";\nimport { createExecutor, type Executor, type SandboxConfig } from \"./sandbox/index.js\";\nimport { reportUserFacingError } from \"./observability/sentry.js\";\nimport { normalizeSharedVaultName, type ResolvedVault, type VaultManager } from \"./vault/index.js\";\nimport { resolveActorVaultKey } from \"./vault/routing.js\";\nimport * as log from \"./log.js\";\n\nexport type { ActorContext, ImageWorkspaceMountMode } from \"./types.js\";\nimport type { ActorContext, ImageWorkspaceMountMode } from \"./types.js\";\n\nexport function readConversationWorkspaceMountMode(\n workspaceDir: string | undefined,\n conversationId: string,\n): ImageWorkspaceMountMode {\n const globalDefault = readGlobalWorkspaceMountMode();\n if (!workspaceDir) {\n return globalDefault;\n }\n\n const conversationDir = join(workspaceDir, conversationId);\n try {\n return resolveConversationSettings(conversationDir).sandboxImageWorkspaceMount ?? globalDefault;\n } catch (err) {\n log.logWarning(\n \"Falling back while resolving conversation workspace mount\",\n err instanceof Error ? err.message : String(err),\n );\n const conversationSettingsPath = join(conversationDir, \"settings.json\");\n const raw = readConversationSettingsFallback(conversationSettingsPath);\n return raw?.sandbox?.image?.workspaceMount ?? globalDefault;\n }\n}\n\nfunction readGlobalWorkspaceMountMode(): ImageWorkspaceMountMode {\n try {\n return loadGlobalSettings().sandboxImageWorkspaceMount ?? \"private\";\n } catch (err) {\n log.logWarning(\n \"Using default workspace mount because global settings could not be read\",\n err instanceof Error ? err.message : String(err),\n );\n return \"private\";\n }\n}\n\nfunction readConversationSettingsFallback(\n settingsPath: string,\n): { sandbox?: { image?: { workspaceMount?: ImageWorkspaceMountMode } } } | undefined {\n try {\n return readJsonFileIfExists(\n settingsPath,\n (value): value is { sandbox?: { image?: { workspaceMount?: ImageWorkspaceMountMode } } } =>\n isRecord(value),\n () => \"Ignoring malformed conversation settings file while resolving workspace mount\",\n );\n } catch (err) {\n log.logWarning(\n \"Ignoring malformed conversation settings fallback while resolving workspace mount\",\n err instanceof Error ? err.message : String(err),\n );\n return undefined;\n }\n}\n\nexport class ActorExecutionResolver {\n private readonly ensuredConversationDirs = new Set<string>();\n\n constructor(\n private baseConfig: SandboxConfig,\n private vaultManager: VaultManager,\n private provisioner?: DockerContainerManager,\n private workspaceDir?: string,\n ) {}\n\n async resolve(context: ActorContext): Promise<Executor> {\n const vaultKey = resolveActorVaultKey(this.baseConfig, context.userId, context.conversationId);\n this.ensureDefaultSharedVault(vaultKey);\n\n const vault = this.vaultManager.resolve(vaultKey);\n const config = this.resolveSandboxConfig(vaultKey);\n const env =\n config.type !== \"host\" && vault && Object.keys(vault.env).length > 0 ? vault.env : undefined;\n return createExecutor(\n config,\n env,\n this.buildEnsureReadyCallback(vaultKey, context.conversationId, config, vault),\n );\n }\n\n private ensureDefaultSharedVault(vaultKey: string): void {\n if (this.baseConfig.type !== \"image\" && this.baseConfig.type !== \"cloudflare\") return;\n if (this.vaultManager.hasEntry(vaultKey)) return;\n\n let profile: string | undefined;\n try {\n profile = loadGlobalSettings().defaultSharedVault;\n } catch {\n return;\n }\n if (!profile || normalizeSharedVaultName(profile) !== profile) return;\n\n this.vaultManager.copySharedVaultTo(profile, vaultKey);\n }\n\n private resolveSandboxConfig(vaultKey: string): SandboxConfig {\n const config = this.vaultManager.getSandboxConfig(vaultKey, this.baseConfig);\n if (this.baseConfig.type !== \"image\") {\n return config;\n }\n\n if (config.type === \"container\") {\n return config;\n }\n\n return {\n type: \"container\",\n container: DockerContainerManager.containerName(vaultKey),\n };\n }\n\n private buildEnsureReadyCallback(\n vaultKey: string,\n conversationId: string,\n config: SandboxConfig,\n vault?: ResolvedVault,\n ): (() => Promise<void>) | undefined {\n if (this.baseConfig.type !== \"image\" || config.type !== \"container\") {\n return undefined;\n }\n\n return async () => {\n const expected = config.container || DockerContainerManager.containerName(vaultKey);\n let actual: string | undefined;\n try {\n actual = await this.provisioner?.provision(vaultKey, {\n containerName: expected,\n mounts: this.resolveMounts(conversationId, vault),\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: \"image\",\n resolvedSandboxType: config.type,\n conversationId,\n vaultKey,\n expectedContainer: expected,\n hasVault: Boolean(vault),\n },\n });\n throw err;\n }\n if (actual && actual !== expected) {\n throw new Error(\n `Provisioner returned container \"${actual}\" for container key \"${vaultKey}\", expected \"${expected}\"`,\n );\n }\n };\n }\n\n private resolveMounts(conversationId: string, vault?: ResolvedVault): ContainerMount[] {\n const mountsByTarget = new Map<string, ContainerMount>();\n for (const mount of this.buildImageSandboxMounts(conversationId)) {\n mountsByTarget.set(mount.target, mount);\n }\n for (const mount of vault?.mounts ?? []) {\n if (!existsSync(mount.source)) {\n reportUserFacingError(new Error(\"Vault mount source is missing\"), {\n domain: \"sandbox\",\n surface: \"vault_injection\",\n operation: \"resolve_mounts\",\n severity: \"warning\",\n context: {\n sandboxType: \"image\",\n conversationId,\n target: mount.target,\n hasVault: Boolean(vault),\n },\n });\n continue;\n }\n mountsByTarget.set(mount.target, { source: mount.source, target: mount.target });\n }\n return [...mountsByTarget.values()];\n }\n\n private buildImageSandboxMounts(conversationId: string): ContainerMount[] {\n if (!this.workspaceDir) {\n return [];\n }\n\n if (readConversationWorkspaceMountMode(this.workspaceDir, conversationId) === \"full\") {\n return [{ source: this.workspaceDir, target: \"/workspace\" }];\n }\n\n const conversationDir = join(this.workspaceDir, conversationId);\n if (!this.ensuredConversationDirs.has(conversationId)) {\n ensureDirExists(conversationDir);\n this.ensuredConversationDirs.add(conversationId);\n }\n\n return [\n { source: join(this.workspaceDir, \"MEMORY.md\"), target: \"/workspace/MEMORY.md\" },\n { source: join(this.workspaceDir, \"skills\"), target: \"/workspace/skills\" },\n { source: join(this.workspaceDir, \"events\"), target: \"/workspace/events\" },\n { source: conversationDir, target: `/workspace/${conversationId}` },\n ];\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"execution-resolver.js","sourceRoot":"","sources":["../src/execution-resolver.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync } from \"fs\";\nimport { join } from \"path\";\nimport {\n conversationSettingsPath,\n loadGlobalSettings,\n resolveConversationSettings,\n} from \"./config.js\";\nimport { ensureDirExists, isRecord, readJsonFileIfExists } from \"./utils/file-guards.js\";\nimport { DockerContainerManager, type ContainerMount } from \"./provisioner.js\";\nimport { createExecutor, type Executor, type SandboxConfig } from \"./sandbox/index.js\";\nimport { reportUserFacingError } from \"./observability/sentry.js\";\nimport { normalizeSharedVaultName, type ResolvedVault, type VaultManager } from \"./vault/index.js\";\nimport { resolveActorVaultKey } from \"./vault/routing.js\";\nimport * as log from \"./log.js\";\n\nexport type { ActorContext, ImageWorkspaceMountMode } from \"./types.js\";\nimport type { ActorContext, ImageWorkspaceMountMode } from \"./types.js\";\n\nexport function readConversationWorkspaceMountMode(\n workspaceDir: string | undefined,\n conversationId: string,\n): ImageWorkspaceMountMode {\n const globalDefault = readGlobalWorkspaceMountMode();\n if (!workspaceDir) {\n return globalDefault;\n }\n\n const conversationDir = join(workspaceDir, conversationId);\n try {\n return resolveConversationSettings(conversationDir).sandboxImageWorkspaceMount ?? globalDefault;\n } catch (err) {\n log.logWarning(\n \"Falling back while resolving conversation workspace mount\",\n err instanceof Error ? err.message : String(err),\n );\n const raw = readConversationSettingsFallback(conversationSettingsPath(conversationDir));\n return raw?.sandbox?.image?.workspaceMount ?? globalDefault;\n }\n}\n\nfunction readGlobalWorkspaceMountMode(): ImageWorkspaceMountMode {\n try {\n return loadGlobalSettings().sandboxImageWorkspaceMount ?? \"private\";\n } catch (err) {\n log.logWarning(\n \"Using default workspace mount because global settings could not be read\",\n err instanceof Error ? err.message : String(err),\n );\n return \"private\";\n }\n}\n\nfunction readConversationSettingsFallback(\n settingsPath: string,\n): { sandbox?: { image?: { workspaceMount?: ImageWorkspaceMountMode } } } | undefined {\n try {\n return readJsonFileIfExists(\n settingsPath,\n (value): value is { sandbox?: { image?: { workspaceMount?: ImageWorkspaceMountMode } } } =>\n isRecord(value),\n () => \"Ignoring malformed conversation settings file while resolving workspace mount\",\n );\n } catch (err) {\n log.logWarning(\n \"Ignoring malformed conversation settings fallback while resolving workspace mount\",\n err instanceof Error ? err.message : String(err),\n );\n return undefined;\n }\n}\n\nexport class ActorExecutionResolver {\n private readonly ensuredConversationDirs = new Set<string>();\n\n constructor(\n private baseConfig: SandboxConfig,\n private vaultManager: VaultManager,\n private provisioner?: DockerContainerManager,\n private workspaceDir?: string,\n ) {}\n\n async resolve(context: ActorContext): Promise<Executor> {\n const vaultKey = resolveActorVaultKey(this.baseConfig, context.userId, context.conversationId);\n this.ensureDefaultSharedVault(vaultKey);\n\n const vault = this.vaultManager.resolve(vaultKey);\n const config = this.resolveSandboxConfig(vaultKey);\n const env =\n config.type !== \"host\" && vault && Object.keys(vault.env).length > 0 ? vault.env : undefined;\n return createExecutor(\n config,\n env,\n this.buildEnsureReadyCallback(vaultKey, context.conversationId, config, vault),\n );\n }\n\n private ensureDefaultSharedVault(vaultKey: string): void {\n if (this.baseConfig.type !== \"image\" && this.baseConfig.type !== \"cloudflare\") return;\n if (this.vaultManager.hasEntry(vaultKey)) return;\n\n let profile: string | undefined;\n try {\n profile = loadGlobalSettings().defaultSharedVault;\n } catch {\n return;\n }\n if (!profile || normalizeSharedVaultName(profile) !== profile) return;\n\n this.vaultManager.copySharedVaultTo(profile, vaultKey);\n }\n\n private resolveSandboxConfig(vaultKey: string): SandboxConfig {\n const config = this.vaultManager.getSandboxConfig(vaultKey, this.baseConfig);\n if (this.baseConfig.type !== \"image\") {\n return config;\n }\n\n if (config.type === \"container\") {\n return config;\n }\n\n return {\n type: \"container\",\n container: DockerContainerManager.containerName(vaultKey),\n };\n }\n\n private buildEnsureReadyCallback(\n vaultKey: string,\n conversationId: string,\n config: SandboxConfig,\n vault?: ResolvedVault,\n ): (() => Promise<void>) | undefined {\n if (this.baseConfig.type !== \"image\" || config.type !== \"container\") {\n return undefined;\n }\n\n return async () => {\n const expected = config.container || DockerContainerManager.containerName(vaultKey);\n let actual: string | undefined;\n try {\n actual = await this.provisioner?.provision(vaultKey, {\n containerName: expected,\n mounts: this.resolveMounts(conversationId, vault),\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: \"image\",\n resolvedSandboxType: config.type,\n conversationId,\n vaultKey,\n expectedContainer: expected,\n hasVault: Boolean(vault),\n },\n });\n throw err;\n }\n if (actual && actual !== expected) {\n throw new Error(\n `Provisioner returned container \"${actual}\" for container key \"${vaultKey}\", expected \"${expected}\"`,\n );\n }\n };\n }\n\n private resolveMounts(conversationId: string, vault?: ResolvedVault): ContainerMount[] {\n const mountsByTarget = new Map<string, ContainerMount>();\n for (const mount of this.buildImageSandboxMounts(conversationId)) {\n mountsByTarget.set(mount.target, mount);\n }\n for (const mount of vault?.mounts ?? []) {\n if (!existsSync(mount.source)) {\n reportUserFacingError(new Error(\"Vault mount source is missing\"), {\n domain: \"sandbox\",\n surface: \"vault_injection\",\n operation: \"resolve_mounts\",\n severity: \"warning\",\n context: {\n sandboxType: \"image\",\n conversationId,\n target: mount.target,\n hasVault: Boolean(vault),\n },\n });\n continue;\n }\n mountsByTarget.set(mount.target, { source: mount.source, target: mount.target });\n }\n return [...mountsByTarget.values()];\n }\n\n private buildImageSandboxMounts(conversationId: string): ContainerMount[] {\n if (!this.workspaceDir) {\n return [];\n }\n\n if (readConversationWorkspaceMountMode(this.workspaceDir, conversationId) === \"full\") {\n return [{ source: this.workspaceDir, target: \"/workspace\" }];\n }\n\n const conversationDir = join(this.workspaceDir, conversationId);\n if (!this.ensuredConversationDirs.has(conversationId)) {\n ensureDirExists(conversationDir);\n this.ensuredConversationDirs.add(conversationId);\n }\n\n return [\n { source: join(this.workspaceDir, \"MEMORY.md\"), target: \"/workspace/MEMORY.md\" },\n { source: join(this.workspaceDir, \"skills\"), target: \"/workspace/skills\" },\n { source: join(this.workspaceDir, \"events\"), target: \"/workspace/events\" },\n { source: conversationDir, target: `/workspace/${conversationId}` },\n ];\n }\n}\n"]}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Credential, CredentialStore } from "@earendil-works/pi-ai";
|
|
2
|
+
/** Default location of mikan's credential file. */
|
|
3
|
+
export declare function defaultAuthPath(): string;
|
|
4
|
+
export declare class FileCredentialStore implements CredentialStore {
|
|
5
|
+
private readonly authPath;
|
|
6
|
+
private chain;
|
|
7
|
+
constructor(authPath?: string);
|
|
8
|
+
private load;
|
|
9
|
+
private save;
|
|
10
|
+
/** Serialize read-modify-write cycles so concurrent refreshes cannot clobber each other. */
|
|
11
|
+
private enqueue;
|
|
12
|
+
read(providerId: string): Promise<Credential | undefined>;
|
|
13
|
+
modify(providerId: string, fn: (current: Credential | undefined) => Promise<Credential | undefined>): Promise<Credential | undefined>;
|
|
14
|
+
delete(providerId: string): Promise<void>;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/harness/auth.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAIzE,mDAAmD;AACnD,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAQD,qBAAa,mBAAoB,YAAW,eAAe;IACzD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,KAAK,CAAqB;IAElC,YAAY,QAAQ,GAAE,MAA0B,EAE/C;IAED,OAAO,CAAC,IAAI;IAmBZ,OAAO,CAAC,IAAI;IAKZ,4FAA4F;IAC5F,OAAO,CAAC,OAAO;IASf,IAAI,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAExD;IAED,MAAM,CACJ,UAAU,EAAE,MAAM,EAClB,EAAE,EAAE,CAAC,OAAO,EAAE,UAAU,GAAG,SAAS,KAAK,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,GACvE,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CASjC;IAED,MAAM,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAOxC;CACF"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File-backed credential store for the mikan harness.
|
|
3
|
+
*
|
|
4
|
+
* Implements pi-ai's `CredentialStore` over mikan's `auth.json`
|
|
5
|
+
* (`~/.mikan/auth.json` by default). The file maps provider ids to
|
|
6
|
+
* type-tagged credentials — the same shape pi-ai documents for auth.json.
|
|
7
|
+
*
|
|
8
|
+
* Writes are atomic (temp file + rename, mode 0600) and serialized per
|
|
9
|
+
* provider within the process. mikan runs as a single process, so no
|
|
10
|
+
* cross-process file lock is taken.
|
|
11
|
+
*/
|
|
12
|
+
import { existsSync, readFileSync } from "fs";
|
|
13
|
+
import { mkdirSync } from "fs";
|
|
14
|
+
import { homedir } from "os";
|
|
15
|
+
import { dirname, join } from "path";
|
|
16
|
+
import { atomicWritePrivateFile } from "../utils/fs-atomic.js";
|
|
17
|
+
import * as log from "../log.js";
|
|
18
|
+
/** Default location of mikan's credential file. */
|
|
19
|
+
export function defaultAuthPath() {
|
|
20
|
+
return join(homedir(), ".mikan", "auth.json");
|
|
21
|
+
}
|
|
22
|
+
function isCredential(value) {
|
|
23
|
+
if (!value || typeof value !== "object")
|
|
24
|
+
return false;
|
|
25
|
+
const type = value.type;
|
|
26
|
+
return type === "api_key" || type === "oauth";
|
|
27
|
+
}
|
|
28
|
+
export class FileCredentialStore {
|
|
29
|
+
constructor(authPath = defaultAuthPath()) {
|
|
30
|
+
this.chain = Promise.resolve();
|
|
31
|
+
this.authPath = authPath;
|
|
32
|
+
}
|
|
33
|
+
load() {
|
|
34
|
+
if (!existsSync(this.authPath))
|
|
35
|
+
return {};
|
|
36
|
+
try {
|
|
37
|
+
const parsed = JSON.parse(readFileSync(this.authPath, "utf-8"));
|
|
38
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
|
|
39
|
+
return {};
|
|
40
|
+
const data = {};
|
|
41
|
+
for (const [provider, credential] of Object.entries(parsed)) {
|
|
42
|
+
if (isCredential(credential))
|
|
43
|
+
data[provider] = credential;
|
|
44
|
+
}
|
|
45
|
+
return data;
|
|
46
|
+
}
|
|
47
|
+
catch (err) {
|
|
48
|
+
log.logWarning(`Failed to read credentials from ${this.authPath}`, err instanceof Error ? err.message : String(err));
|
|
49
|
+
return {};
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
save(data) {
|
|
53
|
+
mkdirSync(dirname(this.authPath), { recursive: true });
|
|
54
|
+
atomicWritePrivateFile(this.authPath, `${JSON.stringify(data, null, 2)}\n`);
|
|
55
|
+
}
|
|
56
|
+
/** Serialize read-modify-write cycles so concurrent refreshes cannot clobber each other. */
|
|
57
|
+
enqueue(task) {
|
|
58
|
+
const result = this.chain.then(task);
|
|
59
|
+
this.chain = result.then(() => undefined, () => undefined);
|
|
60
|
+
return result;
|
|
61
|
+
}
|
|
62
|
+
read(providerId) {
|
|
63
|
+
return this.enqueue(async () => this.load()[providerId]);
|
|
64
|
+
}
|
|
65
|
+
modify(providerId, fn) {
|
|
66
|
+
return this.enqueue(async () => {
|
|
67
|
+
const data = this.load();
|
|
68
|
+
const next = await fn(data[providerId]);
|
|
69
|
+
if (next === undefined)
|
|
70
|
+
return data[providerId];
|
|
71
|
+
data[providerId] = next;
|
|
72
|
+
this.save(data);
|
|
73
|
+
return next;
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
delete(providerId) {
|
|
77
|
+
return this.enqueue(async () => {
|
|
78
|
+
const data = this.load();
|
|
79
|
+
if (!(providerId in data))
|
|
80
|
+
return;
|
|
81
|
+
delete data[providerId];
|
|
82
|
+
this.save(data);
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/harness/auth.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * File-backed credential store for the mikan harness.\n *\n * Implements pi-ai's `CredentialStore` over mikan's `auth.json`\n * (`~/.mikan/auth.json` by default). The file maps provider ids to\n * type-tagged credentials — the same shape pi-ai documents for auth.json.\n *\n * Writes are atomic (temp file + rename, mode 0600) and serialized per\n * provider within the process. mikan runs as a single process, so no\n * cross-process file lock is taken.\n */\nimport { existsSync, readFileSync } from \"fs\";\nimport { mkdirSync } from \"fs\";\nimport { homedir } from \"os\";\nimport { dirname, join } from \"path\";\nimport type { Credential, CredentialStore } from \"@earendil-works/pi-ai\";\nimport { atomicWritePrivateFile } from \"../utils/fs-atomic.js\";\nimport * as log from \"../log.js\";\n\n/** Default location of mikan's credential file. */\nexport function defaultAuthPath(): string {\n return join(homedir(), \".mikan\", \"auth.json\");\n}\n\nfunction isCredential(value: unknown): value is Credential {\n if (!value || typeof value !== \"object\") return false;\n const type = (value as { type?: unknown }).type;\n return type === \"api_key\" || type === \"oauth\";\n}\n\nexport class FileCredentialStore implements CredentialStore {\n private readonly authPath: string;\n private chain = Promise.resolve();\n\n constructor(authPath: string = defaultAuthPath()) {\n this.authPath = authPath;\n }\n\n private load(): Record<string, Credential> {\n if (!existsSync(this.authPath)) return {};\n try {\n const parsed: unknown = JSON.parse(readFileSync(this.authPath, \"utf-8\"));\n if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) return {};\n const data: Record<string, Credential> = {};\n for (const [provider, credential] of Object.entries(parsed)) {\n if (isCredential(credential)) data[provider] = credential;\n }\n return data;\n } catch (err) {\n log.logWarning(\n `Failed to read credentials from ${this.authPath}`,\n err instanceof Error ? err.message : String(err),\n );\n return {};\n }\n }\n\n private save(data: Record<string, Credential>): void {\n mkdirSync(dirname(this.authPath), { recursive: true });\n atomicWritePrivateFile(this.authPath, `${JSON.stringify(data, null, 2)}\\n`);\n }\n\n /** Serialize read-modify-write cycles so concurrent refreshes cannot clobber each other. */\n private enqueue<T>(task: () => Promise<T>): Promise<T> {\n const result = this.chain.then(task);\n this.chain = result.then(\n () => undefined,\n () => undefined,\n );\n return result;\n }\n\n read(providerId: string): Promise<Credential | undefined> {\n return this.enqueue(async () => this.load()[providerId]);\n }\n\n modify(\n providerId: string,\n fn: (current: Credential | undefined) => Promise<Credential | undefined>,\n ): Promise<Credential | undefined> {\n return this.enqueue(async () => {\n const data = this.load();\n const next = await fn(data[providerId]);\n if (next === undefined) return data[providerId];\n data[providerId] = next;\n this.save(data);\n return next;\n });\n }\n\n delete(providerId: string): Promise<void> {\n return this.enqueue(async () => {\n const data = this.load();\n if (!(providerId in data)) return;\n delete data[providerId];\n this.save(data);\n });\n }\n}\n"]}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { ThinkingLevel } from "@earendil-works/pi-agent-core";
|
|
2
|
+
import type { Api, Model } from "@earendil-works/pi-ai";
|
|
3
|
+
import { type MikanSkill } from "../skills.js";
|
|
4
|
+
import { ExtensionRegistry } from "./registry.js";
|
|
5
|
+
import type { ExtensionHostServices, ExtensionLoadError, LoadedExtension } from "./types.js";
|
|
6
|
+
/**
|
|
7
|
+
* Canonical host-only extension directories for a conversation:
|
|
8
|
+
* `<stateDir>/extensions/global` (all conversations) and
|
|
9
|
+
* `<stateDir>/extensions/<conversationId>` (that conversation only).
|
|
10
|
+
* `global` is reserved as a scope name; platform conversation ids never
|
|
11
|
+
* take that value.
|
|
12
|
+
*/
|
|
13
|
+
export declare function defaultExtensionDirs(conversationId: string, stateDir?: string): string[];
|
|
14
|
+
export interface LoadExtensionsOptions {
|
|
15
|
+
/** Directories to scan for extensions. Missing directories are skipped. */
|
|
16
|
+
dirs: string[];
|
|
17
|
+
context: {
|
|
18
|
+
conversationId: string;
|
|
19
|
+
workspaceDir: string;
|
|
20
|
+
model: Model<Api>;
|
|
21
|
+
thinkingLevel: ThinkingLevel;
|
|
22
|
+
};
|
|
23
|
+
/** Embedder-provided services backing the v2 api surface. */
|
|
24
|
+
services?: ExtensionHostServices;
|
|
25
|
+
}
|
|
26
|
+
export interface LoadExtensionsResult {
|
|
27
|
+
registry: ExtensionRegistry;
|
|
28
|
+
extensions: LoadedExtension[];
|
|
29
|
+
errors: ExtensionLoadError[];
|
|
30
|
+
/** Skills contributed by extensions (inline: bodies ride in the prompt). */
|
|
31
|
+
skills: MikanSkill[];
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Filesystem-safe identifier for an extension, derived from its install
|
|
35
|
+
* location (directory name for `<name>/index.mjs`, file basename otherwise).
|
|
36
|
+
* The slug keys the extension's data dir, secrets vault, and schedule
|
|
37
|
+
* ownership — installing the same extension globally and per-conversation
|
|
38
|
+
* shares one slug and therefore one data dir.
|
|
39
|
+
*/
|
|
40
|
+
export declare function extensionSlug(entrypoint: string): string;
|
|
41
|
+
/** Load and activate all extensions found in the given directories. */
|
|
42
|
+
export declare function loadExtensions(options: LoadExtensionsOptions): Promise<LoadExtensionsResult>;
|
|
43
|
+
//# sourceMappingURL=loader.d.ts.map
|