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

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 (199) hide show
  1. package/CHANGELOG.md +55 -0
  2. package/README.md +12 -8
  3. package/dist/adapters/discord/bot.d.ts.map +1 -1
  4. package/dist/adapters/discord/bot.js +13 -14
  5. package/dist/adapters/discord/bot.js.map +1 -1
  6. package/dist/adapters/intake.d.ts.map +1 -1
  7. package/dist/adapters/intake.js +5 -0
  8. package/dist/adapters/intake.js.map +1 -1
  9. package/dist/adapters/slack/bot.d.ts.map +1 -1
  10. package/dist/adapters/slack/bot.js +13 -2
  11. package/dist/adapters/slack/bot.js.map +1 -1
  12. package/dist/adapters/slack/types.d.ts +2 -0
  13. package/dist/adapters/slack/types.d.ts.map +1 -1
  14. package/dist/adapters/slack/types.js.map +1 -1
  15. package/dist/agent.d.ts.map +1 -1
  16. package/dist/agent.js +34 -24
  17. package/dist/agent.js.map +1 -1
  18. package/dist/cli/boot.d.ts +1 -1
  19. package/dist/cli/boot.d.ts.map +1 -1
  20. package/dist/cli/boot.js +7 -15
  21. package/dist/cli/boot.js.map +1 -1
  22. package/dist/commands/login.js +2 -2
  23. package/dist/commands/login.js.map +1 -1
  24. package/dist/commands/sandbox.d.ts.map +1 -1
  25. package/dist/commands/sandbox.js +4 -7
  26. package/dist/commands/sandbox.js.map +1 -1
  27. package/dist/commands/text.js +1 -1
  28. package/dist/commands/text.js.map +1 -1
  29. package/dist/config.d.ts.map +1 -1
  30. package/dist/config.js +12 -39
  31. package/dist/config.js.map +1 -1
  32. package/dist/execution-resolver.d.ts +6 -8
  33. package/dist/execution-resolver.d.ts.map +1 -1
  34. package/dist/execution-resolver.js +73 -107
  35. package/dist/execution-resolver.js.map +1 -1
  36. package/dist/harness/index.d.ts +1 -1
  37. package/dist/harness/index.d.ts.map +1 -1
  38. package/dist/harness/index.js.map +1 -1
  39. package/dist/harness/runner.d.ts +9 -6
  40. package/dist/harness/runner.d.ts.map +1 -1
  41. package/dist/harness/runner.js +42 -20
  42. package/dist/harness/runner.js.map +1 -1
  43. package/dist/harness/subagent-runner.d.ts +14 -13
  44. package/dist/harness/subagent-runner.d.ts.map +1 -1
  45. package/dist/harness/subagent-runner.js +116 -24
  46. package/dist/harness/subagent-runner.js.map +1 -1
  47. package/dist/harness/types.d.ts +14 -0
  48. package/dist/harness/types.d.ts.map +1 -1
  49. package/dist/harness/types.js.map +1 -1
  50. package/dist/harness/usage.d.ts +6 -0
  51. package/dist/harness/usage.d.ts.map +1 -0
  52. package/dist/harness/usage.js +32 -0
  53. package/dist/harness/usage.js.map +1 -0
  54. package/dist/index.d.ts +3 -2
  55. package/dist/index.d.ts.map +1 -1
  56. package/dist/index.js +1 -1
  57. package/dist/index.js.map +1 -1
  58. package/dist/main.js +19 -87
  59. package/dist/main.js.map +1 -1
  60. package/dist/runtime/conversation-runtime.d.ts.map +1 -1
  61. package/dist/runtime/conversation-runtime.js +23 -79
  62. package/dist/runtime/conversation-runtime.js.map +1 -1
  63. package/dist/runtime/session-lifecycle.d.ts +19 -0
  64. package/dist/runtime/session-lifecycle.d.ts.map +1 -0
  65. package/dist/runtime/session-lifecycle.js +76 -0
  66. package/dist/runtime/session-lifecycle.js.map +1 -0
  67. package/dist/runtime/types.d.ts +5 -0
  68. package/dist/runtime/types.d.ts.map +1 -1
  69. package/dist/runtime/types.js.map +1 -1
  70. package/dist/sandbox/agent-sandbox.d.ts +18 -0
  71. package/dist/sandbox/agent-sandbox.d.ts.map +1 -0
  72. package/dist/sandbox/agent-sandbox.js +234 -0
  73. package/dist/sandbox/agent-sandbox.js.map +1 -0
  74. package/dist/sandbox/cloudflare.d.ts.map +1 -1
  75. package/dist/sandbox/cloudflare.js +1 -0
  76. package/dist/sandbox/cloudflare.js.map +1 -1
  77. package/dist/sandbox/container.d.ts.map +1 -1
  78. package/dist/sandbox/container.js +1 -0
  79. package/dist/sandbox/container.js.map +1 -1
  80. package/dist/sandbox/host.d.ts.map +1 -1
  81. package/dist/sandbox/host.js +1 -0
  82. package/dist/sandbox/host.js.map +1 -1
  83. package/dist/sandbox/identity.d.ts +11 -16
  84. package/dist/sandbox/identity.d.ts.map +1 -1
  85. package/dist/sandbox/identity.js +32 -26
  86. package/dist/sandbox/identity.js.map +1 -1
  87. package/dist/sandbox/image.d.ts.map +1 -1
  88. package/dist/sandbox/image.js +1 -0
  89. package/dist/sandbox/image.js.map +1 -1
  90. package/dist/sandbox/index.d.ts +7 -7
  91. package/dist/sandbox/index.d.ts.map +1 -1
  92. package/dist/sandbox/index.js +13 -9
  93. package/dist/sandbox/index.js.map +1 -1
  94. package/dist/sandbox/types.d.ts +17 -16
  95. package/dist/sandbox/types.d.ts.map +1 -1
  96. package/dist/sandbox/types.js.map +1 -1
  97. package/dist/sessions/session-key.d.ts +9 -0
  98. package/dist/sessions/session-key.d.ts.map +1 -1
  99. package/dist/sessions/session-key.js +50 -2
  100. package/dist/sessions/session-key.js.map +1 -1
  101. package/dist/sessions/store.d.ts.map +1 -1
  102. package/dist/sessions/store.js +36 -8
  103. package/dist/sessions/store.js.map +1 -1
  104. package/dist/tools/sandbox.d.ts.map +1 -1
  105. package/dist/tools/sandbox.js +4 -5
  106. package/dist/tools/sandbox.js.map +1 -1
  107. package/dist/tools/subagent-slots.d.ts +3 -3
  108. package/dist/tools/subagent-slots.d.ts.map +1 -1
  109. package/dist/tools/subagent-slots.js +25 -10
  110. package/dist/tools/subagent-slots.js.map +1 -1
  111. package/dist/tools/subagent.d.ts +13 -2
  112. package/dist/tools/subagent.d.ts.map +1 -1
  113. package/dist/tools/subagent.js +16 -16
  114. package/dist/tools/subagent.js.map +1 -1
  115. package/dist/types.d.ts +14 -63
  116. package/dist/types.d.ts.map +1 -1
  117. package/dist/types.js.map +1 -1
  118. package/dist/vault/injection.d.ts +4 -14
  119. package/dist/vault/injection.d.ts.map +1 -1
  120. package/dist/vault/injection.js +5 -2
  121. package/dist/vault/injection.js.map +1 -1
  122. package/dist/vault/policy.d.ts +3 -3
  123. package/dist/vault/policy.d.ts.map +1 -1
  124. package/dist/vault/policy.js +6 -4
  125. package/dist/vault/policy.js.map +1 -1
  126. package/dist/vault/types.d.ts +4 -0
  127. package/dist/vault/types.d.ts.map +1 -1
  128. package/dist/vault/types.js.map +1 -1
  129. package/dist/web/admin/portal.js +2 -2
  130. package/dist/web/admin/portal.js.map +1 -1
  131. package/dist/workspace-projection/index.d.ts +5 -0
  132. package/dist/workspace-projection/index.d.ts.map +1 -0
  133. package/dist/workspace-projection/index.js +71 -0
  134. package/dist/workspace-projection/index.js.map +1 -0
  135. package/dist/workspace-projection/types.d.ts +7 -0
  136. package/dist/workspace-projection/types.d.ts.map +1 -0
  137. package/dist/workspace-projection/types.js +2 -0
  138. package/dist/workspace-projection/types.js.map +1 -0
  139. package/package.json +3 -3
  140. package/dist/sandbox/firecracker.d.ts +0 -18
  141. package/dist/sandbox/firecracker.d.ts.map +0 -1
  142. package/dist/sandbox/firecracker.js +0 -221
  143. package/dist/sandbox/firecracker.js.map +0 -1
  144. package/dist/sandbox/gondolin-bootstrap.d.ts +0 -26
  145. package/dist/sandbox/gondolin-bootstrap.d.ts.map +0 -1
  146. package/dist/sandbox/gondolin-bootstrap.js +0 -27
  147. package/dist/sandbox/gondolin-bootstrap.js.map +0 -1
  148. package/dist/sandbox/gondolin-contract.d.ts +0 -125
  149. package/dist/sandbox/gondolin-contract.d.ts.map +0 -1
  150. package/dist/sandbox/gondolin-contract.js +0 -155
  151. package/dist/sandbox/gondolin-contract.js.map +0 -1
  152. package/dist/sandbox/gondolin-fleet.d.ts +0 -104
  153. package/dist/sandbox/gondolin-fleet.d.ts.map +0 -1
  154. package/dist/sandbox/gondolin-fleet.js +0 -330
  155. package/dist/sandbox/gondolin-fleet.js.map +0 -1
  156. package/dist/sandbox/gondolin-gateway.d.ts +0 -86
  157. package/dist/sandbox/gondolin-gateway.d.ts.map +0 -1
  158. package/dist/sandbox/gondolin-gateway.js +0 -407
  159. package/dist/sandbox/gondolin-gateway.js.map +0 -1
  160. package/dist/sandbox/gondolin-inventory.d.ts +0 -75
  161. package/dist/sandbox/gondolin-inventory.d.ts.map +0 -1
  162. package/dist/sandbox/gondolin-inventory.js +0 -257
  163. package/dist/sandbox/gondolin-inventory.js.map +0 -1
  164. package/dist/sandbox/gondolin-join.d.ts +0 -62
  165. package/dist/sandbox/gondolin-join.d.ts.map +0 -1
  166. package/dist/sandbox/gondolin-join.js +0 -261
  167. package/dist/sandbox/gondolin-join.js.map +0 -1
  168. package/dist/sandbox/gondolin-nfs-advisory.d.ts +0 -15
  169. package/dist/sandbox/gondolin-nfs-advisory.d.ts.map +0 -1
  170. package/dist/sandbox/gondolin-nfs-advisory.js +0 -60
  171. package/dist/sandbox/gondolin-nfs-advisory.js.map +0 -1
  172. package/dist/sandbox/gondolin-placement.d.ts +0 -30
  173. package/dist/sandbox/gondolin-placement.d.ts.map +0 -1
  174. package/dist/sandbox/gondolin-placement.js +0 -77
  175. package/dist/sandbox/gondolin-placement.js.map +0 -1
  176. package/dist/sandbox/gondolin-recovery.d.ts +0 -33
  177. package/dist/sandbox/gondolin-recovery.d.ts.map +0 -1
  178. package/dist/sandbox/gondolin-recovery.js +0 -39
  179. package/dist/sandbox/gondolin-recovery.js.map +0 -1
  180. package/dist/sandbox/gondolin-remote.d.ts +0 -70
  181. package/dist/sandbox/gondolin-remote.d.ts.map +0 -1
  182. package/dist/sandbox/gondolin-remote.js +0 -325
  183. package/dist/sandbox/gondolin-remote.js.map +0 -1
  184. package/dist/sandbox/gondolin-worker-client.d.ts +0 -135
  185. package/dist/sandbox/gondolin-worker-client.d.ts.map +0 -1
  186. package/dist/sandbox/gondolin-worker-client.js +0 -323
  187. package/dist/sandbox/gondolin-worker-client.js.map +0 -1
  188. package/dist/sandbox/gondolin-worker-main.d.ts +0 -2
  189. package/dist/sandbox/gondolin-worker-main.d.ts.map +0 -1
  190. package/dist/sandbox/gondolin-worker-main.js +0 -22
  191. package/dist/sandbox/gondolin-worker-main.js.map +0 -1
  192. package/dist/sandbox/gondolin-worker.d.ts +0 -17
  193. package/dist/sandbox/gondolin-worker.d.ts.map +0 -1
  194. package/dist/sandbox/gondolin-worker.js +0 -201
  195. package/dist/sandbox/gondolin-worker.js.map +0 -1
  196. package/dist/sandbox/gondolin.d.ts +0 -53
  197. package/dist/sandbox/gondolin.d.ts.map +0 -1
  198. package/dist/sandbox/gondolin.js +0 -429
  199. package/dist/sandbox/gondolin.js.map +0 -1
@@ -0,0 +1,5 @@
1
+ import type { ImageWorkspaceMountMode } from "../types.js";
2
+ import type { WorkspaceProjection } from "./types.js";
3
+ export declare function resolveWorkspaceProjection(hostWorkspaceRoot: string | undefined, conversationId: string): WorkspaceProjection;
4
+ export declare function readWorkspaceProjectionMode(hostWorkspaceRoot: string | undefined, conversationId: string): ImageWorkspaceMountMode;
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/workspace-projection/index.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAC3D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEtD,wBAAgB,0BAA0B,CACxC,iBAAiB,EAAE,MAAM,GAAG,SAAS,EACrC,cAAc,EAAE,MAAM,GACrB,mBAAmB,CAsBrB;AAED,wBAAgB,2BAA2B,CACzC,iBAAiB,EAAE,MAAM,GAAG,SAAS,EACrC,cAAc,EAAE,MAAM,GACrB,uBAAuB,CAiBzB"}
@@ -0,0 +1,71 @@
1
+ import { join } from "node:path";
2
+ import { ensureDirExists, isRecord, readJsonFileIfExists } from "../utils/file-guards.js";
3
+ import { conversationSettingsPath, loadGlobalSettings, resolveConversationSettings, } from "../config.js";
4
+ import * as log from "../log.js";
5
+ export function resolveWorkspaceProjection(hostWorkspaceRoot, conversationId) {
6
+ assertConversationPathSegment(conversationId);
7
+ const mode = readWorkspaceProjectionMode(hostWorkspaceRoot, conversationId);
8
+ if (!hostWorkspaceRoot)
9
+ return { mode, mounts: [] };
10
+ if (mode === "full") {
11
+ return {
12
+ mode,
13
+ mounts: [{ source: hostWorkspaceRoot, target: "/workspace" }],
14
+ };
15
+ }
16
+ const conversationDir = join(hostWorkspaceRoot, conversationId);
17
+ ensureDirExists(conversationDir);
18
+ return {
19
+ mode,
20
+ mounts: [
21
+ { source: join(hostWorkspaceRoot, "MEMORY.md"), target: "/workspace/MEMORY.md" },
22
+ { source: join(hostWorkspaceRoot, "skills"), target: "/workspace/skills" },
23
+ { source: join(hostWorkspaceRoot, "events"), target: "/workspace/events" },
24
+ { source: conversationDir, target: `/workspace/${conversationId}` },
25
+ ],
26
+ };
27
+ }
28
+ export function readWorkspaceProjectionMode(hostWorkspaceRoot, conversationId) {
29
+ assertConversationPathSegment(conversationId);
30
+ const globalDefault = readGlobalMode();
31
+ if (!hostWorkspaceRoot)
32
+ return globalDefault;
33
+ const conversationDir = join(hostWorkspaceRoot, conversationId);
34
+ try {
35
+ return (resolveConversationSettings(conversationDir).sandbox?.image?.workspaceMount ?? globalDefault);
36
+ }
37
+ catch (err) {
38
+ log.logWarning("Falling back while resolving conversation workspace projection", err instanceof Error ? err.message : String(err));
39
+ return readFallback(conversationSettingsPath(conversationDir)) ?? globalDefault;
40
+ }
41
+ }
42
+ function assertConversationPathSegment(conversationId) {
43
+ if (conversationId.length === 0 ||
44
+ conversationId === "." ||
45
+ conversationId === ".." ||
46
+ conversationId.includes("/") ||
47
+ conversationId.includes("\\") ||
48
+ conversationId.includes("\0")) {
49
+ throw new Error("Conversation id must be a safe path segment");
50
+ }
51
+ }
52
+ function readGlobalMode() {
53
+ try {
54
+ return loadGlobalSettings().sandbox?.image?.workspaceMount ?? "private";
55
+ }
56
+ catch (err) {
57
+ log.logWarning("Using default workspace projection because global settings could not be read", err instanceof Error ? err.message : String(err));
58
+ return "private";
59
+ }
60
+ }
61
+ function readFallback(settingsPath) {
62
+ try {
63
+ const raw = readJsonFileIfExists(settingsPath, (value) => isRecord(value), () => "Ignoring malformed conversation settings while resolving workspace projection");
64
+ return raw?.sandbox?.image?.workspaceMount;
65
+ }
66
+ catch (err) {
67
+ log.logWarning("Ignoring malformed conversation settings fallback while resolving workspace projection", err instanceof Error ? err.message : String(err));
68
+ return undefined;
69
+ }
70
+ }
71
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/workspace-projection/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { join } from \"node:path\";\nimport { ensureDirExists, isRecord, readJsonFileIfExists } from \"../utils/file-guards.js\";\nimport {\n conversationSettingsPath,\n loadGlobalSettings,\n resolveConversationSettings,\n} from \"../config.js\";\nimport * as log from \"../log.js\";\nimport type { ImageWorkspaceMountMode } from \"../types.js\";\nimport type { WorkspaceProjection } from \"./types.js\";\n\nexport function resolveWorkspaceProjection(\n hostWorkspaceRoot: string | undefined,\n conversationId: string,\n): WorkspaceProjection {\n assertConversationPathSegment(conversationId);\n const mode = readWorkspaceProjectionMode(hostWorkspaceRoot, conversationId);\n if (!hostWorkspaceRoot) return { mode, mounts: [] };\n if (mode === \"full\") {\n return {\n mode,\n mounts: [{ source: hostWorkspaceRoot, target: \"/workspace\" }],\n };\n }\n\n const conversationDir = join(hostWorkspaceRoot, conversationId);\n ensureDirExists(conversationDir);\n return {\n mode,\n mounts: [\n { source: join(hostWorkspaceRoot, \"MEMORY.md\"), target: \"/workspace/MEMORY.md\" },\n { source: join(hostWorkspaceRoot, \"skills\"), target: \"/workspace/skills\" },\n { source: join(hostWorkspaceRoot, \"events\"), target: \"/workspace/events\" },\n { source: conversationDir, target: `/workspace/${conversationId}` },\n ],\n };\n}\n\nexport function readWorkspaceProjectionMode(\n hostWorkspaceRoot: string | undefined,\n conversationId: string,\n): ImageWorkspaceMountMode {\n assertConversationPathSegment(conversationId);\n const globalDefault = readGlobalMode();\n if (!hostWorkspaceRoot) return globalDefault;\n\n const conversationDir = join(hostWorkspaceRoot, 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 projection\",\n err instanceof Error ? err.message : String(err),\n );\n return readFallback(conversationSettingsPath(conversationDir)) ?? globalDefault;\n }\n}\n\nfunction assertConversationPathSegment(conversationId: string): void {\n if (\n conversationId.length === 0 ||\n conversationId === \".\" ||\n conversationId === \"..\" ||\n conversationId.includes(\"/\") ||\n conversationId.includes(\"\\\\\") ||\n conversationId.includes(\"\\0\")\n ) {\n throw new Error(\"Conversation id must be a safe path segment\");\n }\n}\n\nfunction readGlobalMode(): ImageWorkspaceMountMode {\n try {\n return loadGlobalSettings().sandbox?.image?.workspaceMount ?? \"private\";\n } catch (err) {\n log.logWarning(\n \"Using default workspace projection because global settings could not be read\",\n err instanceof Error ? err.message : String(err),\n );\n return \"private\";\n }\n}\n\nfunction readFallback(settingsPath: string): ImageWorkspaceMountMode | undefined {\n try {\n const raw = readJsonFileIfExists(\n settingsPath,\n (value): value is { sandbox?: { image?: { workspaceMount?: ImageWorkspaceMountMode } } } =>\n isRecord(value),\n () => \"Ignoring malformed conversation settings while resolving workspace projection\",\n );\n return raw?.sandbox?.image?.workspaceMount;\n } catch (err) {\n log.logWarning(\n \"Ignoring malformed conversation settings fallback while resolving workspace projection\",\n err instanceof Error ? err.message : String(err),\n );\n return undefined;\n }\n}\n"]}
@@ -0,0 +1,7 @@
1
+ import type { ContainerMount } from "../types.js";
2
+ import type { ImageWorkspaceMountMode } from "../types.js";
3
+ export interface WorkspaceProjection {
4
+ mode: ImageWorkspaceMountMode;
5
+ mounts: ContainerMount[];
6
+ }
7
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/workspace-projection/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAE3D,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,uBAAuB,CAAC;IAC9B,MAAM,EAAE,cAAc,EAAE,CAAC;CAC1B"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/workspace-projection/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { ContainerMount } from \"../types.js\";\nimport type { ImageWorkspaceMountMode } from \"../types.js\";\n\nexport interface WorkspaceProjection {\n mode: ImageWorkspaceMountMode;\n mounts: ContainerMount[];\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@geminixiang/mikan",
3
- "version": "1.0.0-beta.21",
3
+ "version": "1.0.0-beta.23",
4
4
  "description": "Multi-platform AI coding agent for Slack, Telegram, and Discord",
5
5
  "keywords": [
6
6
  "agent",
@@ -43,19 +43,19 @@
43
43
  "test:e2e": "vitest --run --config vitest.e2e.config.ts",
44
44
  "test:e2e:slack": "vitest --run --config vitest.e2e.config.ts e2e/slack",
45
45
  "test:e2e:slack:coverage": "vitest --run --coverage --coverage.reportsDirectory=.workspace/coverage --config vitest.e2e.config.ts e2e/slack",
46
- "gondolin:image:build": "sh scripts/build-gondolin-image.sh",
47
46
  "docs:dev": "astro dev",
48
47
  "docs:build": "astro build",
49
48
  "docs:preview": "astro preview"
50
49
  },
51
50
  "dependencies": {
52
- "@earendil-works/gondolin": "0.12.0",
53
51
  "@earendil-works/pi-agent-core": "^0.80.6",
54
52
  "@earendil-works/pi-ai": "^0.80.6",
53
+ "@kubernetes/client-node": "^1.0.0",
55
54
  "@sentry/node": "^10.60.0",
56
55
  "@sinclair/typebox": "^0.34.49",
57
56
  "@slack/socket-mode": "^2.0.7",
58
57
  "@slack/web-api": "^7.17.0",
58
+ "agentic-sandbox-client": "file:vendor/agent-sandbox-sdk/agentic-sandbox-client-0.1.0.tgz",
59
59
  "chalk": "^5.6.2",
60
60
  "croner": "^10.0.1",
61
61
  "diff": "^9.0.0",
@@ -1,18 +0,0 @@
1
- import type { ExecOptions, ExecResult, Executor, FirecrackerSandboxConfig, RuntimePathContext, SandboxAdapter } from "./types.js";
2
- export declare class FirecrackerExecutor implements Executor {
3
- private vmId;
4
- private hostPath;
5
- private sshUser;
6
- private sshPort;
7
- private env?;
8
- constructor(vmId: string, hostPath: string, sshUser?: string, sshPort?: number, env?: Record<string, string> | undefined);
9
- exec(command: string, options?: ExecOptions): Promise<ExecResult>;
10
- readFile(path: string, options?: ExecOptions): Promise<string>;
11
- readFileBase64(path: string, options?: ExecOptions): Promise<string>;
12
- writeFile(path: string, content: string, options?: ExecOptions): Promise<void>;
13
- getWorkspacePath(_hostPath: string): string;
14
- getPathContext(hostWorkspaceRoot: string): RuntimePathContext;
15
- getSandboxConfig(): FirecrackerSandboxConfig;
16
- }
17
- export declare const firecrackerSandboxAdapter: SandboxAdapter<FirecrackerSandboxConfig>;
18
- //# sourceMappingURL=firecracker.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"firecracker.d.ts","sourceRoot":"","sources":["../../src/sandbox/firecracker.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,WAAW,EACX,UAAU,EACV,QAAQ,EACR,wBAAwB,EACxB,kBAAkB,EAClB,cAAc,EACf,MAAM,YAAY,CAAC;AA2FpB,qBAAa,mBAAoB,YAAW,QAAQ;IAEhD,OAAO,CAAC,IAAI;IACZ,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,GAAG,CAAC;IALd,YACU,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,MAAe,EACxB,OAAO,GAAE,MAAW,EACpB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,YAAA,EAClC;IAEE,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,CAqGtE;IAED,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAE7D;IAED,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAEnE;IAED,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAE7E;IAED,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAE1C;IAED,cAAc,CAAC,iBAAiB,EAAE,MAAM,GAAG,kBAAkB,CAK5D;IAED,gBAAgB,IAAI,wBAAwB,CAQ3C;CACF;AAgBD,eAAO,MAAM,yBAAyB,EAAE,cAAc,CAAC,wBAAwB,CAM9E,CAAC"}
@@ -1,221 +0,0 @@
1
- import { spawn } from "child_process";
2
- import { SandboxError } from "./errors.js";
3
- import { HostExecutor } from "./host.js";
4
- import { execReadFile, execReadFileBase64, execWriteFile, execSimple, killProcessTree, shellEscape, } from "./utils.js";
5
- function parseFirecrackerSandboxArg(value) {
6
- if (!value.startsWith("firecracker:")) {
7
- return undefined;
8
- }
9
- const arg = value.slice("firecracker:".length);
10
- // Format: firecracker:<vm-id>:<host-path>[:<ssh-user>[:<ssh-port>]]
11
- // Example: firecracker:vm1:/home/user/workspace
12
- // firecracker:vm1:/home/user/workspace:root
13
- // firecracker:vm1:/home/user/workspace:root:22
14
- const parts = arg.split(":");
15
- if (parts.length < 2) {
16
- throw new SandboxError("Error: firecracker sandbox requires vm-id and host-path\n" +
17
- "Usage: firecracker:<vm-id>:<host-path>[:<ssh-user>[:<ssh-port>]]\n" +
18
- "Example: firecracker:vm1:/home/user/workspace");
19
- }
20
- const vmId = parts[0];
21
- const hostPath = parts[1];
22
- const sshUser = parts[2] || "root";
23
- const sshPort = parts[3] ? parseInt(parts[3], 10) : 22;
24
- if (!vmId || !hostPath) {
25
- throw new SandboxError("Error: firecracker sandbox requires vm-id and host-path");
26
- }
27
- if (isNaN(sshPort) || sshPort <= 0 || sshPort > 65535) {
28
- throw new SandboxError("Error: invalid SSH port");
29
- }
30
- return { type: "firecracker", vmId, hostPath, sshUser, sshPort };
31
- }
32
- async function validateFirecrackerSandbox(config) {
33
- // Check if fc-agent or firecracker CLI is available
34
- try {
35
- await execSimple("fc-agent", ["--version"]);
36
- }
37
- catch {
38
- // Try alternative: firecracker
39
- try {
40
- await execSimple("firecracker", ["--version"]);
41
- }
42
- catch {
43
- throw new SandboxError("Error: Firecracker tools (fc-agent or firecracker) not found in PATH", ["Install firecracker: https://github.com/firecracker-microvm/firecracker"]);
44
- }
45
- }
46
- // Check if VM is running using fc-agent
47
- try {
48
- const result = await execSimple("fc-agent", ["status", config.vmId]);
49
- if (!result.includes("running") && !result.includes("Running")) {
50
- throw new SandboxError(`Error: Firecracker VM '${config.vmId}' is not running.`, [
51
- `Start it with: fc-agent start ${config.vmId}`,
52
- ]);
53
- }
54
- }
55
- catch (error) {
56
- if (error instanceof SandboxError) {
57
- throw error;
58
- }
59
- // Try alternative: firecracker-ctl or direct check
60
- try {
61
- await execSimple("firecracker-ctl", ["status", config.vmId]);
62
- }
63
- catch {
64
- console.error(`Warning: Could not verify if VM '${config.vmId}' is running.`);
65
- console.error("Make sure the VM is started before running mikan.");
66
- }
67
- }
68
- // Verify host path exists
69
- try {
70
- await execSimple("ls", ["-d", config.hostPath]);
71
- }
72
- catch {
73
- throw new SandboxError(`Error: Host path '${config.hostPath}' does not exist.`);
74
- }
75
- console.log(` Firecracker VM '${config.vmId}' configured with workspace '${config.hostPath}'.`);
76
- }
77
- export class FirecrackerExecutor {
78
- constructor(vmId, hostPath, sshUser = "root", sshPort = 22, env) {
79
- this.vmId = vmId;
80
- this.hostPath = hostPath;
81
- this.sshUser = sshUser;
82
- this.sshPort = sshPort;
83
- this.env = env;
84
- }
85
- async exec(command, options) {
86
- if (!this.env || Object.keys(this.env).length === 0) {
87
- const sshCmd = this.sshPort === 22
88
- ? `ssh -o StrictHostKeyChecking=no -o ConnectTimeout=10 ${this.sshUser}@${this.vmId} sh -c ${shellEscape(command)}`
89
- : `ssh -o StrictHostKeyChecking=no -o ConnectTimeout=10 -p ${this.sshPort} ${this.sshUser}@${this.vmId} sh -c ${shellEscape(command)}`;
90
- const hostExecutor = new HostExecutor();
91
- return hostExecutor.exec(sshCmd, options);
92
- }
93
- return new Promise((resolve, reject) => {
94
- const sshArgs = ["-o", "StrictHostKeyChecking=no", "-o", "ConnectTimeout=10"];
95
- if (this.sshPort !== 22) {
96
- sshArgs.push("-p", String(this.sshPort));
97
- }
98
- sshArgs.push(`${this.sshUser}@${this.vmId}`, "sh", "-se");
99
- const child = spawn("ssh", sshArgs, {
100
- detached: true,
101
- stdio: ["pipe", "pipe", "pipe"],
102
- });
103
- let stdout = "";
104
- let stderr = "";
105
- let timedOut = false;
106
- let settled = false;
107
- const timeoutHandle = options?.timeout && options.timeout > 0
108
- ? setTimeout(() => {
109
- timedOut = true;
110
- if (child.pid)
111
- killProcessTree(child.pid);
112
- }, options.timeout * 1000)
113
- : undefined;
114
- const onAbort = () => {
115
- if (child.pid)
116
- killProcessTree(child.pid);
117
- };
118
- if (options?.signal) {
119
- if (options.signal.aborted) {
120
- onAbort();
121
- }
122
- else {
123
- options.signal.addEventListener("abort", onAbort, { once: true });
124
- }
125
- }
126
- child.on("error", (error) => {
127
- if (settled)
128
- return;
129
- settled = true;
130
- if (timeoutHandle)
131
- clearTimeout(timeoutHandle);
132
- if (options?.signal) {
133
- options.signal.removeEventListener("abort", onAbort);
134
- }
135
- reject(error);
136
- });
137
- child.stdout?.on("data", (data) => {
138
- stdout += data.toString();
139
- if (stdout.length > 10 * 1024 * 1024) {
140
- stdout = stdout.slice(0, 10 * 1024 * 1024);
141
- }
142
- });
143
- child.stderr?.on("data", (data) => {
144
- stderr += data.toString();
145
- if (stderr.length > 10 * 1024 * 1024) {
146
- stderr = stderr.slice(0, 10 * 1024 * 1024);
147
- }
148
- });
149
- child.stdin?.on("error", (error) => {
150
- stderr += `${error.message}\n`;
151
- });
152
- child.stdin?.end(buildRemoteScript(command, this.env));
153
- child.on("close", (code) => {
154
- if (settled)
155
- return;
156
- settled = true;
157
- if (timeoutHandle)
158
- clearTimeout(timeoutHandle);
159
- if (options?.signal) {
160
- options.signal.removeEventListener("abort", onAbort);
161
- }
162
- if (options?.signal?.aborted) {
163
- reject(new Error(`${stdout}\n${stderr}\nCommand aborted`.trim()));
164
- return;
165
- }
166
- if (timedOut) {
167
- reject(new Error(`${stdout}\n${stderr}\nCommand timed out after ${options?.timeout} seconds`.trim()));
168
- return;
169
- }
170
- resolve({ stdout, stderr, code: code ?? 0 });
171
- });
172
- });
173
- }
174
- readFile(path, options) {
175
- return execReadFile(this, path, options);
176
- }
177
- readFileBase64(path, options) {
178
- return execReadFileBase64(this, path, options);
179
- }
180
- writeFile(path, content, options) {
181
- return execWriteFile(this, path, content, options);
182
- }
183
- getWorkspacePath(_hostPath) {
184
- return "/workspace";
185
- }
186
- getPathContext(hostWorkspaceRoot) {
187
- return {
188
- hostWorkspaceRoot,
189
- runtimeWorkspaceRoot: "/workspace",
190
- };
191
- }
192
- getSandboxConfig() {
193
- return {
194
- type: "firecracker",
195
- vmId: this.vmId,
196
- hostPath: this.hostPath,
197
- sshUser: this.sshUser,
198
- sshPort: this.sshPort,
199
- };
200
- }
201
- }
202
- function buildRemoteScript(command, env) {
203
- const exports = env
204
- ? Object.entries(env)
205
- .map(([key, value]) => {
206
- if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(key)) {
207
- throw new SandboxError(`Invalid environment variable name for firecracker: ${key}`);
208
- }
209
- return `export ${key}=${shellEscape(value)}`;
210
- })
211
- .join("\n") + "\n"
212
- : "";
213
- return `${exports}${command}\n`;
214
- }
215
- export const firecrackerSandboxAdapter = {
216
- type: "firecracker",
217
- parse: parseFirecrackerSandboxArg,
218
- validate: validateFirecrackerSandbox,
219
- createExecutor: (config, env) => new FirecrackerExecutor(config.vmId, config.hostPath, config.sshUser, config.sshPort, env),
220
- };
221
- //# sourceMappingURL=firecracker.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"firecracker.js","sourceRoot":"","sources":["../../src/sandbox/firecracker.ts"],"names":[],"mappings":"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","sourcesContent":["import { spawn } from \"child_process\";\nimport type {\n ExecOptions,\n ExecResult,\n Executor,\n FirecrackerSandboxConfig,\n RuntimePathContext,\n SandboxAdapter,\n} from \"./types.js\";\nimport { SandboxError } from \"./errors.js\";\nimport { HostExecutor } from \"./host.js\";\nimport {\n execReadFile,\n execReadFileBase64,\n execWriteFile,\n execSimple,\n killProcessTree,\n shellEscape,\n} from \"./utils.js\";\n\nfunction parseFirecrackerSandboxArg(value: string): FirecrackerSandboxConfig | undefined {\n if (!value.startsWith(\"firecracker:\")) {\n return undefined;\n }\n\n const arg = value.slice(\"firecracker:\".length);\n // Format: firecracker:<vm-id>:<host-path>[:<ssh-user>[:<ssh-port>]]\n // Example: firecracker:vm1:/home/user/workspace\n // firecracker:vm1:/home/user/workspace:root\n // firecracker:vm1:/home/user/workspace:root:22\n const parts = arg.split(\":\");\n if (parts.length < 2) {\n throw new SandboxError(\n \"Error: firecracker sandbox requires vm-id and host-path\\n\" +\n \"Usage: firecracker:<vm-id>:<host-path>[:<ssh-user>[:<ssh-port>]]\\n\" +\n \"Example: firecracker:vm1:/home/user/workspace\",\n );\n }\n const vmId = parts[0];\n const hostPath = parts[1];\n const sshUser = parts[2] || \"root\";\n const sshPort = parts[3] ? parseInt(parts[3], 10) : 22;\n\n if (!vmId || !hostPath) {\n throw new SandboxError(\"Error: firecracker sandbox requires vm-id and host-path\");\n }\n if (isNaN(sshPort) || sshPort <= 0 || sshPort > 65535) {\n throw new SandboxError(\"Error: invalid SSH port\");\n }\n return { type: \"firecracker\", vmId, hostPath, sshUser, sshPort };\n}\n\nasync function validateFirecrackerSandbox(config: FirecrackerSandboxConfig): Promise<void> {\n // Check if fc-agent or firecracker CLI is available\n try {\n await execSimple(\"fc-agent\", [\"--version\"]);\n } catch {\n // Try alternative: firecracker\n try {\n await execSimple(\"firecracker\", [\"--version\"]);\n } catch {\n throw new SandboxError(\n \"Error: Firecracker tools (fc-agent or firecracker) not found in PATH\",\n [\"Install firecracker: https://github.com/firecracker-microvm/firecracker\"],\n );\n }\n }\n\n // Check if VM is running using fc-agent\n try {\n const result = await execSimple(\"fc-agent\", [\"status\", config.vmId]);\n if (!result.includes(\"running\") && !result.includes(\"Running\")) {\n throw new SandboxError(`Error: Firecracker VM '${config.vmId}' is not running.`, [\n `Start it with: fc-agent start ${config.vmId}`,\n ]);\n }\n } catch (error) {\n if (error instanceof SandboxError) {\n throw error;\n }\n // Try alternative: firecracker-ctl or direct check\n try {\n await execSimple(\"firecracker-ctl\", [\"status\", config.vmId]);\n } catch {\n console.error(`Warning: Could not verify if VM '${config.vmId}' is running.`);\n console.error(\"Make sure the VM is started before running mikan.\");\n }\n }\n\n // Verify host path exists\n try {\n await execSimple(\"ls\", [\"-d\", config.hostPath]);\n } catch {\n throw new SandboxError(`Error: Host path '${config.hostPath}' does not exist.`);\n }\n\n console.log(` Firecracker VM '${config.vmId}' configured with workspace '${config.hostPath}'.`);\n}\n\nexport class FirecrackerExecutor implements Executor {\n constructor(\n private vmId: string,\n private hostPath: string,\n private sshUser: string = \"root\",\n private sshPort: number = 22,\n private env?: Record<string, string>,\n ) {}\n\n async exec(command: string, options?: ExecOptions): Promise<ExecResult> {\n if (!this.env || Object.keys(this.env).length === 0) {\n const sshCmd =\n this.sshPort === 22\n ? `ssh -o StrictHostKeyChecking=no -o ConnectTimeout=10 ${this.sshUser}@${this.vmId} sh -c ${shellEscape(command)}`\n : `ssh -o StrictHostKeyChecking=no -o ConnectTimeout=10 -p ${this.sshPort} ${this.sshUser}@${this.vmId} sh -c ${shellEscape(command)}`;\n const hostExecutor = new HostExecutor();\n return hostExecutor.exec(sshCmd, options);\n }\n\n return new Promise((resolve, reject) => {\n const sshArgs = [\"-o\", \"StrictHostKeyChecking=no\", \"-o\", \"ConnectTimeout=10\"];\n if (this.sshPort !== 22) {\n sshArgs.push(\"-p\", String(this.sshPort));\n }\n sshArgs.push(`${this.sshUser}@${this.vmId}`, \"sh\", \"-se\");\n\n const child = spawn(\"ssh\", sshArgs, {\n detached: true,\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n });\n\n let stdout = \"\";\n let stderr = \"\";\n let timedOut = false;\n let settled = false;\n\n const timeoutHandle =\n options?.timeout && options.timeout > 0\n ? setTimeout(() => {\n timedOut = true;\n if (child.pid) killProcessTree(child.pid);\n }, options.timeout * 1000)\n : undefined;\n\n const onAbort = () => {\n if (child.pid) killProcessTree(child.pid);\n };\n\n if (options?.signal) {\n if (options.signal.aborted) {\n onAbort();\n } else {\n options.signal.addEventListener(\"abort\", onAbort, { once: true });\n }\n }\n\n child.on(\"error\", (error) => {\n if (settled) return;\n settled = true;\n if (timeoutHandle) clearTimeout(timeoutHandle);\n if (options?.signal) {\n options.signal.removeEventListener(\"abort\", onAbort);\n }\n reject(error);\n });\n\n child.stdout?.on(\"data\", (data) => {\n stdout += data.toString();\n if (stdout.length > 10 * 1024 * 1024) {\n stdout = stdout.slice(0, 10 * 1024 * 1024);\n }\n });\n\n child.stderr?.on(\"data\", (data) => {\n stderr += data.toString();\n if (stderr.length > 10 * 1024 * 1024) {\n stderr = stderr.slice(0, 10 * 1024 * 1024);\n }\n });\n\n child.stdin?.on(\"error\", (error) => {\n stderr += `${error.message}\\n`;\n });\n child.stdin?.end(buildRemoteScript(command, this.env));\n\n child.on(\"close\", (code) => {\n if (settled) return;\n settled = true;\n if (timeoutHandle) clearTimeout(timeoutHandle);\n if (options?.signal) {\n options.signal.removeEventListener(\"abort\", onAbort);\n }\n\n if (options?.signal?.aborted) {\n reject(new Error(`${stdout}\\n${stderr}\\nCommand aborted`.trim()));\n return;\n }\n\n if (timedOut) {\n reject(\n new Error(\n `${stdout}\\n${stderr}\\nCommand timed out after ${options?.timeout} seconds`.trim(),\n ),\n );\n return;\n }\n\n resolve({ stdout, stderr, code: code ?? 0 });\n });\n });\n }\n\n readFile(path: string, options?: ExecOptions): Promise<string> {\n return execReadFile(this, path, options);\n }\n\n readFileBase64(path: string, options?: ExecOptions): Promise<string> {\n return execReadFileBase64(this, path, options);\n }\n\n writeFile(path: string, content: string, options?: ExecOptions): Promise<void> {\n return execWriteFile(this, path, content, options);\n }\n\n getWorkspacePath(_hostPath: string): string {\n return \"/workspace\";\n }\n\n getPathContext(hostWorkspaceRoot: string): RuntimePathContext {\n return {\n hostWorkspaceRoot,\n runtimeWorkspaceRoot: \"/workspace\",\n };\n }\n\n getSandboxConfig(): FirecrackerSandboxConfig {\n return {\n type: \"firecracker\",\n vmId: this.vmId,\n hostPath: this.hostPath,\n sshUser: this.sshUser,\n sshPort: this.sshPort,\n };\n }\n}\n\nfunction buildRemoteScript(command: string, env?: Record<string, string>): string {\n const exports = env\n ? Object.entries(env)\n .map(([key, value]) => {\n if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(key)) {\n throw new SandboxError(`Invalid environment variable name for firecracker: ${key}`);\n }\n return `export ${key}=${shellEscape(value)}`;\n })\n .join(\"\\n\") + \"\\n\"\n : \"\";\n return `${exports}${command}\\n`;\n}\n\nexport const firecrackerSandboxAdapter: SandboxAdapter<FirecrackerSandboxConfig> = {\n type: \"firecracker\",\n parse: parseFirecrackerSandboxArg,\n validate: validateFirecrackerSandbox,\n createExecutor: (config, env) =>\n new FirecrackerExecutor(config.vmId, config.hostPath, config.sshUser, config.sshPort, env),\n};\n"]}
@@ -1,26 +0,0 @@
1
- import type { GondolinRemoteSettings, ResourceLimits } from "../types.js";
2
- export interface GondolinBootstrapOptions {
3
- /** Host-only state dir; inventory, placements, and gateway CA live under it. */
4
- stateDir: string;
5
- /** Default per-runtime resource limits. */
6
- limits?: ResourceLimits;
7
- /** Boosted limits applied while a runtime holds a boost. */
8
- boostLimits?: ResourceLimits;
9
- /** Remote fleet settings (workers, gateway); omit for local-only gondolin. */
10
- remote?: GondolinRemoteSettings;
11
- /**
12
- * Fail loudly when the remote profile is requested but no worker source is
13
- * configured, instead of discovering it on the first runtime ensure.
14
- */
15
- requireRemote?: boolean;
16
- }
17
- /**
18
- * Configure every gondolin runtime singleton for one process — resources,
19
- * inventory, placements, fleet, join, gateway — from one options object.
20
- * This is the managed-sandbox bootstrap seam: main.ts and embedders
21
- * (src/index.ts) call it before creating conversation runtimes with a
22
- * gondolin sandbox config; nothing else may call the individual configure()
23
- * methods outside tests.
24
- */
25
- export declare function configureGondolinRuntime(options: GondolinBootstrapOptions): void;
26
- //# sourceMappingURL=gondolin-bootstrap.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"gondolin-bootstrap.d.ts","sourceRoot":"","sources":["../../src/sandbox/gondolin-bootstrap.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,sBAAsB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAQ1E,MAAM,WAAW,wBAAwB;IACvC,gFAAgF;IAChF,QAAQ,EAAE,MAAM,CAAC;IACjB,2CAA2C;IAC3C,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,4DAA4D;IAC5D,WAAW,CAAC,EAAE,cAAc,CAAC;IAC7B,8EAA8E;IAC9E,MAAM,CAAC,EAAE,sBAAsB,CAAC;IAChC;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED;;;;;;;GAOG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,wBAAwB,GAAG,IAAI,CAUhF"}
@@ -1,27 +0,0 @@
1
- import { join } from "node:path";
2
- import { assertRemoteConfigured, gondolinResources } from "./gondolin.js";
3
- import { gondolinFleet } from "./gondolin-fleet.js";
4
- import { gondolinGateway } from "./gondolin-gateway.js";
5
- import { gondolinInventory } from "./gondolin-inventory.js";
6
- import { gondolinJoin } from "./gondolin-join.js";
7
- import { gondolinPlacements } from "./gondolin-placement.js";
8
- /**
9
- * Configure every gondolin runtime singleton for one process — resources,
10
- * inventory, placements, fleet, join, gateway — from one options object.
11
- * This is the managed-sandbox bootstrap seam: main.ts and embedders
12
- * (src/index.ts) call it before creating conversation runtimes with a
13
- * gondolin sandbox config; nothing else may call the individual configure()
14
- * methods outside tests.
15
- */
16
- export function configureGondolinRuntime(options) {
17
- gondolinResources.configure(options.limits, options.boostLimits);
18
- gondolinInventory.configure(join(options.stateDir, "gondolin-runtimes"));
19
- gondolinPlacements.configure(join(options.stateDir, "gondolin-placement.json"));
20
- gondolinFleet.configure(options.remote);
21
- gondolinJoin.configure(join(options.stateDir, "gondolin-gateway"));
22
- gondolinGateway.configure(options.remote?.gateway);
23
- if (options.requireRemote) {
24
- assertRemoteConfigured();
25
- }
26
- }
27
- //# sourceMappingURL=gondolin-bootstrap.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"gondolin-bootstrap.js","sourceRoot":"","sources":["../../src/sandbox/gondolin-bootstrap.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAC1E,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAkB7D;;;;;;;GAOG;AACH,MAAM,UAAU,wBAAwB,CAAC,OAAiC;IACxE,iBAAiB,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;IACjE,iBAAiB,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,mBAAmB,CAAC,CAAC,CAAC;IACzE,kBAAkB,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,yBAAyB,CAAC,CAAC,CAAC;IAChF,aAAa,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACxC,YAAY,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,kBAAkB,CAAC,CAAC,CAAC;IACnE,eAAe,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnD,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC;QAC1B,sBAAsB,EAAE,CAAC;IAC3B,CAAC;AACH,CAAC","sourcesContent":["import { join } from \"node:path\";\nimport type { GondolinRemoteSettings, ResourceLimits } from \"../types.js\";\nimport { assertRemoteConfigured, gondolinResources } from \"./gondolin.js\";\nimport { gondolinFleet } from \"./gondolin-fleet.js\";\nimport { gondolinGateway } from \"./gondolin-gateway.js\";\nimport { gondolinInventory } from \"./gondolin-inventory.js\";\nimport { gondolinJoin } from \"./gondolin-join.js\";\nimport { gondolinPlacements } from \"./gondolin-placement.js\";\n\nexport interface GondolinBootstrapOptions {\n /** Host-only state dir; inventory, placements, and gateway CA live under it. */\n stateDir: string;\n /** Default per-runtime resource limits. */\n limits?: ResourceLimits;\n /** Boosted limits applied while a runtime holds a boost. */\n boostLimits?: ResourceLimits;\n /** Remote fleet settings (workers, gateway); omit for local-only gondolin. */\n remote?: GondolinRemoteSettings;\n /**\n * Fail loudly when the remote profile is requested but no worker source is\n * configured, instead of discovering it on the first runtime ensure.\n */\n requireRemote?: boolean;\n}\n\n/**\n * Configure every gondolin runtime singleton for one process — resources,\n * inventory, placements, fleet, join, gateway — from one options object.\n * This is the managed-sandbox bootstrap seam: main.ts and embedders\n * (src/index.ts) call it before creating conversation runtimes with a\n * gondolin sandbox config; nothing else may call the individual configure()\n * methods outside tests.\n */\nexport function configureGondolinRuntime(options: GondolinBootstrapOptions): void {\n gondolinResources.configure(options.limits, options.boostLimits);\n gondolinInventory.configure(join(options.stateDir, \"gondolin-runtimes\"));\n gondolinPlacements.configure(join(options.stateDir, \"gondolin-placement.json\"));\n gondolinFleet.configure(options.remote);\n gondolinJoin.configure(join(options.stateDir, \"gondolin-gateway\"));\n gondolinGateway.configure(options.remote?.gateway);\n if (options.requireRemote) {\n assertRemoteConfigured();\n }\n}\n"]}
@@ -1,125 +0,0 @@
1
- import { type Static } from "@sinclair/typebox";
2
- /**
3
- * Everything a worker process needs to host one Gondolin VM. Serialized as a
4
- * single JSON argv entry by both spawners (the local TS worker client and
5
- * the Go daemon's supervisor).
6
- */
7
- export declare const GondolinWorkerConfigSchema: import("@sinclair/typebox").TObject<{
8
- /** mikan session key the runtime belongs to. */
9
- instanceId: import("@sinclair/typebox").TString;
10
- /** Resolved guest image asset directory. */
11
- image: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
12
- /** Image selector resolved inside the worker (remote workers, where the
13
- * spawning host has no image store). Ignored when `image` is set. */
14
- imageSelector: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
15
- mounts: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
16
- source: import("@sinclair/typebox").TString;
17
- target: import("@sinclair/typebox").TString;
18
- }>>;
19
- cpus: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
20
- memory: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
21
- /** Desired-runtime fingerprint recorded for adoption checks. */
22
- fingerprint: import("@sinclair/typebox").TString;
23
- /** Runtime inventory directory (shared with the spawning mikan). */
24
- inventoryDir: import("@sinclair/typebox").TString;
25
- /** Self-stop when the mikan heartbeat file is older than this. 0 disables. */
26
- heartbeatStaleMs: import("@sinclair/typebox").TNumber;
27
- }>;
28
- export type GondolinWorkerConfig = Static<typeof GondolinWorkerConfigSchema>;
29
- /** First stdout line of a worker, consumed by both spawners. */
30
- export declare const GondolinWorkerHandshakeSchema: import("@sinclair/typebox").TObject<{
31
- ready: import("@sinclair/typebox").TBoolean;
32
- error: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
33
- sessionId: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
34
- socketPath: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
35
- workerPid: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
36
- runnerPid: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TNumber, import("@sinclair/typebox").TNull]>>;
37
- }>;
38
- export type GondolinWorkerHandshake = Static<typeof GondolinWorkerHandshakeSchema>;
39
- /**
40
- * One `<sessionId>.json` inventory record, written by the worker process and
41
- * read back by the TS inventory and the Go daemon's rediscovery.
42
- */
43
- export declare const GondolinRuntimeRecordSchema: import("@sinclair/typebox").TObject<{
44
- /** Gondolin session id (`vm.id`); also names the record file. */
45
- sessionId: import("@sinclair/typebox").TString;
46
- /** mikan session key (vault key) the runtime was created for. */
47
- instanceId: import("@sinclair/typebox").TString;
48
- /** Process that owns the runtime (the worker process). */
49
- ownerPid: import("@sinclair/typebox").TNumber;
50
- /** Host pid of the active VM runner process (QEMU/krun), if started. */
51
- runnerPid: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TNumber, import("@sinclair/typebox").TNull]>;
52
- createdAt: import("@sinclair/typebox").TString;
53
- /** Session IPC socket for adopting the runtime from a new mikan process. */
54
- socketPath: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
55
- /** Desired-runtime fingerprint the VM was created from. */
56
- fingerprint: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
57
- }>;
58
- export type GondolinRuntimeRecord = Static<typeof GondolinRuntimeRecordSchema>;
59
- export declare function isGondolinRuntimeRecord(value: unknown): value is GondolinRuntimeRecord;
60
- /** A vault credential shipped by content on the ensure request (never a shared-fs mount). */
61
- declare const GondolinCredentialFileSchema: import("@sinclair/typebox").TObject<{
62
- target: import("@sinclair/typebox").TString;
63
- contentBase64: import("@sinclair/typebox").TString;
64
- }>;
65
- export type GondolinCredentialFile = Static<typeof GondolinCredentialFileSchema>;
66
- /** POST /v1/runtimes body sent to the remote worker daemon. */
67
- export declare const GondolinEnsureRuntimeRequestSchema: import("@sinclair/typebox").TObject<{
68
- instanceId: import("@sinclair/typebox").TString;
69
- imageSelector: import("@sinclair/typebox").TString;
70
- mounts: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
71
- source: import("@sinclair/typebox").TString;
72
- target: import("@sinclair/typebox").TString;
73
- }>>;
74
- credentialFiles: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
75
- target: import("@sinclair/typebox").TString;
76
- contentBase64: import("@sinclair/typebox").TString;
77
- }>>;
78
- /** Fractional cgroup CPU limit as a string; "" when unset. */
79
- cpus: import("@sinclair/typebox").TString;
80
- memory: import("@sinclair/typebox").TString;
81
- fingerprint: import("@sinclair/typebox").TString;
82
- /** Accepted by the daemon; the TS client currently leaves it unset (0). */
83
- heartbeatStaleMs: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
84
- }>;
85
- export type GondolinEnsureRuntimeRequest = Static<typeof GondolinEnsureRuntimeRequestSchema>;
86
- /**
87
- * One runtime as reported by the daemon (ensure response, GET, and the
88
- * elements of the list response). The daemon's socketPath never crosses the
89
- * wire — sessions reach the runtime through the tunnel, not the socket.
90
- */
91
- export declare const GondolinRemoteRuntimeSchema: import("@sinclair/typebox").TObject<{
92
- sessionId: import("@sinclair/typebox").TString;
93
- instanceId: import("@sinclair/typebox").TString;
94
- fingerprint: import("@sinclair/typebox").TString;
95
- workerPid: import("@sinclair/typebox").TNumber;
96
- runnerPid: import("@sinclair/typebox").TNumber;
97
- epoch: import("@sinclair/typebox").TNumber;
98
- adopted: import("@sinclair/typebox").TBoolean;
99
- }>;
100
- export type GondolinRemoteRuntime = Static<typeof GondolinRemoteRuntimeSchema>;
101
- /** POST /v1/leases response: a fenced, epoch-monotonic per-instance lease. */
102
- export declare const GondolinLeaseGrantSchema: import("@sinclair/typebox").TObject<{
103
- id: import("@sinclair/typebox").TString;
104
- instanceId: import("@sinclair/typebox").TString;
105
- epoch: import("@sinclair/typebox").TNumber;
106
- /** RFC 3339 timestamp (Go time.Time marshalling). */
107
- expiresAt: import("@sinclair/typebox").TString;
108
- }>;
109
- /** Structural shape of the JSON messages on the session protocol. */
110
- export interface SessionFrameCallbacks {
111
- onJson: (message: {
112
- type: string;
113
- id?: number;
114
- exit_code?: number | null;
115
- code?: string;
116
- message?: string;
117
- }) => void;
118
- onBinary: (frame: Buffer) => void;
119
- }
120
- /** Parses the daemon-to-client session framing: u8 type + u32be length + payload. */
121
- export declare function createSessionFrameParser(callbacks: SessionFrameCallbacks): (chunk: Buffer) => void;
122
- /** Encodes a client-to-daemon session message: u32be length + JSON. */
123
- export declare function encodeSessionMessage(message: object): Buffer;
124
- export {};
125
- //# sourceMappingURL=gondolin-contract.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"gondolin-contract.d.ts","sourceRoot":"","sources":["../../src/sandbox/gondolin-contract.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,KAAK,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAuBtD;;;;GAIG;AACH,eAAO,MAAM,0BAA0B;IACrC,gDAAgD;;IAEhD,4CAA4C;;IAE5C;yEACqE;;;;;;;;IAKrE,gEAAgE;;IAEhE,oEAAoE;;IAEpE,8EAA8E;;EAE9E,CAAC;AAEH,MAAM,MAAM,oBAAoB,GAAG,MAAM,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAE7E,gEAAgE;AAChE,eAAO,MAAM,6BAA6B;;;;;;;EAOxC,CAAC;AAEH,MAAM,MAAM,uBAAuB,GAAG,MAAM,CAAC,OAAO,6BAA6B,CAAC,CAAC;AAEnF;;;GAGG;AACH,eAAO,MAAM,2BAA2B;IACtC,iEAAiE;;IAEjE,iEAAiE;;IAEjE,0DAA0D;;IAE1D,wEAAwE;;;IAGxE,4EAA4E;;IAE5E,2DAA2D;;EAE3D,CAAC;AAEH,MAAM,MAAM,qBAAqB,GAAG,MAAM,CAAC,OAAO,2BAA2B,CAAC,CAAC;AAE/E,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,qBAAqB,CAYtF;AAED,6FAA6F;AAC7F,QAAA,MAAM,4BAA4B;;;EAGhC,CAAC;AAEH,MAAM,MAAM,sBAAsB,GAAG,MAAM,CAAC,OAAO,4BAA4B,CAAC,CAAC;AAEjF,+DAA+D;AAC/D,eAAO,MAAM,kCAAkC;;;;;;;;;;;IAK7C,8DAA8D;;;;IAI9D,2EAA2E;;EAE3E,CAAC;AAEH,MAAM,MAAM,4BAA4B,GAAG,MAAM,CAAC,OAAO,kCAAkC,CAAC,CAAC;AAE7F;;;;GAIG;AACH,eAAO,MAAM,2BAA2B;;;;;;;;EAQtC,CAAC;AAEH,MAAM,MAAM,qBAAqB,GAAG,MAAM,CAAC,OAAO,2BAA2B,CAAC,CAAC;AAE/E,8EAA8E;AAC9E,eAAO,MAAM,wBAAwB;;;;IAInC,qDAAqD;;EAErD,CAAC;AAOH,qEAAqE;AACrE,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,CAAC,OAAO,EAAE;QAChB,IAAI,EAAE,MAAM,CAAC;QACb,EAAE,CAAC,EAAE,MAAM,CAAC;QACZ,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,KAAK,IAAI,CAAC;IACX,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACnC;AAED,qFAAqF;AACrF,wBAAgB,wBAAwB,CACtC,SAAS,EAAE,qBAAqB,GAC/B,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAqBzB;AAED,uEAAuE;AACvE,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAK5D"}