@provos/ironcurtain 0.6.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -2
- package/dist/cli-help.d.ts +63 -0
- package/dist/cli-help.js +102 -0
- package/dist/cli-help.js.map +1 -0
- package/dist/cli.js +73 -56
- package/dist/cli.js.map +1 -1
- package/dist/config/config-command.js +136 -2
- package/dist/config/config-command.js.map +1 -1
- package/dist/config/generated/tool-annotations.json +487 -338
- package/dist/config/index.d.ts +21 -1
- package/dist/config/index.js +12 -4
- package/dist/config/index.js.map +1 -1
- package/dist/config/mcp-servers.json +2 -8
- package/dist/config/paths.d.ts +30 -0
- package/dist/config/paths.js +58 -0
- package/dist/config/paths.js.map +1 -1
- package/dist/config/tool-description-hints.json +15 -0
- package/dist/config/types.d.ts +7 -0
- package/dist/config/user-config.d.ts +21 -0
- package/dist/config/user-config.js +8 -0
- package/dist/config/user-config.js.map +1 -1
- package/dist/cron/compile-task-policy.d.ts +17 -0
- package/dist/cron/compile-task-policy.js +39 -0
- package/dist/cron/compile-task-policy.js.map +1 -0
- package/dist/cron/cron-scheduler.d.ts +65 -0
- package/dist/cron/cron-scheduler.js +184 -0
- package/dist/cron/cron-scheduler.js.map +1 -0
- package/dist/cron/file-lock.d.ts +41 -0
- package/dist/cron/file-lock.js +156 -0
- package/dist/cron/file-lock.js.map +1 -0
- package/dist/cron/format-utils.d.ts +18 -0
- package/dist/cron/format-utils.js +145 -0
- package/dist/cron/format-utils.js.map +1 -0
- package/dist/cron/git-sync.d.ts +22 -0
- package/dist/cron/git-sync.js +121 -0
- package/dist/cron/git-sync.js.map +1 -0
- package/dist/cron/headless-transport.d.ts +27 -0
- package/dist/cron/headless-transport.js +43 -0
- package/dist/cron/headless-transport.js.map +1 -0
- package/dist/cron/job-commands.d.ts +39 -0
- package/dist/cron/job-commands.js +522 -0
- package/dist/cron/job-commands.js.map +1 -0
- package/dist/cron/job-store.d.ts +35 -0
- package/dist/cron/job-store.js +111 -0
- package/dist/cron/job-store.js.map +1 -0
- package/dist/cron/types.d.ts +127 -0
- package/dist/cron/types.js +25 -0
- package/dist/cron/types.js.map +1 -0
- package/dist/daemon/control-socket.d.ts +127 -0
- package/dist/daemon/control-socket.js +261 -0
- package/dist/daemon/control-socket.js.map +1 -0
- package/dist/daemon/daemon-command.d.ts +13 -0
- package/dist/daemon/daemon-command.js +230 -0
- package/dist/daemon/daemon-command.js.map +1 -0
- package/dist/daemon/ironcurtain-daemon.d.ts +90 -0
- package/dist/daemon/ironcurtain-daemon.js +548 -0
- package/dist/daemon/ironcurtain-daemon.js.map +1 -0
- package/dist/docker/adapters/claude-code.js +7 -47
- package/dist/docker/adapters/claude-code.js.map +1 -1
- package/dist/docker/adapters/goose.d.ts +58 -0
- package/dist/docker/adapters/goose.js +250 -0
- package/dist/docker/adapters/goose.js.map +1 -0
- package/dist/docker/adapters/shared-scripts.d.ts +29 -0
- package/dist/docker/adapters/shared-scripts.js +80 -0
- package/dist/docker/adapters/shared-scripts.js.map +1 -0
- package/dist/docker/agent-adapter.d.ts +12 -0
- package/dist/docker/agent-adapter.js.map +1 -1
- package/dist/docker/agent-registry.d.ts +6 -1
- package/dist/docker/agent-registry.js +10 -1
- package/dist/docker/agent-registry.js.map +1 -1
- package/dist/docker/docker-agent-session.d.ts +2 -25
- package/dist/docker/docker-agent-session.js +7 -106
- package/dist/docker/docker-agent-session.js.map +1 -1
- package/dist/docker/docker-infrastructure.d.ts +8 -0
- package/dist/docker/docker-infrastructure.js +12 -11
- package/dist/docker/docker-infrastructure.js.map +1 -1
- package/dist/docker/pty-session.js +7 -4
- package/dist/docker/pty-session.js.map +1 -1
- package/dist/escalation/escalation-watcher.d.ts +2 -0
- package/dist/escalation/escalation-watcher.js +3 -0
- package/dist/escalation/escalation-watcher.js.map +1 -1
- package/dist/escalation/session-registry.js +1 -14
- package/dist/escalation/session-registry.js.map +1 -1
- package/dist/index.js +30 -1
- package/dist/index.js.map +1 -1
- package/dist/mux/mux-app.js +11 -6
- package/dist/mux/mux-app.js.map +1 -1
- package/dist/mux/mux-command.js +20 -9
- package/dist/mux/mux-command.js.map +1 -1
- package/dist/mux/mux-input-handler.d.ts +5 -0
- package/dist/mux/mux-input-handler.js +64 -9
- package/dist/mux/mux-input-handler.js.map +1 -1
- package/dist/mux/mux-renderer.d.ts +20 -0
- package/dist/mux/mux-renderer.js +127 -35
- package/dist/mux/mux-renderer.js.map +1 -1
- package/dist/mux/mux-splash.js +2 -1
- package/dist/mux/mux-splash.js.map +1 -1
- package/dist/mux/paste-interceptor.d.ts +22 -0
- package/dist/mux/paste-interceptor.js +143 -0
- package/dist/mux/paste-interceptor.js.map +1 -0
- package/dist/mux/pty-bridge.js +1 -1
- package/dist/mux/pty-bridge.js.map +1 -1
- package/dist/mux/types.d.ts +8 -1
- package/dist/mux/types.js +17 -5
- package/dist/mux/types.js.map +1 -1
- package/dist/pipeline/annotate.js +2 -1
- package/dist/pipeline/annotate.js.map +1 -1
- package/dist/pipeline/compile.d.ts +4 -34
- package/dist/pipeline/compile.js +29 -568
- package/dist/pipeline/compile.js.map +1 -1
- package/dist/pipeline/constitution-compiler.js +1 -1
- package/dist/pipeline/mcp-connections.d.ts +16 -0
- package/dist/pipeline/mcp-connections.js +61 -0
- package/dist/pipeline/mcp-connections.js.map +1 -0
- package/dist/pipeline/pipeline-runner.d.ts +86 -0
- package/dist/pipeline/pipeline-runner.js +554 -0
- package/dist/pipeline/pipeline-runner.js.map +1 -0
- package/dist/pipeline/pipeline-shared.d.ts +29 -2
- package/dist/pipeline/pipeline-shared.js +68 -12
- package/dist/pipeline/pipeline-shared.js.map +1 -1
- package/dist/pipeline/refresh-lists.js +38 -12
- package/dist/pipeline/refresh-lists.js.map +1 -1
- package/dist/pipeline/scenario-generator.js +2 -1
- package/dist/pipeline/scenario-generator.js.map +1 -1
- package/dist/pipeline/tool-annotator.d.ts +3 -3
- package/dist/pipeline/tool-annotator.js +96 -4
- package/dist/pipeline/tool-annotator.js.map +1 -1
- package/dist/pipeline/types.d.ts +52 -0
- package/dist/sandbox/index.js +36 -1
- package/dist/sandbox/index.js.map +1 -1
- package/dist/session/agent-session.d.ts +3 -0
- package/dist/session/agent-session.js +10 -1
- package/dist/session/agent-session.js.map +1 -1
- package/dist/session/index.js +54 -5
- package/dist/session/index.js.map +1 -1
- package/dist/session/preflight.js +26 -6
- package/dist/session/preflight.js.map +1 -1
- package/dist/session/prompts.d.ts +14 -0
- package/dist/session/prompts.js +39 -2
- package/dist/session/prompts.js.map +1 -1
- package/dist/session/session-manager.d.ts +105 -0
- package/dist/session/session-manager.js +134 -0
- package/dist/session/session-manager.js.map +1 -0
- package/dist/session/types.d.ts +27 -0
- package/dist/session/workspace-validation.d.ts +2 -0
- package/dist/session/workspace-validation.js +6 -5
- package/dist/session/workspace-validation.js.map +1 -1
- package/dist/signal/bot-command.d.ts +2 -0
- package/dist/signal/bot-command.js +8 -0
- package/dist/signal/bot-command.js.map +1 -1
- package/dist/signal/format.d.ts +27 -0
- package/dist/signal/format.js +59 -0
- package/dist/signal/format.js.map +1 -1
- package/dist/signal/signal-bot-daemon.d.ts +27 -25
- package/dist/signal/signal-bot-daemon.js +145 -130
- package/dist/signal/signal-bot-daemon.js.map +1 -1
- package/dist/signal/signal-container.js +63 -19
- package/dist/signal/signal-container.js.map +1 -1
- package/dist/signal/signal-transport.js +3 -8
- package/dist/signal/signal-transport.js.map +1 -1
- package/dist/trusted-process/domain-utils.d.ts +38 -4
- package/dist/trusted-process/domain-utils.js +118 -11
- package/dist/trusted-process/domain-utils.js.map +1 -1
- package/dist/trusted-process/index.js +6 -2
- package/dist/trusted-process/index.js.map +1 -1
- package/dist/trusted-process/mcp-client-manager.js +11 -5
- package/dist/trusted-process/mcp-client-manager.js.map +1 -1
- package/dist/trusted-process/mcp-proxy-server.d.ts +2 -0
- package/dist/trusted-process/mcp-proxy-server.js +59 -16
- package/dist/trusted-process/mcp-proxy-server.js.map +1 -1
- package/dist/trusted-process/permissive-output-validator.d.ts +23 -0
- package/dist/trusted-process/permissive-output-validator.js +10 -0
- package/dist/trusted-process/permissive-output-validator.js.map +1 -0
- package/dist/trusted-process/policy-engine.d.ts +27 -4
- package/dist/trusted-process/policy-engine.js +152 -57
- package/dist/trusted-process/policy-engine.js.map +1 -1
- package/dist/trusted-process/tool-description-hints.d.ts +19 -0
- package/dist/trusted-process/tool-description-hints.js +53 -0
- package/dist/trusted-process/tool-description-hints.js.map +1 -0
- package/dist/types/argument-roles.d.ts +33 -1
- package/dist/types/argument-roles.js +129 -1
- package/dist/types/argument-roles.js.map +1 -1
- package/docker/Dockerfile.goose +34 -0
- package/docker/entrypoint-goose.sh +30 -0
- package/package.json +1 -1
- package/src/config/generated/tool-annotations.json +487 -338
- package/src/config/mcp-servers.json +2 -8
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claude-code.js","sourceRoot":"","sources":["../../../src/docker/adapters/claude-code.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAKH,OAAO,EACL,iBAAiB,EACjB,sBAAsB,EACtB,sBAAsB,EACtB,2BAA2B,GAC5B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"claude-code.js","sourceRoot":"","sources":["../../../src/docker/adapters/claude-code.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Goose agent adapter for Docker Agent Mode.
|
|
3
|
+
*
|
|
4
|
+
* Configures a Docker container running Goose (by Block) with:
|
|
5
|
+
* - MCP server discovery via config.yaml (YAML, Goose extensions format)
|
|
6
|
+
* - System prompt injection via --instructions file
|
|
7
|
+
* - Multi-provider support (Anthropic, OpenAI, Google)
|
|
8
|
+
* - GOOSE_MODE=auto to skip all permission prompts
|
|
9
|
+
*
|
|
10
|
+
* Key differences from Claude Code adapter:
|
|
11
|
+
* - Config format is YAML (not JSON)
|
|
12
|
+
* - System prompt is file-based (not inline CLI flag)
|
|
13
|
+
* - No session continuity in batch mode (each turn is independent)
|
|
14
|
+
* - Output is plain text (no --output-format json)
|
|
15
|
+
* - Provider-specific credential detection (not Anthropic-only)
|
|
16
|
+
*/
|
|
17
|
+
import type { AgentAdapter } from '../agent-adapter.js';
|
|
18
|
+
import type { ProviderConfig } from '../provider-config.js';
|
|
19
|
+
import type { ResolvedUserConfig, GooseProvider } from '../../config/user-config.js';
|
|
20
|
+
/**
|
|
21
|
+
* Returns the provider config for the selected Goose provider.
|
|
22
|
+
*/
|
|
23
|
+
export declare function getProviderConfig(provider: GooseProvider): ProviderConfig;
|
|
24
|
+
/**
|
|
25
|
+
* Strips ANSI escape codes from a string.
|
|
26
|
+
*/
|
|
27
|
+
export declare function stripAnsi(text: string): string;
|
|
28
|
+
/**
|
|
29
|
+
* Extracts the final response from Goose's plain-text output.
|
|
30
|
+
*
|
|
31
|
+
* TODO: This heuristic needs validation against real Goose output from
|
|
32
|
+
* Prototype 1 (Section 12 of the design doc). The current implementation
|
|
33
|
+
* extracts the last contiguous block of non-empty lines, which is a
|
|
34
|
+
* reasonable starting point based on similar CLI agent output patterns.
|
|
35
|
+
*
|
|
36
|
+
* The parser should be refined once actual Goose headless output samples
|
|
37
|
+
* are captured. If the heuristic proves unreliable, the fallback is to
|
|
38
|
+
* return the full ANSI-stripped output (noisy but functional).
|
|
39
|
+
*/
|
|
40
|
+
export declare function extractFinalResponse(raw: string): string;
|
|
41
|
+
/**
|
|
42
|
+
* Ensures a heredoc delimiter does not collide with the input content.
|
|
43
|
+
*
|
|
44
|
+
* If the default delimiter appears in the content, appends random hex
|
|
45
|
+
* suffixes until a unique delimiter is found. The content itself is
|
|
46
|
+
* never modified -- only the delimiter changes.
|
|
47
|
+
*/
|
|
48
|
+
export declare function escapeHeredoc(content: string): {
|
|
49
|
+
delimiter: string;
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* Creates a Goose agent adapter configured with the user's provider preferences.
|
|
53
|
+
*
|
|
54
|
+
* @param userConfig - Resolved user config. When undefined, uses defaults
|
|
55
|
+
* (anthropic provider, default model). This enables --list-agents to work
|
|
56
|
+
* without loading config.
|
|
57
|
+
*/
|
|
58
|
+
export declare function createGooseAdapter(userConfig?: ResolvedUserConfig): AgentAdapter;
|
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Goose agent adapter for Docker Agent Mode.
|
|
3
|
+
*
|
|
4
|
+
* Configures a Docker container running Goose (by Block) with:
|
|
5
|
+
* - MCP server discovery via config.yaml (YAML, Goose extensions format)
|
|
6
|
+
* - System prompt injection via --instructions file
|
|
7
|
+
* - Multi-provider support (Anthropic, OpenAI, Google)
|
|
8
|
+
* - GOOSE_MODE=auto to skip all permission prompts
|
|
9
|
+
*
|
|
10
|
+
* Key differences from Claude Code adapter:
|
|
11
|
+
* - Config format is YAML (not JSON)
|
|
12
|
+
* - System prompt is file-based (not inline CLI flag)
|
|
13
|
+
* - No session continuity in batch mode (each turn is independent)
|
|
14
|
+
* - Output is plain text (no --output-format json)
|
|
15
|
+
* - Provider-specific credential detection (not Anthropic-only)
|
|
16
|
+
*/
|
|
17
|
+
import { randomBytes } from 'node:crypto';
|
|
18
|
+
import { anthropicProvider, openaiProvider, googleProvider } from '../provider-config.js';
|
|
19
|
+
import { buildSystemPrompt } from '../../session/prompts.js';
|
|
20
|
+
import { resolveApiKeyForProvider } from '../../config/model-provider.js';
|
|
21
|
+
import { buildResizePtyScript, buildCheckPtySizeScript, buildNetworkSection, buildPolicySection, buildAttributionSection, } from './shared-scripts.js';
|
|
22
|
+
const GOOSE_IMAGE = 'ironcurtain-goose:latest';
|
|
23
|
+
/** Default heredoc delimiter for shell commands. */
|
|
24
|
+
const DEFAULT_HEREDOC_DELIMITER = 'IRONCURTAIN_EOF';
|
|
25
|
+
// ─── Provider Helpers ────────────────────────────────────────
|
|
26
|
+
/**
|
|
27
|
+
* Returns the provider config for the selected Goose provider.
|
|
28
|
+
*/
|
|
29
|
+
export function getProviderConfig(provider) {
|
|
30
|
+
switch (provider) {
|
|
31
|
+
case 'anthropic':
|
|
32
|
+
return anthropicProvider;
|
|
33
|
+
case 'openai':
|
|
34
|
+
return openaiProvider;
|
|
35
|
+
case 'google':
|
|
36
|
+
return googleProvider;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
// ─── Response Parsing ────────────────────────────────────────
|
|
40
|
+
/**
|
|
41
|
+
* Strips ANSI escape codes from a string.
|
|
42
|
+
*/
|
|
43
|
+
export function stripAnsi(text) {
|
|
44
|
+
// Matches common ANSI escape sequences: CSI (ESC[), OSC (ESC]), and simple ESC sequences
|
|
45
|
+
// eslint-disable-next-line no-control-regex -- ANSI escape codes are control characters by definition
|
|
46
|
+
return text.replace(/\x1b\[[0-9;]*[a-zA-Z]|\x1b\][^\x07]*\x07|\x1b[()][AB012]/g, '');
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Extracts the final response from Goose's plain-text output.
|
|
50
|
+
*
|
|
51
|
+
* TODO: This heuristic needs validation against real Goose output from
|
|
52
|
+
* Prototype 1 (Section 12 of the design doc). The current implementation
|
|
53
|
+
* extracts the last contiguous block of non-empty lines, which is a
|
|
54
|
+
* reasonable starting point based on similar CLI agent output patterns.
|
|
55
|
+
*
|
|
56
|
+
* The parser should be refined once actual Goose headless output samples
|
|
57
|
+
* are captured. If the heuristic proves unreliable, the fallback is to
|
|
58
|
+
* return the full ANSI-stripped output (noisy but functional).
|
|
59
|
+
*/
|
|
60
|
+
export function extractFinalResponse(raw) {
|
|
61
|
+
const lines = raw.split('\n');
|
|
62
|
+
// Walk backwards from the end, collecting lines until we hit
|
|
63
|
+
// a blank line preceded by content (end of final block).
|
|
64
|
+
const result = [];
|
|
65
|
+
let foundContent = false;
|
|
66
|
+
for (let i = lines.length - 1; i >= 0; i--) {
|
|
67
|
+
if (lines[i].trim() === '') {
|
|
68
|
+
if (foundContent)
|
|
69
|
+
break;
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
foundContent = true;
|
|
73
|
+
result.unshift(lines[i]);
|
|
74
|
+
}
|
|
75
|
+
return result.length > 0 ? result.join('\n') : raw.trim();
|
|
76
|
+
}
|
|
77
|
+
// ─── Heredoc Escaping ────────────────────────────────────────
|
|
78
|
+
/**
|
|
79
|
+
* Ensures a heredoc delimiter does not collide with the input content.
|
|
80
|
+
*
|
|
81
|
+
* If the default delimiter appears in the content, appends random hex
|
|
82
|
+
* suffixes until a unique delimiter is found. The content itself is
|
|
83
|
+
* never modified -- only the delimiter changes.
|
|
84
|
+
*/
|
|
85
|
+
export function escapeHeredoc(content) {
|
|
86
|
+
let delimiter = DEFAULT_HEREDOC_DELIMITER;
|
|
87
|
+
while (content.includes(delimiter)) {
|
|
88
|
+
const suffix = randomBytes(4).toString('hex');
|
|
89
|
+
delimiter = `${DEFAULT_HEREDOC_DELIMITER}_${suffix}`;
|
|
90
|
+
}
|
|
91
|
+
return { delimiter };
|
|
92
|
+
}
|
|
93
|
+
// ─── System Prompt ───────────────────────────────────────────
|
|
94
|
+
function buildGooseDockerEnvironmentPrompt(context) {
|
|
95
|
+
return `## Docker Environment
|
|
96
|
+
|
|
97
|
+
### Workspace (\`${context.workspaceDir}\`)
|
|
98
|
+
This is your workspace inside the container. You have full access here.
|
|
99
|
+
For local file operations inside ${context.workspaceDir}, use your built-in tools.
|
|
100
|
+
|
|
101
|
+
### External Operations (MCP tools)
|
|
102
|
+
Use the IronCurtain MCP extension for operations that require external access:
|
|
103
|
+
- Network requests (HTTP fetches, web searches, API calls)
|
|
104
|
+
- Git remote operations (clone, push, pull, fetch)
|
|
105
|
+
- Reading files outside ${context.workspaceDir}
|
|
106
|
+
|
|
107
|
+
After cloning a repo or writing files via MCP tools, use your built-in
|
|
108
|
+
tools for subsequent file operations.
|
|
109
|
+
|
|
110
|
+
${buildNetworkSection('the IronCurtain MCP tools')}
|
|
111
|
+
${buildPolicySection('MCP tool call')}
|
|
112
|
+
${buildAttributionSection()}`;
|
|
113
|
+
}
|
|
114
|
+
// ─── Orientation Scripts ─────────────────────────────────────
|
|
115
|
+
function buildStartScript() {
|
|
116
|
+
return `#!/bin/bash
|
|
117
|
+
# Set initial terminal size from host env vars
|
|
118
|
+
if [ -n "$IRONCURTAIN_INITIAL_COLS" ] && [ -n "$IRONCURTAIN_INITIAL_ROWS" ]; then
|
|
119
|
+
stty cols "$IRONCURTAIN_INITIAL_COLS" rows "$IRONCURTAIN_INITIAL_ROWS" 2>/dev/null
|
|
120
|
+
fi
|
|
121
|
+
# Write system prompt to temp file for --instructions
|
|
122
|
+
PROMPT_FILE=$(mktemp /tmp/goose-prompt-XXXXXX.md)
|
|
123
|
+
trap 'rm -f "$PROMPT_FILE"' EXIT
|
|
124
|
+
printf '%s' "$IRONCURTAIN_SYSTEM_PROMPT" > "$PROMPT_FILE"
|
|
125
|
+
exec goose run -s -i "$PROMPT_FILE"
|
|
126
|
+
`;
|
|
127
|
+
}
|
|
128
|
+
// ─── Adapter Factory ─────────────────────────────────────────
|
|
129
|
+
/**
|
|
130
|
+
* Creates a Goose agent adapter configured with the user's provider preferences.
|
|
131
|
+
*
|
|
132
|
+
* @param userConfig - Resolved user config. When undefined, uses defaults
|
|
133
|
+
* (anthropic provider, default model). This enables --list-agents to work
|
|
134
|
+
* without loading config.
|
|
135
|
+
*/
|
|
136
|
+
export function createGooseAdapter(userConfig) {
|
|
137
|
+
const gooseProvider = userConfig?.gooseProvider ?? 'anthropic';
|
|
138
|
+
const gooseModel = userConfig?.gooseModel ?? 'claude-sonnet-4-20250514';
|
|
139
|
+
const credentialHelpText = `No API key found for Goose provider "${gooseProvider}". ` +
|
|
140
|
+
'Set the appropriate API key in your environment ' +
|
|
141
|
+
'(ANTHROPIC_API_KEY, OPENAI_API_KEY, or GOOGLE_API_KEY) ' +
|
|
142
|
+
'or via `ironcurtain config`.';
|
|
143
|
+
const adapter = {
|
|
144
|
+
id: 'goose',
|
|
145
|
+
displayName: 'Goose',
|
|
146
|
+
credentialHelpText,
|
|
147
|
+
// eslint-disable-next-line @typescript-eslint/require-await -- interface requires Promise return
|
|
148
|
+
async getImage() {
|
|
149
|
+
return GOOSE_IMAGE;
|
|
150
|
+
},
|
|
151
|
+
generateMcpConfig(socketPath) {
|
|
152
|
+
const isTcp = socketPath.includes(':');
|
|
153
|
+
const connectTarget = isTcp ? `TCP:${socketPath}` : `UNIX-CONNECT:${socketPath}`;
|
|
154
|
+
const yaml = [
|
|
155
|
+
'GOOSE_TELEMETRY_ENABLED: false',
|
|
156
|
+
'extensions:',
|
|
157
|
+
' ironcurtain:',
|
|
158
|
+
' name: IronCurtain Sandbox',
|
|
159
|
+
' type: stdio',
|
|
160
|
+
' enabled: true',
|
|
161
|
+
' cmd: socat',
|
|
162
|
+
' args:',
|
|
163
|
+
' - STDIO',
|
|
164
|
+
` - ${connectTarget}`,
|
|
165
|
+
' timeout: 600',
|
|
166
|
+
'',
|
|
167
|
+
].join('\n');
|
|
168
|
+
return [{ path: 'goose-config.yaml', content: yaml }];
|
|
169
|
+
},
|
|
170
|
+
generateOrientationFiles() {
|
|
171
|
+
return [
|
|
172
|
+
{ path: 'start-goose.sh', content: buildStartScript(), mode: 0o755 },
|
|
173
|
+
{ path: 'resize-pty.sh', content: buildResizePtyScript('goose'), mode: 0o755 },
|
|
174
|
+
{ path: 'check-pty-size.sh', content: buildCheckPtySizeScript('goose'), mode: 0o755 },
|
|
175
|
+
];
|
|
176
|
+
},
|
|
177
|
+
buildCommand(message, systemPrompt) {
|
|
178
|
+
const instructions = `${systemPrompt}\n\n---\n\nUser request:\n${message}`;
|
|
179
|
+
const { delimiter } = escapeHeredoc(instructions);
|
|
180
|
+
return [
|
|
181
|
+
'/bin/sh',
|
|
182
|
+
'-c',
|
|
183
|
+
`PROMPT_FILE=$(mktemp /tmp/goose-prompt-XXXXXX.md) && ` +
|
|
184
|
+
`trap 'rm -f "$PROMPT_FILE"' EXIT && ` +
|
|
185
|
+
`cat > "$PROMPT_FILE" << '${delimiter}'\n${instructions}\n${delimiter}\n` +
|
|
186
|
+
`goose run --no-session -i "$PROMPT_FILE"`,
|
|
187
|
+
];
|
|
188
|
+
},
|
|
189
|
+
buildSystemPrompt(context) {
|
|
190
|
+
const codeModePrompt = buildSystemPrompt(context.serverListings, context.hostSandboxDir);
|
|
191
|
+
const dockerPrompt = buildGooseDockerEnvironmentPrompt(context);
|
|
192
|
+
return `${codeModePrompt}\n${dockerPrompt}`;
|
|
193
|
+
},
|
|
194
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars -- interface requires authKind parameter
|
|
195
|
+
getProviders(_authKind) {
|
|
196
|
+
// Goose uses exactly one provider based on user config.
|
|
197
|
+
// The authKind parameter is ignored because Goose does not support OAuth.
|
|
198
|
+
return [getProviderConfig(gooseProvider)];
|
|
199
|
+
},
|
|
200
|
+
buildEnv(_config, fakeKeys) {
|
|
201
|
+
const env = {
|
|
202
|
+
GOOSE_PROVIDER: gooseProvider,
|
|
203
|
+
GOOSE_MODEL: gooseModel,
|
|
204
|
+
GOOSE_MODE: 'auto',
|
|
205
|
+
GOOSE_MAX_TURNS: '200',
|
|
206
|
+
// Defensive TLS cert env vars for Rust-based Goose.
|
|
207
|
+
// Covers native-tls and rustls-native-certs backends.
|
|
208
|
+
SSL_CERT_FILE: '/etc/ssl/certs/ca-certificates.crt',
|
|
209
|
+
SSL_CERT_DIR: '/etc/ssl/certs',
|
|
210
|
+
};
|
|
211
|
+
const providerHost = getProviderConfig(gooseProvider).host;
|
|
212
|
+
const fakeKey = fakeKeys.get(providerHost);
|
|
213
|
+
if (!fakeKey) {
|
|
214
|
+
throw new Error(`No fake key generated for ${providerHost}`);
|
|
215
|
+
}
|
|
216
|
+
switch (gooseProvider) {
|
|
217
|
+
case 'anthropic':
|
|
218
|
+
env.ANTHROPIC_API_KEY = fakeKey;
|
|
219
|
+
break;
|
|
220
|
+
case 'openai':
|
|
221
|
+
env.OPENAI_API_KEY = fakeKey;
|
|
222
|
+
break;
|
|
223
|
+
case 'google':
|
|
224
|
+
env.GOOGLE_API_KEY = fakeKey;
|
|
225
|
+
break;
|
|
226
|
+
}
|
|
227
|
+
return env;
|
|
228
|
+
},
|
|
229
|
+
extractResponse(exitCode, stdout) {
|
|
230
|
+
const clean = stripAnsi(stdout);
|
|
231
|
+
if (exitCode !== 0) {
|
|
232
|
+
return { text: `Goose exited with code ${exitCode}.\n\nOutput:\n${clean.trim()}` };
|
|
233
|
+
}
|
|
234
|
+
const text = extractFinalResponse(clean);
|
|
235
|
+
return { text };
|
|
236
|
+
},
|
|
237
|
+
buildPtyCommand(_systemPrompt, ptySockPath, ptyPort) {
|
|
238
|
+
const listenArg = ptySockPath ? `UNIX-LISTEN:${ptySockPath},fork` : `TCP-LISTEN:${ptyPort},reuseaddr`;
|
|
239
|
+
return ['socat', listenArg, 'EXEC:/etc/ironcurtain/start-goose.sh,pty,setsid,ctty,stderr,rawer'];
|
|
240
|
+
},
|
|
241
|
+
detectCredential(config) {
|
|
242
|
+
const key = resolveApiKeyForProvider(gooseProvider, config.userConfig);
|
|
243
|
+
if (key)
|
|
244
|
+
return { kind: 'apikey', key };
|
|
245
|
+
return { kind: 'none' };
|
|
246
|
+
},
|
|
247
|
+
};
|
|
248
|
+
return adapter;
|
|
249
|
+
}
|
|
250
|
+
//# sourceMappingURL=goose.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"goose.js","sourceRoot":"","sources":["../../../src/docker/adapters/goose.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared shell script generators and prompt sections used by multiple agent adapters.
|
|
3
|
+
*
|
|
4
|
+
* These are extracted to avoid duplication between the Claude Code and Goose adapters.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Generates a resize-pty.sh script parameterized by the agent's process name.
|
|
8
|
+
* Called from the host via: docker exec <cid> /etc/ironcurtain/resize-pty.sh <cols> <rows>
|
|
9
|
+
*/
|
|
10
|
+
export declare function buildResizePtyScript(processName: string): string;
|
|
11
|
+
/**
|
|
12
|
+
* Generates a check-pty-size.sh script parameterized by the agent's process name.
|
|
13
|
+
* Returns "rows cols" of the container PTY.
|
|
14
|
+
*/
|
|
15
|
+
export declare function buildCheckPtySizeScript(processName: string): string;
|
|
16
|
+
/**
|
|
17
|
+
* Network restriction section. `toolReference` describes how to access network
|
|
18
|
+
* (e.g. "the sandbox tools via `execute_code`" or "the IronCurtain MCP tools").
|
|
19
|
+
*/
|
|
20
|
+
export declare function buildNetworkSection(toolReference: string): string;
|
|
21
|
+
/**
|
|
22
|
+
* Policy enforcement section. `callType` describes what is being evaluated
|
|
23
|
+
* (e.g. "tool call through `execute_code`" or "MCP tool call").
|
|
24
|
+
*/
|
|
25
|
+
export declare function buildPolicySection(callType: string): string;
|
|
26
|
+
/**
|
|
27
|
+
* Attribution section (identical for all agents).
|
|
28
|
+
*/
|
|
29
|
+
export declare function buildAttributionSection(): string;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared shell script generators and prompt sections used by multiple agent adapters.
|
|
3
|
+
*
|
|
4
|
+
* These are extracted to avoid duplication between the Claude Code and Goose adapters.
|
|
5
|
+
*/
|
|
6
|
+
// ─── PTY Shell Scripts ──────────────────────────────────────
|
|
7
|
+
/**
|
|
8
|
+
* Generates a resize-pty.sh script parameterized by the agent's process name.
|
|
9
|
+
* Called from the host via: docker exec <cid> /etc/ironcurtain/resize-pty.sh <cols> <rows>
|
|
10
|
+
*/
|
|
11
|
+
export function buildResizePtyScript(processName) {
|
|
12
|
+
const varPrefix = processName.toUpperCase().replace(/-/g, '_');
|
|
13
|
+
return `#!/bin/bash
|
|
14
|
+
# Called from the host via: docker exec <cid> /etc/ironcurtain/resize-pty.sh <cols> <rows>
|
|
15
|
+
COLS=$1
|
|
16
|
+
ROWS=$2
|
|
17
|
+
|
|
18
|
+
${varPrefix}_PID=$(pgrep -x ${processName} | head -1)
|
|
19
|
+
if [ -z "$${varPrefix}_PID" ]; then
|
|
20
|
+
echo "no-${processName}" >&2
|
|
21
|
+
exit 0
|
|
22
|
+
fi
|
|
23
|
+
|
|
24
|
+
PTS=$(readlink /proc/$${varPrefix}_PID/fd/0 2>/dev/null)
|
|
25
|
+
if [ -z "$PTS" ] || ! [ -e "$PTS" ]; then
|
|
26
|
+
echo "no-pty pid=$${varPrefix}_PID pts=$PTS" >&2
|
|
27
|
+
exit 0
|
|
28
|
+
fi
|
|
29
|
+
|
|
30
|
+
stty -F "$PTS" cols "$COLS" rows "$ROWS" 2>/dev/null
|
|
31
|
+
RC=$?
|
|
32
|
+
kill -WINCH "$${varPrefix}_PID" 2>/dev/null
|
|
33
|
+
echo "ok pid=$${varPrefix}_PID pts=$PTS stty=$RC \${COLS}x\${ROWS}" >&2
|
|
34
|
+
`;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Generates a check-pty-size.sh script parameterized by the agent's process name.
|
|
38
|
+
* Returns "rows cols" of the container PTY.
|
|
39
|
+
*/
|
|
40
|
+
export function buildCheckPtySizeScript(processName) {
|
|
41
|
+
const varPrefix = processName.toUpperCase().replace(/-/g, '_');
|
|
42
|
+
return `#!/bin/bash
|
|
43
|
+
# Returns "rows cols" of the container PTY
|
|
44
|
+
${varPrefix}_PID=$(pgrep -x ${processName} | head -1)
|
|
45
|
+
if [ -z "$${varPrefix}_PID" ]; then echo "0 0"; exit 0; fi
|
|
46
|
+
PTS=$(readlink /proc/$${varPrefix}_PID/fd/0 2>/dev/null)
|
|
47
|
+
if [ -z "$PTS" ] || ! [ -e "$PTS" ]; then echo "0 0"; exit 0; fi
|
|
48
|
+
stty -F "$PTS" size 2>/dev/null || echo "0 0"
|
|
49
|
+
`;
|
|
50
|
+
}
|
|
51
|
+
// ─── Shared Docker Environment Prompt Sections ──────────────
|
|
52
|
+
/**
|
|
53
|
+
* Network restriction section. `toolReference` describes how to access network
|
|
54
|
+
* (e.g. "the sandbox tools via `execute_code`" or "the IronCurtain MCP tools").
|
|
55
|
+
*/
|
|
56
|
+
export function buildNetworkSection(toolReference) {
|
|
57
|
+
return `### Network
|
|
58
|
+
The container has NO direct internet access. All HTTP requests and
|
|
59
|
+
git operations MUST go through ${toolReference}.`;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Policy enforcement section. `callType` describes what is being evaluated
|
|
63
|
+
* (e.g. "tool call through `execute_code`" or "MCP tool call").
|
|
64
|
+
*/
|
|
65
|
+
export function buildPolicySection(callType) {
|
|
66
|
+
return `### Policy Enforcement
|
|
67
|
+
Every ${callType} is evaluated against security policy rules:
|
|
68
|
+
- **Allowed**: proceeds automatically
|
|
69
|
+
- **Denied**: blocked -- do NOT retry denied operations
|
|
70
|
+
- **Escalated**: requires human approval -- you will receive the result once approved`;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Attribution section (identical for all agents).
|
|
74
|
+
*/
|
|
75
|
+
export function buildAttributionSection() {
|
|
76
|
+
return `### Attribution
|
|
77
|
+
When adding attribution lines (e.g. Co-Authored-By, "Generated with"), include
|
|
78
|
+
"running under IronCurtain" alongside the tool name.`;
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=shared-scripts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared-scripts.js","sourceRoot":"","sources":["../../../src/docker/adapters/shared-scripts.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,+DAA+D;AAE/D;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAAC,WAAmB;IACtD,MAAM,SAAS,GAAG,WAAW,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IAC/D,OAAO;;;;;EAKP,SAAS,mBAAmB,WAAW;YAC7B,SAAS;aACR,WAAW;;;;wBAIA,SAAS;;sBAEX,SAAS;;;;;;gBAMf,SAAS;gBACT,SAAS;CACxB,CAAC;AACF,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,uBAAuB,CAAC,WAAmB;IACzD,MAAM,SAAS,GAAG,WAAW,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IAC/D,OAAO;;EAEP,SAAS,mBAAmB,WAAW;YAC7B,SAAS;wBACG,SAAS;;;CAGhC,CAAC;AACF,CAAC;AAED,+DAA+D;AAE/D;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,aAAqB;IACvD,OAAO;;iCAEwB,aAAa,GAAG,CAAC;AAClD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,QAAgB;IACjD,OAAO;QACD,QAAQ;;;sFAGsE,CAAC;AACvF,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,uBAAuB;IACrC,OAAO;;qDAE4C,CAAC;AACtD,CAAC"}
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
import type { IronCurtainConfig } from '../config/types.js';
|
|
9
9
|
import type { ProviderConfig } from './provider-config.js';
|
|
10
10
|
import type { ServerListing } from '../session/prompts.js';
|
|
11
|
+
import type { AuthMethod } from './oauth-credentials.js';
|
|
11
12
|
/**
|
|
12
13
|
* The workspace directory inside Docker containers. The host sandbox
|
|
13
14
|
* directory is bind-mounted at this path. Used for path rewriting
|
|
@@ -134,4 +135,15 @@ export interface AgentAdapter {
|
|
|
134
135
|
* @param ptyPort - the TCP port for the PTY listener (macOS), or undefined for UDS mode
|
|
135
136
|
*/
|
|
136
137
|
buildPtyCommand?(systemPrompt: string, ptySockPath: string | undefined, ptyPort: number | undefined): readonly string[];
|
|
138
|
+
/**
|
|
139
|
+
* Detects available credentials for this agent.
|
|
140
|
+
* When not implemented, prepareDockerInfrastructure() falls back to
|
|
141
|
+
* detectAuthMethod() (Anthropic OAuth + API key detection).
|
|
142
|
+
*/
|
|
143
|
+
detectCredential?(config: IronCurtainConfig): AuthMethod;
|
|
144
|
+
/**
|
|
145
|
+
* Error message to show when no credentials are detected.
|
|
146
|
+
* When not set, the default Anthropic-oriented message is used.
|
|
147
|
+
*/
|
|
148
|
+
readonly credentialHelpText?: string;
|
|
137
149
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-adapter.js","sourceRoot":"","sources":["../../src/docker/agent-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;
|
|
1
|
+
{"version":3,"file":"agent-adapter.js","sourceRoot":"","sources":["../../src/docker/agent-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAOH;;;;GAIG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,YAAY,CAAC"}
|
|
@@ -5,11 +5,16 @@
|
|
|
5
5
|
* The registry is a simple Map -- no dynamic loading or plugin system.
|
|
6
6
|
*/
|
|
7
7
|
import type { AgentAdapter, AgentId } from './agent-adapter.js';
|
|
8
|
+
import type { ResolvedUserConfig } from '../config/user-config.js';
|
|
8
9
|
export declare function registerAgent(adapter: AgentAdapter): void;
|
|
9
10
|
export declare function getAgent(id: AgentId): AgentAdapter;
|
|
10
11
|
export declare function listAgents(): readonly AgentAdapter[];
|
|
11
12
|
/**
|
|
12
13
|
* Ensures all built-in agent adapters are registered. Safe to call
|
|
13
14
|
* multiple times -- skips adapters that are already registered.
|
|
15
|
+
*
|
|
16
|
+
* @param userConfig - Resolved user config. When provided, the Goose adapter
|
|
17
|
+
* uses it for provider selection. When undefined, defaults apply (anthropic
|
|
18
|
+
* provider, default model). This allows --list-agents to work without config.
|
|
14
19
|
*/
|
|
15
|
-
export declare function registerBuiltinAdapters(): Promise<void>;
|
|
20
|
+
export declare function registerBuiltinAdapters(userConfig?: ResolvedUserConfig): Promise<void>;
|
|
@@ -25,11 +25,20 @@ export function listAgents() {
|
|
|
25
25
|
/**
|
|
26
26
|
* Ensures all built-in agent adapters are registered. Safe to call
|
|
27
27
|
* multiple times -- skips adapters that are already registered.
|
|
28
|
+
*
|
|
29
|
+
* @param userConfig - Resolved user config. When provided, the Goose adapter
|
|
30
|
+
* uses it for provider selection. When undefined, defaults apply (anthropic
|
|
31
|
+
* provider, default model). This allows --list-agents to work without config.
|
|
28
32
|
*/
|
|
29
|
-
export async function registerBuiltinAdapters() {
|
|
33
|
+
export async function registerBuiltinAdapters(userConfig) {
|
|
30
34
|
const { claudeCodeAdapter } = await import('./adapters/claude-code.js');
|
|
31
35
|
if (!registry.has(claudeCodeAdapter.id)) {
|
|
32
36
|
registry.set(claudeCodeAdapter.id, claudeCodeAdapter);
|
|
33
37
|
}
|
|
38
|
+
if (!registry.has('goose')) {
|
|
39
|
+
const { createGooseAdapter } = await import('./adapters/goose.js');
|
|
40
|
+
const gooseAdapter = createGooseAdapter(userConfig);
|
|
41
|
+
registry.set(gooseAdapter.id, gooseAdapter);
|
|
42
|
+
}
|
|
34
43
|
}
|
|
35
44
|
//# sourceMappingURL=agent-registry.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-registry.js","sourceRoot":"","sources":["../../src/docker/agent-registry.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;
|
|
1
|
+
{"version":3,"file":"agent-registry.js","sourceRoot":"","sources":["../../src/docker/agent-registry.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAyB,CAAC;AAElD,MAAM,UAAU,aAAa,CAAC,OAAqB;IACjD,IAAI,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CAAC,qCAAqC,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC;IACrE,CAAC;IACD,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;AACpC,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,EAAW;IAClC,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACjC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,SAAS,GAAG,CAAC,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAClD,MAAM,IAAI,KAAK,CAAC,kBAAkB,EAAE,gBAAgB,SAAS,IAAI,MAAM,EAAE,CAAC,CAAC;IAC7E,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,OAAO,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;AAChC,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,UAA+B;IAC3E,MAAM,EAAE,iBAAiB,EAAE,GAAG,MAAM,MAAM,CAAC,2BAA2B,CAAC,CAAC;IACxE,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,iBAAiB,CAAC,EAAE,CAAC,EAAE,CAAC;QACxC,QAAQ,CAAC,GAAG,CAAC,iBAAiB,CAAC,EAAE,EAAE,iBAAiB,CAAC,CAAC;IACxD,CAAC;IAED,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAkB,CAAC,EAAE,CAAC;QACtC,MAAM,EAAE,kBAAkB,EAAE,GAAG,MAAM,MAAM,CAAC,qBAAqB,CAAC,CAAC;QACnE,MAAM,YAAY,GAAG,kBAAkB,CAAC,UAAU,CAAC,CAAC;QACpD,QAAQ,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,EAAE,YAAY,CAAC,CAAC;IAC9C,CAAC;AACH,CAAC"}
|
|
@@ -35,6 +35,7 @@ export interface DockerAgentSessionDeps {
|
|
|
35
35
|
readonly useTcp?: boolean;
|
|
36
36
|
readonly onEscalation?: (request: EscalationRequest) => void;
|
|
37
37
|
readonly onEscalationExpired?: () => void;
|
|
38
|
+
readonly onEscalationResolved?: (escalationId: string, decision: 'approved' | 'denied') => void;
|
|
38
39
|
readonly onDiagnostic?: (event: DiagnosticEvent) => void;
|
|
39
40
|
/**
|
|
40
41
|
* When set, proxies are already started, orientation is built, and
|
|
@@ -78,6 +79,7 @@ export declare class DockerAgentSession implements Session {
|
|
|
78
79
|
private cumulativeCostUsd;
|
|
79
80
|
private readonly onEscalation?;
|
|
80
81
|
private readonly onEscalationExpired?;
|
|
82
|
+
private readonly onEscalationResolved?;
|
|
81
83
|
private readonly onDiagnostic?;
|
|
82
84
|
private readonly preBuiltInfrastructure?;
|
|
83
85
|
constructor(deps: DockerAgentSessionDeps);
|
|
@@ -109,29 +111,4 @@ export declare class DockerAgentSession implements Session {
|
|
|
109
111
|
*/
|
|
110
112
|
private checkInternalNetworkConnectivity;
|
|
111
113
|
private writeUserContext;
|
|
112
|
-
/**
|
|
113
|
-
* Ensures the Docker image exists and is up-to-date, building it
|
|
114
|
-
* (and the base image) if needed.
|
|
115
|
-
*
|
|
116
|
-
* Staleness detection uses a content hash of all build inputs
|
|
117
|
-
* (Dockerfiles, entrypoint scripts, CA certificate) stored as
|
|
118
|
-
* Docker image labels.
|
|
119
|
-
*/
|
|
120
|
-
private ensureImage;
|
|
121
|
-
/**
|
|
122
|
-
* Ensures the base image exists and is up-to-date.
|
|
123
|
-
* Returns true if the base image was (re)built.
|
|
124
|
-
*/
|
|
125
|
-
private ensureBaseImage;
|
|
126
|
-
/**
|
|
127
|
-
* Checks if an image needs (re)building by comparing the stored
|
|
128
|
-
* build hash label against the expected hash.
|
|
129
|
-
*/
|
|
130
|
-
private isImageStale;
|
|
131
|
-
/**
|
|
132
|
-
* Computes a SHA-256 content hash of all files in the docker directory
|
|
133
|
-
* plus the CA certificate. This captures changes to Dockerfiles,
|
|
134
|
-
* entrypoint scripts, and the CA cert.
|
|
135
|
-
*/
|
|
136
|
-
private computeBuildHash;
|
|
137
114
|
}
|