create-claude-workspace 1.1.53 → 1.1.54

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.
@@ -203,32 +203,41 @@ function preflight(opts, log) {
203
203
  }
204
204
  // ─── Signal handling ───
205
205
  let stopping = false;
206
- let forceKilling = false;
207
206
  const stoppingRef = { value: false };
208
207
  function setupSignals(opts, log, checkpoint) {
209
- const gracefulStop = (label) => {
210
- if (forceKilling)
211
- return; // CONC-5: ignore rapid signals during exit
212
- forceKilling = true;
208
+ const die = (label, code) => {
213
209
  stopping = true;
214
210
  stoppingRef.value = true;
215
- log.info(`${label}. Killing child process and exiting...`);
216
- currentChild?.kill();
217
- finalCleanup(opts, checkpoint, log);
218
- process.exit(0);
211
+ try {
212
+ log.info(`${label}. Killing child process...`);
213
+ }
214
+ catch { /* ignore */ }
215
+ try {
216
+ currentChild?.kill();
217
+ }
218
+ catch { /* ignore */ }
219
+ try {
220
+ finalCleanup(opts, checkpoint, log);
221
+ }
222
+ catch { /* ignore */ }
223
+ process.exit(code);
219
224
  };
220
- process.on('SIGINT', () => gracefulStop('SIGINT'));
221
- process.on('SIGTERM', () => gracefulStop('SIGTERM'));
222
- process.on('SIGPIPE', () => { }); // CONC-6: ignore
225
+ process.on('SIGINT', () => die('SIGINT', 0));
226
+ process.on('SIGTERM', () => die('SIGTERM', 0));
227
+ process.on('SIGPIPE', () => { }); // ignore
223
228
  process.on('uncaughtException', (err) => {
224
- log.error(`Uncaught exception: ${err.message}`);
225
- finalCleanup(opts, checkpoint, log);
226
- process.exit(1);
229
+ try {
230
+ log.error(`Uncaught exception: ${err.message}`);
231
+ }
232
+ catch { /* ignore */ }
233
+ die('uncaughtException', 1);
227
234
  });
228
235
  process.on('unhandledRejection', (reason) => {
229
- log.error(`Unhandled rejection: ${reason}`);
230
- finalCleanup(opts, checkpoint, log);
231
- process.exit(1);
236
+ try {
237
+ log.error(`Unhandled rejection: ${reason}`);
238
+ }
239
+ catch { /* ignore */ }
240
+ die('unhandledRejection', 1);
232
241
  });
233
242
  }
234
243
  function finalCleanup(opts, checkpoint, log) {
@@ -152,13 +152,12 @@ export function killProcessTree(pid, isWin) {
152
152
  catch { /* already dead */ }
153
153
  return;
154
154
  }
155
- // Unix: SIGKILL the entire process group immediately (no SIGTERM grace period
156
- // when the user presses Ctrl+C they want it dead NOW, not in 5 seconds)
155
+ // Unix: SIGKILL immediately no SIGTERM grace period.
156
+ // Try process group first (negative PID), fall back to specific PID.
157
157
  try {
158
158
  process.kill(-pid, 'SIGKILL');
159
159
  }
160
160
  catch { /* no group or already dead */ }
161
- // Fallback: kill the specific PID if process group kill failed
162
161
  try {
163
162
  process.kill(pid, 'SIGKILL');
164
163
  }
@@ -196,19 +195,19 @@ export function runClaude(opts, log, runOpts = {}) {
196
195
  flags.push('--dangerously-skip-permissions');
197
196
  // Reset stream state for this invocation
198
197
  resetStreamState();
199
- // Spawn detached on both platforms so killProcessTree can target the process group.
200
- // CTRL+C kills the child immediately (SIGKILL/taskkill) and exits the parent via process.exit().
198
+ // Spawn WITHOUT detached child stays in the same process group as parent.
199
+ // When user presses Ctrl+C, BOTH parent and child receive the signal from the OS.
200
+ // Parent's SIGINT handler kills child (backup) and calls process.exit().
201
+ // Child's own SIGINT handler also fires, causing it to exit.
201
202
  const child = isWin
202
203
  ? spawn(process.env.ComSpec ?? 'cmd.exe', ['/c', 'claude', ...flags], {
203
204
  cwd: opts.projectDir,
204
205
  stdio: ['pipe', 'pipe', 'pipe'],
205
- detached: true,
206
206
  windowsHide: true,
207
207
  })
208
208
  : spawn('claude', [...flags, prompt], {
209
209
  cwd: opts.projectDir,
210
210
  stdio: ['ignore', 'pipe', 'pipe'],
211
- detached: true,
212
211
  });
213
212
  if (isWin && child.stdin) {
214
213
  child.stdin.write(prompt);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-claude-workspace",
3
- "version": "1.1.53",
3
+ "version": "1.1.54",
4
4
  "description": "Scaffold a project with Claude Code agents for autonomous AI-driven development",
5
5
  "type": "module",
6
6
  "bin": {