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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/dist/adapters/intake.d.ts.map +1 -1
  3. package/dist/adapters/intake.js +5 -0
  4. package/dist/adapters/intake.js.map +1 -1
  5. package/dist/adapters/slack/bot.d.ts.map +1 -1
  6. package/dist/adapters/slack/bot.js +13 -2
  7. package/dist/adapters/slack/bot.js.map +1 -1
  8. package/dist/adapters/slack/types.d.ts +2 -0
  9. package/dist/adapters/slack/types.d.ts.map +1 -1
  10. package/dist/adapters/slack/types.js.map +1 -1
  11. package/dist/agent.d.ts.map +1 -1
  12. package/dist/agent.js +26 -15
  13. package/dist/agent.js.map +1 -1
  14. package/dist/commands/login.js +2 -2
  15. package/dist/commands/login.js.map +1 -1
  16. package/dist/commands/sandbox.js +2 -2
  17. package/dist/commands/sandbox.js.map +1 -1
  18. package/dist/execution-resolver.d.ts +5 -6
  19. package/dist/execution-resolver.d.ts.map +1 -1
  20. package/dist/execution-resolver.js +72 -103
  21. package/dist/execution-resolver.js.map +1 -1
  22. package/dist/harness/index.d.ts +1 -1
  23. package/dist/harness/index.d.ts.map +1 -1
  24. package/dist/harness/index.js.map +1 -1
  25. package/dist/harness/runner.d.ts +4 -0
  26. package/dist/harness/runner.d.ts.map +1 -1
  27. package/dist/harness/runner.js +16 -2
  28. package/dist/harness/runner.js.map +1 -1
  29. package/dist/harness/subagent-runner.d.ts +14 -13
  30. package/dist/harness/subagent-runner.d.ts.map +1 -1
  31. package/dist/harness/subagent-runner.js +105 -19
  32. package/dist/harness/subagent-runner.js.map +1 -1
  33. package/dist/harness/types.d.ts +11 -0
  34. package/dist/harness/types.d.ts.map +1 -1
  35. package/dist/harness/types.js.map +1 -1
  36. package/dist/runtime/conversation-runtime.d.ts.map +1 -1
  37. package/dist/runtime/conversation-runtime.js +23 -79
  38. package/dist/runtime/conversation-runtime.js.map +1 -1
  39. package/dist/runtime/session-lifecycle.d.ts +19 -0
  40. package/dist/runtime/session-lifecycle.d.ts.map +1 -0
  41. package/dist/runtime/session-lifecycle.js +76 -0
  42. package/dist/runtime/session-lifecycle.js.map +1 -0
  43. package/dist/runtime/types.d.ts +5 -0
  44. package/dist/runtime/types.d.ts.map +1 -1
  45. package/dist/runtime/types.js.map +1 -1
  46. package/dist/sandbox/cloudflare.d.ts.map +1 -1
  47. package/dist/sandbox/cloudflare.js +1 -0
  48. package/dist/sandbox/cloudflare.js.map +1 -1
  49. package/dist/sandbox/container.d.ts.map +1 -1
  50. package/dist/sandbox/container.js +1 -0
  51. package/dist/sandbox/container.js.map +1 -1
  52. package/dist/sandbox/firecracker.d.ts.map +1 -1
  53. package/dist/sandbox/firecracker.js +1 -0
  54. package/dist/sandbox/firecracker.js.map +1 -1
  55. package/dist/sandbox/gondolin.d.ts.map +1 -1
  56. package/dist/sandbox/gondolin.js +1 -0
  57. package/dist/sandbox/gondolin.js.map +1 -1
  58. package/dist/sandbox/host.d.ts.map +1 -1
  59. package/dist/sandbox/host.js +1 -0
  60. package/dist/sandbox/host.js.map +1 -1
  61. package/dist/sandbox/identity.d.ts +11 -16
  62. package/dist/sandbox/identity.d.ts.map +1 -1
  63. package/dist/sandbox/identity.js +32 -26
  64. package/dist/sandbox/identity.js.map +1 -1
  65. package/dist/sandbox/image.d.ts.map +1 -1
  66. package/dist/sandbox/image.js +1 -0
  67. package/dist/sandbox/image.js.map +1 -1
  68. package/dist/sandbox/index.d.ts +1 -0
  69. package/dist/sandbox/index.d.ts.map +1 -1
  70. package/dist/sandbox/index.js +6 -0
  71. package/dist/sandbox/index.js.map +1 -1
  72. package/dist/sandbox/types.d.ts +5 -0
  73. package/dist/sandbox/types.d.ts.map +1 -1
  74. package/dist/sandbox/types.js.map +1 -1
  75. package/dist/sessions/session-key.d.ts +9 -0
  76. package/dist/sessions/session-key.d.ts.map +1 -1
  77. package/dist/sessions/session-key.js +50 -2
  78. package/dist/sessions/session-key.js.map +1 -1
  79. package/dist/sessions/store.d.ts.map +1 -1
  80. package/dist/sessions/store.js +36 -8
  81. package/dist/sessions/store.js.map +1 -1
  82. package/dist/tools/sandbox.js +2 -2
  83. package/dist/tools/sandbox.js.map +1 -1
  84. package/dist/tools/subagent-slots.d.ts +3 -3
  85. package/dist/tools/subagent-slots.d.ts.map +1 -1
  86. package/dist/tools/subagent-slots.js +25 -10
  87. package/dist/tools/subagent-slots.js.map +1 -1
  88. package/dist/tools/subagent.d.ts +13 -2
  89. package/dist/tools/subagent.d.ts.map +1 -1
  90. package/dist/tools/subagent.js +16 -16
  91. package/dist/tools/subagent.js.map +1 -1
  92. package/dist/types.d.ts +7 -0
  93. package/dist/types.d.ts.map +1 -1
  94. package/dist/types.js.map +1 -1
  95. package/dist/vault/injection.d.ts +4 -14
  96. package/dist/vault/injection.d.ts.map +1 -1
  97. package/dist/vault/injection.js +5 -2
  98. package/dist/vault/injection.js.map +1 -1
  99. package/dist/vault/types.d.ts +4 -0
  100. package/dist/vault/types.d.ts.map +1 -1
  101. package/dist/vault/types.js.map +1 -1
  102. package/dist/web/admin/portal.js +2 -2
  103. package/dist/web/admin/portal.js.map +1 -1
  104. package/dist/workspace-projection/index.d.ts +5 -0
  105. package/dist/workspace-projection/index.d.ts.map +1 -0
  106. package/dist/workspace-projection/index.js +71 -0
  107. package/dist/workspace-projection/index.js.map +1 -0
  108. package/dist/workspace-projection/types.d.ts +7 -0
  109. package/dist/workspace-projection/types.d.ts.map +1 -0
  110. package/dist/workspace-projection/types.js +2 -0
  111. package/dist/workspace-projection/types.js.map +1 -0
  112. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"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","sourcesContent":["import * as log from \"../log.js\";\nimport { actorKey } from \"../sandbox/identity.js\";\nimport { sharedVaultKey } from \"../vault/index.js\";\nimport { slashForms } from \"./manifest.js\";\nimport { matchCommand } from \"./parse.js\";\nimport type { CommandContext, CommandHandler, ParsedLoginCommand } from \"./types.js\";\nimport { formatCommandSummary, replyDiagnosticWithContext } from \"./utils.js\";\n\nconst LOGIN_COMMANDS = slashForms(\"login\");\n\nexport function parseLoginCommand(text: string): ParsedLoginCommand | null {\n const matched = matchCommand(text, LOGIN_COMMANDS);\n if (!matched) return null;\n\n const [subcommand, operation, name, ...extra] = matched.args;\n if (!subcommand) return { action: \"setup\" };\n\n if (subcommand.toLowerCase() === \"shared\") {\n const op = operation?.toLowerCase();\n if (op === \"list\" && !name && extra.length === 0) return { action: \"shared_list\" };\n if ((op === \"create\" || op === \"update\" || op === \"delete\") && name && extra.length === 0) {\n return {\n action: `shared_${op}` as \"shared_create\" | \"shared_update\" | \"shared_delete\",\n name,\n };\n }\n return null;\n }\n\n if (subcommand.toLowerCase() === \"copy\" && operation && !name && extra.length === 0) {\n return { action: \"copy_shared\", name: operation };\n }\n\n // Backward-compatible provider arguments open the generic login page.\n if (!operation && extra.length === 0) return { action: \"setup\" };\n return null;\n}\n\nfunction ensureLoginVault(context: CommandContext): string {\n const { services, platformUserId, conversationId, vaultConversationId } = context;\n return actorKey(services.sandbox, {\n userId: platformUserId,\n conversationId: vaultConversationId ?? conversationId,\n });\n}\n\nasync function replyVault(context: CommandContext, lines: string[]): Promise<void> {\n await replyDiagnosticWithContext(context.responder, formatCommandSummary(\"Vault\", lines), {\n style: \"muted\",\n });\n}\n\nasync function refreshCopiedVaultRuntime(\n context: CommandContext,\n vaultId: string,\n): Promise<string | undefined> {\n if (context.services.sandbox.type !== \"image\") return undefined;\n\n const targetConversationId = context.vaultConversationId ?? context.conversationId;\n const cleared = context.services.runtime?.refreshConversationEnvironment(targetConversationId);\n if (cleared === false) {\n return \"A session is currently running, so the sandbox was not restarted. The copied credentials will be applied after the run finishes and the sandbox is recreated.\";\n }\n\n if (!context.services.provisioner) {\n return \"The cached session was refreshed. The sandbox will pick up copied credentials on the next provision.\";\n }\n\n await context.services.provisioner.remove(vaultId);\n return \"The sandbox container was removed and will be recreated with the copied env and file mounts on the next message.\";\n}\n\nexport class LoginCommandHandler implements CommandHandler {\n async tryHandle(context: CommandContext): Promise<boolean> {\n const parsed = parseLoginCommand(context.commandText);\n if (!parsed) return false;\n\n if (!context.privateConversation) {\n await replyVault(context, [\n \"為了保護你的憑證,`/login` 只能在與機器人的私訊中使用。\",\n \"請先私訊機器人,再重新執行 `/login`。\",\n ]);\n return true;\n }\n\n if (parsed.action === \"shared_list\") {\n const profiles = context.services.vaultManager.listSharedVaults();\n await replyVault(\n context,\n profiles.length > 0\n ? [\"Shared login profiles:\", ...profiles.map((name) => `- ${name}`)]\n : [\"No shared login profiles found.\"],\n );\n return true;\n }\n\n if (parsed.action === \"shared_delete\") {\n try {\n const deleted = context.services.vaultManager.deleteSharedVault(parsed.name);\n await replyVault(context, [\n deleted\n ? `Deleted shared login profile \\`${parsed.name}\\`.`\n : `Shared login profile \\`${parsed.name}\\` does not exist.`,\n ]);\n } catch (error) {\n await replyVault(context, [error instanceof Error ? error.message : String(error)]);\n }\n return true;\n }\n\n if (parsed.action === \"copy_shared\") {\n try {\n const vaultId = ensureLoginVault(context);\n const result = context.services.vaultManager.copySharedVaultTo(parsed.name, vaultId);\n const refreshNote = await refreshCopiedVaultRuntime(context, vaultId);\n await replyVault(context, [\n `Copied shared login profile \\`${parsed.name}\\` into this conversation.`,\n \"Shared values overwrite matching conversation values; conversation-only values are kept.\",\n `Copied: ${result.envKeysCopied} env key(s), ${result.filesCopied} file(s).`,\n ...(refreshNote ? [refreshNote] : []),\n ]);\n } catch (error) {\n await replyVault(context, [error instanceof Error ? error.message : String(error)]);\n }\n return true;\n }\n\n if (!context.services.portalBaseUrl) {\n await replyVault(context, [\n \"Login is not configured.\",\n \"Set `MIKAN_LINK_URL` or `MIKAN_LINK_PORT` on the server.\",\n ]);\n return true;\n }\n\n const isSharedSetup = parsed.action === \"shared_create\" || parsed.action === \"shared_update\";\n let vaultId: string;\n try {\n vaultId = isSharedSetup ? (sharedVaultKey(parsed.name) ?? \"\") : ensureLoginVault(context);\n if (!vaultId) {\n throw new Error(\n isSharedSetup ? `Invalid shared login profile name: ${parsed.name}` : \"Invalid vault id\",\n );\n }\n } catch (error) {\n log.logWarning(\n `[${context.conversationId}] Failed to prepare login vault for ${context.platform}/${context.platformUserId}`,\n error instanceof Error ? error.message : String(error),\n );\n await replyVault(context, [\n \"Login setup failed on the server.\",\n \"請稍後重試,或聯絡管理員檢查 vault 儲存權限。\",\n ]);\n return true;\n }\n\n const token = context.services.linkTokenStore.create(\n context.platform,\n context.platformUserId,\n context.conversationId,\n vaultId,\n \"\",\n );\n const vaultLabel = isSharedSetup\n ? `shared login profile (${parsed.name})`\n : context.services.sandbox.type === \"container\"\n ? `container vault (${vaultId})`\n : \"your vault\";\n await replyVault(context, [\n `${context.services.portalBaseUrl}/link?token=${token.token}`,\n `Target: ${vaultLabel} · Expires: 15 minutes`,\n ]);\n return true;\n }\n}\n"]}
1
+ {"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"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","sourcesContent":["import * as log from \"../log.js\";\nimport { credentialAuthorizationKey } from \"../sandbox/identity.js\";\nimport { sharedVaultKey } from \"../vault/index.js\";\nimport { slashForms } from \"./manifest.js\";\nimport { matchCommand } from \"./parse.js\";\nimport type { CommandContext, CommandHandler, ParsedLoginCommand } from \"./types.js\";\nimport { formatCommandSummary, replyDiagnosticWithContext } from \"./utils.js\";\n\nconst LOGIN_COMMANDS = slashForms(\"login\");\n\nexport function parseLoginCommand(text: string): ParsedLoginCommand | null {\n const matched = matchCommand(text, LOGIN_COMMANDS);\n if (!matched) return null;\n\n const [subcommand, operation, name, ...extra] = matched.args;\n if (!subcommand) return { action: \"setup\" };\n\n if (subcommand.toLowerCase() === \"shared\") {\n const op = operation?.toLowerCase();\n if (op === \"list\" && !name && extra.length === 0) return { action: \"shared_list\" };\n if ((op === \"create\" || op === \"update\" || op === \"delete\") && name && extra.length === 0) {\n return {\n action: `shared_${op}` as \"shared_create\" | \"shared_update\" | \"shared_delete\",\n name,\n };\n }\n return null;\n }\n\n if (subcommand.toLowerCase() === \"copy\" && operation && !name && extra.length === 0) {\n return { action: \"copy_shared\", name: operation };\n }\n\n // Backward-compatible provider arguments open the generic login page.\n if (!operation && extra.length === 0) return { action: \"setup\" };\n return null;\n}\n\nfunction ensureLoginVault(context: CommandContext): string {\n const { services, platformUserId, conversationId, vaultConversationId } = context;\n return credentialAuthorizationKey(services.sandbox, {\n userId: platformUserId,\n conversationId: vaultConversationId ?? conversationId,\n });\n}\n\nasync function replyVault(context: CommandContext, lines: string[]): Promise<void> {\n await replyDiagnosticWithContext(context.responder, formatCommandSummary(\"Vault\", lines), {\n style: \"muted\",\n });\n}\n\nasync function refreshCopiedVaultRuntime(\n context: CommandContext,\n vaultId: string,\n): Promise<string | undefined> {\n if (context.services.sandbox.type !== \"image\") return undefined;\n\n const targetConversationId = context.vaultConversationId ?? context.conversationId;\n const cleared = context.services.runtime?.refreshConversationEnvironment(targetConversationId);\n if (cleared === false) {\n return \"A session is currently running, so the sandbox was not restarted. The copied credentials will be applied after the run finishes and the sandbox is recreated.\";\n }\n\n if (!context.services.provisioner) {\n return \"The cached session was refreshed. The sandbox will pick up copied credentials on the next provision.\";\n }\n\n await context.services.provisioner.remove(vaultId);\n return \"The sandbox container was removed and will be recreated with the copied env and file mounts on the next message.\";\n}\n\nexport class LoginCommandHandler implements CommandHandler {\n async tryHandle(context: CommandContext): Promise<boolean> {\n const parsed = parseLoginCommand(context.commandText);\n if (!parsed) return false;\n\n if (!context.privateConversation) {\n await replyVault(context, [\n \"為了保護你的憑證,`/login` 只能在與機器人的私訊中使用。\",\n \"請先私訊機器人,再重新執行 `/login`。\",\n ]);\n return true;\n }\n\n if (parsed.action === \"shared_list\") {\n const profiles = context.services.vaultManager.listSharedVaults();\n await replyVault(\n context,\n profiles.length > 0\n ? [\"Shared login profiles:\", ...profiles.map((name) => `- ${name}`)]\n : [\"No shared login profiles found.\"],\n );\n return true;\n }\n\n if (parsed.action === \"shared_delete\") {\n try {\n const deleted = context.services.vaultManager.deleteSharedVault(parsed.name);\n await replyVault(context, [\n deleted\n ? `Deleted shared login profile \\`${parsed.name}\\`.`\n : `Shared login profile \\`${parsed.name}\\` does not exist.`,\n ]);\n } catch (error) {\n await replyVault(context, [error instanceof Error ? error.message : String(error)]);\n }\n return true;\n }\n\n if (parsed.action === \"copy_shared\") {\n try {\n const vaultId = ensureLoginVault(context);\n const result = context.services.vaultManager.copySharedVaultTo(parsed.name, vaultId);\n const refreshNote = await refreshCopiedVaultRuntime(context, vaultId);\n await replyVault(context, [\n `Copied shared login profile \\`${parsed.name}\\` into this conversation.`,\n \"Shared values overwrite matching conversation values; conversation-only values are kept.\",\n `Copied: ${result.envKeysCopied} env key(s), ${result.filesCopied} file(s).`,\n ...(refreshNote ? [refreshNote] : []),\n ]);\n } catch (error) {\n await replyVault(context, [error instanceof Error ? error.message : String(error)]);\n }\n return true;\n }\n\n if (!context.services.portalBaseUrl) {\n await replyVault(context, [\n \"Login is not configured.\",\n \"Set `MIKAN_LINK_URL` or `MIKAN_LINK_PORT` on the server.\",\n ]);\n return true;\n }\n\n const isSharedSetup = parsed.action === \"shared_create\" || parsed.action === \"shared_update\";\n let vaultId: string;\n try {\n vaultId = isSharedSetup ? (sharedVaultKey(parsed.name) ?? \"\") : ensureLoginVault(context);\n if (!vaultId) {\n throw new Error(\n isSharedSetup ? `Invalid shared login profile name: ${parsed.name}` : \"Invalid vault id\",\n );\n }\n } catch (error) {\n log.logWarning(\n `[${context.conversationId}] Failed to prepare login vault for ${context.platform}/${context.platformUserId}`,\n error instanceof Error ? error.message : String(error),\n );\n await replyVault(context, [\n \"Login setup failed on the server.\",\n \"請稍後重試,或聯絡管理員檢查 vault 儲存權限。\",\n ]);\n return true;\n }\n\n const token = context.services.linkTokenStore.create(\n context.platform,\n context.platformUserId,\n context.conversationId,\n vaultId,\n \"\",\n );\n const vaultLabel = isSharedSetup\n ? `shared login profile (${parsed.name})`\n : context.services.sandbox.type === \"container\"\n ? `container vault (${vaultId})`\n : \"your vault\";\n await replyVault(context, [\n `${context.services.portalBaseUrl}/link?token=${token.token}`,\n `Target: ${vaultLabel} · Expires: 15 minutes`,\n ]);\n return true;\n }\n}\n"]}
@@ -1,6 +1,6 @@
1
1
  import { readConversationWorkspaceMountMode } from "../execution-resolver.js";
2
2
  import { applyConversationSettings } from "../settings-mutation.js";
3
- import { actorKey } from "../sandbox/identity.js";
3
+ import { runtimeResourceKey } from "../sandbox/identity.js";
4
4
  import { slashForms } from "./manifest.js";
5
5
  import { matchCommand } from "./parse.js";
6
6
  import { formatCommandSummary, replyDiagnosticWithContext } from "./utils.js";
@@ -27,7 +27,7 @@ export class SandboxCommandHandler {
27
27
  ]), { style: "muted" });
28
28
  return true;
29
29
  }
30
- const containerKey = actorKey(context.services.sandbox, {
30
+ const containerKey = runtimeResourceKey(context.services.sandbox, {
31
31
  userId: context.platformUserId,
32
32
  conversationId: context.conversationId,
33
33
  });
@@ -1 +1 @@
1
- {"version":3,"file":"sandbox.js","sourceRoot":"","sources":["../../src/commands/sandbox.ts"],"names":[],"mappings":"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","sourcesContent":["import { readConversationWorkspaceMountMode } from \"../execution-resolver.js\";\nimport { applyConversationSettings } from \"../settings-mutation.js\";\nimport { actorKey } from \"../sandbox/identity.js\";\nimport { slashForms } from \"./manifest.js\";\nimport { matchCommand } from \"./parse.js\";\nimport type { CommandContext, CommandHandler, ParsedSandboxCommand } from \"./types.js\";\nimport { formatCommandSummary, replyDiagnosticWithContext } from \"./utils.js\";\n\nexport type { ParsedSandboxCommand } from \"./types.js\";\n\nconst SANDBOX_COMMANDS = slashForms(\"sandbox\");\n\nexport function parseSandboxCommand(text: string): ParsedSandboxCommand | null {\n const matched = matchCommand(text, SANDBOX_COMMANDS, { stripMention: true });\n if (!matched) return null;\n\n const action = matched.args.length === 1 ? matched.args[0].toLowerCase() : undefined;\n if (action === \"boost\" || action === \"private\" || action === \"full\") {\n return { action };\n }\n return {};\n}\n\nexport class SandboxCommandHandler implements CommandHandler {\n async tryHandle(context: CommandContext): Promise<boolean> {\n const parsed = parseSandboxCommand(context.commandText);\n if (!parsed) return false;\n\n if (\n (context.services.sandbox.type !== \"image\" && context.services.sandbox.type !== \"gondolin\") ||\n !context.services.resourceController\n ) {\n await replyDiagnosticWithContext(\n context.responder,\n formatCommandSummary(\"Sandbox\", [\n \"`/pi-sandbox` 目前只支援 `image:*` 與 `gondolin:*` managed sandbox。\",\n ]),\n { style: \"muted\" },\n );\n return true;\n }\n\n const containerKey = actorKey(context.services.sandbox, {\n userId: context.platformUserId,\n conversationId: context.conversationId,\n });\n\n if (parsed.action === \"private\" || parsed.action === \"full\") {\n applyConversationSettings(\n context.services.runtime,\n context.services.workingDir,\n context.conversationId,\n {\n sandbox: { image: { workspaceMount: parsed.action } },\n },\n );\n await replyDiagnosticWithContext(\n context.responder,\n formatCommandSummary(\"Sandbox Workspace\", [\n parsed.action === \"full\"\n ? \"已將此 conversation 的 sandbox 設為 full workspace mode。\"\n : \"已將此 conversation 的 sandbox 設為 private workspace mode。\",\n `Workspace mount: ${parsed.action}`,\n parsed.action === \"full\"\n ? \"之後這個 runtime 會把整個 host workspace 掛到 /workspace。\"\n : \"之後這個 runtime 只會掛載 private workspace 檔案與當前 conversation 目錄。\",\n ]),\n { style: \"muted\" },\n );\n return true;\n }\n\n if (parsed.action === \"boost\") {\n const boostLimits = context.services.resourceController.getBoostLimits();\n if (!boostLimits?.cpus && !boostLimits?.memory) {\n await replyDiagnosticWithContext(\n context.responder,\n formatCommandSummary(\"Sandbox Boost\", [\n \"此 mikan instance 尚未設定 sandbox boost 規格。\",\n \"請先在全域 settings.json 設定 `sandbox.boost`。\",\n ]),\n { style: \"muted\" },\n );\n return true;\n }\n\n const status = await context.services.resourceController.boost(containerKey);\n await replyDiagnosticWithContext(\n context.responder,\n formatCommandSummary(\"Sandbox Boost\", [\n \"已暫時提升此 conversation 的 sandbox 規格。\",\n `Current: ${formatLimits(status.limits)}`,\n \"boost 會在此 sandbox runtime 關閉後結束。\",\n ]),\n { style: \"muted\" },\n );\n return true;\n }\n\n const status = context.services.resourceController.getLimitStatus(containerKey);\n const defaultLimits = context.services.resourceController.getDefaultLimits();\n const boostLimits = context.services.resourceController.getBoostLimits();\n const workspaceMount = readConversationWorkspaceMountMode(\n context.services.workingDir,\n context.conversationId,\n );\n await replyDiagnosticWithContext(\n context.responder,\n formatCommandSummary(\n \"Sandbox\",\n [\n `Current: ${formatLimits(status.limits)}`,\n `Status: ${status.boosted ? \"boosted\" : \"default\"}`,\n `Workspace mount: ${workspaceMount}`,\n \"\",\n `Default: ${formatLimits(defaultLimits)}`,\n boostLimits ? `Boost: ${formatLimits({ ...defaultLimits, ...boostLimits })}` : undefined,\n ].filter((line): line is string => line !== undefined),\n ),\n { style: \"muted\" },\n );\n return true;\n }\n}\n\nfunction formatLimits(limits: { cpus?: string; memory?: string } | undefined): string {\n return `CPU ${limits?.cpus ?? \"unlimited\"} / Memory ${limits?.memory ?? \"unlimited\"}`;\n}\n"]}
1
+ {"version":3,"file":"sandbox.js","sourceRoot":"","sources":["../../src/commands/sandbox.ts"],"names":[],"mappings":"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","sourcesContent":["import { readConversationWorkspaceMountMode } from \"../execution-resolver.js\";\nimport { applyConversationSettings } from \"../settings-mutation.js\";\nimport { runtimeResourceKey } from \"../sandbox/identity.js\";\nimport { slashForms } from \"./manifest.js\";\nimport { matchCommand } from \"./parse.js\";\nimport type { CommandContext, CommandHandler, ParsedSandboxCommand } from \"./types.js\";\nimport { formatCommandSummary, replyDiagnosticWithContext } from \"./utils.js\";\n\nexport type { ParsedSandboxCommand } from \"./types.js\";\n\nconst SANDBOX_COMMANDS = slashForms(\"sandbox\");\n\nexport function parseSandboxCommand(text: string): ParsedSandboxCommand | null {\n const matched = matchCommand(text, SANDBOX_COMMANDS, { stripMention: true });\n if (!matched) return null;\n\n const action = matched.args.length === 1 ? matched.args[0].toLowerCase() : undefined;\n if (action === \"boost\" || action === \"private\" || action === \"full\") {\n return { action };\n }\n return {};\n}\n\nexport class SandboxCommandHandler implements CommandHandler {\n async tryHandle(context: CommandContext): Promise<boolean> {\n const parsed = parseSandboxCommand(context.commandText);\n if (!parsed) return false;\n\n if (\n (context.services.sandbox.type !== \"image\" && context.services.sandbox.type !== \"gondolin\") ||\n !context.services.resourceController\n ) {\n await replyDiagnosticWithContext(\n context.responder,\n formatCommandSummary(\"Sandbox\", [\n \"`/pi-sandbox` 目前只支援 `image:*` 與 `gondolin:*` managed sandbox。\",\n ]),\n { style: \"muted\" },\n );\n return true;\n }\n\n const containerKey = runtimeResourceKey(context.services.sandbox, {\n userId: context.platformUserId,\n conversationId: context.conversationId,\n });\n\n if (parsed.action === \"private\" || parsed.action === \"full\") {\n applyConversationSettings(\n context.services.runtime,\n context.services.workingDir,\n context.conversationId,\n {\n sandbox: { image: { workspaceMount: parsed.action } },\n },\n );\n await replyDiagnosticWithContext(\n context.responder,\n formatCommandSummary(\"Sandbox Workspace\", [\n parsed.action === \"full\"\n ? \"已將此 conversation 的 sandbox 設為 full workspace mode。\"\n : \"已將此 conversation 的 sandbox 設為 private workspace mode。\",\n `Workspace mount: ${parsed.action}`,\n parsed.action === \"full\"\n ? \"之後這個 runtime 會把整個 host workspace 掛到 /workspace。\"\n : \"之後這個 runtime 只會掛載 private workspace 檔案與當前 conversation 目錄。\",\n ]),\n { style: \"muted\" },\n );\n return true;\n }\n\n if (parsed.action === \"boost\") {\n const boostLimits = context.services.resourceController.getBoostLimits();\n if (!boostLimits?.cpus && !boostLimits?.memory) {\n await replyDiagnosticWithContext(\n context.responder,\n formatCommandSummary(\"Sandbox Boost\", [\n \"此 mikan instance 尚未設定 sandbox boost 規格。\",\n \"請先在全域 settings.json 設定 `sandbox.boost`。\",\n ]),\n { style: \"muted\" },\n );\n return true;\n }\n\n const status = await context.services.resourceController.boost(containerKey);\n await replyDiagnosticWithContext(\n context.responder,\n formatCommandSummary(\"Sandbox Boost\", [\n \"已暫時提升此 conversation 的 sandbox 規格。\",\n `Current: ${formatLimits(status.limits)}`,\n \"boost 會在此 sandbox runtime 關閉後結束。\",\n ]),\n { style: \"muted\" },\n );\n return true;\n }\n\n const status = context.services.resourceController.getLimitStatus(containerKey);\n const defaultLimits = context.services.resourceController.getDefaultLimits();\n const boostLimits = context.services.resourceController.getBoostLimits();\n const workspaceMount = readConversationWorkspaceMountMode(\n context.services.workingDir,\n context.conversationId,\n );\n await replyDiagnosticWithContext(\n context.responder,\n formatCommandSummary(\n \"Sandbox\",\n [\n `Current: ${formatLimits(status.limits)}`,\n `Status: ${status.boosted ? \"boosted\" : \"default\"}`,\n `Workspace mount: ${workspaceMount}`,\n \"\",\n `Default: ${formatLimits(defaultLimits)}`,\n boostLimits ? `Boost: ${formatLimits({ ...defaultLimits, ...boostLimits })}` : undefined,\n ].filter((line): line is string => line !== undefined),\n ),\n { style: \"muted\" },\n );\n return true;\n }\n}\n\nfunction formatLimits(limits: { cpus?: string; memory?: string } | undefined): string {\n return `CPU ${limits?.cpus ?? \"unlimited\"} / Memory ${limits?.memory ?? \"unlimited\"}`;\n}\n"]}
@@ -1,23 +1,22 @@
1
1
  import { DockerContainerManager } from "./provisioner.js";
2
2
  import { type Executor, type SandboxConfig } from "./sandbox/index.js";
3
3
  import { type VaultManager } from "./vault/index.js";
4
- export type { ActorContext, ImageWorkspaceMountMode } from "./types.js";
5
- import type { ActorContext, ImageWorkspaceMountMode } from "./types.js";
6
- export declare function readConversationWorkspaceMountMode(workspaceDir: string | undefined, conversationId: string): ImageWorkspaceMountMode;
4
+ import { readWorkspaceProjectionMode } from "./workspace-projection/index.js";
5
+ export type { ActorContext } from "./types.js";
6
+ import type { ActorContext } from "./types.js";
7
+ export declare const readConversationWorkspaceMountMode: typeof readWorkspaceProjectionMode;
7
8
  export declare class ActorExecutionResolver {
8
9
  private baseConfig;
9
10
  private vaultManager;
10
11
  private provisioner?;
11
12
  private workspaceDir?;
12
13
  private hostWorkspacePath?;
13
- private readonly ensuredConversationDirs;
14
14
  constructor(baseConfig: SandboxConfig, vaultManager: VaultManager, provisioner?: DockerContainerManager | undefined, workspaceDir?: string | undefined, hostWorkspacePath?: string | undefined);
15
15
  resolve(context: ActorContext): Promise<Executor>;
16
+ private resolvePlan;
16
17
  private ensureDefaultSharedVault;
17
18
  private resolveSandboxConfig;
18
19
  private buildEnsureReadyCallback;
19
- /** Workspace layout overlaid by the vault's (already validated) credential mounts. */
20
20
  private resolveMounts;
21
- private buildWorkspaceMounts;
22
21
  }
23
22
  //# sourceMappingURL=execution-resolver.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"execution-resolver.d.ts","sourceRoot":"","sources":["../src/execution-resolver.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,sBAAsB,EAAuB,MAAM,kBAAkB,CAAC;AAC/E,OAAO,EAAkB,KAAK,QAAQ,EAAE,KAAK,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEvF,OAAO,EAA4B,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAO/E,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,CAmBzB;AAiCD,qBAAa,sBAAsB;IAI/B,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,YAAY;IACpB,OAAO,CAAC,WAAW,CAAC;IACpB,OAAO,CAAC,YAAY,CAAC;IACrB,OAAO,CAAC,iBAAiB,CAAC;IAP5B,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,EACrB,iBAAiB,CAAC,EAAE,MAAM,YAAA,EAChC;IAEE,OAAO,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,QAAQ,CAAC,CAsBtD;IAED,OAAO,CAAC,wBAAwB;IAsBhC,OAAO,CAAC,oBAAoB;IA8B5B,OAAO,CAAC,wBAAwB;IA4ChC,sFAAsF;IACtF,OAAO,CAAC,aAAa;IAcrB,OAAO,CAAC,oBAAoB;CAsB7B"}
1
+ {"version":3,"file":"execution-resolver.d.ts","sourceRoot":"","sources":["../src/execution-resolver.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,sBAAsB,EAAuB,MAAM,kBAAkB,CAAC;AAC/E,OAAO,EAGL,KAAK,QAAQ,EACb,KAAK,aAAa,EACnB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAA4B,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAS/E,OAAO,EAEL,2BAA2B,EAC5B,MAAM,iCAAiC,CAAC;AAEzC,YAAY,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,KAAK,EAAE,YAAY,EAAiB,MAAM,YAAY,CAAC;AAE9D,eAAO,MAAM,kCAAkC,oCAA8B,CAAC;AAE9E,qBAAa,sBAAsB;IAE/B,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,YAAY;IACpB,OAAO,CAAC,WAAW,CAAC;IACpB,OAAO,CAAC,YAAY,CAAC;IACrB,OAAO,CAAC,iBAAiB,CAAC;IAL5B,YACU,UAAU,EAAE,aAAa,EACzB,YAAY,EAAE,YAAY,EAC1B,WAAW,CAAC,EAAE,sBAAsB,YAAA,EACpC,YAAY,CAAC,EAAE,MAAM,YAAA,EACrB,iBAAiB,CAAC,EAAE,MAAM,YAAA,EAChC;IAEE,OAAO,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,QAAQ,CAAC,CAOtD;IAED,OAAO,CAAC,WAAW;IA2BnB,OAAO,CAAC,wBAAwB;IAuBhC,OAAO,CAAC,oBAAoB;IAuB5B,OAAO,CAAC,wBAAwB;IA0ChC,OAAO,CAAC,aAAa;CAwBtB"}
@@ -1,47 +1,14 @@
1
- import { join } from "path";
2
- import { conversationSettingsPath, loadGlobalSettings, resolveConversationSettings, } from "./config.js";
3
- import { ensureDirExists, isRecord, readJsonFileIfExists } from "./utils/file-guards.js";
1
+ import { posix } from "node:path";
2
+ import { loadGlobalSettings } from "./config.js";
4
3
  import { DockerContainerManager } from "./provisioner.js";
5
- import { createExecutor } from "./sandbox/index.js";
4
+ import { createExecutor, getSandboxCredentialCapabilities, } from "./sandbox/index.js";
6
5
  import { reportUserFacingError } from "./observability/sentry.js";
7
6
  import { normalizeSharedVaultName } from "./vault/index.js";
8
7
  import { resolveVaultInjection } from "./vault/injection.js";
9
8
  import { allowsAmbientDefaultSharedVault } from "./vault/policy.js";
10
- import { actorKey, scopeCloudflareSandboxId } from "./sandbox/identity.js";
11
- import * as log from "./log.js";
12
- export function readConversationWorkspaceMountMode(workspaceDir, conversationId) {
13
- const globalDefault = readGlobalWorkspaceMountMode();
14
- if (!workspaceDir) {
15
- return globalDefault;
16
- }
17
- const conversationDir = join(workspaceDir, conversationId);
18
- try {
19
- return (resolveConversationSettings(conversationDir).sandbox?.image?.workspaceMount ?? globalDefault);
20
- }
21
- catch (err) {
22
- log.logWarning("Falling back while resolving conversation workspace mount", err instanceof Error ? err.message : String(err));
23
- const raw = readConversationSettingsFallback(conversationSettingsPath(conversationDir));
24
- return raw?.sandbox?.image?.workspaceMount ?? globalDefault;
25
- }
26
- }
27
- function readGlobalWorkspaceMountMode() {
28
- try {
29
- return loadGlobalSettings().sandbox?.image?.workspaceMount ?? "private";
30
- }
31
- catch (err) {
32
- log.logWarning("Using default workspace mount because global settings could not be read", err instanceof Error ? err.message : String(err));
33
- return "private";
34
- }
35
- }
36
- function readConversationSettingsFallback(settingsPath) {
37
- try {
38
- return readJsonFileIfExists(settingsPath, (value) => isRecord(value), () => "Ignoring malformed conversation settings file while resolving workspace mount");
39
- }
40
- catch (err) {
41
- log.logWarning("Ignoring malformed conversation settings fallback while resolving workspace mount", err instanceof Error ? err.message : String(err));
42
- return undefined;
43
- }
44
- }
9
+ import { credentialAuthorizationKey, legacyExactCredentialAuthorizationKey, runtimeResourceKey, scopeCloudflareSandboxId, } from "./sandbox/identity.js";
10
+ import { resolveWorkspaceProjection, readWorkspaceProjectionMode, } from "./workspace-projection/index.js";
11
+ export const readConversationWorkspaceMountMode = readWorkspaceProjectionMode;
45
12
  export class ActorExecutionResolver {
46
13
  constructor(baseConfig, vaultManager, provisioner, workspaceDir, hostWorkspacePath) {
47
14
  this.baseConfig = baseConfig;
@@ -49,35 +16,42 @@ export class ActorExecutionResolver {
49
16
  this.provisioner = provisioner;
50
17
  this.workspaceDir = workspaceDir;
51
18
  this.hostWorkspacePath = hostWorkspacePath;
52
- this.ensuredConversationDirs = new Set();
53
19
  }
54
20
  async resolve(context) {
55
- const vaultKey = actorKey(this.baseConfig, {
56
- userId: context.userId,
57
- conversationId: context.conversationId,
58
- });
59
- this.ensureDefaultSharedVault(vaultKey, context.trustModel);
60
- const vault = this.vaultManager.resolve(vaultKey);
61
- // The vault decides what it contributes (env, validated credential
62
- // mounts); this resolver only composes that with workspace layout and
63
- // per-actor config shaping.
21
+ const plan = this.resolvePlan(context);
22
+ return createExecutor(plan.sandboxConfig, plan.env, this.buildEnsureReadyCallback(plan, context.conversationId));
23
+ }
24
+ resolvePlan(context) {
25
+ const ids = { userId: context.userId, conversationId: context.conversationId };
26
+ const credentialKey = credentialAuthorizationKey(this.baseConfig, ids);
27
+ const legacyCredentialKey = legacyExactCredentialAuthorizationKey(this.baseConfig, ids);
28
+ const resourceKey = runtimeResourceKey(this.baseConfig, ids);
29
+ this.ensureDefaultSharedVault(credentialKey, legacyCredentialKey, context.trustModel);
30
+ const vault = this.vaultManager.resolve(credentialKey) ??
31
+ (legacyCredentialKey ? this.vaultManager.resolve(legacyCredentialKey) : undefined);
32
+ const capabilities = getSandboxCredentialCapabilities(this.baseConfig.type);
64
33
  const injection = resolveVaultInjection({
65
34
  vault,
35
+ capabilities,
66
36
  sandboxType: this.baseConfig.type,
67
37
  conversationId: context.conversationId,
68
38
  });
69
- const config = this.resolveSandboxConfig(vaultKey, context.conversationId, injection);
70
- return createExecutor(config, injection.env, this.buildEnsureReadyCallback(vaultKey, context.conversationId, config, injection));
39
+ const mounts = this.resolveMounts(context.conversationId, injection.mounts);
40
+ return {
41
+ credentialKey,
42
+ resourceKey,
43
+ sandboxConfig: this.resolveSandboxConfig(resourceKey, mounts),
44
+ env: injection.env,
45
+ mounts,
46
+ };
71
47
  }
72
- ensureDefaultSharedVault(vaultKey, trustModel) {
73
- if (!allowsAmbientDefaultSharedVault({
74
- trustModel,
75
- sandboxType: this.baseConfig.type,
76
- })) {
48
+ ensureDefaultSharedVault(credentialKey, legacyCredentialKey, trustModel) {
49
+ if (!allowsAmbientDefaultSharedVault({ trustModel, sandboxType: this.baseConfig.type }))
77
50
  return;
78
- }
79
- if (this.vaultManager.hasEntry(vaultKey))
51
+ if (this.vaultManager.hasEntry(credentialKey) ||
52
+ (legacyCredentialKey && this.vaultManager.hasEntry(legacyCredentialKey))) {
80
53
  return;
54
+ }
81
55
  let profile;
82
56
  try {
83
57
  profile = loadGlobalSettings().sandbox?.defaultSharedVault;
@@ -87,43 +61,42 @@ export class ActorExecutionResolver {
87
61
  }
88
62
  if (!profile || normalizeSharedVaultName(profile) !== profile)
89
63
  return;
90
- this.vaultManager.copySharedVaultTo(profile, vaultKey);
64
+ this.vaultManager.copySharedVaultTo(profile, credentialKey);
91
65
  }
92
- resolveSandboxConfig(vaultKey, conversationId, injection) {
66
+ resolveSandboxConfig(resourceKey, mounts) {
93
67
  if (this.baseConfig.type === "cloudflare") {
94
68
  return {
95
69
  type: "cloudflare",
96
- sandboxId: scopeCloudflareSandboxId(this.baseConfig.sandboxId, vaultKey),
70
+ sandboxId: scopeCloudflareSandboxId(this.baseConfig.sandboxId, resourceKey),
97
71
  };
98
72
  }
99
73
  if (this.baseConfig.type === "gondolin") {
100
74
  return {
101
75
  ...this.baseConfig,
102
76
  workspacePath: this.hostWorkspacePath,
103
- mounts: this.resolveMounts(conversationId, injection.mounts),
104
- instanceId: vaultKey,
105
- resourceKey: vaultKey,
77
+ mounts,
78
+ instanceId: resourceKey,
79
+ resourceKey,
106
80
  };
107
81
  }
108
- if (this.baseConfig.type !== "image") {
82
+ if (this.baseConfig.type !== "image")
109
83
  return this.baseConfig;
110
- }
111
84
  return {
112
85
  type: "container",
113
- container: DockerContainerManager.containerName(vaultKey),
86
+ container: DockerContainerManager.containerName(resourceKey),
114
87
  };
115
88
  }
116
- buildEnsureReadyCallback(vaultKey, conversationId, config, injection) {
117
- if (this.baseConfig.type !== "image" || config.type !== "container") {
89
+ buildEnsureReadyCallback(plan, conversationId) {
90
+ if (this.baseConfig.type !== "image" || plan.sandboxConfig.type !== "container") {
118
91
  return undefined;
119
92
  }
120
93
  return async () => {
121
- const expected = config.container || DockerContainerManager.containerName(vaultKey);
94
+ const expected = plan.sandboxConfig.type === "container" ? plan.sandboxConfig.container : "";
122
95
  let actual;
123
96
  try {
124
- actual = await this.provisioner?.provision(vaultKey, {
97
+ actual = await this.provisioner?.provision(plan.resourceKey, {
125
98
  containerName: expected,
126
- mounts: this.resolveMounts(conversationId, injection.mounts),
99
+ mounts: plan.mounts,
127
100
  conversationId,
128
101
  });
129
102
  }
@@ -135,49 +108,45 @@ export class ActorExecutionResolver {
135
108
  severity: "error",
136
109
  context: {
137
110
  sandboxType: "image",
138
- resolvedSandboxType: config.type,
139
111
  conversationId,
140
- vaultKey,
112
+ credentialKey: plan.credentialKey,
113
+ resourceKey: plan.resourceKey,
141
114
  expectedContainer: expected,
142
- hasVault: Boolean(injection.env || injection.mounts.length > 0),
115
+ hasVault: Boolean(plan.env || plan.mounts.length > 0),
143
116
  },
144
117
  });
145
118
  throw err;
146
119
  }
147
120
  if (actual && actual !== expected) {
148
- throw new Error(`Provisioner returned container "${actual}" for container key "${vaultKey}", expected "${expected}"`);
121
+ throw new Error(`Provisioner returned container "${actual}" for resource key "${plan.resourceKey}", expected "${expected}"`);
149
122
  }
150
123
  };
151
124
  }
152
- /** Workspace layout overlaid by the vault's (already validated) credential mounts. */
153
125
  resolveMounts(conversationId, vaultMounts) {
154
- const mountsByTarget = new Map();
155
- for (const mount of this.buildWorkspaceMounts(conversationId)) {
156
- mountsByTarget.set(mount.target, mount);
157
- }
158
- for (const mount of vaultMounts) {
159
- mountsByTarget.set(mount.target, { source: mount.source, target: mount.target });
160
- }
161
- return [...mountsByTarget.values()];
162
- }
163
- buildWorkspaceMounts(conversationId) {
164
- if (!this.workspaceDir) {
165
- return [];
166
- }
167
- if (readConversationWorkspaceMountMode(this.workspaceDir, conversationId) === "full") {
168
- return [{ source: this.workspaceDir, target: "/workspace" }];
169
- }
170
- const conversationDir = join(this.workspaceDir, conversationId);
171
- if (!this.ensuredConversationDirs.has(conversationId)) {
172
- ensureDirExists(conversationDir);
173
- this.ensuredConversationDirs.add(conversationId);
126
+ const workspaceMounts = resolveWorkspaceProjection(this.workspaceDir, conversationId).mounts;
127
+ for (let index = 0; index < vaultMounts.length; index += 1) {
128
+ const vaultMount = vaultMounts[index];
129
+ const workspaceCollision = workspaceMounts.find((workspaceMount) => targetsOverlap(workspaceMount.target, vaultMount.target));
130
+ if (workspaceCollision) {
131
+ throw new Error(`Vault mount target "${vaultMount.target}" overlaps protected workspace target "${workspaceCollision.target}"`);
132
+ }
133
+ const vaultCollision = vaultMounts
134
+ .slice(0, index)
135
+ .find((other) => targetsOverlap(other.target, vaultMount.target));
136
+ if (vaultCollision) {
137
+ throw new Error(`Vault mount target "${vaultMount.target}" overlaps vault target "${vaultCollision.target}"`);
138
+ }
174
139
  }
175
- return [
176
- { source: join(this.workspaceDir, "MEMORY.md"), target: "/workspace/MEMORY.md" },
177
- { source: join(this.workspaceDir, "skills"), target: "/workspace/skills" },
178
- { source: join(this.workspaceDir, "events"), target: "/workspace/events" },
179
- { source: conversationDir, target: `/workspace/${conversationId}` },
180
- ];
140
+ return [...workspaceMounts, ...vaultMounts];
181
141
  }
182
142
  }
143
+ function targetsOverlap(left, right) {
144
+ const a = normalizeMountTarget(left);
145
+ const b = normalizeMountTarget(right);
146
+ return a === b || a.startsWith(`${b}/`) || b.startsWith(`${a}/`);
147
+ }
148
+ function normalizeMountTarget(value) {
149
+ const normalized = posix.normalize(value);
150
+ return normalized.replace(/\/+$/, "") || "/";
151
+ }
183
152
  //# sourceMappingURL=execution-resolver.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"execution-resolver.js","sourceRoot":"","sources":["../src/execution-resolver.ts"],"names":[],"mappings":"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","sourcesContent":["import { 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 VaultManager } from \"./vault/index.js\";\nimport { resolveVaultInjection, type VaultInjection } from \"./vault/injection.js\";\nimport { allowsAmbientDefaultSharedVault } from \"./vault/policy.js\";\nimport { actorKey, scopeCloudflareSandboxId } from \"./sandbox/identity.js\";\nimport type { ResolvedVaultMount } from \"./vault/types.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 (\n resolveConversationSettings(conversationDir).sandbox?.image?.workspaceMount ?? globalDefault\n );\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().sandbox?.image?.workspaceMount ?? \"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 private hostWorkspacePath?: string,\n ) {}\n\n async resolve(context: ActorContext): Promise<Executor> {\n const vaultKey = actorKey(this.baseConfig, {\n userId: context.userId,\n conversationId: context.conversationId,\n });\n this.ensureDefaultSharedVault(vaultKey, context.trustModel);\n\n const vault = this.vaultManager.resolve(vaultKey);\n // The vault decides what it contributes (env, validated credential\n // mounts); this resolver only composes that with workspace layout and\n // per-actor config shaping.\n const injection = resolveVaultInjection({\n vault,\n sandboxType: this.baseConfig.type,\n conversationId: context.conversationId,\n });\n const config = this.resolveSandboxConfig(vaultKey, context.conversationId, injection);\n return createExecutor(\n config,\n injection.env,\n this.buildEnsureReadyCallback(vaultKey, context.conversationId, config, injection),\n );\n }\n\n private ensureDefaultSharedVault(vaultKey: string, trustModel: ActorContext[\"trustModel\"]): void {\n if (\n !allowsAmbientDefaultSharedVault({\n trustModel,\n sandboxType: this.baseConfig.type,\n })\n ) {\n return;\n }\n if (this.vaultManager.hasEntry(vaultKey)) return;\n\n let profile: string | undefined;\n try {\n profile = loadGlobalSettings().sandbox?.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(\n vaultKey: string,\n conversationId: string,\n injection: VaultInjection,\n ): SandboxConfig {\n if (this.baseConfig.type === \"cloudflare\") {\n return {\n type: \"cloudflare\",\n sandboxId: scopeCloudflareSandboxId(this.baseConfig.sandboxId, vaultKey),\n };\n }\n if (this.baseConfig.type === \"gondolin\") {\n return {\n ...this.baseConfig,\n workspacePath: this.hostWorkspacePath,\n mounts: this.resolveMounts(conversationId, injection.mounts),\n instanceId: vaultKey,\n resourceKey: vaultKey,\n };\n }\n if (this.baseConfig.type !== \"image\") {\n return this.baseConfig;\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 injection: VaultInjection,\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, injection.mounts),\n conversationId,\n });\n } catch (err) {\n reportUserFacingError(err, {\n domain: \"sandbox\",\n surface: \"sandbox_provision\",\n operation: \"ensure_image_container_ready\",\n severity: \"error\",\n context: {\n sandboxType: \"image\",\n resolvedSandboxType: config.type,\n conversationId,\n vaultKey,\n expectedContainer: expected,\n hasVault: Boolean(injection.env || injection.mounts.length > 0),\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 /** Workspace layout overlaid by the vault's (already validated) credential mounts. */\n private resolveMounts(\n conversationId: string,\n vaultMounts: ResolvedVaultMount[],\n ): ContainerMount[] {\n const mountsByTarget = new Map<string, ContainerMount>();\n for (const mount of this.buildWorkspaceMounts(conversationId)) {\n mountsByTarget.set(mount.target, mount);\n }\n for (const mount of vaultMounts) {\n mountsByTarget.set(mount.target, { source: mount.source, target: mount.target });\n }\n return [...mountsByTarget.values()];\n }\n\n private buildWorkspaceMounts(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 { posix } from \"node:path\";\nimport { loadGlobalSettings } from \"./config.js\";\nimport { DockerContainerManager, type ContainerMount } from \"./provisioner.js\";\nimport {\n createExecutor,\n getSandboxCredentialCapabilities,\n type Executor,\n type SandboxConfig,\n} from \"./sandbox/index.js\";\nimport { reportUserFacingError } from \"./observability/sentry.js\";\nimport { normalizeSharedVaultName, type VaultManager } from \"./vault/index.js\";\nimport { resolveVaultInjection } from \"./vault/injection.js\";\nimport { allowsAmbientDefaultSharedVault } from \"./vault/policy.js\";\nimport {\n credentialAuthorizationKey,\n legacyExactCredentialAuthorizationKey,\n runtimeResourceKey,\n scopeCloudflareSandboxId,\n} from \"./sandbox/identity.js\";\nimport {\n resolveWorkspaceProjection,\n readWorkspaceProjectionMode,\n} from \"./workspace-projection/index.js\";\n\nexport type { ActorContext } from \"./types.js\";\nimport type { ActorContext, ExecutionPlan } from \"./types.js\";\n\nexport const readConversationWorkspaceMountMode = readWorkspaceProjectionMode;\n\nexport class ActorExecutionResolver {\n constructor(\n private baseConfig: SandboxConfig,\n private vaultManager: VaultManager,\n private provisioner?: DockerContainerManager,\n private workspaceDir?: string,\n private hostWorkspacePath?: string,\n ) {}\n\n async resolve(context: ActorContext): Promise<Executor> {\n const plan = this.resolvePlan(context);\n return createExecutor(\n plan.sandboxConfig,\n plan.env,\n this.buildEnsureReadyCallback(plan, context.conversationId),\n );\n }\n\n private resolvePlan(context: ActorContext): ExecutionPlan {\n const ids = { userId: context.userId, conversationId: context.conversationId };\n const credentialKey = credentialAuthorizationKey(this.baseConfig, ids);\n const legacyCredentialKey = legacyExactCredentialAuthorizationKey(this.baseConfig, ids);\n const resourceKey = runtimeResourceKey(this.baseConfig, ids);\n this.ensureDefaultSharedVault(credentialKey, legacyCredentialKey, context.trustModel);\n\n const vault =\n this.vaultManager.resolve(credentialKey) ??\n (legacyCredentialKey ? this.vaultManager.resolve(legacyCredentialKey) : undefined);\n const capabilities = getSandboxCredentialCapabilities(this.baseConfig.type);\n const injection = resolveVaultInjection({\n vault,\n capabilities,\n sandboxType: this.baseConfig.type,\n conversationId: context.conversationId,\n });\n const mounts = this.resolveMounts(context.conversationId, injection.mounts);\n return {\n credentialKey,\n resourceKey,\n sandboxConfig: this.resolveSandboxConfig(resourceKey, mounts),\n env: injection.env,\n mounts,\n };\n }\n\n private ensureDefaultSharedVault(\n credentialKey: string,\n legacyCredentialKey: string | undefined,\n trustModel: ActorContext[\"trustModel\"],\n ): void {\n if (!allowsAmbientDefaultSharedVault({ trustModel, sandboxType: this.baseConfig.type })) return;\n if (\n this.vaultManager.hasEntry(credentialKey) ||\n (legacyCredentialKey && this.vaultManager.hasEntry(legacyCredentialKey))\n ) {\n return;\n }\n\n let profile: string | undefined;\n try {\n profile = loadGlobalSettings().sandbox?.defaultSharedVault;\n } catch {\n return;\n }\n if (!profile || normalizeSharedVaultName(profile) !== profile) return;\n this.vaultManager.copySharedVaultTo(profile, credentialKey);\n }\n\n private resolveSandboxConfig(resourceKey: string, mounts: ContainerMount[]): SandboxConfig {\n if (this.baseConfig.type === \"cloudflare\") {\n return {\n type: \"cloudflare\",\n sandboxId: scopeCloudflareSandboxId(this.baseConfig.sandboxId, resourceKey),\n };\n }\n if (this.baseConfig.type === \"gondolin\") {\n return {\n ...this.baseConfig,\n workspacePath: this.hostWorkspacePath,\n mounts,\n instanceId: resourceKey,\n resourceKey,\n };\n }\n if (this.baseConfig.type !== \"image\") return this.baseConfig;\n return {\n type: \"container\",\n container: DockerContainerManager.containerName(resourceKey),\n };\n }\n\n private buildEnsureReadyCallback(\n plan: ExecutionPlan,\n conversationId: string,\n ): (() => Promise<void>) | undefined {\n if (this.baseConfig.type !== \"image\" || plan.sandboxConfig.type !== \"container\") {\n return undefined;\n }\n\n return async () => {\n const expected = plan.sandboxConfig.type === \"container\" ? plan.sandboxConfig.container : \"\";\n let actual: string | undefined;\n try {\n actual = await this.provisioner?.provision(plan.resourceKey, {\n containerName: expected,\n mounts: plan.mounts,\n conversationId,\n });\n } catch (err) {\n reportUserFacingError(err, {\n domain: \"sandbox\",\n surface: \"sandbox_provision\",\n operation: \"ensure_image_container_ready\",\n severity: \"error\",\n context: {\n sandboxType: \"image\",\n conversationId,\n credentialKey: plan.credentialKey,\n resourceKey: plan.resourceKey,\n expectedContainer: expected,\n hasVault: Boolean(plan.env || plan.mounts.length > 0),\n },\n });\n throw err;\n }\n if (actual && actual !== expected) {\n throw new Error(\n `Provisioner returned container \"${actual}\" for resource key \"${plan.resourceKey}\", expected \"${expected}\"`,\n );\n }\n };\n }\n\n private resolveMounts(conversationId: string, vaultMounts: ContainerMount[]): ContainerMount[] {\n const workspaceMounts = resolveWorkspaceProjection(this.workspaceDir, conversationId).mounts;\n for (let index = 0; index < vaultMounts.length; index += 1) {\n const vaultMount = vaultMounts[index];\n const workspaceCollision = workspaceMounts.find((workspaceMount) =>\n targetsOverlap(workspaceMount.target, vaultMount.target),\n );\n if (workspaceCollision) {\n throw new Error(\n `Vault mount target \"${vaultMount.target}\" overlaps protected workspace target \"${workspaceCollision.target}\"`,\n );\n }\n\n const vaultCollision = vaultMounts\n .slice(0, index)\n .find((other) => targetsOverlap(other.target, vaultMount.target));\n if (vaultCollision) {\n throw new Error(\n `Vault mount target \"${vaultMount.target}\" overlaps vault target \"${vaultCollision.target}\"`,\n );\n }\n }\n return [...workspaceMounts, ...vaultMounts];\n }\n}\n\nfunction targetsOverlap(left: string, right: string): boolean {\n const a = normalizeMountTarget(left);\n const b = normalizeMountTarget(right);\n return a === b || a.startsWith(`${b}/`) || b.startsWith(`${a}/`);\n}\n\nfunction normalizeMountTarget(value: string): string {\n const normalized = posix.normalize(value);\n return normalized.replace(/\\/+$/, \"\") || \"/\";\n}\n"]}
@@ -16,5 +16,5 @@ export { buildEventPayload, EventTypeSchema, parseEventPayload, type EventConver
16
16
  export { ExtensionRegistry, parseCommandInput } from "./extensions/registry.js";
17
17
  export { defaultExtensionDirs, extensionSlug, listInstalledExtensions, loadExtensions, validateExtension, type ExtensionValidation, type InstalledExtensionInfo, type LoadExtensionsOptions, type LoadExtensionsResult, } from "./extensions/loader.js";
18
18
  export type { AgentErrorHookEvent, BeforeAgentStartHookEvent, BeforeAgentStartHookResult, BudgetExceededHookEvent, SubagentApi, ExtensionCommand, ExtensionCommandContext, ExtensionDisposer, ExtensionHostServices, ExtensionLoadError, ExtensionManifest, ExtensionScheduleInfo, ExtensionSchedulePayload, ExtensionScheduleSpec, ExtensionScheduleStore, LoadedExtension, MessageEndHookEvent, MikanExtensionActivate, MikanExtensionApi, MikanExtensionModule, MikanHookMap, MikanHookName, RunOrigin, SessionCompactHookEvent, ToolCallHookEvent, ToolCallHookResult, ToolResultHookEvent, ToolResultHookResult, TurnEndHookEvent, } from "./extensions/types.js";
19
- export { type SubagentModelSpec, type SubagentRunBudget, type SubagentRunOutput, type SubagentRunRequest, type SubagentRunResult, type SubagentRunStatus, CURRENT_SESSION_VERSION, type BranchSummaryEntry, type CompactionEntry, type CustomEntry, type CustomMessageEntry, type SessionContext, type SessionEntry, type SessionFileEntry, type SessionHeader, type SessionInfoEntry, type SessionMessageEntry, } from "./types.js";
19
+ export { type SubagentModelSpec, type SubagentParentContext, type SubagentRunBudget, type SubagentRunOutput, type SubagentRunRequest, type SubagentRunResult, type SubagentRunStatus, type SubagentUsage, CURRENT_SESSION_VERSION, type BranchSummaryEntry, type CompactionEntry, type CustomEntry, type CustomMessageEntry, type SessionContext, type SessionEntry, type SessionFileEntry, type SessionHeader, type SessionInfoEntry, type SessionMessageEntry, } from "./types.js";
20
20
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/harness/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AACjE,OAAO,EACL,4BAA4B,EAC5B,uBAAuB,EACvB,sBAAsB,GACvB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,WAAW,EAAE,qBAAqB,EAAE,KAAK,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAChG,OAAO,EAAE,YAAY,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AACnG,OAAO,EACL,iBAAiB,EACjB,KAAK,gBAAgB,EACrB,KAAK,YAAY,EACjB,KAAK,oBAAoB,EACzB,KAAK,wBAAwB,EAC7B,KAAK,oBAAoB,GAC1B,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,qBAAqB,EACrB,iBAAiB,EACjB,gBAAgB,EAChB,KAAK,gBAAgB,EACrB,KAAK,UAAU,EACf,KAAK,eAAe,GACrB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,uBAAuB,EACvB,oBAAoB,EACpB,sBAAsB,EACtB,sBAAsB,EACtB,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACvB,KAAK,eAAe,EACpB,KAAK,aAAa,GACnB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,iBAAiB,EACjB,eAAe,EACf,iBAAiB,EACjB,KAAK,qBAAqB,EAC1B,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EACtB,KAAK,SAAS,EACd,KAAK,qBAAqB,EAC1B,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,GAC1B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAChF,OAAO,EACL,oBAAoB,EACpB,aAAa,EACb,uBAAuB,EACvB,cAAc,EACd,iBAAiB,EACjB,KAAK,mBAAmB,EACxB,KAAK,sBAAsB,EAC3B,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,GAC1B,MAAM,wBAAwB,CAAC;AAChC,YAAY,EACV,mBAAmB,EACnB,yBAAyB,EACzB,0BAA0B,EAC1B,uBAAuB,EACvB,WAAW,EACX,gBAAgB,EAChB,uBAAuB,EACvB,iBAAiB,EACjB,qBAAqB,EACrB,kBAAkB,EAClB,iBAAiB,EACjB,qBAAqB,EACrB,wBAAwB,EACxB,qBAAqB,EACrB,sBAAsB,EACtB,eAAe,EACf,mBAAmB,EACnB,sBAAsB,EACtB,iBAAiB,EACjB,oBAAoB,EACpB,YAAY,EACZ,aAAa,EACb,SAAS,EACT,uBAAuB,EACvB,iBAAiB,EACjB,kBAAkB,EAClB,mBAAmB,EACnB,oBAAoB,EACpB,gBAAgB,GACjB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EACtB,uBAAuB,EACvB,KAAK,kBAAkB,EACvB,KAAK,eAAe,EACpB,KAAK,WAAW,EAChB,KAAK,kBAAkB,EACvB,KAAK,cAAc,EACnB,KAAK,YAAY,EACjB,KAAK,gBAAgB,EACrB,KAAK,aAAa,EAClB,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,GACzB,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/harness/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AACjE,OAAO,EACL,4BAA4B,EAC5B,uBAAuB,EACvB,sBAAsB,GACvB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,WAAW,EAAE,qBAAqB,EAAE,KAAK,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAChG,OAAO,EAAE,YAAY,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AACnG,OAAO,EACL,iBAAiB,EACjB,KAAK,gBAAgB,EACrB,KAAK,YAAY,EACjB,KAAK,oBAAoB,EACzB,KAAK,wBAAwB,EAC7B,KAAK,oBAAoB,GAC1B,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,qBAAqB,EACrB,iBAAiB,EACjB,gBAAgB,EAChB,KAAK,gBAAgB,EACrB,KAAK,UAAU,EACf,KAAK,eAAe,GACrB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,uBAAuB,EACvB,oBAAoB,EACpB,sBAAsB,EACtB,sBAAsB,EACtB,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACvB,KAAK,eAAe,EACpB,KAAK,aAAa,GACnB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,iBAAiB,EACjB,eAAe,EACf,iBAAiB,EACjB,KAAK,qBAAqB,EAC1B,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EACtB,KAAK,SAAS,EACd,KAAK,qBAAqB,EAC1B,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,GAC1B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAChF,OAAO,EACL,oBAAoB,EACpB,aAAa,EACb,uBAAuB,EACvB,cAAc,EACd,iBAAiB,EACjB,KAAK,mBAAmB,EACxB,KAAK,sBAAsB,EAC3B,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,GAC1B,MAAM,wBAAwB,CAAC;AAChC,YAAY,EACV,mBAAmB,EACnB,yBAAyB,EACzB,0BAA0B,EAC1B,uBAAuB,EACvB,WAAW,EACX,gBAAgB,EAChB,uBAAuB,EACvB,iBAAiB,EACjB,qBAAqB,EACrB,kBAAkB,EAClB,iBAAiB,EACjB,qBAAqB,EACrB,wBAAwB,EACxB,qBAAqB,EACrB,sBAAsB,EACtB,eAAe,EACf,mBAAmB,EACnB,sBAAsB,EACtB,iBAAiB,EACjB,oBAAoB,EACpB,YAAY,EACZ,aAAa,EACb,SAAS,EACT,uBAAuB,EACvB,iBAAiB,EACjB,kBAAkB,EAClB,mBAAmB,EACnB,oBAAoB,EACpB,gBAAgB,GACjB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,KAAK,iBAAiB,EACtB,KAAK,qBAAqB,EAC1B,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EACtB,KAAK,aAAa,EAClB,uBAAuB,EACvB,KAAK,kBAAkB,EACvB,KAAK,eAAe,EACpB,KAAK,WAAW,EAChB,KAAK,kBAAkB,EACvB,KAAK,cAAc,EACnB,KAAK,YAAY,EACjB,KAAK,gBAAgB,EACrB,KAAK,aAAa,EAClB,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,GACzB,MAAM,YAAY,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/harness/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AACjE,OAAO,EACL,4BAA4B,EAC5B,uBAAuB,EACvB,sBAAsB,GACvB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,WAAW,EAAE,qBAAqB,EAAiC,MAAM,aAAa,CAAC;AAChG,OAAO,EAAE,YAAY,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AACnG,OAAO,EACL,iBAAiB,GAMlB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,qBAAqB,EACrB,iBAAiB,EACjB,gBAAgB,GAIjB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,uBAAuB,EACvB,oBAAoB,EACpB,sBAAsB,EACtB,sBAAsB,GAKvB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,iBAAiB,EACjB,eAAe,EACf,iBAAiB,GAQlB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAChF,OAAO,EACL,oBAAoB,EACpB,aAAa,EACb,uBAAuB,EACvB,cAAc,EACd,iBAAiB,GAKlB,MAAM,wBAAwB,CAAC;AAgChC,OAAO,EAOL,uBAAuB,GAWxB,MAAM,YAAY,CAAC","sourcesContent":["/**\n * mikan agent harness.\n *\n * mikan's own harness engineering layer, built directly on pi-agent-core\n * (agent loop, compaction, context building) and pi-ai (providers, models,\n * auth). See `src/harness/README.md` for the architecture.\n */\nexport { FileCredentialStore, defaultAuthPath } from \"./auth.js\";\nexport {\n DEFAULT_HTTP_IDLE_TIMEOUT_MS,\n configureHttpDispatcher,\n parseHttpIdleTimeoutMs,\n} from \"./http.js\";\nexport { MikanModels, defaultModelsJsonPath, type CreateMikanModelsOptions } from \"./models.js\";\nexport { SessionStore, loadSessionFileEntries, parseSessionFileEntries } from \"./session-store.js\";\nexport {\n MikanAgentSession,\n type CompactionReason,\n type HarnessEvent,\n type HarnessEventListener,\n type MikanAgentSessionOptions,\n type PromptBlockedOutcome,\n} from \"./runner.js\";\nexport {\n formatSkillsForPrompt,\n loadSkillsFromDir,\n parseFrontmatter,\n type LoadSkillsResult,\n type MikanSkill,\n type SkillDiagnostic,\n} from \"./skills.js\";\nexport {\n DEFAULT_BUDGET_SETTINGS,\n DEFAULT_EVENT_BUDGET,\n DEFAULT_RETRY_SETTINGS,\n resolveHarnessSettings,\n type BudgetSettings,\n type CompactionSettings,\n type HarnessSettings,\n type RetrySettings,\n} from \"./settings.js\";\nexport {\n buildEventPayload,\n EventTypeSchema,\n parseEventPayload,\n type EventConversationKind,\n type EventFilePayload,\n type EventPayloadInput,\n type EventType,\n type ImmediateEventPayload,\n type OneShotEventPayload,\n type PeriodicEventPayload,\n} from \"./event-format.js\";\nexport { ExtensionRegistry, parseCommandInput } from \"./extensions/registry.js\";\nexport {\n defaultExtensionDirs,\n extensionSlug,\n listInstalledExtensions,\n loadExtensions,\n validateExtension,\n type ExtensionValidation,\n type InstalledExtensionInfo,\n type LoadExtensionsOptions,\n type LoadExtensionsResult,\n} from \"./extensions/loader.js\";\nexport type {\n AgentErrorHookEvent,\n BeforeAgentStartHookEvent,\n BeforeAgentStartHookResult,\n BudgetExceededHookEvent,\n SubagentApi,\n ExtensionCommand,\n ExtensionCommandContext,\n ExtensionDisposer,\n ExtensionHostServices,\n ExtensionLoadError,\n ExtensionManifest,\n ExtensionScheduleInfo,\n ExtensionSchedulePayload,\n ExtensionScheduleSpec,\n ExtensionScheduleStore,\n LoadedExtension,\n MessageEndHookEvent,\n MikanExtensionActivate,\n MikanExtensionApi,\n MikanExtensionModule,\n MikanHookMap,\n MikanHookName,\n RunOrigin,\n SessionCompactHookEvent,\n ToolCallHookEvent,\n ToolCallHookResult,\n ToolResultHookEvent,\n ToolResultHookResult,\n TurnEndHookEvent,\n} from \"./extensions/types.js\";\nexport {\n type SubagentModelSpec,\n type SubagentRunBudget,\n type SubagentRunOutput,\n type SubagentRunRequest,\n type SubagentRunResult,\n type SubagentRunStatus,\n CURRENT_SESSION_VERSION,\n type BranchSummaryEntry,\n type CompactionEntry,\n type CustomEntry,\n type CustomMessageEntry,\n type SessionContext,\n type SessionEntry,\n type SessionFileEntry,\n type SessionHeader,\n type SessionInfoEntry,\n type SessionMessageEntry,\n} from \"./types.js\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/harness/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AACjE,OAAO,EACL,4BAA4B,EAC5B,uBAAuB,EACvB,sBAAsB,GACvB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,WAAW,EAAE,qBAAqB,EAAiC,MAAM,aAAa,CAAC;AAChG,OAAO,EAAE,YAAY,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AACnG,OAAO,EACL,iBAAiB,GAMlB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,qBAAqB,EACrB,iBAAiB,EACjB,gBAAgB,GAIjB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,uBAAuB,EACvB,oBAAoB,EACpB,sBAAsB,EACtB,sBAAsB,GAKvB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,iBAAiB,EACjB,eAAe,EACf,iBAAiB,GAQlB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAChF,OAAO,EACL,oBAAoB,EACpB,aAAa,EACb,uBAAuB,EACvB,cAAc,EACd,iBAAiB,GAKlB,MAAM,wBAAwB,CAAC;AAgChC,OAAO,EASL,uBAAuB,GAWxB,MAAM,YAAY,CAAC","sourcesContent":["/**\n * mikan agent harness.\n *\n * mikan's own harness engineering layer, built directly on pi-agent-core\n * (agent loop, compaction, context building) and pi-ai (providers, models,\n * auth). See `src/harness/README.md` for the architecture.\n */\nexport { FileCredentialStore, defaultAuthPath } from \"./auth.js\";\nexport {\n DEFAULT_HTTP_IDLE_TIMEOUT_MS,\n configureHttpDispatcher,\n parseHttpIdleTimeoutMs,\n} from \"./http.js\";\nexport { MikanModels, defaultModelsJsonPath, type CreateMikanModelsOptions } from \"./models.js\";\nexport { SessionStore, loadSessionFileEntries, parseSessionFileEntries } from \"./session-store.js\";\nexport {\n MikanAgentSession,\n type CompactionReason,\n type HarnessEvent,\n type HarnessEventListener,\n type MikanAgentSessionOptions,\n type PromptBlockedOutcome,\n} from \"./runner.js\";\nexport {\n formatSkillsForPrompt,\n loadSkillsFromDir,\n parseFrontmatter,\n type LoadSkillsResult,\n type MikanSkill,\n type SkillDiagnostic,\n} from \"./skills.js\";\nexport {\n DEFAULT_BUDGET_SETTINGS,\n DEFAULT_EVENT_BUDGET,\n DEFAULT_RETRY_SETTINGS,\n resolveHarnessSettings,\n type BudgetSettings,\n type CompactionSettings,\n type HarnessSettings,\n type RetrySettings,\n} from \"./settings.js\";\nexport {\n buildEventPayload,\n EventTypeSchema,\n parseEventPayload,\n type EventConversationKind,\n type EventFilePayload,\n type EventPayloadInput,\n type EventType,\n type ImmediateEventPayload,\n type OneShotEventPayload,\n type PeriodicEventPayload,\n} from \"./event-format.js\";\nexport { ExtensionRegistry, parseCommandInput } from \"./extensions/registry.js\";\nexport {\n defaultExtensionDirs,\n extensionSlug,\n listInstalledExtensions,\n loadExtensions,\n validateExtension,\n type ExtensionValidation,\n type InstalledExtensionInfo,\n type LoadExtensionsOptions,\n type LoadExtensionsResult,\n} from \"./extensions/loader.js\";\nexport type {\n AgentErrorHookEvent,\n BeforeAgentStartHookEvent,\n BeforeAgentStartHookResult,\n BudgetExceededHookEvent,\n SubagentApi,\n ExtensionCommand,\n ExtensionCommandContext,\n ExtensionDisposer,\n ExtensionHostServices,\n ExtensionLoadError,\n ExtensionManifest,\n ExtensionScheduleInfo,\n ExtensionSchedulePayload,\n ExtensionScheduleSpec,\n ExtensionScheduleStore,\n LoadedExtension,\n MessageEndHookEvent,\n MikanExtensionActivate,\n MikanExtensionApi,\n MikanExtensionModule,\n MikanHookMap,\n MikanHookName,\n RunOrigin,\n SessionCompactHookEvent,\n ToolCallHookEvent,\n ToolCallHookResult,\n ToolResultHookEvent,\n ToolResultHookResult,\n TurnEndHookEvent,\n} from \"./extensions/types.js\";\nexport {\n type SubagentModelSpec,\n type SubagentParentContext,\n type SubagentRunBudget,\n type SubagentRunOutput,\n type SubagentRunRequest,\n type SubagentRunResult,\n type SubagentRunStatus,\n type SubagentUsage,\n CURRENT_SESSION_VERSION,\n type BranchSummaryEntry,\n type CompactionEntry,\n type CustomEntry,\n type CustomMessageEntry,\n type SessionContext,\n type SessionEntry,\n type SessionFileEntry,\n type SessionHeader,\n type SessionInfoEntry,\n type SessionMessageEntry,\n} from \"./types.js\";\n"]}
@@ -83,6 +83,7 @@ export declare class MikanAgentSession {
83
83
  private overflowRecoveryAttempted;
84
84
  private retryAbortController;
85
85
  private compactionAbortController;
86
+ private runActive;
86
87
  private tally;
87
88
  private runBudget;
88
89
  private budgetExceededReason;
@@ -91,6 +92,8 @@ export declare class MikanAgentSession {
91
92
  /** Conversation transcript currently held by the agent. */
92
93
  get messages(): AgentMessage[];
93
94
  get model(): Model<Api>;
95
+ /** Whether this session currently owns a prompt, including pre-model hooks. */
96
+ get isActiveRun(): boolean;
94
97
  /** Resource totals and terminal budget state from the most recent prompt. */
95
98
  getLastRunStats(): Readonly<{
96
99
  tokens: number;
@@ -131,6 +134,7 @@ export declare class MikanAgentSession {
131
134
  budget?: BudgetSettings;
132
135
  origin?: RunOrigin;
133
136
  }): Promise<PromptBlockedOutcome | undefined>;
137
+ private runPrompt;
134
138
  /** Abort the active run, pending retry backoff, and in-flight compaction. */
135
139
  abort(): void;
136
140
  private ensureAuthConfigured;
@@ -1 +1 @@
1
- {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/harness/runner.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/harness/runner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EACL,KAAK,EAQL,KAAK,UAAU,EACf,KAAK,YAAY,EACjB,KAAK,SAAS,EAEd,KAAK,aAAa,EACnB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAEL,KAAK,GAAG,EAER,KAAK,YAAY,EACjB,KAAK,KAAK,EACX,MAAM,uBAAuB,CAAC;AAE/B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,sBAAsB,EAAE,KAAK,cAAc,EAAwB,MAAM,eAAe,CAAC;AAClG,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGvD,MAAM,MAAM,gBAAgB,GAAG,WAAW,GAAG,UAAU,GAAG,QAAQ,CAAC;AAUnE,UAAU,uBAAuB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,MAAM,YAAY,GACpB,UAAU,GACV;IAAE,IAAI,EAAE,kBAAkB,CAAC;IAAC,MAAM,EAAE,gBAAgB,CAAA;CAAE,GACtD;IACE,IAAI,EAAE,gBAAgB,CAAC;IACvB,MAAM,EAAE,gBAAgB,CAAC;IACzB,MAAM,CAAC,EAAE,uBAAuB,CAAC;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,GACD;IACE,IAAI,EAAE,kBAAkB,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;CACtB,GACD;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,GAClF;IACE,IAAI,EAAE,iBAAiB,CAAC;IACxB,6DAA6D;IAC7D,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEN,MAAM,MAAM,oBAAoB,GAAG,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAEjF,mFAAmF;AACnF,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,IAAI,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAyBD,MAAM,WAAW,wBAAwB;IACvC,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IAClB,aAAa,EAAE,aAAa,CAAC;IAC7B,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,MAAM,EAAE,WAAW,CAAC;IACpB,YAAY,EAAE,YAAY,CAAC;IAC3B,QAAQ,CAAC,EAAE,UAAU,CAAC,OAAO,sBAAsB,CAAC,CAAC,CAAC,CAAC,CAAC;IACxD,UAAU,CAAC,EAAE,iBAAiB,CAAC;CAChC;AAED,qBAAa,iBAAiB;IAC5B,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAC;IACpC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAc;IACrC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAkB;IAC3C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAgC;IAC3D,OAAO,CAAC,SAAS,CAAmC;IACpD,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,yBAAyB,CAAS;IAC1C,OAAO,CAAC,oBAAoB,CAA8B;IAC1D,OAAO,CAAC,yBAAyB,CAA8B;IAC/D,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,KAAK,CAAkE;IAC/E,OAAO,CAAC,SAAS,CAAsB;IACvC,OAAO,CAAC,oBAAoB,CAAqB;IACjD,OAAO,CAAC,SAAS,CAAwB;IAEzC,YAAY,OAAO,EAAE,wBAAwB,EA8C5C;IAED,2DAA2D;IAC3D,IAAI,QAAQ,IAAI,YAAY,EAAE,CAE7B;IAED,IAAI,KAAK,IAAI,KAAK,CAAC,GAAG,CAAC,CAEtB;IAED,+EAA+E;IAC/E,IAAI,WAAW,IAAI,OAAO,CAEzB;IAED,6EAA6E;IAC7E,eAAe,IAAI,QAAQ,CAAC;QAC1B,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,MAAM,CAAC;QAChB,QAAQ,EAAE,MAAM,CAAC;QACjB,UAAU,EAAE,MAAM,CAAC;QACnB,oBAAoB,CAAC,EAAE,MAAM,CAAC;KAC/B,CAAC,CAQD;IAED;;;;;;;OAOG;IACG,iBAAiB,CAAC,KAAK,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAMnF;IAED,SAAS,CAAC,QAAQ,EAAE,oBAAoB,GAAG,MAAM,IAAI,CAGpD;IAED,oEAAoE;IACpE,iBAAiB,IAAI,MAAM,CAM1B;IAED;;;;;;;;;;;OAWG;IACG,MAAM,CACV,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,YAAY,EAAE,CAAC;QAAC,MAAM,CAAC,EAAE,cAAc,CAAC;QAAC,MAAM,CAAC,EAAE,SAAS,CAAA;KAAE,GACjF,OAAO,CAAC,oBAAoB,GAAG,SAAS,CAAC,CAU3C;YAEa,SAAS;IAoFvB,6EAA6E;IAC7E,KAAK,IAAI,IAAI,CAIZ;YAEa,oBAAoB;YASpB,IAAI;YAaJ,gBAAgB;IAmC9B,sEAAsE;IACtE,OAAO,CAAC,WAAW;IAQnB,sFAAsF;YACxE,aAAa;IAO3B,kFAAkF;YACpE,YAAY;IAwB1B,OAAO,CAAC,gBAAgB;IAUxB,+EAA+E;IAC/E,OAAO,CAAC,wBAAwB;IAchC,OAAO,CAAC,wBAAwB;IAShC,0FAA0F;YAC5E,aAAa;YAsBb,cAAc;YAgBd,wBAAwB;YAiBxB,aAAa;IAmF3B,OAAO,CAAC,gBAAgB;YAKV,YAAY;IA+C1B,OAAO,CAAC,wBAAwB;CAMjC"}