@proletariat/cli 0.3.45 → 0.3.47

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 (77) hide show
  1. package/bin/validate-better-sqlite3.cjs +55 -0
  2. package/dist/commands/config/index.js +39 -1
  3. package/dist/commands/linear/auth.d.ts +14 -0
  4. package/dist/commands/linear/auth.js +211 -0
  5. package/dist/commands/linear/import.d.ts +21 -0
  6. package/dist/commands/linear/import.js +260 -0
  7. package/dist/commands/linear/status.d.ts +11 -0
  8. package/dist/commands/linear/status.js +88 -0
  9. package/dist/commands/linear/sync.d.ts +15 -0
  10. package/dist/commands/linear/sync.js +233 -0
  11. package/dist/commands/orchestrator/attach.d.ts +10 -1
  12. package/dist/commands/orchestrator/attach.js +102 -18
  13. package/dist/commands/orchestrator/index.js +22 -7
  14. package/dist/commands/orchestrator/start.d.ts +13 -1
  15. package/dist/commands/orchestrator/start.js +96 -25
  16. package/dist/commands/orchestrator/status.d.ts +1 -0
  17. package/dist/commands/orchestrator/status.js +10 -5
  18. package/dist/commands/orchestrator/stop.d.ts +1 -0
  19. package/dist/commands/orchestrator/stop.js +9 -4
  20. package/dist/commands/session/attach.js +32 -9
  21. package/dist/commands/ticket/link/duplicates.d.ts +15 -0
  22. package/dist/commands/ticket/link/duplicates.js +95 -0
  23. package/dist/commands/ticket/link/index.js +14 -0
  24. package/dist/commands/ticket/link/relates.d.ts +15 -0
  25. package/dist/commands/ticket/link/relates.js +95 -0
  26. package/dist/commands/work/index.js +4 -0
  27. package/dist/commands/work/review.d.ts +45 -0
  28. package/dist/commands/work/review.js +401 -0
  29. package/dist/commands/work/revise.js +4 -3
  30. package/dist/commands/work/spawn.d.ts +5 -0
  31. package/dist/commands/work/spawn.js +195 -14
  32. package/dist/commands/work/start.js +75 -19
  33. package/dist/hooks/init.js +18 -5
  34. package/dist/lib/database/native-validation.d.ts +21 -0
  35. package/dist/lib/database/native-validation.js +49 -0
  36. package/dist/lib/execution/config.d.ts +15 -0
  37. package/dist/lib/execution/config.js +54 -0
  38. package/dist/lib/execution/devcontainer.d.ts +6 -3
  39. package/dist/lib/execution/devcontainer.js +39 -12
  40. package/dist/lib/execution/runners.d.ts +28 -32
  41. package/dist/lib/execution/runners.js +353 -277
  42. package/dist/lib/execution/spawner.js +62 -5
  43. package/dist/lib/execution/types.d.ts +4 -0
  44. package/dist/lib/execution/types.js +3 -0
  45. package/dist/lib/external-issues/adapters.d.ts +26 -0
  46. package/dist/lib/external-issues/adapters.js +251 -0
  47. package/dist/lib/external-issues/index.d.ts +10 -0
  48. package/dist/lib/external-issues/index.js +14 -0
  49. package/dist/lib/external-issues/mapper.d.ts +21 -0
  50. package/dist/lib/external-issues/mapper.js +86 -0
  51. package/dist/lib/external-issues/types.d.ts +144 -0
  52. package/dist/lib/external-issues/types.js +26 -0
  53. package/dist/lib/external-issues/validation.d.ts +34 -0
  54. package/dist/lib/external-issues/validation.js +219 -0
  55. package/dist/lib/linear/client.d.ts +55 -0
  56. package/dist/lib/linear/client.js +254 -0
  57. package/dist/lib/linear/config.d.ts +37 -0
  58. package/dist/lib/linear/config.js +100 -0
  59. package/dist/lib/linear/index.d.ts +11 -0
  60. package/dist/lib/linear/index.js +10 -0
  61. package/dist/lib/linear/mapper.d.ts +67 -0
  62. package/dist/lib/linear/mapper.js +219 -0
  63. package/dist/lib/linear/sync.d.ts +37 -0
  64. package/dist/lib/linear/sync.js +89 -0
  65. package/dist/lib/linear/types.d.ts +139 -0
  66. package/dist/lib/linear/types.js +34 -0
  67. package/dist/lib/mcp/helpers.d.ts +8 -0
  68. package/dist/lib/mcp/helpers.js +10 -0
  69. package/dist/lib/mcp/tools/board.js +63 -11
  70. package/dist/lib/mcp/tools/work.js +36 -0
  71. package/dist/lib/pmo/schema.d.ts +2 -0
  72. package/dist/lib/pmo/schema.js +20 -0
  73. package/dist/lib/pmo/storage/base.js +92 -13
  74. package/dist/lib/pmo/storage/dependencies.js +15 -0
  75. package/dist/lib/prompt-json.d.ts +4 -0
  76. package/oclif.manifest.json +3205 -2537
  77. package/package.json +3 -2
@@ -23,12 +23,14 @@ declare const CONFIG_KEYS: {
23
23
  dockerNetwork: string;
24
24
  dockerMemory: string;
25
25
  dockerCpus: string;
26
+ firewallAllowlistDomains: string;
26
27
  vmDefaultHost: string;
27
28
  vmUser: string;
28
29
  vmKeyPath: string;
29
30
  vmSyncMethod: string;
30
31
  coderName: string;
31
32
  authMethod: string;
33
+ createPrDefault: string;
32
34
  };
33
35
  /**
34
36
  * Load execution config from database, merging with defaults
@@ -56,6 +58,10 @@ export declare function saveTmuxControlMode(db: Database.Database, enabled: bool
56
58
  * When enabled, new terminal tabs open without stealing focus from current window.
57
59
  */
58
60
  export declare function saveTerminalOpenInBackground(db: Database.Database, enabled: boolean): void;
61
+ /**
62
+ * Save extra firewall allowlist domains.
63
+ */
64
+ export declare function saveFirewallAllowlistDomains(db: Database.Database, domains: string[]): void;
59
65
  /**
60
66
  * Save auth method preference (oauth or apikey)
61
67
  */
@@ -69,6 +75,15 @@ export declare function getAuthMethod(db: Database.Database): AuthMethod | null;
69
75
  * Clear saved auth method preference (will prompt again next time)
70
76
  */
71
77
  export declare function clearAuthMethod(db: Database.Database): void;
78
+ /**
79
+ * Get saved PR creation default preference.
80
+ * Returns null if no preference has been saved (user should be prompted).
81
+ */
82
+ export declare function getCreatePrDefault(db: Database.Database): boolean | null;
83
+ /**
84
+ * Save PR creation default preference.
85
+ */
86
+ export declare function saveCreatePrDefault(db: Database.Database, createPr: boolean): void;
72
87
  /**
73
88
  * Check if terminal app preference has been set
74
89
  */
@@ -27,12 +27,14 @@ const CONFIG_KEYS = {
27
27
  dockerNetwork: 'execution.docker.network',
28
28
  dockerMemory: 'execution.docker.memory',
29
29
  dockerCpus: 'execution.docker.cpus',
30
+ firewallAllowlistDomains: 'execution.firewall.allowlist_domains',
30
31
  vmDefaultHost: 'execution.vm.default_host',
31
32
  vmUser: 'execution.vm.user',
32
33
  vmKeyPath: 'execution.vm.key_path',
33
34
  vmSyncMethod: 'execution.vm.sync_method',
34
35
  coderName: 'coder.name',
35
36
  authMethod: 'execution.auth_method',
37
+ createPrDefault: 'execution.create_pr_default',
36
38
  };
37
39
  /**
38
40
  * Get a setting value from the database
@@ -103,6 +105,11 @@ export function loadExecutionConfig(db) {
103
105
  if (authMethod) {
104
106
  config.authMethod = authMethod;
105
107
  }
108
+ // Load create PR default preference
109
+ const createPrDefault = getSetting(db, CONFIG_KEYS.createPrDefault);
110
+ if (createPrDefault !== null) {
111
+ config.createPrDefault = createPrDefault === 'true';
112
+ }
106
113
  // Load tmux settings
107
114
  const tmuxSession = getSetting(db, CONFIG_KEYS.tmuxSession);
108
115
  if (tmuxSession) {
@@ -133,6 +140,28 @@ export function loadExecutionConfig(db) {
133
140
  if (dockerCpus) {
134
141
  config.docker = { ...config.docker, cpus: parseInt(dockerCpus, 10) };
135
142
  }
143
+ // Load firewall allowlist domains
144
+ const firewallAllowlistDomains = getSetting(db, CONFIG_KEYS.firewallAllowlistDomains);
145
+ if (firewallAllowlistDomains) {
146
+ let parsed = [];
147
+ try {
148
+ const jsonValue = JSON.parse(firewallAllowlistDomains);
149
+ if (Array.isArray(jsonValue)) {
150
+ parsed = jsonValue
151
+ .filter((domain) => typeof domain === 'string')
152
+ .map(domain => domain.trim())
153
+ .filter(Boolean);
154
+ }
155
+ }
156
+ catch {
157
+ // Backward-compatible fallback: comma-separated string
158
+ parsed = firewallAllowlistDomains
159
+ .split(',')
160
+ .map(domain => domain.trim())
161
+ .filter(Boolean);
162
+ }
163
+ config.firewall = { ...config.firewall, allowlistDomains: parsed };
164
+ }
136
165
  // Load VM settings
137
166
  const vmDefaultHost = getSetting(db, CONFIG_KEYS.vmDefaultHost);
138
167
  if (vmDefaultHost) {
@@ -184,6 +213,13 @@ export function saveTmuxControlMode(db, enabled) {
184
213
  export function saveTerminalOpenInBackground(db, enabled) {
185
214
  setSetting(db, CONFIG_KEYS.terminalOpenInBackground, enabled.toString());
186
215
  }
216
+ /**
217
+ * Save extra firewall allowlist domains.
218
+ */
219
+ export function saveFirewallAllowlistDomains(db, domains) {
220
+ const cleaned = [...new Set(domains.map(domain => domain.trim()).filter(Boolean))];
221
+ setSetting(db, CONFIG_KEYS.firewallAllowlistDomains, JSON.stringify(cleaned));
222
+ }
187
223
  /**
188
224
  * Save auth method preference (oauth or apikey)
189
225
  */
@@ -206,6 +242,24 @@ export function getAuthMethod(db) {
206
242
  export function clearAuthMethod(db) {
207
243
  db.prepare(`DELETE FROM ${SETTINGS_TABLE} WHERE key = ?`).run(CONFIG_KEYS.authMethod);
208
244
  }
245
+ /**
246
+ * Get saved PR creation default preference.
247
+ * Returns null if no preference has been saved (user should be prompted).
248
+ */
249
+ export function getCreatePrDefault(db) {
250
+ const value = getSetting(db, CONFIG_KEYS.createPrDefault);
251
+ if (value === 'true')
252
+ return true;
253
+ if (value === 'false')
254
+ return false;
255
+ return null;
256
+ }
257
+ /**
258
+ * Save PR creation default preference.
259
+ */
260
+ export function saveCreatePrDefault(db, createPr) {
261
+ setSetting(db, CONFIG_KEYS.createPrDefault, createPr.toString());
262
+ }
209
263
  /**
210
264
  * Check if terminal app preference has been set
211
265
  */
@@ -4,7 +4,7 @@
4
4
  * Generates .devcontainer/ configuration for agent sandboxed execution.
5
5
  * Uses a custom Dockerfile with network firewall for security sandboxing.
6
6
  */
7
- import { ExecutionConfig } from './types.js';
7
+ import { ExecutionConfig, ExecutorType } from './types.js';
8
8
  export type MountMode = 'worktree' | 'clone';
9
9
  export interface DevcontainerOptions {
10
10
  agentName: string;
@@ -21,6 +21,8 @@ export interface DevcontainerOptions {
21
21
  gitUserName?: string;
22
22
  /** Git user.email for commit attribution (detected from gh/git config on host) */
23
23
  gitUserEmail?: string;
24
+ /** Executor type - determines which CLI tools to install and which API domains to whitelist */
25
+ executor?: ExecutorType;
24
26
  }
25
27
  export interface DevcontainerJson {
26
28
  name: string;
@@ -58,9 +60,10 @@ export declare function generateDevcontainerJson(options: DevcontainerOptions, c
58
60
  export declare function generateDockerfile(options: DevcontainerOptions): string;
59
61
  /**
60
62
  * Generate firewall initialization script.
61
- * Whitelists only necessary domains for Claude Code operation.
63
+ * Whitelists only necessary domains for the configured executor.
64
+ * Claude Code requires api.anthropic.com; Codex requires api.openai.com.
62
65
  */
63
- export declare function generateFirewallScript(): string;
66
+ export declare function generateFirewallScript(executor?: ExecutorType, extraAllowedDomains?: string[]): string;
64
67
  /**
65
68
  * Generate prlt setup script.
66
69
  * Rebuilds better-sqlite3 if prlt is mounted from host (not installed via npm).
@@ -35,13 +35,16 @@ export function generateDevcontainerJson(options, config) {
35
35
  if (channel.registry === 'gh') {
36
36
  buildArgs.GITHUB_TOKEN = '${localEnv:GITHUB_TOKEN}';
37
37
  }
38
+ // Determine if this is a Claude Code executor (for Claude-specific mounts/config)
39
+ const isClaude = !options.executor || options.executor === 'claude-code';
38
40
  // Build mounts array - parent repo mounts only needed for worktree mode
39
41
  // TKT-801: Use consistency=cached to reduce grpcfuse contention on Docker Desktop.
40
42
  // This helps prevent kernel panics when multiple containers mount the same paths concurrently.
41
43
  const mounts = [
42
44
  'source=${localWorkspaceFolder},target=/workspace,type=bind,consistency=cached',
43
45
  'source=claude-bash-history,target=/commandhistory,type=volume',
44
- 'source=claude-credentials,target=/home/node/.claude,type=volume',
46
+ // Claude credentials volume - only needed for Claude Code executor
47
+ ...(isClaude ? ['source=claude-credentials,target=/home/node/.claude,type=volume'] : []),
45
48
  // NOTE: ~/.claude.json is COPIED (not mounted) to /workspace/.claude.json
46
49
  // to avoid corruption from concurrent writes by multiple containers
47
50
  // NOTE: SSH agent socket mounting doesn't work reliably on Docker Desktop for Mac
@@ -170,9 +173,9 @@ RUN mkdir -p /home/node/.npm-global/bin /home/node/.npm-global/lib \\
170
173
  ENV NPM_CONFIG_PREFIX=/home/node/.npm-global
171
174
  ENV PATH=/home/node/.npm-global/bin:\$PATH
172
175
 
173
- # Install pnpm and Claude Code as node user so files are owned correctly
176
+ # Install pnpm and executor CLI as node user so files are owned correctly
174
177
  USER node
175
- RUN npm install -g pnpm && npm install -g @anthropic-ai/claude-code
178
+ RUN npm install -g pnpm && npm install -g @anthropic-ai/claude-code${options.executor === 'codex' ? ' && npm install -g @openai/codex' : ''}
176
179
  USER root
177
180
 
178
181
  # Install prlt CLI from public npm
@@ -207,9 +210,15 @@ WORKDIR /workspace
207
210
  }
208
211
  /**
209
212
  * Generate firewall initialization script.
210
- * Whitelists only necessary domains for Claude Code operation.
213
+ * Whitelists only necessary domains for the configured executor.
214
+ * Claude Code requires api.anthropic.com; Codex requires api.openai.com.
211
215
  */
212
- export function generateFirewallScript() {
216
+ export function generateFirewallScript(executor, extraAllowedDomains = []) {
217
+ const extraDomainCommands = [...new Set(extraAllowedDomains
218
+ .map(domain => domain.trim().toLowerCase())
219
+ .filter(domain => /^[a-z0-9.-]+$/.test(domain)))]
220
+ .map(domain => `add_domain "${domain}"`)
221
+ .join('\n');
213
222
  return `#!/bin/bash
214
223
  set -e
215
224
 
@@ -291,9 +300,12 @@ add_domain "objects.githubusercontent.com"
291
300
  add_domain "raw.githubusercontent.com"
292
301
  add_domain "npm.pkg.github.com"
293
302
 
294
- # Add other allowed domains
303
+ # Add executor-specific API domains
295
304
  add_domain "api.anthropic.com"
296
305
  add_domain "console.anthropic.com"
306
+ ${executor === 'codex' ? `# Codex API domains
307
+ add_domain "api.openai.com"
308
+ add_domain "openai.com"` : ''}
297
309
  add_domain "statsigapi.net"
298
310
  add_domain "sentry.io"
299
311
  add_domain "registry.npmjs.org"
@@ -301,6 +313,19 @@ add_domain "npmjs.com"
301
313
  add_domain "nodejs.org"
302
314
  add_domain "update.code.visualstudio.com"
303
315
  add_domain "vscode.download.prss.microsoft.com"
316
+ ${extraDomainCommands ? `# Additional user-configured allowlist domains
317
+ ${extraDomainCommands}` : ''}
318
+
319
+ # Runtime allowlist domains (comma-separated), e.g. PRLT_EXTRA_ALLOWLIST_DOMAINS=api.staging.example.com
320
+ if [ -n "\${PRLT_EXTRA_ALLOWLIST_DOMAINS:-}" ]; then
321
+ IFS=',' read -ra EXTRA_DOMAINS <<< "$PRLT_EXTRA_ALLOWLIST_DOMAINS"
322
+ for domain in "\${EXTRA_DOMAINS[@]}"; do
323
+ domain="\${domain//[[:space:]]/}"
324
+ if [ -n "$domain" ]; then
325
+ add_domain "$domain"
326
+ fi
327
+ done
328
+ fi
304
329
 
305
330
  # Allow traffic to whitelisted IPs
306
331
  iptables -A OUTPUT -m set --match-set allowed-domains dst -j ACCEPT
@@ -522,6 +547,8 @@ configure_git_identity
522
547
 
523
548
  # Check if prlt is already installed globally (via npm)
524
549
  # TKT-954: Also check for updates - Docker layer caching may have installed an older version
550
+ # TKT-1029: Don't exit early - continue to workspace dependency installation
551
+ PRLT_CONFIGURED=false
525
552
  if command -v prlt &> /dev/null; then
526
553
  PRLT_PATH=$(which prlt)
527
554
  if [[ "$PRLT_PATH" == "/home/node/.npm-global/bin/prlt" ]]; then
@@ -544,12 +571,12 @@ if command -v prlt &> /dev/null; then
544
571
  else
545
572
  echo "prlt v\${CURRENT_VERSION} is up to date"
546
573
  fi
547
- exit 0
574
+ PRLT_CONFIGURED=true
548
575
  fi
549
576
  fi
550
577
 
551
- # Check if mounted prlt exists at /opt/prlt
552
- if [ -d "/opt/prlt/apps/cli" ]; then
578
+ # Check if mounted prlt exists at /opt/prlt (skip if already configured via npm)
579
+ if [ "$PRLT_CONFIGURED" = "false" ] && [ -d "/opt/prlt/apps/cli" ]; then
553
580
  echo "Setting up mounted prlt..."
554
581
 
555
582
  PRLT_LOCAL="/home/node/.prlt-local"
@@ -597,7 +624,7 @@ WRAPPER_EOF
597
624
  # Create prltdev symlink for consistency with dev environment
598
625
  ln -sf "$WRAPPER" /home/node/.npm-global/bin/prltdev
599
626
  echo "prlt wrapper ready at $WRAPPER (also available as prltdev)"
600
- else
627
+ elif [ "$PRLT_CONFIGURED" = "false" ]; then
601
628
  echo "No mounted prlt found, skipping setup"
602
629
  fi
603
630
 
@@ -647,8 +674,8 @@ export function createDevcontainerConfig(options, config) {
647
674
  const dockerfile = generateDockerfile(options);
648
675
  const dockerfilePath = path.join(devcontainerDir, 'Dockerfile');
649
676
  fs.writeFileSync(dockerfilePath, dockerfile);
650
- // Generate and write firewall script
651
- const firewallScript = generateFirewallScript();
677
+ // Generate and write firewall script (executor-aware for API domain whitelisting)
678
+ const firewallScript = generateFirewallScript(options.executor, config?.firewall.allowlistDomains ?? []);
652
679
  const firewallScriptPath = path.join(devcontainerDir, 'init-firewall.sh');
653
680
  fs.writeFileSync(firewallScriptPath, firewallScript, { mode: 0o755 });
654
681
  // Generate and write prlt setup script
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * Implementations for each execution environment (devcontainer, host, docker, vm).
5
5
  */
6
- import { ExecutionEnvironment, DisplayMode, SessionManager, ExecutorType, ExecutionContext, ExecutionConfig } from './types.js';
6
+ import { ExecutionEnvironment, DisplayMode, OutputMode, SessionManager, ExecutorType, ExecutionContext, ExecutionConfig } from './types.js';
7
7
  /**
8
8
  * Build a unified name for tmux sessions, window names, and tab titles.
9
9
  * Format: "{ticketId}-{action}-{agentName}"
@@ -41,17 +41,6 @@ export declare function buildTmuxAttachCommand(useControlMode: boolean, includeU
41
41
  */
42
42
  export declare function configureITermTmuxPreferences(mode: 'tab' | 'window'): void;
43
43
  export declare function configureITermTmuxWindowMode(mode: 'tab' | 'window'): void;
44
- /**
45
- * Build the tmux script that runs inside the container.
46
- * In background mode: kills PID 1 (sleep infinity) after Claude exits to stop/remove container.
47
- * In terminal/foreground mode: drops into exec bash for user inspection.
48
- */
49
- export declare function buildTmuxScript(sessionName: string, claudeCmd: string, displayMode: DisplayMode): string;
50
- /**
51
- * Get the auto-remove flags for docker run based on display mode.
52
- * Background mode containers get --rm so Docker removes them when they stop.
53
- */
54
- export declare function getDockerAutoRemoveFlags(displayMode: DisplayMode): string[];
55
44
  /**
56
45
  * Check if the claude-credentials Docker volume exists.
57
46
  */
@@ -74,40 +63,41 @@ export declare function getDockerCredentialInfo(): {
74
63
  expiresAt: Date;
75
64
  subscriptionType?: string;
76
65
  } | null;
66
+ export declare function getExecutorCommand(executor: ExecutorType, prompt: string, skipPermissions?: boolean): {
67
+ cmd: string;
68
+ args: string[];
69
+ };
70
+ /**
71
+ * Check if an executor is Claude Code.
72
+ * Used to gate Claude-specific flags and configuration.
73
+ */
74
+ export declare function isClaudeExecutor(executor: ExecutorType): boolean;
77
75
  /**
78
- * Preflight result indicating whether the executor is ready to run.
76
+ * Get the display name for an executor type.
79
77
  */
78
+ export declare function getExecutorDisplayName(executor: ExecutorType): string;
79
+ /**
80
+ * Get the npm package name for an executor (for container installation).
81
+ */
82
+ export declare function getExecutorPackage(executor: ExecutorType): string | null;
80
83
  export interface PreflightResult {
81
84
  ok: boolean;
82
85
  error?: string;
83
86
  }
84
87
  /**
85
- * Check if an executor binary is available on the host.
86
- * Returns a PreflightResult with ok=true if the binary is found,
87
- * or ok=false with a descriptive error and remediation hint.
88
+ * Check executor binary availability on host.
88
89
  */
89
90
  export declare function checkExecutorOnHost(executor: ExecutorType): PreflightResult;
90
91
  /**
91
- * Check if an executor binary is available inside a Docker container.
92
- * Returns a PreflightResult with ok=true if the binary is found,
93
- * or ok=false with a descriptive error and remediation hint.
92
+ * Check executor binary availability inside a container.
94
93
  */
95
94
  export declare function checkExecutorInContainer(executor: ExecutorType, containerId: string): PreflightResult;
96
95
  /**
97
- * Run preflight checks for a given execution environment and executor.
98
- * Validates that the executor binary is available before spawning.
99
- *
100
- * Checks performed per environment:
101
- * - host: Verify binary on PATH
102
- * - devcontainer: Verify binary inside container (if container running)
103
- * - docker: Verify binary on host (used in docker run command)
104
- * - vm: Verify binary on host (will be checked on remote separately)
96
+ * Run executor preflight checks for the target environment.
105
97
  */
106
- export declare function runExecutorPreflight(executor: ExecutorType, environment: ExecutionEnvironment, containerId?: string): PreflightResult;
107
- export declare function getExecutorCommand(executor: ExecutorType, prompt: string, skipPermissions?: boolean): {
108
- cmd: string;
109
- args: string[];
110
- };
98
+ export declare function runExecutorPreflight(environment: ExecutionEnvironment, executor: ExecutorType, options?: {
99
+ containerId?: string;
100
+ }): PreflightResult;
111
101
  export interface RunnerResult {
112
102
  success: boolean;
113
103
  pid?: string;
@@ -167,6 +157,12 @@ export declare function isContainerRunning(containerName: string): boolean;
167
157
  * Get the container ID for a running container.
168
158
  */
169
159
  export declare function getContainerId(containerName: string): string | null;
160
+ /**
161
+ * Build the command to run Claude inside the container.
162
+ * Uses docker exec for direct container access.
163
+ * Uses a prompt file to avoid shell escaping issues.
164
+ */
165
+ export declare function buildDevcontainerCommand(context: ExecutionContext, executor: ExecutorType, promptFile: string, containerId?: string, outputMode?: OutputMode, sandboxed?: boolean, displayMode?: DisplayMode): string;
170
166
  /**
171
167
  * Run command inside a Docker container.
172
168
  * Uses raw Docker commands for filesystem isolation - no devcontainer CLI required.