@provos/ironcurtain 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (161) hide show
  1. package/README.md +219 -248
  2. package/dist/cli.js +10 -0
  3. package/dist/cli.js.map +1 -1
  4. package/dist/config/config-command.js +144 -6
  5. package/dist/config/config-command.js.map +1 -1
  6. package/dist/config/constitution-user-base.md +2 -0
  7. package/dist/config/first-start.js +77 -12
  8. package/dist/config/first-start.js.map +1 -1
  9. package/dist/config/generated/compiled-policy.json +199 -72
  10. package/dist/config/generated/tool-annotations.json +1018 -36
  11. package/dist/config/index.js +6 -0
  12. package/dist/config/index.js.map +1 -1
  13. package/dist/config/mcp-servers.json +13 -0
  14. package/dist/config/paths.d.ts +31 -0
  15. package/dist/config/paths.js +52 -2
  16. package/dist/config/paths.js.map +1 -1
  17. package/dist/config/types.d.ts +10 -0
  18. package/dist/config/user-config.d.ts +21 -3
  19. package/dist/config/user-config.js +34 -3
  20. package/dist/config/user-config.js.map +1 -1
  21. package/dist/docker/adapters/claude-code.d.ts +4 -0
  22. package/dist/docker/adapters/claude-code.js +96 -37
  23. package/dist/docker/adapters/claude-code.js.map +1 -1
  24. package/dist/docker/agent-adapter.d.ts +22 -13
  25. package/dist/docker/code-mode-proxy.d.ts +34 -0
  26. package/dist/docker/code-mode-proxy.js +137 -0
  27. package/dist/docker/code-mode-proxy.js.map +1 -0
  28. package/dist/docker/docker-agent-session.d.ts +22 -14
  29. package/dist/docker/docker-agent-session.js +144 -117
  30. package/dist/docker/docker-agent-session.js.map +1 -1
  31. package/dist/docker/docker-infrastructure.d.ts +51 -0
  32. package/dist/docker/docker-infrastructure.js +261 -0
  33. package/dist/docker/docker-infrastructure.js.map +1 -0
  34. package/dist/docker/docker-manager.js +27 -0
  35. package/dist/docker/docker-manager.js.map +1 -1
  36. package/dist/docker/mitm-proxy.js +4 -0
  37. package/dist/docker/mitm-proxy.js.map +1 -1
  38. package/dist/docker/oauth-credentials.d.ts +81 -0
  39. package/dist/docker/oauth-credentials.js +178 -0
  40. package/dist/docker/oauth-credentials.js.map +1 -0
  41. package/dist/docker/orientation.d.ts +3 -2
  42. package/dist/docker/orientation.js +4 -4
  43. package/dist/docker/orientation.js.map +1 -1
  44. package/dist/docker/provider-config.d.ts +3 -0
  45. package/dist/docker/provider-config.js +28 -0
  46. package/dist/docker/provider-config.js.map +1 -1
  47. package/dist/docker/pty-session.d.ts +27 -0
  48. package/dist/docker/pty-session.js +420 -0
  49. package/dist/docker/pty-session.js.map +1 -0
  50. package/dist/docker/pty-types.d.ts +24 -0
  51. package/dist/docker/pty-types.js +12 -0
  52. package/dist/docker/pty-types.js.map +1 -0
  53. package/dist/docker/types.d.ts +18 -2
  54. package/dist/escalation/escalation-watcher.d.ts +44 -0
  55. package/dist/escalation/escalation-watcher.js +92 -0
  56. package/dist/escalation/escalation-watcher.js.map +1 -0
  57. package/dist/escalation/listener-command.d.ts +10 -0
  58. package/dist/escalation/listener-command.js +407 -0
  59. package/dist/escalation/listener-command.js.map +1 -0
  60. package/dist/escalation/listener-state.d.ts +49 -0
  61. package/dist/escalation/listener-state.js +104 -0
  62. package/dist/escalation/listener-state.js.map +1 -0
  63. package/dist/escalation/session-registry.d.ts +17 -0
  64. package/dist/escalation/session-registry.js +98 -0
  65. package/dist/escalation/session-registry.js.map +1 -0
  66. package/dist/index.js +15 -0
  67. package/dist/index.js.map +1 -1
  68. package/dist/logger.js +2 -3
  69. package/dist/logger.js.map +1 -1
  70. package/dist/pipeline/annotate.js +35 -15
  71. package/dist/pipeline/annotate.js.map +1 -1
  72. package/dist/pipeline/constitution-customizer.d.ts +2 -1
  73. package/dist/pipeline/constitution-customizer.js +36 -3
  74. package/dist/pipeline/constitution-customizer.js.map +1 -1
  75. package/dist/pipeline/github-identity.d.ts +38 -0
  76. package/dist/pipeline/github-identity.js +64 -0
  77. package/dist/pipeline/github-identity.js.map +1 -0
  78. package/dist/pipeline/handwritten-scenarios.js +34 -0
  79. package/dist/pipeline/handwritten-scenarios.js.map +1 -1
  80. package/dist/sandbox/index.d.ts +25 -1
  81. package/dist/sandbox/index.js +90 -12
  82. package/dist/sandbox/index.js.map +1 -1
  83. package/dist/servers/fetch-server.d.ts +6 -1
  84. package/dist/servers/fetch-server.js +26 -14
  85. package/dist/servers/fetch-server.js.map +1 -1
  86. package/dist/session/agent-session.js +9 -5
  87. package/dist/session/agent-session.js.map +1 -1
  88. package/dist/session/base-transport.d.ts +19 -0
  89. package/dist/session/base-transport.js +36 -0
  90. package/dist/session/base-transport.js.map +1 -0
  91. package/dist/session/cli-transport.d.ts +3 -3
  92. package/dist/session/cli-transport.js +7 -4
  93. package/dist/session/cli-transport.js.map +1 -1
  94. package/dist/session/index.js +24 -106
  95. package/dist/session/index.js.map +1 -1
  96. package/dist/session/interaction-log.d.ts +13 -0
  97. package/dist/session/interaction-log.js +28 -0
  98. package/dist/session/interaction-log.js.map +1 -0
  99. package/dist/session/preflight.d.ts +3 -0
  100. package/dist/session/preflight.js +45 -18
  101. package/dist/session/preflight.js.map +1 -1
  102. package/dist/session/prompts.d.ts +9 -3
  103. package/dist/session/prompts.js +28 -10
  104. package/dist/session/prompts.js.map +1 -1
  105. package/dist/session/types.d.ts +2 -0
  106. package/dist/signal/bot-command.js +5 -0
  107. package/dist/signal/bot-command.js.map +1 -1
  108. package/dist/signal/format.d.ts +21 -1
  109. package/dist/signal/format.js +41 -3
  110. package/dist/signal/format.js.map +1 -1
  111. package/dist/signal/signal-bot-daemon.d.ts +53 -18
  112. package/dist/signal/signal-bot-daemon.js +344 -106
  113. package/dist/signal/signal-bot-daemon.js.map +1 -1
  114. package/dist/signal/signal-config.d.ts +4 -0
  115. package/dist/signal/signal-config.js +2 -0
  116. package/dist/signal/signal-config.js.map +1 -1
  117. package/dist/signal/signal-transport.d.ts +13 -7
  118. package/dist/signal/signal-transport.js +36 -12
  119. package/dist/signal/signal-transport.js.map +1 -1
  120. package/dist/trusted-process/audit-log.d.ts +6 -1
  121. package/dist/trusted-process/audit-log.js +22 -2
  122. package/dist/trusted-process/audit-log.js.map +1 -1
  123. package/dist/trusted-process/audit-redactor.d.ts +25 -0
  124. package/dist/trusted-process/audit-redactor.js +121 -0
  125. package/dist/trusted-process/audit-redactor.js.map +1 -0
  126. package/dist/trusted-process/escalation.d.ts +1 -1
  127. package/dist/trusted-process/escalation.js +6 -1
  128. package/dist/trusted-process/escalation.js.map +1 -1
  129. package/dist/trusted-process/index.d.ts +2 -1
  130. package/dist/trusted-process/index.js +24 -6
  131. package/dist/trusted-process/index.js.map +1 -1
  132. package/dist/trusted-process/mcp-client-manager.js +14 -2
  133. package/dist/trusted-process/mcp-client-manager.js.map +1 -1
  134. package/dist/trusted-process/mcp-error-utils.d.ts +11 -0
  135. package/dist/trusted-process/mcp-error-utils.js +50 -0
  136. package/dist/trusted-process/mcp-error-utils.js.map +1 -0
  137. package/dist/trusted-process/mcp-proxy-server.d.ts +115 -1
  138. package/dist/trusted-process/mcp-proxy-server.js +318 -267
  139. package/dist/trusted-process/mcp-proxy-server.js.map +1 -1
  140. package/dist/trusted-process/policy-engine.d.ts +3 -1
  141. package/dist/trusted-process/policy-engine.js +17 -6
  142. package/dist/trusted-process/policy-engine.js.map +1 -1
  143. package/dist/trusted-process/sandbox-integration.d.ts +16 -4
  144. package/dist/trusted-process/sandbox-integration.js +14 -8
  145. package/dist/trusted-process/sandbox-integration.js.map +1 -1
  146. package/dist/trusted-process/server-context.d.ts +21 -0
  147. package/dist/trusted-process/server-context.js +42 -0
  148. package/dist/trusted-process/server-context.js.map +1 -0
  149. package/dist/types/argument-roles.d.ts +12 -2
  150. package/dist/types/argument-roles.js +37 -4
  151. package/dist/types/argument-roles.js.map +1 -1
  152. package/docker/Dockerfile.claude-code +8 -3
  153. package/docker/entrypoint-claude-code.sh +64 -4
  154. package/package.json +19 -9
  155. package/src/config/constitution-user-base.md +2 -0
  156. package/src/config/generated/compiled-policy.json +199 -72
  157. package/src/config/generated/tool-annotations.json +1018 -36
  158. package/src/config/mcp-servers.json +13 -0
  159. package/dist/docker/managed-proxy.d.ts +0 -31
  160. package/dist/docker/managed-proxy.js +0 -265
  161. package/dist/docker/managed-proxy.js.map +0 -1
@@ -6,14 +6,16 @@
6
6
  * - System prompt injection via --append-system-prompt
7
7
  * - --continue for session resume across turns
8
8
  * - --dangerously-skip-permissions (IronCurtain handles security)
9
+ *
10
+ * The system prompt composes two layers:
11
+ * 1. Code Mode instructions (from session/prompts.ts) for tool discovery
12
+ * 2. Docker environment context explaining workspace, host access, and policy
9
13
  */
10
- import { anthropicProvider } from '../provider-config.js';
14
+ import { anthropicProvider, claudePlatformProvider, anthropicOAuthProvider, claudePlatformOAuthProvider, } from '../provider-config.js';
15
+ import { buildSystemPrompt } from '../../session/prompts.js';
11
16
  const CLAUDE_CODE_IMAGE = 'ironcurtain-claude-code:latest';
12
- function buildOrientationPrompt(context) {
13
- const toolList = context.tools.map((t) => `- \`${t.name}\` -- ${t.description ?? 'no description'}`).join('\n');
14
- return `You are running inside a sandboxed Docker container managed by IronCurtain.
15
-
16
- ## Environment Constraints
17
+ function buildDockerEnvironmentPrompt(context) {
18
+ return `## Docker Environment
17
19
 
18
20
  ### Workspace (\`${context.workspaceDir}\`)
19
21
  This is YOUR local workspace inside the container. Use your normal built-in
@@ -24,40 +26,35 @@ Files you create at \`${context.workspaceDir}/foo.txt\` are visible to MCP tools
24
26
  at \`${context.hostSandboxDir}/foo.txt\` and vice versa.
25
27
 
26
28
  ### Host Filesystem
27
- To read or modify files on the host operating system you MUST use the MCP
28
- tools listed below. These tools are mediated by IronCurtain's policy engine:
29
- every call is evaluated against security rules and recorded in the audit log.
29
+ To read or modify files on the host operating system you MUST use the
30
+ \`execute_code\` MCP tool with the sandbox tools listed above. These tools are
31
+ mediated by IronCurtain's policy engine: every call is evaluated against
32
+ security rules and recorded in the audit log.
30
33
  Your built-in file tools cannot reach the host filesystem.
31
34
 
32
35
  ### Network
33
- ${context.networkMode === 'none'
34
- ? `The container has NO network access (--network=none). All HTTP requests and
35
- git operations MUST go through the MCP tools below.
36
+ The container has NO direct internet access. All HTTP requests and
37
+ git operations MUST go through the sandbox tools via \`execute_code\`.
36
38
 
37
- Your built-in web search and web fetch tools route through the Anthropic API
38
- and will work, but they bypass IronCurtain's audit log. Prefer the MCP fetch
39
- tool when an auditable record of network access is required.`
40
- : `The container's outbound network is restricted to IronCurtain's host-side
41
- proxies. Direct internet access is blocked by firewall rules. All HTTP
42
- requests and git operations MUST go through the MCP tools below.
39
+ IMPORTANT: Your built-in server-side web search tool (WebSearch) is DISABLED
40
+ and will NOT work it is stripped by the security proxy. You MUST use the
41
+ sandbox tools via \`execute_code\` instead. Do NOT attempt to use your
42
+ built-in WebSearch or WebFetch tools.
43
43
 
44
- Your built-in web search and web fetch tools route through the Anthropic API
45
- via the MITM proxy and will work, but they bypass IronCurtain's audit log.
46
- Prefer the MCP fetch tool when an auditable record of network access is
47
- required.`}
48
-
49
- ### Available MCP Tools
50
- ${toolList}
44
+ To search the web:
45
+ \`const results = tools.fetch_web_search({ query: "search terms" });\`
46
+ To fetch a URL:
47
+ \`const page = tools.fetch_http_fetch({ url: "https://example.com" });\`
51
48
 
52
49
  ### Policy Enforcement
53
- Every MCP tool call is evaluated against security policy rules:
50
+ Every tool call through \`execute_code\` is evaluated against security policy rules:
54
51
  - **Allowed**: proceeds automatically
55
52
  - **Denied**: blocked -- do NOT retry denied operations
56
53
  - **Escalated**: requires human approval -- you will receive the result once approved
57
54
 
58
55
  ### Best Practices
59
56
  1. Use your built-in tools for work inside ${context.workspaceDir}
60
- 2. Use MCP tools for anything on the host filesystem or network
57
+ 2. Use \`execute_code\` for anything on the host filesystem or network
61
58
  3. Batch external operations to minimize escalation prompts
62
59
  4. If an operation is denied, explain the denial and suggest alternatives
63
60
  5. Do not attempt to bypass the sandbox
@@ -90,8 +87,37 @@ export const claudeCodeAdapter = {
90
87
  ];
91
88
  },
92
89
  generateOrientationFiles() {
93
- // Orientation is delivered via --append-system-prompt, not files
94
- return [];
90
+ // Wrapper script for PTY mode -- avoids shell quoting issues by reading
91
+ // the system prompt from $IRONCURTAIN_SYSTEM_PROMPT (set by entrypoint).
92
+ const startScript = `#!/bin/bash
93
+ exec claude --dangerously-skip-permissions \\
94
+ --mcp-config /etc/ironcurtain/claude-mcp-config.json \\
95
+ --append-system-prompt "$IRONCURTAIN_SYSTEM_PROMPT"
96
+ `;
97
+ // Helper script to resize the PTY that Claude Code is actually running on.
98
+ // docker exec stty targets a transient exec session PTY, not socat's PTY.
99
+ const resizeScript = `#!/bin/bash
100
+ # Called from the host via: docker exec <cid> /etc/ironcurtain/resize-pty.sh <cols> <rows>
101
+ COLS=$1
102
+ ROWS=$2
103
+
104
+ CLAUDE_PID=$(pgrep -f "claude --dangerously" | head -1)
105
+ if [ -z "$CLAUDE_PID" ]; then
106
+ exit 0 # claude not started yet; resize will be retried
107
+ fi
108
+
109
+ PTS=$(readlink /proc/$CLAUDE_PID/fd/0 2>/dev/null)
110
+ if [ -z "$PTS" ]; then
111
+ exit 0
112
+ fi
113
+
114
+ stty -F "$PTS" cols "$COLS" rows "$ROWS" 2>/dev/null
115
+ kill -WINCH "$CLAUDE_PID" 2>/dev/null
116
+ `;
117
+ return [
118
+ { path: 'start-claude.sh', content: startScript, mode: 0o755 },
119
+ { path: 'resize-pty.sh', content: resizeScript, mode: 0o755 },
120
+ ];
95
121
  },
96
122
  buildCommand(message, systemPrompt) {
97
123
  return [
@@ -109,18 +135,39 @@ export const claudeCodeAdapter = {
109
135
  ];
110
136
  },
111
137
  buildSystemPrompt(context) {
112
- return buildOrientationPrompt(context);
138
+ // Layer 1: Code Mode instructions (tool discovery, sync calls, return semantics)
139
+ const codeModePrompt = buildSystemPrompt(context.serverListings, context.hostSandboxDir);
140
+ // Layer 2: Docker environment specifics (workspace, host access, policy)
141
+ const dockerPrompt = buildDockerEnvironmentPrompt(context);
142
+ return `${codeModePrompt}\n${dockerPrompt}`;
113
143
  },
114
- getProviders() {
115
- return [anthropicProvider];
144
+ getProviders(authKind) {
145
+ if (authKind === 'oauth') {
146
+ return [anthropicOAuthProvider, claudePlatformOAuthProvider];
147
+ }
148
+ return [anthropicProvider, claudePlatformProvider];
116
149
  },
117
- buildEnv(_config, fakeKeys) {
118
- return {
119
- ANTHROPIC_API_KEY: fakeKeys.get('api.anthropic.com') ?? '',
150
+ buildEnv(config, fakeKeys) {
151
+ const env = {
120
152
  CLAUDE_CODE_DISABLE_UPDATE_CHECK: '1',
121
153
  // Node.js does not use the system CA store -- must set this explicitly
122
154
  NODE_EXTRA_CA_CERTS: '/usr/local/share/ca-certificates/ironcurtain-ca.crt',
123
155
  };
156
+ const fakeKey = fakeKeys.get('api.anthropic.com');
157
+ if (!fakeKey) {
158
+ throw new Error('No fake key generated for api.anthropic.com — cannot configure Claude Code authentication');
159
+ }
160
+ if (config.dockerAuth?.kind === 'oauth') {
161
+ // OAuth mode: pass fake token via Claude Code's native env var.
162
+ // Claude Code reads CLAUDE_CODE_OAUTH_TOKEN as its highest-priority auth.
163
+ env.CLAUDE_CODE_OAUTH_TOKEN = fakeKey;
164
+ }
165
+ else {
166
+ // API key mode: pass the fake key via a non-Claude env var; apiKeyHelper
167
+ // in settings.json echoes it so Claude Code never prompts for approval.
168
+ env.IRONCURTAIN_API_KEY = fakeKey;
169
+ }
170
+ return env;
124
171
  },
125
172
  extractResponse(exitCode, stdout) {
126
173
  if (exitCode !== 0) {
@@ -128,6 +175,16 @@ export const claudeCodeAdapter = {
128
175
  }
129
176
  return parseClaudeCodeJson(stdout);
130
177
  },
178
+ buildPtyCommand(_systemPrompt, ptySockPath, ptyPort) {
179
+ // The socat listener target depends on platform
180
+ const listenArg = ptySockPath
181
+ ? `UNIX-LISTEN:${ptySockPath},fork` // Linux UDS
182
+ : `TCP-LISTEN:${ptyPort},reuseaddr`; // macOS TCP
183
+ // Interactive mode: claude runs via a wrapper script that reads the system
184
+ // prompt from an env var set by the entrypoint. This avoids shell quoting
185
+ // issues that occur when embedding large prompts in socat EXEC: strings.
186
+ return ['socat', listenArg, 'EXEC:/etc/ironcurtain/start-claude.sh,pty,setsid,ctty,stderr'];
187
+ },
131
188
  };
132
189
  /**
133
190
  * Parses Claude Code's `--output-format json` response.
@@ -139,8 +196,10 @@ function parseClaudeCodeJson(stdout) {
139
196
  if (parsed && typeof parsed === 'object' && 'result' in parsed) {
140
197
  const obj = parsed;
141
198
  const text = typeof obj.result === 'string' ? obj.result : stdout.trim();
142
- const costUsd = typeof obj.total_cost_usd === 'number' ? obj.total_cost_usd : undefined;
143
- return costUsd !== undefined ? { text, costUsd } : { text };
199
+ if (typeof obj.total_cost_usd === 'number') {
200
+ return { text, costUsd: obj.total_cost_usd };
201
+ }
202
+ return { text };
144
203
  }
145
204
  }
146
205
  catch {
@@ -1 +1 @@
1
- {"version":3,"file":"claude-code.js","sourceRoot":"","sources":["../../../src/docker/adapters/claude-code.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"claude-code.js","sourceRoot":"","sources":["../../../src/docker/adapters/claude-code.ts"],"names":[],"mappings":"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"}
@@ -7,6 +7,7 @@
7
7
  */
8
8
  import type { IronCurtainConfig } from '../config/types.js';
9
9
  import type { ProviderConfig } from './provider-config.js';
10
+ import type { ServerListing } from '../session/prompts.js';
10
11
  /**
11
12
  * Structured response from an agent adapter, carrying both the
12
13
  * text response and optional cost/usage metadata reported by the agent.
@@ -31,14 +32,8 @@ export interface AgentConfigFile {
31
32
  readonly path: string;
32
33
  /** File content. */
33
34
  readonly content: string;
34
- }
35
- /**
36
- * Information about a single MCP tool, used for orientation content.
37
- */
38
- export interface ToolInfo {
39
- readonly name: string;
40
- readonly description?: string;
41
- readonly inputSchema: Record<string, unknown>;
35
+ /** Optional file mode (e.g. 0o755 for executable scripts). */
36
+ readonly mode?: number;
42
37
  }
43
38
  /**
44
39
  * Context passed to the adapter for generating orientation content.
@@ -48,8 +43,8 @@ export interface OrientationContext {
48
43
  readonly workspaceDir: string;
49
44
  /** The host-side path that is bind-mounted as workspaceDir. */
50
45
  readonly hostSandboxDir: string;
51
- /** List of available MCP tools with descriptions. */
52
- readonly tools: ToolInfo[];
46
+ /** Server listings for progressive tool disclosure. */
47
+ readonly serverListings: ServerListing[];
53
48
  /** Domains the agent may access via fetch MCP tool. */
54
49
  readonly allowedDomains: string[];
55
50
  /** Container network mode: 'none' (Linux UDS) or 'bridge' (macOS TCP). */
@@ -79,9 +74,8 @@ export interface AgentAdapter {
79
74
  * the agent how to connect to IronCurtain's proxy.
80
75
  *
81
76
  * @param socketPath - container-side UDS path (e.g., /run/ironcurtain/proxy.sock)
82
- * @param tools - list of available MCP tools for documentation
83
77
  */
84
- generateMcpConfig(socketPath: string, tools: ToolInfo[]): AgentConfigFile[];
78
+ generateMcpConfig(socketPath: string): AgentConfigFile[];
85
79
  /**
86
80
  * Generates orientation documents that teach the agent about
87
81
  * the MCP-mediated environment.
@@ -102,8 +96,11 @@ export interface AgentAdapter {
102
96
  * Returns LLM provider configurations for this agent.
103
97
  * The MITM proxy uses these to build the host allowlist,
104
98
  * generate fake API keys, swap keys in requests, and filter endpoints.
99
+ *
100
+ * @param authKind - When 'oauth', returns providers configured for bearer
101
+ * token injection instead of header-based API key injection.
105
102
  */
106
- getProviders(): readonly ProviderConfig[];
103
+ getProviders(authKind?: 'oauth' | 'apikey'): readonly ProviderConfig[];
107
104
  /**
108
105
  * Constructs environment variables for the container.
109
106
  * Receives fake keys instead of real keys -- the real keys never
@@ -119,4 +116,16 @@ export interface AgentAdapter {
119
116
  * @param stdout - captured stdout from the container
120
117
  */
121
118
  extractResponse(exitCode: number, stdout: string): AgentResponse;
119
+ /**
120
+ * Returns the Docker container command for PTY mode.
121
+ * When provided, the container runs this command directly instead of
122
+ * `sleep infinity`, and the host attaches via a PTY proxy.
123
+ *
124
+ * Adapters that do not implement this method do not support PTY mode.
125
+ *
126
+ * @param systemPrompt - the orientation prompt (written to a file, not embedded in shell)
127
+ * @param ptySockPath - the UDS path for the PTY listener (Linux), or undefined for TCP mode
128
+ * @param ptyPort - the TCP port for the PTY listener (macOS), or undefined for UDS mode
129
+ */
130
+ buildPtyCommand?(systemPrompt: string, ptySockPath: string | undefined, ptyPort: number | undefined): readonly string[];
122
131
  }
@@ -0,0 +1,34 @@
1
+ /**
2
+ * CodeModeProxy -- MCP server that exposes a single `execute_code` tool
3
+ * backed by the UTCP Code Mode sandbox.
4
+ *
5
+ * Replaces the old ManagedProxy (which spawned mcp-proxy-server.ts as a
6
+ * child process). Docker agents now send TypeScript via `execute_code`,
7
+ * sharing the same execution engine as builtin Code Mode sessions.
8
+ *
9
+ * Architecture:
10
+ * Container (Claude Code) → socat → UDS/TCP socket
11
+ * → CodeModeProxy (MCP Server with execute_code)
12
+ * → Sandbox.executeCode(code)
13
+ * → V8 isolate → UTCP → per-server mcp-proxy-server.ts (stdio)
14
+ * → PolicyEngine → real MCP servers
15
+ */
16
+ import { type HelpData } from '../sandbox/index.js';
17
+ import type { IronCurtainConfig } from '../config/types.js';
18
+ /** Public interface for the Docker session's proxy. */
19
+ export interface DockerProxy {
20
+ start(): Promise<void>;
21
+ getHelpData(): HelpData;
22
+ stop(): Promise<void>;
23
+ readonly socketPath: string;
24
+ readonly port: number | undefined;
25
+ }
26
+ export interface CodeModeProxyOptions {
27
+ /** Absolute path for the UDS socket (used in UDS mode, also stored for reference in TCP mode). */
28
+ readonly socketPath: string;
29
+ /** Session configuration passed to the Sandbox. */
30
+ readonly config: IronCurtainConfig;
31
+ /** Listen mode: 'uds' (default) or 'tcp'. TCP mode uses OS-assigned port. */
32
+ readonly listenMode?: 'uds' | 'tcp';
33
+ }
34
+ export declare function createCodeModeProxy(options: CodeModeProxyOptions): DockerProxy;
@@ -0,0 +1,137 @@
1
+ /**
2
+ * CodeModeProxy -- MCP server that exposes a single `execute_code` tool
3
+ * backed by the UTCP Code Mode sandbox.
4
+ *
5
+ * Replaces the old ManagedProxy (which spawned mcp-proxy-server.ts as a
6
+ * child process). Docker agents now send TypeScript via `execute_code`,
7
+ * sharing the same execution engine as builtin Code Mode sessions.
8
+ *
9
+ * Architecture:
10
+ * Container (Claude Code) → socat → UDS/TCP socket
11
+ * → CodeModeProxy (MCP Server with execute_code)
12
+ * → Sandbox.executeCode(code)
13
+ * → V8 isolate → UTCP → per-server mcp-proxy-server.ts (stdio)
14
+ * → PolicyEngine → real MCP servers
15
+ */
16
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
17
+ import { ListToolsRequestSchema, CallToolRequestSchema } from '@modelcontextprotocol/sdk/types.js';
18
+ import { UdsServerTransport } from '../trusted-process/uds-server-transport.js';
19
+ import { TcpServerTransport } from '../trusted-process/tcp-server-transport.js';
20
+ import { Sandbox } from '../sandbox/index.js';
21
+ import { VERSION } from '../version.js';
22
+ export function createCodeModeProxy(options) {
23
+ const sandbox = new Sandbox();
24
+ const useTcp = options.listenMode === 'tcp';
25
+ let mcpServer = null; // eslint-disable-line @typescript-eslint/no-deprecated
26
+ let transport = null;
27
+ return {
28
+ socketPath: options.socketPath,
29
+ get port() {
30
+ if (transport instanceof TcpServerTransport) {
31
+ try {
32
+ return transport.port;
33
+ }
34
+ catch {
35
+ return undefined;
36
+ }
37
+ }
38
+ return undefined;
39
+ },
40
+ async start() {
41
+ // 1. Initialize the sandbox (registers MCP proxy servers per backend)
42
+ await sandbox.initialize(options.config);
43
+ // 2. Create the MCP server exposing a single execute_code tool
44
+ mcpServer = new Server(// eslint-disable-line @typescript-eslint/no-deprecated
45
+ { name: 'ironcurtain-code-mode', version: VERSION }, { capabilities: { tools: {} } });
46
+ // eslint-disable-next-line @typescript-eslint/require-await -- MCP SDK handler must return Promise
47
+ mcpServer.setRequestHandler(ListToolsRequestSchema, async () => ({
48
+ tools: [
49
+ {
50
+ name: 'execute_code',
51
+ description: 'Execute TypeScript code in a secure sandbox. ' +
52
+ 'Tool calls are synchronous (no await). ' +
53
+ 'Use `return` to send a value back. ' +
54
+ 'Call help.help() to discover available tools.',
55
+ inputSchema: {
56
+ type: 'object',
57
+ properties: {
58
+ code: {
59
+ type: 'string',
60
+ description: 'TypeScript code to execute',
61
+ },
62
+ },
63
+ required: ['code'],
64
+ },
65
+ },
66
+ ],
67
+ }));
68
+ mcpServer.setRequestHandler(CallToolRequestSchema, async (request) => {
69
+ if (request.params.name !== 'execute_code') {
70
+ return {
71
+ content: [{ type: 'text', text: `Unknown tool: ${request.params.name}` }],
72
+ isError: true,
73
+ };
74
+ }
75
+ const args = request.params.arguments;
76
+ const code = args?.code;
77
+ if (!code || typeof code !== 'string') {
78
+ return {
79
+ content: [{ type: 'text', text: 'Missing required parameter: code' }],
80
+ isError: true,
81
+ };
82
+ }
83
+ try {
84
+ const { result, logs } = await sandbox.executeCode(code);
85
+ const parts = [];
86
+ if (logs.length > 0) {
87
+ parts.push(`[logs]\n${logs.join('\n')}`);
88
+ }
89
+ if (result === undefined) {
90
+ parts.push('(no return value)');
91
+ }
92
+ else if (typeof result === 'string') {
93
+ parts.push(result);
94
+ }
95
+ else {
96
+ parts.push(JSON.stringify(result, null, 2));
97
+ }
98
+ return {
99
+ content: [{ type: 'text', text: parts.join('\n\n') }],
100
+ };
101
+ }
102
+ catch (err) {
103
+ return {
104
+ content: [
105
+ {
106
+ type: 'text',
107
+ text: `Execution error: ${err instanceof Error ? err.message : String(err)}`,
108
+ },
109
+ ],
110
+ isError: true,
111
+ };
112
+ }
113
+ });
114
+ // 3. Start the transport
115
+ if (useTcp) {
116
+ transport = new TcpServerTransport('127.0.0.1', 0);
117
+ }
118
+ else {
119
+ transport = new UdsServerTransport(options.socketPath);
120
+ }
121
+ await mcpServer.connect(transport);
122
+ },
123
+ getHelpData() {
124
+ return sandbox.getHelpData();
125
+ },
126
+ async stop() {
127
+ if (mcpServer) {
128
+ await mcpServer.close();
129
+ mcpServer = null;
130
+ }
131
+ // mcpServer.close() closes the transport, but shutdown sandbox separately
132
+ transport = null;
133
+ await sandbox.shutdown();
134
+ },
135
+ };
136
+ }
137
+ //# sourceMappingURL=code-mode-proxy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"code-mode-proxy.js","sourceRoot":"","sources":["../../src/docker/code-mode-proxy.ts"],"names":[],"mappings":"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"}
@@ -15,7 +15,7 @@ import type { Session, SessionId, SessionInfo, ConversationTurn, DiagnosticEvent
15
15
  import type { IronCurtainConfig } from '../config/types.js';
16
16
  import type { AgentAdapter } from './agent-adapter.js';
17
17
  import type { DockerManager } from './types.js';
18
- import type { ManagedProxy } from './managed-proxy.js';
18
+ import type { DockerProxy } from './code-mode-proxy.js';
19
19
  import type { MitmProxy } from './mitm-proxy.js';
20
20
  import type { CertificateAuthority } from './ca.js';
21
21
  export interface DockerAgentSessionDeps {
@@ -23,7 +23,7 @@ export interface DockerAgentSessionDeps {
23
23
  readonly sessionId: SessionId;
24
24
  readonly adapter: AgentAdapter;
25
25
  readonly docker: DockerManager;
26
- readonly proxy: ManagedProxy;
26
+ readonly proxy: DockerProxy;
27
27
  readonly mitmProxy: MitmProxy;
28
28
  readonly ca: CertificateAuthority;
29
29
  readonly fakeKeys: ReadonlyMap<string, string>;
@@ -36,6 +36,19 @@ export interface DockerAgentSessionDeps {
36
36
  readonly onEscalation?: (request: EscalationRequest) => void;
37
37
  readonly onEscalationExpired?: () => void;
38
38
  readonly onDiagnostic?: (event: DiagnosticEvent) => void;
39
+ /**
40
+ * When set, proxies are already started, orientation is built, and
41
+ * the image name is resolved. initialize() skips those steps and
42
+ * proceeds directly to container creation + watchers.
43
+ */
44
+ readonly preBuiltInfrastructure?: {
45
+ readonly systemPrompt: string;
46
+ readonly image: string;
47
+ readonly mitmAddr: {
48
+ socketPath?: string;
49
+ port?: number;
50
+ };
51
+ };
39
52
  }
40
53
  export declare class DockerAgentSession implements Session {
41
54
  private readonly sessionId;
@@ -54,25 +67,25 @@ export declare class DockerAgentSession implements Session {
54
67
  private status;
55
68
  private readonly createdAt;
56
69
  private containerId;
70
+ private sidecarContainerId;
57
71
  private networkName;
58
72
  private systemPrompt;
59
73
  private turns;
60
74
  private diagnosticLog;
61
- private pendingEscalation;
62
- private seenEscalationIds;
63
- private escalationPollInterval;
75
+ private escalationWatcher;
64
76
  private auditTailer;
65
77
  private cumulativeActiveMs;
66
78
  private cumulativeCostUsd;
67
79
  private readonly onEscalation?;
68
80
  private readonly onEscalationExpired?;
69
81
  private readonly onDiagnostic?;
82
+ private readonly preBuiltInfrastructure?;
70
83
  constructor(deps: DockerAgentSessionDeps);
71
84
  /**
72
85
  * Initialize the Docker agent session:
73
- * 1. Start MCP proxy (UDS)
74
- * 2. Start MITM proxy (UDS)
75
- * 3. Query proxy for available tools
86
+ * 1. Start Code Mode proxy (UDS/TCP)
87
+ * 2. Start MITM proxy (UDS/TCP)
88
+ * 3. Build server listings from sandbox help data
76
89
  * 4. Generate orientation files
77
90
  * 5. Ensure Docker image exists (with CA cert baked in)
78
91
  * 6. Create and start container (--network=none)
@@ -92,15 +105,10 @@ export declare class DockerAgentSession implements Session {
92
105
  private emitDiagnostic;
93
106
  /**
94
107
  * Checks whether the container can reach host-side proxies via the
95
- * internal Docker network. Throws if connectivity fails.
108
+ * socat sidecar on the internal Docker network. Throws if connectivity fails.
96
109
  */
97
110
  private checkInternalNetworkConnectivity;
98
- private startEscalationWatcher;
99
- private stopEscalationWatcher;
100
- private pollEscalationDirectory;
101
- private checkEscalationExpiry;
102
111
  private writeUserContext;
103
- private extractEscalationId;
104
112
  /**
105
113
  * Ensures the Docker image exists and is up-to-date, building it
106
114
  * (and the base image) if needed.