claude-task-worker 0.11.0 → 0.13.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.
Files changed (2) hide show
  1. package/dist/index.js +53 -16
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -81,13 +81,13 @@ function runHerdr(args) {
81
81
  } catch {
82
82
  parsed = void 0;
83
83
  }
84
- resolve2({ execError: error, parsed, stderr });
84
+ resolve2({ execError: error, parsed, stdout, stderr });
85
85
  }
86
86
  );
87
87
  });
88
88
  }
89
- async function execHerdr(args) {
90
- const { execError, parsed, stderr } = await runHerdr(args);
89
+ async function execHerdr(args, options) {
90
+ const { execError, parsed, stdout, stderr } = await runHerdr(args);
91
91
  const stderrSuffix = stderr.trim() ? `: ${stderr.trim()}` : "";
92
92
  if (parsed?.error) {
93
93
  throw new HerdrError(
@@ -99,6 +99,9 @@ async function execHerdr(args) {
99
99
  throw new Error(`herdr ${args.join(" ")} failed: ${execError.message}${stderrSuffix}`);
100
100
  }
101
101
  if (!parsed) {
102
+ if (options?.allowEmptyResult && stdout.trim() === "" && stderr.trim() === "") {
103
+ return void 0;
104
+ }
102
105
  throw new Error(`herdr ${args.join(" ")} failed: invalid JSON output${stderrSuffix}`);
103
106
  }
104
107
  return parsed.result;
@@ -127,10 +130,10 @@ async function tabList() {
127
130
  }));
128
131
  }
129
132
  async function paneSendText(paneId, text) {
130
- await execHerdr(["pane", "send-text", paneId, text]);
133
+ await execHerdr(["pane", "send-text", paneId, text], { allowEmptyResult: true });
131
134
  }
132
135
  async function paneSendKeys(paneId, ...keys) {
133
- await execHerdr(["pane", "send-keys", paneId, ...keys]);
136
+ await execHerdr(["pane", "send-keys", paneId, ...keys], { allowEmptyResult: true });
134
137
  }
135
138
  async function paneProcessInfo(paneId) {
136
139
  const result = await execHerdr(["pane", "process-info", "--pane", paneId]);
@@ -190,6 +193,7 @@ __export(dispatcher_exports, {
190
193
  POLL_INTERVAL_MS: () => POLL_INTERVAL_MS,
191
194
  SHUTDOWN_RETRY_TIMEOUT_MS: () => SHUTDOWN_RETRY_TIMEOUT_MS,
192
195
  SHUTDOWN_TIMEOUT_MS: () => SHUTDOWN_TIMEOUT_MS,
196
+ createDispatcherShutdownHandler: () => createDispatcherShutdownHandler,
193
197
  formatUptime: () => formatUptime,
194
198
  monitorSessions: () => monitorSessions,
195
199
  pollOnce: () => pollOnce,
@@ -335,11 +339,9 @@ function monitorSessions(sessions, herdr, options) {
335
339
  }
336
340
  });
337
341
  }, pollIntervalMs);
338
- pollInterval.unref();
339
342
  const renderInterval2 = setInterval(() => {
340
343
  renderSessionTable(sessions);
341
344
  }, renderIntervalMs);
342
- renderInterval2.unref();
343
345
  return {
344
346
  stop: finish,
345
347
  done
@@ -433,6 +435,33 @@ async function shutdownDispatcher(sessions, monitorHandle, options) {
433
435
  shutdownPromise = void 0;
434
436
  }
435
437
  }
438
+ function createDispatcherShutdownHandler(shutdown2) {
439
+ let shuttingDown2 = false;
440
+ let forceKilling = false;
441
+ const handle = async () => {
442
+ if (shuttingDown2) {
443
+ if (forceKilling) return;
444
+ forceKilling = true;
445
+ console.log("\n[dispatcher] Force killing sessions immediately...");
446
+ try {
447
+ await shutdown2({ forceKill: true });
448
+ } catch (error) {
449
+ console.error(`[dispatcher] force-kill shutdown failed: ${error}`);
450
+ process.exit(1);
451
+ }
452
+ return;
453
+ }
454
+ shuttingDown2 = true;
455
+ console.log("\n[dispatcher] Stopping sessions. Waiting for them to finish... (Press Ctrl-C again to force kill)");
456
+ try {
457
+ await shutdown2();
458
+ } catch (error) {
459
+ console.error(`[dispatcher] shutdown failed: ${error}`);
460
+ process.exit(1);
461
+ }
462
+ };
463
+ return { handle, isShuttingDown: () => shuttingDown2 };
464
+ }
436
465
  var getDisplayWidth2, truncateToWidth2, padToWidth2, POLL_INTERVAL_MS, SHUTDOWN_TIMEOUT_MS, SHUTDOWN_RETRY_TIMEOUT_MS, shutdownPromise;
437
466
  var init_dispatcher = __esm({
438
467
  async "src/dispatcher.ts"() {
@@ -2569,20 +2598,28 @@ if (hasProjectFilter()) {
2569
2598
  (async () => {
2570
2599
  let sessions = /* @__PURE__ */ new Map();
2571
2600
  let monitorHandle;
2572
- const handleShutdown = async () => {
2573
- const { shutdownDispatcher: shutdownDispatcher2 } = await init_dispatcher().then(() => dispatcher_exports);
2574
- await shutdownDispatcher2(sessions, monitorHandle);
2575
- };
2576
- process.on("SIGTERM", handleShutdown);
2577
- process.on("SIGINT", handleShutdown);
2578
2601
  const herdr = await Promise.resolve().then(() => (init_herdr(), herdr_exports));
2602
+ const dispatcher = await init_dispatcher().then(() => dispatcher_exports);
2603
+ const shutdownController = dispatcher.createDispatcherShutdownHandler(
2604
+ (options) => dispatcher.shutdownDispatcher(sessions, monitorHandle, options)
2605
+ );
2606
+ process.on("SIGTERM", shutdownController.handle);
2607
+ process.on("SIGINT", shutdownController.handle);
2579
2608
  try {
2580
2609
  const config = loadProjectsConfig();
2581
2610
  const projects = resolveTargetProjects(parseProjectFilters(), config);
2582
2611
  const forwardedCommand = buildForwardedCommand(process.argv.slice(2));
2583
- const { runDispatcher: runDispatcher2, monitorSessions: monitorSessions2 } = await init_dispatcher().then(() => dispatcher_exports);
2584
- sessions = await runDispatcher2(projects, forwardedCommand);
2585
- monitorHandle = monitorSessions2(sessions, herdr);
2612
+ sessions = await dispatcher.runDispatcher(projects, forwardedCommand);
2613
+ if (sessions.size === 0) {
2614
+ console.log("[dispatcher] no sessions were dispatched, exiting");
2615
+ process.exit(0);
2616
+ }
2617
+ monitorHandle = dispatcher.monitorSessions(sessions, herdr);
2618
+ await monitorHandle.done;
2619
+ if (!shutdownController.isShuttingDown()) {
2620
+ console.log("[dispatcher] all sessions finished, exiting");
2621
+ process.exit(0);
2622
+ }
2586
2623
  } catch (err) {
2587
2624
  if (err instanceof ProjectsConfigError || err instanceof herdr.HerdrUnavailableError) {
2588
2625
  console.error(`[dispatcher] ${err.message}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-task-worker",
3
- "version": "0.11.0",
3
+ "version": "0.13.0",
4
4
  "description": "CLI tool that polls GitHub Issues/PRs and delegates work to Claude CLI",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",