create-claude-workspace 1.1.12 → 1.1.13

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.
@@ -13,6 +13,10 @@ RUN useradd -m -s /bin/bash claude && \
13
13
  RUN gosu claude bash -c 'curl -fsSL https://claude.ai/install.sh | bash'
14
14
  ENV PATH="/home/claude/.local/bin:$PATH"
15
15
 
16
+ # Pre-configure Claude to skip first-run onboarding (theme, permissions prompts)
17
+ RUN echo '{"hasCompletedOnboarding":true,"theme":"dark"}' > /home/claude/.claude.json && \
18
+ chown claude:claude /home/claude/.claude.json
19
+
16
20
  # Git config for commits inside container
17
21
  RUN git config --system user.name "Claude Code" && \
18
22
  git config --system user.email "claude@localhost"
@@ -8,15 +8,16 @@ if [[ -n "${NPM_TOKEN:-}" ]]; then
8
8
  chown claude:claude /home/claude/.npmrc
9
9
  fi
10
10
 
11
- # Restore .claude.json from backup if missing.
12
- # .claude.json lives in $HOME but the volume only mounts $HOME/.claude/,
13
- # so .claude.json is lost on container restart — restore from backup each time.
11
+ # Restore .claude.json if missing (volume only mounts $HOME/.claude/, not $HOME/.claude.json).
12
+ # First try backup from previous session, then fall back to onboarding-skip defaults.
14
13
  if [[ ! -f /home/claude/.claude.json ]]; then
15
14
  backup=$(find /home/claude/.claude/backups -name '.claude.json.backup.*' 2>/dev/null | sort -V | tail -1)
16
15
  if [[ -n "$backup" ]]; then
17
16
  cp "$backup" /home/claude/.claude.json
18
- chown claude:claude /home/claude/.claude.json
17
+ else
18
+ echo '{"hasCompletedOnboarding":true,"theme":"dark"}' > /home/claude/.claude.json
19
19
  fi
20
+ chown claude:claude /home/claude/.claude.json
20
21
  fi
21
22
 
22
23
  # Ensure claude user owns its home dir (volume mounts come in as root)
@@ -195,46 +195,57 @@ function runClaude(projectDir, opts) {
195
195
  let child;
196
196
  const isWin = process.platform === 'win32';
197
197
 
198
- // Run Claude in interactive mode (no -p) so the full TUI is visible.
199
- // Prompt is sent via stdin then closed — Claude processes it and exits on EOF.
200
- // stdout+stderr inherited so the terminal UI renders directly.
201
198
  if (isWin) {
199
+ // Windows: claude is a .cmd shim requiring shell execution.
200
+ // cmd.exe mangles quoted arguments, so pipe prompt via stdin instead.
202
201
  const permFlag = opts.skipPermissions ? ' --dangerously-skip-permissions' : '';
203
- child = spawn(`claude --agent orchestrator --max-turns ${opts.maxTurns}${permFlag}`, [], {
202
+ child = spawn(`claude -p --agent orchestrator --max-turns ${opts.maxTurns}${permFlag}`, [], {
204
203
  cwd: projectDir,
205
- stdio: ['pipe', 'inherit', 'inherit'],
204
+ stdio: ['pipe', 'pipe', 'pipe'],
206
205
  shell: true,
207
206
  });
207
+ child.stdin.write(PROMPT);
208
+ child.stdin.end();
208
209
  } else {
209
- const args = ['--agent', 'orchestrator', '--max-turns', String(opts.maxTurns)];
210
+ const args = ['-p', PROMPT, '--agent', 'orchestrator', '--max-turns', String(opts.maxTurns)];
210
211
  if (opts.skipPermissions) args.push('--dangerously-skip-permissions');
211
212
  child = spawn('claude', args, {
212
213
  cwd: projectDir,
213
- stdio: ['pipe', 'inherit', 'inherit'],
214
+ stdio: ['ignore', 'pipe', 'pipe'],
214
215
  });
215
216
  }
216
217
 
217
- child.stdin.write(PROMPT);
218
- child.stdin.end();
219
-
220
218
  currentChild = child;
219
+ let stderr = '';
220
+
221
+ child.stdout.on('data', chunk => {
222
+ process.stdout.write(chunk);
223
+ });
224
+
225
+ child.stderr.on('data', chunk => {
226
+ const text = chunk.toString();
227
+ stderr += text;
228
+ process.stderr.write(text);
229
+ });
221
230
 
222
231
  child.on('close', code => {
223
232
  currentChild = null;
224
- resolvePromise({ code });
233
+ resolvePromise({ code, stderr });
225
234
  });
226
235
 
227
236
  child.on('error', err => {
228
237
  currentChild = null;
229
- resolvePromise({ code: 1 });
238
+ resolvePromise({ code: 1, stderr: err.message });
230
239
  });
231
240
  });
232
241
  }
233
242
 
234
- function detectRateLimit(result) {
235
- // Without stderr capture, rate limits are detected by specific exit codes.
236
- // Claude CLI exits with code 2 for rate limit / overloaded errors.
237
- return result.code === 2;
243
+ function detectRateLimit(output) {
244
+ const stderr = output.stderr.toLowerCase();
245
+ return stderr.includes('rate limit') ||
246
+ stderr.includes('rate_limit') ||
247
+ stderr.includes('too many requests') ||
248
+ stderr.includes('overloaded');
238
249
  }
239
250
 
240
251
  async function main() {
@@ -358,5 +358,5 @@ if (opts.shell) {
358
358
  info('Autonomous mode — isolated in Docker, --skip-permissions is safe.');
359
359
  info('Press Ctrl+C to stop after current iteration.');
360
360
  console.log('');
361
- compose(['run', '--rm', 'claude', '-c', `node .claude/scripts/autonomous.mjs ${autoArgs}`]);
361
+ compose(['run', '--rm', '-T', 'claude', '-c', `node .claude/scripts/autonomous.mjs ${autoArgs}`]);
362
362
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-claude-workspace",
3
- "version": "1.1.12",
3
+ "version": "1.1.13",
4
4
  "description": "Scaffold a project with Claude Code agents for autonomous AI-driven development",
5
5
  "type": "module",
6
6
  "bin": {