@proletariat/cli 0.3.69 → 0.3.71

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 (56) hide show
  1. package/dist/commands/session/health.d.ts +11 -0
  2. package/dist/commands/session/health.js +1 -1
  3. package/dist/commands/session/health.js.map +1 -1
  4. package/dist/lib/execution/runners/cloud.d.ts +16 -0
  5. package/dist/lib/execution/runners/cloud.js +88 -0
  6. package/dist/lib/execution/runners/cloud.js.map +1 -0
  7. package/dist/lib/execution/runners/devcontainer-terminal.d.ts +13 -0
  8. package/dist/lib/execution/runners/devcontainer-terminal.js +184 -0
  9. package/dist/lib/execution/runners/devcontainer-terminal.js.map +1 -0
  10. package/dist/lib/execution/runners/devcontainer-tmux.d.ts +16 -0
  11. package/dist/lib/execution/runners/devcontainer-tmux.js +270 -0
  12. package/dist/lib/execution/runners/devcontainer-tmux.js.map +1 -0
  13. package/dist/lib/execution/runners/devcontainer.d.ts +19 -0
  14. package/dist/lib/execution/runners/devcontainer.js +261 -0
  15. package/dist/lib/execution/runners/devcontainer.js.map +1 -0
  16. package/dist/lib/execution/runners/docker-credentials.d.ts +51 -0
  17. package/dist/lib/execution/runners/docker-credentials.js +175 -0
  18. package/dist/lib/execution/runners/docker-credentials.js.map +1 -0
  19. package/dist/lib/execution/runners/docker-management.d.ts +49 -0
  20. package/dist/lib/execution/runners/docker-management.js +300 -0
  21. package/dist/lib/execution/runners/docker-management.js.map +1 -0
  22. package/dist/lib/execution/runners/docker.d.ts +13 -0
  23. package/dist/lib/execution/runners/docker.js +75 -0
  24. package/dist/lib/execution/runners/docker.js.map +1 -0
  25. package/dist/lib/execution/runners/executor.d.ts +41 -0
  26. package/dist/lib/execution/runners/executor.js +108 -0
  27. package/dist/lib/execution/runners/executor.js.map +1 -0
  28. package/dist/lib/execution/runners/host.d.ts +14 -0
  29. package/dist/lib/execution/runners/host.js +437 -0
  30. package/dist/lib/execution/runners/host.js.map +1 -0
  31. package/dist/lib/execution/runners/index.d.ts +29 -0
  32. package/dist/lib/execution/runners/index.js +79 -0
  33. package/dist/lib/execution/runners/index.js.map +1 -0
  34. package/dist/lib/execution/runners/orchestrator.d.ts +30 -0
  35. package/dist/lib/execution/runners/orchestrator.js +332 -0
  36. package/dist/lib/execution/runners/orchestrator.js.map +1 -0
  37. package/dist/lib/execution/runners/prompt-builder.d.ts +12 -0
  38. package/dist/lib/execution/runners/prompt-builder.js +337 -0
  39. package/dist/lib/execution/runners/prompt-builder.js.map +1 -0
  40. package/dist/lib/execution/runners/sandbox.d.ts +34 -0
  41. package/dist/lib/execution/runners/sandbox.js +108 -0
  42. package/dist/lib/execution/runners/sandbox.js.map +1 -0
  43. package/dist/lib/execution/runners/shared.d.ts +62 -0
  44. package/dist/lib/execution/runners/shared.js +141 -0
  45. package/dist/lib/execution/runners/shared.js.map +1 -0
  46. package/dist/lib/execution/runners.d.ts +12 -272
  47. package/dist/lib/execution/runners.js +12 -3200
  48. package/dist/lib/execution/runners.js.map +1 -1
  49. package/dist/lib/external-issues/outbound-sync.d.ts +15 -0
  50. package/dist/lib/external-issues/outbound-sync.js +11 -1
  51. package/dist/lib/external-issues/outbound-sync.js.map +1 -1
  52. package/dist/lib/telemetry/analytics.d.ts +2 -1
  53. package/dist/lib/telemetry/analytics.js +39 -9
  54. package/dist/lib/telemetry/analytics.js.map +1 -1
  55. package/oclif.manifest.json +3080 -3080
  56. package/package.json +1 -1
@@ -0,0 +1,175 @@
1
+ /**
2
+ * Docker Credential Helpers
3
+ *
4
+ * Functions for checking and managing Claude Code credentials
5
+ * in Docker volumes, host filesystem, and macOS keychain.
6
+ * Also includes tmux server keychain access management.
7
+ */
8
+ import { execSync } from 'node:child_process';
9
+ import * as fs from 'node:fs';
10
+ import * as path from 'node:path';
11
+ import * as os from 'node:os';
12
+ export const CLAUDE_CREDENTIALS_VOLUME = 'claude-credentials';
13
+ /**
14
+ * Check if the claude-credentials Docker volume exists.
15
+ */
16
+ export function credentialsVolumeExists() {
17
+ try {
18
+ execSync(`docker volume inspect ${CLAUDE_CREDENTIALS_VOLUME}`, { stdio: 'pipe' });
19
+ return true;
20
+ }
21
+ catch {
22
+ return false;
23
+ }
24
+ }
25
+ /**
26
+ * Check if valid Claude OAuth credentials exist in the Docker volume.
27
+ * Returns true if OAuth credentials are stored (even if access token is expired,
28
+ * since Claude Code handles refresh internally using stored refresh tokens).
29
+ *
30
+ * NOTE: This intentionally does NOT check for ANTHROPIC_API_KEY. If the user
31
+ * has an API key but no OAuth credentials, we want to prompt them to set up
32
+ * OAuth (which uses their Max subscription) rather than silently burning API credits.
33
+ */
34
+ export function dockerCredentialsExist() {
35
+ try {
36
+ const result = execSync(`docker run --rm -v ${CLAUDE_CREDENTIALS_VOLUME}:/data alpine cat /data/.credentials.json 2>/dev/null`, { stdio: 'pipe', encoding: 'utf-8' });
37
+ const creds = JSON.parse(result);
38
+ if (creds.claudeAiOauth?.accessToken) {
39
+ return true;
40
+ }
41
+ return false;
42
+ }
43
+ catch {
44
+ return false;
45
+ }
46
+ }
47
+ /**
48
+ * Get Docker credential info for display.
49
+ * Returns expiration date and subscription type if available.
50
+ */
51
+ export function getDockerCredentialInfo() {
52
+ try {
53
+ const result = execSync(`docker run --rm -v ${CLAUDE_CREDENTIALS_VOLUME}:/data alpine cat /data/.credentials.json 2>/dev/null`, { stdio: 'pipe', encoding: 'utf-8' });
54
+ const creds = JSON.parse(result);
55
+ if (creds.claudeAiOauth?.expiresAt) {
56
+ return {
57
+ expiresAt: new Date(creds.claudeAiOauth.expiresAt),
58
+ subscriptionType: creds.claudeAiOauth.subscriptionType,
59
+ };
60
+ }
61
+ return null;
62
+ }
63
+ catch {
64
+ return null;
65
+ }
66
+ }
67
+ /**
68
+ * Check if Claude Code authentication is available on the host system.
69
+ * Returns true if any of:
70
+ * 1. ANTHROPIC_API_KEY environment variable is set
71
+ * 2. OAuth credentials exist in ~/.claude/.credentials.json (Claude Code 1.x)
72
+ * 3. OAuth credentials exist in macOS keychain (Claude Code 2.x)
73
+ */
74
+ export function hostCredentialsExist() {
75
+ if (process.env.ANTHROPIC_API_KEY) {
76
+ return true;
77
+ }
78
+ try {
79
+ const homeDir = process.env.HOME || os.homedir();
80
+ const credPath = path.join(homeDir, '.claude', '.credentials.json');
81
+ if (fs.existsSync(credPath)) {
82
+ const credData = fs.readFileSync(credPath, 'utf-8');
83
+ const creds = JSON.parse(credData);
84
+ if (creds.claudeAiOauth?.accessToken) {
85
+ return true;
86
+ }
87
+ }
88
+ }
89
+ catch {
90
+ // Fall through to keychain check
91
+ }
92
+ if (process.platform === 'darwin') {
93
+ try {
94
+ execSync('security find-generic-password -s "Claude Code-credentials" 2>/dev/null', {
95
+ stdio: 'pipe',
96
+ timeout: 5000,
97
+ });
98
+ return true;
99
+ }
100
+ catch {
101
+ // Keychain entry not found or keychain is locked
102
+ }
103
+ }
104
+ return false;
105
+ }
106
+ /**
107
+ * Ensure tmux server has keychain access for Claude Code OAuth.
108
+ *
109
+ * On macOS, tmux sessions can lose access to the keychain if the tmux server
110
+ * was started in a context without keychain access. This function tests and
111
+ * restarts the tmux server if needed.
112
+ */
113
+ export async function ensureTmuxServerHasKeychainAccess() {
114
+ try {
115
+ const serverRunning = execSync('tmux list-sessions 2>/dev/null || echo ""', {
116
+ encoding: 'utf-8',
117
+ stdio: 'pipe'
118
+ });
119
+ if (!serverRunning.trim()) {
120
+ return;
121
+ }
122
+ }
123
+ catch {
124
+ return;
125
+ }
126
+ const testSession = `prlt-keychain-test-${Date.now()}`;
127
+ try {
128
+ execSync(`tmux new-session -d -s "${testSession}"`, { stdio: 'pipe' });
129
+ execSync(`tmux send-keys -t "${testSession}" "unset CLAUDECODE && claude -p 'test' 2>&1 | head -1" Enter`, { stdio: 'pipe' });
130
+ await new Promise(resolve => setTimeout(resolve, 3000));
131
+ const output = execSync(`tmux capture-pane -t "${testSession}" -p`, {
132
+ encoding: 'utf-8',
133
+ stdio: 'pipe'
134
+ });
135
+ execSync(`tmux kill-session -t "${testSession}"`, { stdio: 'pipe' });
136
+ if (output.includes('Not logged in') || output.includes('Please run /login')) {
137
+ execSync('tmux kill-server', { stdio: 'pipe' });
138
+ for (let i = 0; i < 10; i++) {
139
+ await new Promise(resolve => setTimeout(resolve, 300));
140
+ try {
141
+ execSync('tmux list-sessions 2>/dev/null', { stdio: 'pipe' });
142
+ }
143
+ catch {
144
+ break;
145
+ }
146
+ }
147
+ }
148
+ }
149
+ catch (_error) {
150
+ try {
151
+ execSync(`tmux kill-session -t "${testSession}"`, { stdio: 'pipe' });
152
+ }
153
+ catch {
154
+ // Ignore cleanup errors
155
+ }
156
+ }
157
+ }
158
+ /**
159
+ * Copy Claude Code credentials (~/.claude.json) into the agent directory.
160
+ * This makes the subscription credentials available inside the devcontainer.
161
+ */
162
+ export function copyClaudeCredentials(agentDir) {
163
+ const sourceFile = path.join(os.homedir(), '.claude.json');
164
+ const destFile = path.join(agentDir, '.claude.json');
165
+ if (fs.existsSync(sourceFile)) {
166
+ try {
167
+ fs.copyFileSync(sourceFile, destFile);
168
+ console.debug('[runners:credentials] Copied .claude.json to workspace');
169
+ }
170
+ catch (err) {
171
+ console.debug('[runners:credentials] Failed to copy .claude.json:', err);
172
+ }
173
+ }
174
+ }
175
+ //# sourceMappingURL=docker-credentials.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"docker-credentials.js","sourceRoot":"","sources":["../../../../src/lib/execution/runners/docker-credentials.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Docker Container Management
3
+ *
4
+ * Functions for managing Docker containers, images, and setup.
5
+ * Uses raw Docker commands instead of devcontainer CLI.
6
+ */
7
+ import { PermissionMode, ExecutorType, ExecutionContext, ExecutionConfig } from '../types.js';
8
+ /**
9
+ * Get the host's installed prlt CLI version.
10
+ * Returns the semver version string (e.g., "0.3.35") or null if not available.
11
+ */
12
+ export declare function getHostPrltVersion(): string | null;
13
+ /**
14
+ * Get the container name for an agent.
15
+ * Format: prlt-agent-{agentName}
16
+ */
17
+ export declare function getAgentContainerName(agentName: string): string;
18
+ export declare const getContainerName: typeof getAgentContainerName;
19
+ export declare function getImageName(agentName: string): string;
20
+ /**
21
+ * Check if a Docker container exists (running or stopped).
22
+ */
23
+ export declare function containerExists(containerName: string): boolean;
24
+ /**
25
+ * Check if a Docker container is running.
26
+ */
27
+ export declare function isContainerRunning(containerName: string): boolean;
28
+ /**
29
+ * Get the container ID for a running container.
30
+ */
31
+ export declare function getContainerId(containerName: string): string | null;
32
+ export declare function buildDockerImage(agentDir: string, imageName: string, buildArgs?: Record<string, string>): boolean;
33
+ export declare function imageExists(imageName: string): boolean;
34
+ /**
35
+ * Create and start a Docker container for an agent.
36
+ */
37
+ export declare function createDockerContainer(context: ExecutionContext, containerName: string, imageName: string, config: ExecutionConfig, executor?: ExecutorType, prltInfo?: {
38
+ registry: string;
39
+ version: string;
40
+ }): boolean;
41
+ /**
42
+ * Run the post-start setup commands in a container.
43
+ */
44
+ export declare function runContainerSetup(containerId: string, permissionMode?: PermissionMode, executor?: ExecutorType): boolean;
45
+ /**
46
+ * Ensure a Docker container is running for the agent.
47
+ * Reuses running containers to preserve in-progress work (TKT-1028).
48
+ */
49
+ export declare function ensureDockerContainer(context: ExecutionContext, config: ExecutionConfig, executor?: ExecutorType): string | null;
@@ -0,0 +1,300 @@
1
+ /**
2
+ * Docker Container Management
3
+ *
4
+ * Functions for managing Docker containers, images, and setup.
5
+ * Uses raw Docker commands instead of devcontainer CLI.
6
+ */
7
+ import { execSync } from 'node:child_process';
8
+ import * as fs from 'node:fs';
9
+ import * as path from 'node:path';
10
+ import * as os from 'node:os';
11
+ import { readDevcontainerJson } from '../devcontainer.js';
12
+ import { isClaudeExecutor } from './executor.js';
13
+ /**
14
+ * Get the host's installed prlt CLI version.
15
+ * Returns the semver version string (e.g., "0.3.35") or null if not available.
16
+ */
17
+ export function getHostPrltVersion() {
18
+ try {
19
+ const output = execSync('prlt --version', {
20
+ encoding: 'utf-8',
21
+ stdio: ['pipe', 'pipe', 'pipe'],
22
+ }).trim();
23
+ const match = output.match(/(\d+\.\d+\.\d+)/);
24
+ return match ? match[1] : null;
25
+ }
26
+ catch {
27
+ return null;
28
+ }
29
+ }
30
+ /**
31
+ * Get the container name for an agent.
32
+ * Format: prlt-agent-{agentName}
33
+ */
34
+ export function getAgentContainerName(agentName) {
35
+ const sanitized = agentName.replace(/[^a-zA-Z0-9_-]/g, '-');
36
+ return `prlt-agent-${sanitized}`;
37
+ }
38
+ export const getContainerName = getAgentContainerName;
39
+ export function getImageName(agentName) {
40
+ const sanitized = agentName.replace(/[^a-zA-Z0-9_-]/g, '-');
41
+ return `prlt-agent-${sanitized}:latest`;
42
+ }
43
+ /**
44
+ * Check if a Docker container exists (running or stopped).
45
+ */
46
+ export function containerExists(containerName) {
47
+ try {
48
+ execSync(`docker container inspect ${containerName}`, { stdio: 'pipe', timeout: 5000 });
49
+ return true;
50
+ }
51
+ catch {
52
+ return false;
53
+ }
54
+ }
55
+ /**
56
+ * Check if a Docker container is running.
57
+ */
58
+ export function isContainerRunning(containerName) {
59
+ try {
60
+ const status = execSync(`docker container inspect -f '{{.State.Running}}' ${containerName}`, { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'], timeout: 5000 }).trim();
61
+ return status === 'true';
62
+ }
63
+ catch {
64
+ return false;
65
+ }
66
+ }
67
+ /**
68
+ * Get the container ID for a running container.
69
+ */
70
+ export function getContainerId(containerName) {
71
+ try {
72
+ const containerId = execSync(`docker container inspect -f '{{.Id}}' ${containerName}`, { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'], timeout: 5000 }).trim();
73
+ return containerId ? containerId.substring(0, 12) : null;
74
+ }
75
+ catch {
76
+ return null;
77
+ }
78
+ }
79
+ export function buildDockerImage(agentDir, imageName, buildArgs = {}) {
80
+ const dockerfilePath = path.join(agentDir, '.devcontainer', 'Dockerfile');
81
+ if (!fs.existsSync(dockerfilePath)) {
82
+ console.debug(`[runners:docker] Dockerfile not found at ${dockerfilePath}`);
83
+ return false;
84
+ }
85
+ try {
86
+ const buildArgFlags = Object.entries(buildArgs)
87
+ .map(([key, value]) => `--build-arg ${key}="${value}"`)
88
+ .join(' ');
89
+ const buildCmd = `docker build -t ${imageName} -f "${dockerfilePath}" ${buildArgFlags} "${path.join(agentDir, '.devcontainer')}"`;
90
+ console.debug(`[runners:docker] Building image: ${buildCmd}`);
91
+ execSync(buildCmd, { stdio: 'pipe' });
92
+ return true;
93
+ }
94
+ catch (error) {
95
+ console.debug(`[runners:docker] Failed to build image:`, error);
96
+ return false;
97
+ }
98
+ }
99
+ export function imageExists(imageName) {
100
+ try {
101
+ execSync(`docker image inspect ${imageName}`, { stdio: 'pipe', timeout: 5000 });
102
+ return true;
103
+ }
104
+ catch {
105
+ return false;
106
+ }
107
+ }
108
+ /**
109
+ * Create and start a Docker container for an agent.
110
+ */
111
+ export function createDockerContainer(context, containerName, imageName, config, executor = 'claude-code', prltInfo) {
112
+ const mounts = [
113
+ `-v "${context.agentDir}:/workspace:cached"`,
114
+ ...(context.hqPath ? [`-v "${context.hqPath}/.proletariat:/hq/.proletariat:cached"`] : []),
115
+ ...(context.pmoPath ? [`-v "${context.pmoPath}:/hq/pmo:cached"`] : []),
116
+ ...(context.repoWorktrees || []).map(repoName => `-v "${context.hqPath}/repos/${repoName}:/hq/repos/${repoName}:cached"`),
117
+ ...(isClaudeExecutor(executor) ? [`-v "claude-credentials:/home/node/.claude"`] : []),
118
+ ];
119
+ const hasWorktrees = context.repoWorktrees && context.repoWorktrees.length > 0;
120
+ const firewallAllowlistDomains = [...new Set((config.firewall?.allowlistDomains || [])
121
+ .map(domain => domain.trim().toLowerCase())
122
+ .filter(domain => /^[a-z0-9.-]+$/.test(domain)))];
123
+ const envVars = [
124
+ `-e DEVCONTAINER=true`,
125
+ `-e PRLT_HQ_PATH=/hq`,
126
+ `-e PRLT_AGENT_NAME="${context.agentName}"`,
127
+ `-e PRLT_HOST_PATH="${context.agentDir}"`,
128
+ ...(context.useApiKey && process.env.ANTHROPIC_API_KEY ? [`-e ANTHROPIC_API_KEY="${process.env.ANTHROPIC_API_KEY}"`] : []),
129
+ ...(process.env.GITHUB_TOKEN ? [`-e GITHUB_TOKEN="${process.env.GITHUB_TOKEN}"`] : []),
130
+ ...(process.env.GH_TOKEN ? [`-e GH_TOKEN="${process.env.GH_TOKEN}"`] : []),
131
+ ...(firewallAllowlistDomains.length > 0 ? [`-e PRLT_EXTRA_ALLOWLIST_DOMAINS="${firewallAllowlistDomains.join(',')}"`] : []),
132
+ ...(hasWorktrees ? [`-e PRLT_MOUNT_MODE=worktree`] : []),
133
+ ...(prltInfo ? [
134
+ `-e PRLT_REGISTRY="${prltInfo.registry}"`,
135
+ `-e PRLT_VERSION="${prltInfo.version}"`,
136
+ ] : []),
137
+ ];
138
+ const resourceFlags = [
139
+ `--memory=${config.devcontainer.memory}`,
140
+ `--cpus=${config.devcontainer.cpus}`,
141
+ ];
142
+ const securityFlags = [
143
+ '--cap-add=NET_ADMIN',
144
+ '--cap-add=NET_RAW',
145
+ ];
146
+ try {
147
+ const createCmd = [
148
+ 'docker run -d',
149
+ `--name ${containerName}`,
150
+ '--user node',
151
+ '-w /workspace',
152
+ ...mounts,
153
+ ...envVars,
154
+ ...resourceFlags,
155
+ ...securityFlags,
156
+ imageName,
157
+ 'sleep infinity',
158
+ ].join(' ');
159
+ console.debug(`[runners:docker] Creating container: ${createCmd}`);
160
+ execSync(createCmd, { stdio: 'pipe' });
161
+ return true;
162
+ }
163
+ catch (error) {
164
+ console.debug(`[runners:docker] Failed to create container:`, error);
165
+ return false;
166
+ }
167
+ }
168
+ /**
169
+ * Run the post-start setup commands in a container.
170
+ */
171
+ export function runContainerSetup(containerId, permissionMode = 'safe', executor = 'claude-code') {
172
+ try {
173
+ execSync(`docker exec ${containerId} sudo /usr/local/bin/init-firewall.sh`, { stdio: 'pipe' });
174
+ execSync(`docker exec ${containerId} /usr/local/bin/setup-prlt.sh`, { stdio: 'pipe' });
175
+ }
176
+ catch (error) {
177
+ console.debug(`[runners:docker] Container setup scripts failed:`, error);
178
+ }
179
+ try {
180
+ execSync(`docker exec ${containerId} pnpm config set store-dir /tmp/pnpm-store`, { stdio: 'pipe' });
181
+ console.debug(`[runners:docker] Configured pnpm store-dir to /tmp/pnpm-store`);
182
+ }
183
+ catch (error) {
184
+ console.debug(`[runners:docker] Failed to configure pnpm store (pnpm may not be installed):`, error);
185
+ }
186
+ if (isClaudeExecutor(executor)) {
187
+ try {
188
+ const hostClaudeJson = path.join(os.homedir(), '.claude.json');
189
+ let settings = {};
190
+ if (fs.existsSync(hostClaudeJson)) {
191
+ try {
192
+ settings = JSON.parse(fs.readFileSync(hostClaudeJson, 'utf-8'));
193
+ }
194
+ catch {
195
+ console.debug('[runners:docker] Failed to parse host .claude.json, using empty settings');
196
+ }
197
+ }
198
+ if (permissionMode === 'danger') {
199
+ settings.bypassPermissionsModeAccepted = true;
200
+ }
201
+ settings.numStartups = settings.numStartups || 1;
202
+ settings.hasCompletedOnboarding = true;
203
+ settings.theme = settings.theme || 'dark';
204
+ if (!settings.tipsHistory || typeof settings.tipsHistory !== 'object') {
205
+ settings.tipsHistory = {};
206
+ }
207
+ const tips = settings.tipsHistory;
208
+ tips['new-user-warmup'] = tips['new-user-warmup'] || 1;
209
+ settings.effortCalloutDismissed = true;
210
+ if (!settings.projects || typeof settings.projects !== 'object') {
211
+ settings.projects = {};
212
+ }
213
+ const projects = settings.projects;
214
+ for (const projectPath of ['/workspace', '/']) {
215
+ if (!projects[projectPath]) {
216
+ projects[projectPath] = {};
217
+ }
218
+ projects[projectPath].hasTrustDialogAccepted = true;
219
+ projects[projectPath].hasCompletedProjectOnboarding = true;
220
+ }
221
+ const settingsJson = JSON.stringify(settings);
222
+ execSync(`docker exec -i ${containerId} bash -c 'cat > /home/node/.claude.json'`, { input: settingsJson, stdio: ['pipe', 'pipe', 'pipe'] });
223
+ console.debug(`[runners:docker] Copied .claude.json settings to container (bypassPermissionsModeAccepted=${permissionMode === 'danger'})`);
224
+ const claudeSettings = JSON.stringify({ skipDangerousModePermissionPrompt: true });
225
+ execSync(`docker exec -i ${containerId} bash -c 'mkdir -p /home/node/.claude && cat > /home/node/.claude/settings.json'`, { input: claudeSettings, stdio: ['pipe', 'pipe', 'pipe'] });
226
+ console.debug(`[runners:docker] Wrote ~/.claude/settings.json to container`);
227
+ }
228
+ catch (error) {
229
+ console.debug('[runners:docker] Failed to copy Claude settings to container:', error);
230
+ }
231
+ }
232
+ else {
233
+ console.debug(`[runners:docker] Skipping .claude.json settings injection for ${executor} executor`);
234
+ }
235
+ return true;
236
+ }
237
+ /**
238
+ * Ensure a Docker container is running for the agent.
239
+ * Reuses running containers to preserve in-progress work (TKT-1028).
240
+ */
241
+ export function ensureDockerContainer(context, config, executor = 'claude-code') {
242
+ const containerName = getContainerName(context.agentName);
243
+ const imageName = getImageName(context.agentName);
244
+ if (containerExists(containerName)) {
245
+ if (isContainerRunning(containerName)) {
246
+ const containerId = getContainerId(containerName);
247
+ if (containerId) {
248
+ console.debug(`[runners:docker] Reusing running container ${containerName} (${containerId}), skipping setup`);
249
+ return containerId;
250
+ }
251
+ }
252
+ console.debug(`[runners:docker] Removing stopped container ${containerName} to create fresh one`);
253
+ try {
254
+ execSync(`docker rm -f ${containerName}`, { stdio: 'pipe', timeout: 10000 });
255
+ }
256
+ catch {
257
+ // Ignore removal errors
258
+ }
259
+ }
260
+ const devcontainerJson = readDevcontainerJson(context.agentDir);
261
+ const buildArgs = {
262
+ TZ: devcontainerJson?.build?.args?.TZ || 'America/Los_Angeles',
263
+ PRLT_REGISTRY: devcontainerJson?.build?.args?.PRLT_REGISTRY || 'npm',
264
+ };
265
+ const configuredVersion = devcontainerJson?.build?.args?.PRLT_VERSION || 'latest';
266
+ const isTagVersion = ['latest', 'dev', 'next'].includes(configuredVersion);
267
+ const hostPrltVersion = isTagVersion ? getHostPrltVersion() : null;
268
+ if (hostPrltVersion) {
269
+ buildArgs.PRLT_VERSION = hostPrltVersion;
270
+ console.debug(`[runners:docker] Using host prlt version ${hostPrltVersion} for image build`);
271
+ }
272
+ else {
273
+ buildArgs.PRLT_VERSION = configuredVersion;
274
+ }
275
+ console.debug(`[runners:docker] Building image ${imageName} (PRLT_VERSION=${buildArgs.PRLT_VERSION})`);
276
+ if (!buildDockerImage(context.agentDir, imageName, buildArgs)) {
277
+ if (!imageExists(imageName)) {
278
+ return null;
279
+ }
280
+ console.debug(`[runners:docker] Build failed but existing image found, continuing with runtime update`);
281
+ }
282
+ const prltInfo = {
283
+ registry: buildArgs.PRLT_REGISTRY,
284
+ version: buildArgs.PRLT_VERSION,
285
+ };
286
+ console.debug(`[runners:docker] Creating container ${containerName}`);
287
+ if (!createDockerContainer(context, containerName, imageName, config, executor, prltInfo)) {
288
+ return null;
289
+ }
290
+ const containerId = getContainerId(containerName);
291
+ if (!containerId) {
292
+ return null;
293
+ }
294
+ console.debug(`[runners:docker] Running container setup (permissionMode=${config.permissionMode}, executor=${executor})`);
295
+ if (!runContainerSetup(containerId, config.permissionMode, executor)) {
296
+ console.debug(`[runners:docker] Setup failed, but continuing...`);
297
+ }
298
+ return containerId;
299
+ }
300
+ //# sourceMappingURL=docker-management.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"docker-management.js","sourceRoot":"","sources":["../../../../src/lib/execution/runners/docker-management.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Docker Runner
3
+ *
4
+ * Runs commands in detached Docker containers.
5
+ * Uses simple docker run for standalone container execution.
6
+ */
7
+ import { ExecutorType, ExecutionContext, ExecutionConfig } from './shared.js';
8
+ import { RunnerResult } from './shared.js';
9
+ /**
10
+ * Run command in a detached Docker container.
11
+ * Uses simple docker run with -d flag for background execution.
12
+ */
13
+ export declare function runDocker(context: ExecutionContext, executor: ExecutorType, config: ExecutionConfig): Promise<RunnerResult>;
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Docker Runner
3
+ *
4
+ * Runs commands in detached Docker containers.
5
+ * Uses simple docker run for standalone container execution.
6
+ */
7
+ import { execSync, validateCodexMode, } from './shared.js';
8
+ import { buildPrompt, getExecutorCommand, isClaudeExecutor, checkDockerDaemon, } from './shared.js';
9
+ /**
10
+ * Run command in a detached Docker container.
11
+ * Uses simple docker run with -d flag for background execution.
12
+ */
13
+ export async function runDocker(context, executor, config) {
14
+ const prompt = buildPrompt(context);
15
+ const containerName = `work-${context.ticketId}-${Date.now()}`;
16
+ try {
17
+ // Check if docker is available and daemon is responsive (TKT-081)
18
+ const dockerStatus = checkDockerDaemon();
19
+ if (!dockerStatus.available) {
20
+ return {
21
+ success: false,
22
+ error: `Docker daemon is not available. ${dockerStatus.message}`,
23
+ };
24
+ }
25
+ // Build docker run command
26
+ let dockerCmd = `docker run -d --name ${containerName}`;
27
+ dockerCmd += ` -v "${context.worktreePath}:/workspace"`;
28
+ dockerCmd += ` -w /workspace`;
29
+ dockerCmd += ` -e TICKET_ID="${context.ticketId}"`;
30
+ if (config.docker.network) {
31
+ dockerCmd += ` --network ${config.docker.network}`;
32
+ }
33
+ if (config.docker.memory) {
34
+ dockerCmd += ` --memory ${config.docker.memory}`;
35
+ }
36
+ if (config.docker.cpus) {
37
+ dockerCmd += ` --cpus ${config.docker.cpus}`;
38
+ }
39
+ // Validate Codex mode: Docker runner is always non-tty (detached with -d)
40
+ if (executor === 'codex') {
41
+ const codexPermission = config.permissionMode;
42
+ const modeError = validateCodexMode(codexPermission, 'non-tty');
43
+ if (modeError) {
44
+ return { success: false, error: modeError.message };
45
+ }
46
+ }
47
+ // Build executor command using getExecutorCommand() for correct invocation
48
+ const escapedPrompt = prompt.replace(/'/g, "'\\''");
49
+ const { cmd, args } = getExecutorCommand(executor, escapedPrompt, config.permissionMode === 'danger');
50
+ // For Claude Code in Docker, use --print for non-interactive output
51
+ // Non-Claude executors use their native command format from getExecutorCommand()
52
+ dockerCmd += ` ${config.docker.image}`;
53
+ if (isClaudeExecutor(executor)) {
54
+ // TKT-053: Disable plan mode — Docker runner is always detached (no user to approve)
55
+ // PRLT-950: Use -- to separate flags from positional prompt argument.
56
+ dockerCmd += ` ${cmd} --print --disallowedTools EnterPlanMode -- '${escapedPrompt}'`;
57
+ }
58
+ else {
59
+ const argsStr = args.map(a => a === escapedPrompt ? `'${escapedPrompt}'` : a).join(' ');
60
+ dockerCmd += ` ${cmd} ${argsStr}`;
61
+ }
62
+ const containerId = execSync(dockerCmd, { encoding: 'utf-8' }).trim();
63
+ return {
64
+ success: true,
65
+ containerId: containerId.substring(0, 12),
66
+ };
67
+ }
68
+ catch (error) {
69
+ return {
70
+ success: false,
71
+ error: error instanceof Error ? error.message : 'Failed to start docker container',
72
+ };
73
+ }
74
+ }
75
+ //# sourceMappingURL=docker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"docker.js","sourceRoot":"","sources":["../../../../src/lib/execution/runners/docker.ts"],"names":[],"mappings":"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"}