@rarebit-one/harness-kernel 0.5.1

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 (163) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +286 -0
  3. package/dist/agent.d.ts +71 -0
  4. package/dist/agent.d.ts.map +1 -0
  5. package/dist/agent.js +258 -0
  6. package/dist/agent.js.map +1 -0
  7. package/dist/connectors/mcpClient.d.ts +22 -0
  8. package/dist/connectors/mcpClient.d.ts.map +1 -0
  9. package/dist/connectors/mcpClient.js +63 -0
  10. package/dist/connectors/mcpClient.js.map +1 -0
  11. package/dist/context/types.d.ts +68 -0
  12. package/dist/context/types.d.ts.map +1 -0
  13. package/dist/context/types.js +43 -0
  14. package/dist/context/types.js.map +1 -0
  15. package/dist/engines/capability.d.ts +67 -0
  16. package/dist/engines/capability.d.ts.map +1 -0
  17. package/dist/engines/capability.js +73 -0
  18. package/dist/engines/capability.js.map +1 -0
  19. package/dist/engines/capabilityEmissions.d.ts +27 -0
  20. package/dist/engines/capabilityEmissions.d.ts.map +1 -0
  21. package/dist/engines/capabilityEmissions.js +37 -0
  22. package/dist/engines/capabilityEmissions.js.map +1 -0
  23. package/dist/engines/capabilityMcp.d.ts +23 -0
  24. package/dist/engines/capabilityMcp.d.ts.map +1 -0
  25. package/dist/engines/capabilityMcp.js +36 -0
  26. package/dist/engines/capabilityMcp.js.map +1 -0
  27. package/dist/engines/capabilityStdio.d.ts +46 -0
  28. package/dist/engines/capabilityStdio.d.ts.map +1 -0
  29. package/dist/engines/capabilityStdio.js +39 -0
  30. package/dist/engines/capabilityStdio.js.map +1 -0
  31. package/dist/engines/claudeCode.d.ts +73 -0
  32. package/dist/engines/claudeCode.d.ts.map +1 -0
  33. package/dist/engines/claudeCode.js +100 -0
  34. package/dist/engines/claudeCode.js.map +1 -0
  35. package/dist/engines/claudeCodeDriver.d.ts +14 -0
  36. package/dist/engines/claudeCodeDriver.d.ts.map +1 -0
  37. package/dist/engines/claudeCodeDriver.js +90 -0
  38. package/dist/engines/claudeCodeDriver.js.map +1 -0
  39. package/dist/engines/codex.d.ts +72 -0
  40. package/dist/engines/codex.d.ts.map +1 -0
  41. package/dist/engines/codex.js +157 -0
  42. package/dist/engines/codex.js.map +1 -0
  43. package/dist/engines/codexDriver.d.ts +43 -0
  44. package/dist/engines/codexDriver.d.ts.map +1 -0
  45. package/dist/engines/codexDriver.js +110 -0
  46. package/dist/engines/codexDriver.js.map +1 -0
  47. package/dist/engines/connectorMcp.d.ts +60 -0
  48. package/dist/engines/connectorMcp.d.ts.map +1 -0
  49. package/dist/engines/connectorMcp.js +137 -0
  50. package/dist/engines/connectorMcp.js.map +1 -0
  51. package/dist/engines/index.d.ts +33 -0
  52. package/dist/engines/index.d.ts.map +1 -0
  53. package/dist/engines/index.js +29 -0
  54. package/dist/engines/index.js.map +1 -0
  55. package/dist/engines/native.d.ts +55 -0
  56. package/dist/engines/native.d.ts.map +1 -0
  57. package/dist/engines/native.js +117 -0
  58. package/dist/engines/native.js.map +1 -0
  59. package/dist/engines/types.d.ts +107 -0
  60. package/dist/engines/types.d.ts.map +1 -0
  61. package/dist/engines/types.js +2 -0
  62. package/dist/engines/types.js.map +1 -0
  63. package/dist/events.d.ts +211 -0
  64. package/dist/events.d.ts.map +1 -0
  65. package/dist/events.js +69 -0
  66. package/dist/events.js.map +1 -0
  67. package/dist/index.d.ts +63 -0
  68. package/dist/index.d.ts.map +1 -0
  69. package/dist/index.js +82 -0
  70. package/dist/index.js.map +1 -0
  71. package/dist/loop.d.ts +132 -0
  72. package/dist/loop.d.ts.map +1 -0
  73. package/dist/loop.js +77 -0
  74. package/dist/loop.js.map +1 -0
  75. package/dist/models/chat.d.ts +65 -0
  76. package/dist/models/chat.d.ts.map +1 -0
  77. package/dist/models/chat.js +66 -0
  78. package/dist/models/chat.js.map +1 -0
  79. package/dist/models/middleware.d.ts +63 -0
  80. package/dist/models/middleware.d.ts.map +1 -0
  81. package/dist/models/middleware.js +139 -0
  82. package/dist/models/middleware.js.map +1 -0
  83. package/dist/models/registry.d.ts +78 -0
  84. package/dist/models/registry.d.ts.map +1 -0
  85. package/dist/models/registry.js +0 -0
  86. package/dist/models/registry.js.map +1 -0
  87. package/dist/models/types.d.ts +149 -0
  88. package/dist/models/types.d.ts.map +1 -0
  89. package/dist/models/types.js +64 -0
  90. package/dist/models/types.js.map +1 -0
  91. package/dist/primitives/codeExec.d.ts +25 -0
  92. package/dist/primitives/codeExec.d.ts.map +1 -0
  93. package/dist/primitives/codeExec.js +69 -0
  94. package/dist/primitives/codeExec.js.map +1 -0
  95. package/dist/primitives/download.d.ts +19 -0
  96. package/dist/primitives/download.d.ts.map +1 -0
  97. package/dist/primitives/download.js +113 -0
  98. package/dist/primitives/download.js.map +1 -0
  99. package/dist/primitives/fs.d.ts +5 -0
  100. package/dist/primitives/fs.d.ts.map +1 -0
  101. package/dist/primitives/fs.js +59 -0
  102. package/dist/primitives/fs.js.map +1 -0
  103. package/dist/primitives/http.d.ts +100 -0
  104. package/dist/primitives/http.d.ts.map +1 -0
  105. package/dist/primitives/http.js +257 -0
  106. package/dist/primitives/http.js.map +1 -0
  107. package/dist/providers/anthropic.d.ts +15 -0
  108. package/dist/providers/anthropic.d.ts.map +1 -0
  109. package/dist/providers/anthropic.js +90 -0
  110. package/dist/providers/anthropic.js.map +1 -0
  111. package/dist/providers/clientOptions.d.ts +14 -0
  112. package/dist/providers/clientOptions.d.ts.map +1 -0
  113. package/dist/providers/clientOptions.js +26 -0
  114. package/dist/providers/clientOptions.js.map +1 -0
  115. package/dist/providers/index.d.ts +24 -0
  116. package/dist/providers/index.d.ts.map +1 -0
  117. package/dist/providers/index.js +51 -0
  118. package/dist/providers/index.js.map +1 -0
  119. package/dist/providers/mock.d.ts +25 -0
  120. package/dist/providers/mock.d.ts.map +1 -0
  121. package/dist/providers/mock.js +85 -0
  122. package/dist/providers/mock.js.map +1 -0
  123. package/dist/providers/openai.d.ts +32 -0
  124. package/dist/providers/openai.d.ts.map +1 -0
  125. package/dist/providers/openai.js +118 -0
  126. package/dist/providers/openai.js.map +1 -0
  127. package/dist/providers/openrouter.d.ts +29 -0
  128. package/dist/providers/openrouter.d.ts.map +1 -0
  129. package/dist/providers/openrouter.js +35 -0
  130. package/dist/providers/openrouter.js.map +1 -0
  131. package/dist/providers/types.d.ts +60 -0
  132. package/dist/providers/types.d.ts.map +1 -0
  133. package/dist/providers/types.js +2 -0
  134. package/dist/providers/types.js.map +1 -0
  135. package/dist/routing/staticResolver.d.ts +41 -0
  136. package/dist/routing/staticResolver.d.ts.map +1 -0
  137. package/dist/routing/staticResolver.js +67 -0
  138. package/dist/routing/staticResolver.js.map +1 -0
  139. package/dist/routing/types.d.ts +72 -0
  140. package/dist/routing/types.d.ts.map +1 -0
  141. package/dist/routing/types.js +11 -0
  142. package/dist/routing/types.js.map +1 -0
  143. package/dist/secrets.d.ts +8 -0
  144. package/dist/secrets.d.ts.map +1 -0
  145. package/dist/secrets.js +14 -0
  146. package/dist/secrets.js.map +1 -0
  147. package/dist/tools/metadata.d.ts +93 -0
  148. package/dist/tools/metadata.d.ts.map +1 -0
  149. package/dist/tools/metadata.js +49 -0
  150. package/dist/tools/metadata.js.map +1 -0
  151. package/dist/tools/modelTool.d.ts +35 -0
  152. package/dist/tools/modelTool.d.ts.map +1 -0
  153. package/dist/tools/modelTool.js +37 -0
  154. package/dist/tools/modelTool.js.map +1 -0
  155. package/dist/tools/registry.d.ts +65 -0
  156. package/dist/tools/registry.d.ts.map +1 -0
  157. package/dist/tools/registry.js +166 -0
  158. package/dist/tools/registry.js.map +1 -0
  159. package/dist/types.d.ts +71 -0
  160. package/dist/types.d.ts.map +1 -0
  161. package/dist/types.js +10 -0
  162. package/dist/types.js.map +1 -0
  163. package/package.json +72 -0
@@ -0,0 +1,110 @@
1
+ import { spawn } from "node:child_process";
2
+ import { mkdtemp, readFile, rm } from "node:fs/promises";
3
+ import { tmpdir } from "node:os";
4
+ import path from "node:path";
5
+ /**
6
+ * The default codex driver: the single integration boundary to the OpenAI Codex
7
+ * CLI, mirroring claudeCodeDriver's injectable shape. It runs codex
8
+ * non-interactively (`codex exec`) against the prepared sandbox. The engine has
9
+ * already written the run's MCP servers (connectors + the runner-hosted capability
10
+ * server) into `config.toml` inside `opts.codexHome`; pointing the child at it via
11
+ * the `CODEX_HOME` env var is how codex discovers them.
12
+ *
13
+ * Invocation (verified against the OpenAI Codex CLI reference, `codex exec`):
14
+ * - `-m <model>` — model override
15
+ * - `-C <cwd>` — workspace root
16
+ * - `--skip-git-repo-check` — the tarball sandbox is not a git repo; without this
17
+ * `codex exec` refuses to run ("not inside a trusted
18
+ * directory")
19
+ * - `-o <file>` — write only the assistant's final message to a file,
20
+ * which we read back as the result (cleaner than the
21
+ * formatted stdout transcript)
22
+ * - `--dangerously-bypass-approvals-and-sandbox`
23
+ * — auto-approve every action (incl. MCP tool calls such
24
+ * as the runner-hosted open_issue) and disable codex's
25
+ * local sandbox. Under the default `approval: never` +
26
+ * `sandbox: read-only`, codex auto-CANCELS tool calls
27
+ * it would otherwise need approval for, so the
28
+ * capability tools never fire. This is codex's
29
+ * equivalent of the Claude Code driver's
30
+ * `bypassPermissions` and is justified the same way:
31
+ * this engine only runs inside a throwaway ephemeral
32
+ * container, so the container — not codex's sandbox —
33
+ * is the safety boundary.
34
+ * - `-` — read the prompt from stdin
35
+ * The API key rides on `CODEX_API_KEY` (codex exec's dedicated, preferred key,
36
+ * which also avoids reading `~/.codex/auth.json`); `OPENAI_API_KEY` is set too for
37
+ * compatibility (codex deprioritizes it but still accepts it).
38
+ *
39
+ * Like the Claude Code driver this only runs inside a throwaway ephemeral
40
+ * container (enforced by CodexEngine.supports) — the container, not a human, is
41
+ * the safety boundary. It is exercised only when the operator sets
42
+ * RUNNER_ENABLE_CODEX=1; every test injects a fake driver, so no binary/network
43
+ * is touched in CI.
44
+ */
45
+ export async function* defaultCodexDriver(opts) {
46
+ const controller = new AbortController();
47
+ const timer = opts.maxDurationMs && opts.maxDurationMs > 0
48
+ ? setTimeout(() => controller.abort(), opts.maxDurationMs)
49
+ : undefined;
50
+ const outDir = await mkdtemp(path.join(tmpdir(), "harness-codex-out-"));
51
+ const lastMessageFile = path.join(outDir, "last-message.txt");
52
+ try {
53
+ const child = spawn("codex", [
54
+ "exec",
55
+ "-m",
56
+ opts.model,
57
+ "-C",
58
+ opts.cwd,
59
+ "--skip-git-repo-check",
60
+ "--dangerously-bypass-approvals-and-sandbox",
61
+ "-o",
62
+ lastMessageFile,
63
+ "-",
64
+ ], {
65
+ cwd: opts.cwd,
66
+ signal: controller.signal,
67
+ env: {
68
+ ...process.env,
69
+ CODEX_HOME: opts.codexHome,
70
+ // The capability stdio MCP server reads these from its env; set them on the
71
+ // codex process env so the spawned server inherits them even if codex does
72
+ // not forward the config.toml env table (belt-and-suspenders with that table).
73
+ ...opts.capabilityEnv,
74
+ ...(opts.apiKey ? { CODEX_API_KEY: opts.apiKey, OPENAI_API_KEY: opts.apiKey } : {}),
75
+ },
76
+ stdio: ["pipe", "pipe", "pipe"],
77
+ });
78
+ child.stdin.end(opts.prompt);
79
+ let out = "";
80
+ let err = "";
81
+ child.stdout.setEncoding("utf8");
82
+ child.stderr.setEncoding("utf8");
83
+ child.stdout.on("data", (chunk) => (out += chunk));
84
+ child.stderr.on("data", (chunk) => (err += chunk));
85
+ const code = await new Promise((resolve, reject) => {
86
+ child.on("error", reject);
87
+ child.on("close", (c) => resolve(c ?? 0));
88
+ });
89
+ // On a FAILED run, surface a tail of codex's stderr as an assistant message so it
90
+ // lands in the run logs for diagnosis — codex logs MCP-server startup + tool-call
91
+ // activity there, which is otherwise invisible (the `-o` file holds only the final
92
+ // assistant message). Gated to `code !== 0`: on the happy path this tail is the
93
+ // full codex transcript (including the entire prompt), so emitting it every run is
94
+ // pure log bloat + prompt duplication.
95
+ if (code !== 0 && err.trim()) {
96
+ const tail = err.length > 4000 ? `…${err.slice(-4000)}` : err;
97
+ yield { kind: "assistant", text: `codex stderr:\n${tail}` };
98
+ }
99
+ // Prefer codex's final-message file; fall back to the raw stdout/stderr transcript.
100
+ const lastMessage = await readFile(lastMessageFile, "utf8").catch(() => "");
101
+ const text = lastMessage.trim() || out.trim() || err.trim();
102
+ yield { kind: "result", text, isError: code !== 0 };
103
+ }
104
+ finally {
105
+ if (timer)
106
+ clearTimeout(timer);
107
+ await rm(outDir, { recursive: true, force: true });
108
+ }
109
+ }
110
+ //# sourceMappingURL=codexDriver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codexDriver.js","sourceRoot":"","sources":["../../src/engines/codexDriver.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,60 @@
1
+ import type { ConnectorConfig } from "../types.js";
2
+ /**
3
+ * A serializable MCP server config — the shape both the Anthropic Agent SDK's
4
+ * `mcpServers` option (for its process-transport servers) and a `.mcp.json` file
5
+ * (for codex / external-CLI engines) understand. The runner resolves connector
6
+ * auth tokens caller-side, so they are inlined here as the transport
7
+ * expects (a bearer header for HTTP-family, `MCP_AUTH_TOKEN` env for stdio —
8
+ * mirroring src/connectors/mcpClient.ts, the native engine's connector client).
9
+ */
10
+ export type SerializableMcpServer = {
11
+ type: "stdio";
12
+ command: string;
13
+ args?: string[];
14
+ env?: Record<string, string>;
15
+ } | {
16
+ type: "http";
17
+ url: string;
18
+ headers?: Record<string, string>;
19
+ } | {
20
+ type: "sse";
21
+ url: string;
22
+ headers?: Record<string, string>;
23
+ };
24
+ /**
25
+ * Translate one connector into a serializable MCP server config, or null when it
26
+ * isn't an MCP connector this seam can carry (a plain `http` service, or a
27
+ * malformed config missing its endpoint/command). Same source data the native
28
+ * engine's connector client consumes — one definition, every engine.
29
+ */
30
+ export declare function connectorToMcpServer(config: ConnectorConfig): SerializableMcpServer | null;
31
+ /**
32
+ * Build the `<name> → server config` map for a run's MCP connectors, skipping any
33
+ * that don't translate. Suitable both for the Agent SDK's `mcpServers` option and
34
+ * for a `.mcp.json` file's `mcpServers` field.
35
+ */
36
+ export declare function connectorServers(connectors: ConnectorConfig[]): Record<string, SerializableMcpServer>;
37
+ /**
38
+ * Write a `.mcp.json` at the sandbox root — the shape a generic CLI harness that
39
+ * follows the Claude Code convention reads. No-op when there are no servers.
40
+ * Returns the servers written (for logging / assertions).
41
+ *
42
+ * NOTE: the OpenAI Codex CLI does NOT read `.mcp.json` — it discovers MCP servers
43
+ * from `$CODEX_HOME/config.toml` under `[mcp_servers.<name>]`. The codex engine
44
+ * uses {@link writeCodexConfig} instead; this seam is kept for any generic-CLI use.
45
+ */
46
+ export declare function writeMcpJson(workdir: string, servers: Record<string, SerializableMcpServer>): Promise<Record<string, SerializableMcpServer>>;
47
+ /**
48
+ * Write a `config.toml` into a codex home directory so the OpenAI Codex CLI (run
49
+ * with `CODEX_HOME` pointed here) discovers the run's MCP servers — the run's
50
+ * connectors plus the runner-hosted capability server — as `[mcp_servers.<name>]`
51
+ * tables. This is codex's REAL discovery mechanism (it ignores `.mcp.json`).
52
+ *
53
+ * The file can carry resolved connector auth tokens (inline `http_headers`, or a
54
+ * stdio server's `MCP_AUTH_TOKEN` env), so callers MUST write it to a transient
55
+ * location outside the sandbox tree and delete it after the run — never let it
56
+ * reach the change set. No-op when there are no servers. Returns the path written
57
+ * (or null when nothing was written), for logging / assertions.
58
+ */
59
+ export declare function writeCodexConfig(codexHome: string, servers: Record<string, SerializableMcpServer>): Promise<string | null>;
60
+ //# sourceMappingURL=connectorMcp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connectorMcp.d.ts","sourceRoot":"","sources":["../../src/engines/connectorMcp.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAElD;;;;;;;GAOG;AACH,MAAM,MAAM,qBAAqB,GAC7B;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,GACjF;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,GAC/D;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,CAAA;AASlE;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,eAAe,GAAG,qBAAqB,GAAG,IAAI,CA8B1F;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,eAAe,EAAE,GAC5B,MAAM,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAOvC;AAED;;;;;;;;GAQG;AACH,wBAAsB,YAAY,CAChC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,qBAAqB,CAAC,GAC7C,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAAC,CAKhD;AA2CD;;;;;;;;;;;GAWG;AACH,wBAAsB,gBAAgB,CACpC,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,qBAAqB,CAAC,GAC7C,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAMxB"}
@@ -0,0 +1,137 @@
1
+ import { writeFile } from "node:fs/promises";
2
+ import path from "node:path";
3
+ function bearerHeaders(config) {
4
+ if (config.auth?.type === "bearer" && config.auth.token) {
5
+ return { Authorization: `Bearer ${config.auth.token}` };
6
+ }
7
+ return undefined;
8
+ }
9
+ /**
10
+ * Translate one connector into a serializable MCP server config, or null when it
11
+ * isn't an MCP connector this seam can carry (a plain `http` service, or a
12
+ * malformed config missing its endpoint/command). Same source data the native
13
+ * engine's connector client consumes — one definition, every engine.
14
+ */
15
+ export function connectorToMcpServer(config) {
16
+ if (config.kind !== "mcp")
17
+ return null;
18
+ switch (config.transport) {
19
+ case "stdio": {
20
+ if (!config.command)
21
+ return null;
22
+ const env = config.auth?.type === "bearer" && config.auth.token
23
+ ? { MCP_AUTH_TOKEN: config.auth.token }
24
+ : undefined;
25
+ return {
26
+ type: "stdio",
27
+ command: config.command,
28
+ ...(config.args && config.args.length > 0 ? { args: config.args } : {}),
29
+ ...(env ? { env } : {}),
30
+ };
31
+ }
32
+ case "streamable_http": {
33
+ if (!config.endpoint)
34
+ return null;
35
+ const headers = bearerHeaders(config);
36
+ return { type: "http", url: config.endpoint, ...(headers ? { headers } : {}) };
37
+ }
38
+ case "sse": {
39
+ if (!config.endpoint)
40
+ return null;
41
+ const headers = bearerHeaders(config);
42
+ return { type: "sse", url: config.endpoint, ...(headers ? { headers } : {}) };
43
+ }
44
+ default:
45
+ return null;
46
+ }
47
+ }
48
+ /**
49
+ * Build the `<name> → server config` map for a run's MCP connectors, skipping any
50
+ * that don't translate. Suitable both for the Agent SDK's `mcpServers` option and
51
+ * for a `.mcp.json` file's `mcpServers` field.
52
+ */
53
+ export function connectorServers(connectors) {
54
+ const servers = {};
55
+ for (const config of connectors) {
56
+ const server = connectorToMcpServer(config);
57
+ if (server)
58
+ servers[config.name] = server;
59
+ }
60
+ return servers;
61
+ }
62
+ /**
63
+ * Write a `.mcp.json` at the sandbox root — the shape a generic CLI harness that
64
+ * follows the Claude Code convention reads. No-op when there are no servers.
65
+ * Returns the servers written (for logging / assertions).
66
+ *
67
+ * NOTE: the OpenAI Codex CLI does NOT read `.mcp.json` — it discovers MCP servers
68
+ * from `$CODEX_HOME/config.toml` under `[mcp_servers.<name>]`. The codex engine
69
+ * uses {@link writeCodexConfig} instead; this seam is kept for any generic-CLI use.
70
+ */
71
+ export async function writeMcpJson(workdir, servers) {
72
+ if (Object.keys(servers).length === 0)
73
+ return servers;
74
+ const file = path.join(workdir, ".mcp.json");
75
+ await writeFile(file, `${JSON.stringify({ mcpServers: servers }, null, 2)}\n`);
76
+ return servers;
77
+ }
78
+ /** Escape a string for a TOML basic (double-quoted) string. */
79
+ function tomlString(value) {
80
+ const escaped = value
81
+ .replace(/\\/g, "\\\\")
82
+ .replace(/"/g, '\\"')
83
+ .replace(/\n/g, "\\n")
84
+ .replace(/\r/g, "\\r")
85
+ .replace(/\t/g, "\\t");
86
+ return `"${escaped}"`;
87
+ }
88
+ /** Serialize a `{ KEY: "value" }` map as a TOML inline table with quoted keys. */
89
+ function tomlInlineTable(map) {
90
+ const pairs = Object.entries(map).map(([k, v]) => `${tomlString(k)} = ${tomlString(v)}`);
91
+ return `{ ${pairs.join(", ")} }`;
92
+ }
93
+ /** Render one MCP server as a `[mcp_servers."<name>"]` TOML section. */
94
+ function codexServerSection(name, server) {
95
+ const lines = [`[mcp_servers.${tomlString(name)}]`];
96
+ if (server.type === "stdio") {
97
+ lines.push(`command = ${tomlString(server.command)}`);
98
+ if (server.args && server.args.length > 0) {
99
+ lines.push(`args = [${server.args.map(tomlString).join(", ")}]`);
100
+ }
101
+ if (server.env && Object.keys(server.env).length > 0) {
102
+ lines.push(`env = ${tomlInlineTable(server.env)}`);
103
+ }
104
+ }
105
+ else {
106
+ // Codex speaks Streamable HTTP over `url`; it has no distinct SSE transport, so
107
+ // an `sse` connector is carried the same way (a legacy SSE-only endpoint may not
108
+ // work). Resolved bearer tokens ride inline in `http_headers` (Authorization),
109
+ // which is exactly why the config file must be written pre-run and deleted after.
110
+ lines.push(`url = ${tomlString(server.url)}`);
111
+ if (server.headers && Object.keys(server.headers).length > 0) {
112
+ lines.push(`http_headers = ${tomlInlineTable(server.headers)}`);
113
+ }
114
+ }
115
+ return lines.join("\n");
116
+ }
117
+ /**
118
+ * Write a `config.toml` into a codex home directory so the OpenAI Codex CLI (run
119
+ * with `CODEX_HOME` pointed here) discovers the run's MCP servers — the run's
120
+ * connectors plus the runner-hosted capability server — as `[mcp_servers.<name>]`
121
+ * tables. This is codex's REAL discovery mechanism (it ignores `.mcp.json`).
122
+ *
123
+ * The file can carry resolved connector auth tokens (inline `http_headers`, or a
124
+ * stdio server's `MCP_AUTH_TOKEN` env), so callers MUST write it to a transient
125
+ * location outside the sandbox tree and delete it after the run — never let it
126
+ * reach the change set. No-op when there are no servers. Returns the path written
127
+ * (or null when nothing was written), for logging / assertions.
128
+ */
129
+ export async function writeCodexConfig(codexHome, servers) {
130
+ if (Object.keys(servers).length === 0)
131
+ return null;
132
+ const sections = Object.entries(servers).map(([name, server]) => codexServerSection(name, server));
133
+ const file = path.join(codexHome, "config.toml");
134
+ await writeFile(file, `${sections.join("\n\n")}\n`);
135
+ return file;
136
+ }
137
+ //# sourceMappingURL=connectorMcp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connectorMcp.js","sourceRoot":"","sources":["../../src/engines/connectorMcp.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ import { type DomainToolFactory } from "./native.js";
2
+ import { type CapabilityToolFactory } from "./claudeCode.js";
3
+ import type { AgentEngine } from "./types.js";
4
+ export type { AgentEngine, EngineContext, EngineResult, EngineSupport, RunSpec } from "./types.js";
5
+ /**
6
+ * The application-supplied seams an engine needs. The kernel defines no domain
7
+ * tools and no application capabilities, so anything product-specific reaches
8
+ * the engines through here rather than being baked in.
9
+ */
10
+ export interface EngineSelection {
11
+ /** Extra tools for the in-process loop, beyond the generic primitives. */
12
+ domainTools?: DomainToolFactory;
13
+ /** The capability surface exposed to Claude Code over its in-process MCP server. */
14
+ capabilityTools?: CapabilityToolFactory;
15
+ /**
16
+ * Entrypoint script the codex engine spawns to serve its capability surface.
17
+ * Required to select `codex` — a child process cannot be handed a closure, so
18
+ * the application must own that script.
19
+ */
20
+ capabilityServerScript?: string;
21
+ }
22
+ /**
23
+ * Resolve the agent harness for a run from the workflow's `provider.engine`.
24
+ * Defaults to the native loop; an unknown name also falls back to native (the
25
+ * safe default), so a typo can't silently route to nothing. Capability gating
26
+ * (isolation, enablement) is the engine's own `supports()` responsibility.
27
+ *
28
+ * Selecting `codex` without `capabilityServerScript` throws rather than
29
+ * defaulting: the alternative is an external engine that comes up with an empty
30
+ * capability surface, which looks like a working run that quietly emits nothing.
31
+ */
32
+ export declare function selectEngine(name?: string | null, selection?: EngineSelection): AgentEngine;
33
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/engines/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAClE,OAAO,EAAoB,KAAK,qBAAqB,EAAE,MAAM,iBAAiB,CAAA;AAE9E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAE7C,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,YAAY,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AAElG;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B,0EAA0E;IAC1E,WAAW,CAAC,EAAE,iBAAiB,CAAA;IAC/B,oFAAoF;IACpF,eAAe,CAAC,EAAE,qBAAqB,CAAA;IACvC;;;;OAIG;IACH,sBAAsB,CAAC,EAAE,MAAM,CAAA;CAChC;AAED;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,EAAE,SAAS,GAAE,eAAoB,GAAG,WAAW,CAgB/F"}
@@ -0,0 +1,29 @@
1
+ import { NativeEngine } from "./native.js";
2
+ import { ClaudeCodeEngine } from "./claudeCode.js";
3
+ import { CodexEngine } from "./codex.js";
4
+ /**
5
+ * Resolve the agent harness for a run from the workflow's `provider.engine`.
6
+ * Defaults to the native loop; an unknown name also falls back to native (the
7
+ * safe default), so a typo can't silently route to nothing. Capability gating
8
+ * (isolation, enablement) is the engine's own `supports()` responsibility.
9
+ *
10
+ * Selecting `codex` without `capabilityServerScript` throws rather than
11
+ * defaulting: the alternative is an external engine that comes up with an empty
12
+ * capability surface, which looks like a working run that quietly emits nothing.
13
+ */
14
+ export function selectEngine(name, selection = {}) {
15
+ switch (name) {
16
+ case "claude-code":
17
+ return new ClaudeCodeEngine(undefined, selection.capabilityTools);
18
+ case "codex": {
19
+ if (!selection.capabilityServerScript) {
20
+ throw new Error("the codex engine requires selection.capabilityServerScript — the capability surface is " +
21
+ "injected, and an external process cannot be handed one implicitly");
22
+ }
23
+ return new CodexEngine(undefined, selection.capabilityServerScript);
24
+ }
25
+ default:
26
+ return new NativeEngine(selection.domainTools ? { domainTools: selection.domainTools } : {});
27
+ }
28
+ }
29
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/engines/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAA0B,MAAM,aAAa,CAAA;AAClE,OAAO,EAAE,gBAAgB,EAA8B,MAAM,iBAAiB,CAAA;AAC9E,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAuBxC;;;;;;;;;GASG;AACH,MAAM,UAAU,YAAY,CAAC,IAAoB,EAAE,YAA6B,EAAE;IAChF,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,aAAa;YAChB,OAAO,IAAI,gBAAgB,CAAC,SAAS,EAAE,SAAS,CAAC,eAAe,CAAC,CAAA;QACnE,KAAK,OAAO,CAAC,CAAC,CAAC;YACb,IAAI,CAAC,SAAS,CAAC,sBAAsB,EAAE,CAAC;gBACtC,MAAM,IAAI,KAAK,CACb,yFAAyF;oBACvF,mEAAmE,CACtE,CAAA;YACH,CAAC;YACD,OAAO,IAAI,WAAW,CAAC,SAAS,EAAE,SAAS,CAAC,sBAAsB,CAAC,CAAA;QACrE,CAAC;QACD;YACE,OAAO,IAAI,YAAY,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,SAAS,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;IAChG,CAAC;AACH,CAAC"}
@@ -0,0 +1,55 @@
1
+ import { type ContextProvider } from "../context/types.js";
2
+ import { type Loop } from "../loop.js";
3
+ import type { Tool } from "../tools/registry.js";
4
+ import type { AgentEngine, EngineContext, EngineResult, EngineSupport, RunSpec } from "./types.js";
5
+ /**
6
+ * Builds the non-generic tools a run gets on top of the primitives, gated by the
7
+ * same permissions allowlist. An application closes over whatever sinks it wants
8
+ * the results to land in — the kernel neither supplies nor inspects them.
9
+ */
10
+ export type DomainToolFactory = (allowed?: string[]) => Tool[];
11
+ export interface NativeEngineOptions {
12
+ /**
13
+ * Application tools composed in alongside the generic primitives. Defaults to
14
+ * none: the kernel ships no domain tools, because what a run may emit is the
15
+ * application's vocabulary. Pass a factory to add them.
16
+ */
17
+ domainTools?: DomainToolFactory;
18
+ /**
19
+ * Extra context sources asked for fragments at run time, appended after the
20
+ * spec's own pre-assembled `context`. Absent (the default) means the prompt is
21
+ * built from `spec.context` alone, exactly as before this seam existed.
22
+ */
23
+ contextProviders?: ContextProvider[];
24
+ /**
25
+ * The control loop that drives the run. Defaults to `nativeLoop` — the loop
26
+ * this engine has always run — so an engine constructed without one is
27
+ * unchanged. Pass your own to change control flow (a confirmation gate, a
28
+ * plan-then-execute shape) without forking the engine or the loop.
29
+ */
30
+ loop?: Loop;
31
+ }
32
+ /**
33
+ * The in-process native engine: the provider-neutral tool-use loop over the
34
+ * general-purpose primitives (run_code, read_file, list_files, http_fetch) plus
35
+ * the run's domain tools and MCP connectors. This is the default engine and the
36
+ * only one safe to run on a warm shared host — the primitives are the isolation
37
+ * boundary.
38
+ */
39
+ export declare class NativeEngine implements AgentEngine {
40
+ readonly name = "native";
41
+ private readonly domainTools;
42
+ private readonly contextProviders;
43
+ private readonly loop;
44
+ constructor(options?: NativeEngineOptions);
45
+ supports(): EngineSupport;
46
+ run(spec: RunSpec, ctx: EngineContext): Promise<EngineResult>;
47
+ /**
48
+ * The run's context text: the spec's own pre-assembled context, then whatever
49
+ * the configured providers contribute. With no providers this returns
50
+ * `spec.context` unchanged, so the prompt is byte-identical to a run that
51
+ * predates the seam.
52
+ */
53
+ private buildContext;
54
+ }
55
+ //# sourceMappingURL=native.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"native.d.ts","sourceRoot":"","sources":["../../src/engines/native.ts"],"names":[],"mappings":"AACA,OAAO,EAAkC,KAAK,eAAe,EAAE,MAAM,qBAAqB,CAAA;AAE1F,OAAO,EAA6B,KAAK,IAAI,EAAE,MAAM,YAAY,CAAA;AAKjE,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAA;AAEhD,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,YAAY,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AAElG;;;;GAIG;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,IAAI,EAAE,CAAA;AAE9D,MAAM,WAAW,mBAAmB;IAClC;;;;OAIG;IACH,WAAW,CAAC,EAAE,iBAAiB,CAAA;IAC/B;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,eAAe,EAAE,CAAA;IACpC;;;;;OAKG;IACH,IAAI,CAAC,EAAE,IAAI,CAAA;CACZ;AAED;;;;;;GAMG;AACH,qBAAa,YAAa,YAAW,WAAW;IAC9C,QAAQ,CAAC,IAAI,YAAW;IAExB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAmB;IAC/C,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAmB;IACpD,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAM;gBAEf,OAAO,GAAE,mBAAwB;IAM7C,QAAQ,IAAI,aAAa;IAInB,GAAG,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC;IAsDnE;;;;;OAKG;YACW,YAAY;CAY3B"}
@@ -0,0 +1,117 @@
1
+ import { resolveLoopLimits } from "../agent.js";
2
+ import { assembleContext, renderContext } from "../context/types.js";
3
+ import { runEventEmitter } from "../events.js";
4
+ import { nativeLoop, runWithEvents } from "../loop.js";
5
+ import { asChatModel } from "../models/chat.js";
6
+ import { selectProvider } from "../providers/index.js";
7
+ import { secretsToEnv } from "../secrets.js";
8
+ import { primitiveTools, connectorTools } from "../tools/registry.js";
9
+ /**
10
+ * The in-process native engine: the provider-neutral tool-use loop over the
11
+ * general-purpose primitives (run_code, read_file, list_files, http_fetch) plus
12
+ * the run's domain tools and MCP connectors. This is the default engine and the
13
+ * only one safe to run on a warm shared host — the primitives are the isolation
14
+ * boundary.
15
+ */
16
+ export class NativeEngine {
17
+ name = "native";
18
+ domainTools;
19
+ contextProviders;
20
+ loop;
21
+ constructor(options = {}) {
22
+ this.domainTools = options.domainTools ?? (() => []);
23
+ this.contextProviders = options.contextProviders ?? [];
24
+ this.loop = options.loop ?? nativeLoop;
25
+ }
26
+ supports() {
27
+ return { ok: true };
28
+ }
29
+ async run(spec, ctx) {
30
+ const provider = selectProvider(spec.provider.preferred, {
31
+ model: spec.provider.model,
32
+ credentials: spec.provider.credentials,
33
+ });
34
+ ctx.log(`provider: ${provider.name}`);
35
+ // General-purpose primitives (secrets injected as env) + the run's connectors.
36
+ const env = secretsToEnv(spec.secrets);
37
+ const allowed = Array.isArray(spec.permissions.tools) ? spec.permissions.tools : undefined;
38
+ const allowHosts = Array.isArray(spec.permissions.hosts) ? spec.permissions.hosts : undefined;
39
+ // Generic primitives + the application's own domain tools, both gated by the
40
+ // run's permissions allowlist. Anything the domain tools collect goes to
41
+ // sinks the application owns; the kernel never sees them.
42
+ const primitives = [
43
+ ...primitiveTools(spec.workdir, env, allowed, allowHosts),
44
+ ...this.domainTools(allowed),
45
+ ];
46
+ // Connector tools are NOT re-gated by permissions.tools: the caller
47
+ // already authorized them per connector (scope + grants) when it populated
48
+ // connectors, and their names are namespaced `<connector>__<tool>`.
49
+ const connectors = await connectorTools(spec.connectors);
50
+ try {
51
+ const tools = [...primitives, ...connectors.tools];
52
+ ctx.log(`tools: ${tools.map((t) => t.spec.name).join(", ") || "(none)"}`);
53
+ // Budgets are resolved before the call: a loop is handed numbers, not
54
+ // optionals, so a second implementation cannot accidentally run to a
55
+ // different ceiling than the one the kernel ships.
56
+ const result = await runWithEvents(this.loop, {
57
+ model: asChatModel(provider),
58
+ system: buildSystemPrompt(spec.workflow, spec.workspaceId, spec.workflowPath),
59
+ userPrompt: buildUserPrompt(spec.workflow, await this.buildContext(spec, ctx), spec.inputs),
60
+ tools,
61
+ limits: resolveLoopLimits(spec.limits),
62
+ },
63
+ // The bookends come from `runWithEvents`, so an application's own loop
64
+ // gets them without having to know they exist.
65
+ { log: ctx.log, events: runEventEmitter(ctx.emit, ctx.log) });
66
+ return { text: result.text };
67
+ }
68
+ finally {
69
+ // Connectors are only needed during the loop; close them here (the engine
70
+ // opened them) regardless of how run() exits.
71
+ await connectors.close();
72
+ }
73
+ }
74
+ /**
75
+ * The run's context text: the spec's own pre-assembled context, then whatever
76
+ * the configured providers contribute. With no providers this returns
77
+ * `spec.context` unchanged, so the prompt is byte-identical to a run that
78
+ * predates the seam.
79
+ */
80
+ async buildContext(spec, ctx) {
81
+ if (this.contextProviders.length === 0)
82
+ return spec.context;
83
+ const fragments = await assembleContext(this.contextProviders, spec, ctx.log);
84
+ if (fragments.length === 0)
85
+ return spec.context;
86
+ ctx.log(`context: ${fragments.length} fragment(s) from ${this.contextProviders.length} provider(s)`);
87
+ const assembled = renderContext(fragments);
88
+ return spec.context ? `${spec.context}\n\n${assembled}` : assembled;
89
+ }
90
+ }
91
+ function buildSystemPrompt(workflow, workspaceId, workflowPath) {
92
+ return [
93
+ "You are an autonomous workflow executing in an isolated workspace sandbox.",
94
+ `Workspace: ${workspaceId}`,
95
+ `Workflow: ${workflow.name ?? workflowPath}`,
96
+ "Use the provided tools to inspect the workspace, run the repo's own code, and",
97
+ "call connectors as needed. Delegate anything that must be precise or",
98
+ "reproducible (calculations, dates, side effects) to code via run_code rather",
99
+ "than doing it yourself. When finished, reply with the workflow's output as",
100
+ "Markdown and no further tool calls.",
101
+ ].join("\n");
102
+ }
103
+ function buildUserPrompt(workflow, context, inputs) {
104
+ const inputsJson = JSON.stringify(inputs ?? {}, null, 2);
105
+ return [
106
+ workflow.prompt ?? `Execute the "${workflow.name}" workflow.`,
107
+ "",
108
+ "## Inputs",
109
+ "```json",
110
+ inputsJson,
111
+ "```",
112
+ "",
113
+ "## Workspace context",
114
+ context || "(no context files matched)",
115
+ ].join("\n");
116
+ }
117
+ //# sourceMappingURL=native.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"native.js","sourceRoot":"","sources":["../../src/engines/native.ts"],"names":[],"mappings":"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"}