claude-task-worker 0.31.0 → 0.33.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.
- package/README.md +26 -1
- package/dist/index.js +124 -37
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -274,7 +274,7 @@ claude-task-worker yolo --epic 100 --epic 200 --label priority-high
|
|
|
274
274
|
}
|
|
275
275
|
```
|
|
276
276
|
|
|
277
|
-
`mode` については [`mode`(タスクの実行形態)](#modeタスクの実行形態) を参照。
|
|
277
|
+
`mode` については [`mode`(タスクの実行形態)](#modeタスクの実行形態) を、`headroom` については [`headroom`(Headroom 経由でのタスク実行)](#headroomheadroom-経由でのタスク実行) を参照。
|
|
278
278
|
|
|
279
279
|
`--project` は繰り返し指定可能で、複数指定した場合は解決後のプロジェクト集合の和集合が対象になる(重複は一意化される)。`--epic` / `--label` と併用でき、ディスパッチ先の各プロジェクトで実行されるコマンドにそのまま引き継がれる。
|
|
280
280
|
|
|
@@ -331,6 +331,31 @@ claude-task-worker exec-issue --project app-a --epic 100 --label priority-high
|
|
|
331
331
|
|
|
332
332
|
適用は `herdr server reload-config`。この設定は herdr サーバー全体に効くため、ワーカー以外の対話セッションの完了音も鳴らなくなる(`[ui.sound.agents] claude = "off"` でも実質同じ範囲)。ワーカーだけを無音にしたい場合は、`HERDR_DISABLE_SOUND=1 herdr --session <name>` で別セッションを起動し、その中でディスパッチャーを動かす
|
|
333
333
|
|
|
334
|
+
### `headroom`(Headroom 経由でのタスク実行)
|
|
335
|
+
|
|
336
|
+
`config.json` のトップレベルに `"headroom": true` を書くと、ワーカーは各タスクの claude を [Headroom](https://github.com/headroom-ai/headroom) 経由(`headroom wrap claude`)で起動する。Headroom がローカルプロキシを立ててコンテキストを圧縮し、`ANTHROPIC_BASE_URL` を差し替えた状態で claude を起動する。既定は `false`(`claude` を直接起動する)。
|
|
337
|
+
|
|
338
|
+
`mode` と同じくトップレベル一括の設定で、プロジェクト単位・ワーカー単位の指定はできない。
|
|
339
|
+
|
|
340
|
+
```json
|
|
341
|
+
{
|
|
342
|
+
"headroom": true,
|
|
343
|
+
"projects": { "app-a": "/Users/me/repos/app-a" }
|
|
344
|
+
}
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
| `headroom` | 実行されるコマンド |
|
|
348
|
+
|-----------|------------------|
|
|
349
|
+
| `false`(既定) | `claude <引数>` |
|
|
350
|
+
| `true` | `headroom wrap claude -- <引数>` |
|
|
351
|
+
|
|
352
|
+
補足:
|
|
353
|
+
|
|
354
|
+
- `mode` とは独立して組み合わせられる(`mode: "herdr"` の TUI 起動も `headroom wrap claude` になる)
|
|
355
|
+
- claude へ渡す引数はすべて `--` の後ろに置かれる。`headroom wrap claude` 自身も `--port` / `--memory` などのオプションを持ち、`-p` のように衝突しうるフラグは `--` の後ろでないと claude に届かないため
|
|
356
|
+
- `headroom: true` で headroom コマンドが PATH に無い場合、ワーカーは起動時にエラー終了する(`mode: "herdr"` と同じく、サイレントに直接起動へフォールバックはしない)
|
|
357
|
+
- `headroom wrap claude` は claude を起動する前に起動バナー(枠線・`ANTHROPIC_BASE_URL=...` など)を stdout へ出力し、これを抑止するオプションは無い。ワーカーは空振りセッション検知(exit 0 かつ無出力を失敗とみなす判定)の前にこのバナーを取り除くため、検知は `headroom: true` でも従来どおり機能する。ただし Slack 通知の本文にはバナーがそのまま含まれる
|
|
358
|
+
|
|
334
359
|
### exec-issue
|
|
335
360
|
|
|
336
361
|
`cc-exec-issue` ラベルが付いた自分にアサインされたIssueを定期取得し、Claude Codeで処理を実行する。(デフォルト1分間隔)
|
package/dist/index.js
CHANGED
|
@@ -132,6 +132,38 @@ var init_table = __esm({
|
|
|
132
132
|
}
|
|
133
133
|
});
|
|
134
134
|
|
|
135
|
+
// src/task-result.ts
|
|
136
|
+
function stripHeadroomBanner(stdout) {
|
|
137
|
+
const lines = stdout.split("\n");
|
|
138
|
+
let i = 0;
|
|
139
|
+
while (i < lines.length && (lines[i].trim() === "" || lines[i].startsWith(" "))) i++;
|
|
140
|
+
return lines.slice(i).join("\n");
|
|
141
|
+
}
|
|
142
|
+
function buildTaskResult(code, stdout, stderrTail, options) {
|
|
143
|
+
const meaningful = options?.headroom ? stripHeadroomBanner(stdout) : stdout;
|
|
144
|
+
const emptyOutput = meaningful.trim() === "";
|
|
145
|
+
const completed = code === 0 && !emptyOutput;
|
|
146
|
+
let output = stdout;
|
|
147
|
+
if (code === 0 && emptyOutput) {
|
|
148
|
+
output += "[worker] claude exited with code 0 but produced no output (session aborted before the model ran; e.g. a skill preamble command failed)";
|
|
149
|
+
} else if (!completed) {
|
|
150
|
+
output += `
|
|
151
|
+
[worker] claude exited with code ${code}`;
|
|
152
|
+
}
|
|
153
|
+
if (!completed && stderrTail.trim() !== "") {
|
|
154
|
+
output += `
|
|
155
|
+
[stderr] ${stderrTail.trim()}`;
|
|
156
|
+
}
|
|
157
|
+
return { status: completed ? "completed" : "failed", output };
|
|
158
|
+
}
|
|
159
|
+
var STDERR_TAIL_LIMIT;
|
|
160
|
+
var init_task_result = __esm({
|
|
161
|
+
"src/task-result.ts"() {
|
|
162
|
+
"use strict";
|
|
163
|
+
STDERR_TAIL_LIMIT = 8 * 1024;
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
|
|
135
167
|
// src/herdr.ts
|
|
136
168
|
var herdr_exports = {};
|
|
137
169
|
__export(herdr_exports, {
|
|
@@ -490,8 +522,9 @@ function observeAgentStatus(tracker, status) {
|
|
|
490
522
|
}
|
|
491
523
|
return { tracker, decision: "running" };
|
|
492
524
|
}
|
|
493
|
-
function buildHerdrTaskResult(paneOutput) {
|
|
494
|
-
|
|
525
|
+
function buildHerdrTaskResult(paneOutput, options) {
|
|
526
|
+
const meaningful = options?.headroom ? stripHeadroomBanner(paneOutput) : paneOutput;
|
|
527
|
+
if (meaningful.trim() === "") {
|
|
495
528
|
return {
|
|
496
529
|
status: "failed",
|
|
497
530
|
output: "[worker] the claude session became idle but its pane produced no output (session aborted before the model ran; e.g. a skill preamble command failed)"
|
|
@@ -549,7 +582,7 @@ async function waitForHerdrTask(paneId, options) {
|
|
|
549
582
|
tracker = observed.tracker;
|
|
550
583
|
if (observed.decision === "completed") {
|
|
551
584
|
const output = await readPaneOutput(paneId, mod);
|
|
552
|
-
return buildHerdrTaskResult(output);
|
|
585
|
+
return buildHerdrTaskResult(output, { headroom: options?.headroom });
|
|
553
586
|
}
|
|
554
587
|
if (observed.decision === "blocked-first-seen") {
|
|
555
588
|
options?.onBlocked?.();
|
|
@@ -609,6 +642,7 @@ var AGENT_POLL_INTERVAL_MS, PANE_OUTPUT_LINES, CLAUDE_EXIT_TIMEOUT_MS, CLAUDE_EX
|
|
|
609
642
|
var init_herdr_runner = __esm({
|
|
610
643
|
"src/herdr-runner.ts"() {
|
|
611
644
|
"use strict";
|
|
645
|
+
init_task_result();
|
|
612
646
|
AGENT_POLL_INTERVAL_MS = 3 * 1e3;
|
|
613
647
|
PANE_OUTPUT_LINES = 300;
|
|
614
648
|
CLAUDE_EXIT_TIMEOUT_MS = 15 * 1e3;
|
|
@@ -1378,6 +1412,9 @@ var SYSTEM_PROMPT = `\u3053\u306E\u30BB\u30C3\u30B7\u30E7\u30F3\u306F \`claude-t
|
|
|
1378
1412
|
- CodeGraph \u304C\u8FD4\u3057\u305F\u30BD\u30FC\u30B9\u306F\u300C\u8AAD\u307F\u7D42\u3048\u305F\u3082\u306E\u300D\u3068\u3057\u3066\u6271\u3044\u3001\u540C\u3058\u7B87\u6240\u3092 \`Grep\`/\`Read\` \u3067\u88CF\u53D6\u308A\u3057\u76F4\u3055\u306A\u3044\u3002\u305F\u3060\u3057\u51FA\u529B\u306B staleness\uFF08\u30A4\u30F3\u30C7\u30C3\u30AF\u30B9\u304C\u53E4\u3044\u65E8\uFF09\u306E\u8B66\u544A\u304C\u51FA\u3066\u3044\u308B\u5834\u5408\u306F\u8A72\u5F53\u30D5\u30A1\u30A4\u30EB\u3092 \`Read\` \u3057\u3066\u73FE\u7269\u3092\u78BA\u8A8D\u3059\u308B
|
|
1379
1413
|
- \u8A2D\u5B9A\u30D5\u30A1\u30A4\u30EB\u30FB\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u30FB\u30B3\u30E1\u30F3\u30C8/\u6587\u5B57\u5217\u30EA\u30C6\u30E9\u30EB\u30FB\u672A\u5BFE\u5FDC\u8A00\u8A9E\u306A\u3069 CodeGraph \u304C\u6271\u308F\u306A\u3044\u5BFE\u8C61\u306F\u3001\u5F93\u6765\u3069\u304A\u308A\u30C6\u30AD\u30B9\u30C8\u691C\u7D22\u3067\u88DC\u3046
|
|
1380
1414
|
- \u63A2\u7D22\u3092\u30B5\u30D6\u30A8\u30FC\u30B8\u30A7\u30F3\u30C8\u3078\u59D4\u8B72\u3059\u308B\u5834\u5408\u306F\u3001\u3053\u306E\u65B9\u91DD\u3082\u59D4\u8B72\u30D7\u30ED\u30F3\u30D7\u30C8\u306B\u660E\u8A18\u3057\u3066\u4F1D\u3048\u308B`;
|
|
1415
|
+
var CLAUDE_COMMAND = "claude";
|
|
1416
|
+
var HEADROOM_COMMAND = "headroom";
|
|
1417
|
+
var HEADROOM_WRAP_OPTIONS = ["--1m", "--memory", "--code-graph"];
|
|
1381
1418
|
function buildClaudeArgs({ mode, prompt, model, effort }) {
|
|
1382
1419
|
return [
|
|
1383
1420
|
...mode === "herdr" ? [] : ["-p"],
|
|
@@ -1394,6 +1431,16 @@ function buildClaudeArgs({ mode, prompt, model, effort }) {
|
|
|
1394
1431
|
effort
|
|
1395
1432
|
];
|
|
1396
1433
|
}
|
|
1434
|
+
function buildClaudeExecution(invocation) {
|
|
1435
|
+
const args = buildClaudeArgs(invocation);
|
|
1436
|
+
if (!invocation.headroom) {
|
|
1437
|
+
return { command: CLAUDE_COMMAND, args };
|
|
1438
|
+
}
|
|
1439
|
+
return {
|
|
1440
|
+
command: HEADROOM_COMMAND,
|
|
1441
|
+
args: ["wrap", CLAUDE_COMMAND, ...HEADROOM_WRAP_OPTIONS, "--", ...args]
|
|
1442
|
+
};
|
|
1443
|
+
}
|
|
1397
1444
|
function buildClaudeEnv(mode) {
|
|
1398
1445
|
if (mode === "herdr") {
|
|
1399
1446
|
return {
|
|
@@ -1648,25 +1695,7 @@ async function assertRemoteTrackingExists(epicBranch) {
|
|
|
1648
1695
|
import { spawn } from "node:child_process";
|
|
1649
1696
|
import { basename } from "node:path";
|
|
1650
1697
|
init_table();
|
|
1651
|
-
|
|
1652
|
-
// src/task-result.ts
|
|
1653
|
-
var STDERR_TAIL_LIMIT = 8 * 1024;
|
|
1654
|
-
function buildTaskResult(code, stdout, stderrTail) {
|
|
1655
|
-
const emptyOutput = stdout.trim() === "";
|
|
1656
|
-
const completed = code === 0 && !emptyOutput;
|
|
1657
|
-
let output = stdout;
|
|
1658
|
-
if (code === 0 && emptyOutput) {
|
|
1659
|
-
output += "[worker] claude exited with code 0 but produced no output (session aborted before the model ran; e.g. a skill preamble command failed)";
|
|
1660
|
-
} else if (!completed) {
|
|
1661
|
-
output += `
|
|
1662
|
-
[worker] claude exited with code ${code}`;
|
|
1663
|
-
}
|
|
1664
|
-
if (!completed && stderrTail.trim() !== "") {
|
|
1665
|
-
output += `
|
|
1666
|
-
[stderr] ${stderrTail.trim()}`;
|
|
1667
|
-
}
|
|
1668
|
-
return { status: completed ? "completed" : "failed", output };
|
|
1669
|
-
}
|
|
1698
|
+
init_task_result();
|
|
1670
1699
|
|
|
1671
1700
|
// src/user-config.ts
|
|
1672
1701
|
import { readFileSync as readFileSync2, statSync } from "node:fs";
|
|
@@ -1674,6 +1703,7 @@ import { homedir } from "node:os";
|
|
|
1674
1703
|
import { isAbsolute, join as join2, resolve } from "node:path";
|
|
1675
1704
|
var RESERVED_ALL = "all";
|
|
1676
1705
|
var DEFAULT_RUN_MODE = "default";
|
|
1706
|
+
var DEFAULT_HEADROOM = false;
|
|
1677
1707
|
var UserConfigError = class extends Error {
|
|
1678
1708
|
constructor(message) {
|
|
1679
1709
|
super(message);
|
|
@@ -1722,6 +1752,13 @@ function parseMode(raw, path) {
|
|
|
1722
1752
|
console.warn(`[config] invalid mode: ${JSON.stringify(value)} in ${path}, using "${DEFAULT_RUN_MODE}"`);
|
|
1723
1753
|
return DEFAULT_RUN_MODE;
|
|
1724
1754
|
}
|
|
1755
|
+
function parseHeadroom(raw, path) {
|
|
1756
|
+
if (!("headroom" in raw)) return DEFAULT_HEADROOM;
|
|
1757
|
+
const value = raw["headroom"];
|
|
1758
|
+
if (typeof value === "boolean") return value;
|
|
1759
|
+
console.warn(`[config] invalid headroom: ${JSON.stringify(value)} in ${path}, using ${DEFAULT_HEADROOM}`);
|
|
1760
|
+
return DEFAULT_HEADROOM;
|
|
1761
|
+
}
|
|
1725
1762
|
function loadUserConfig() {
|
|
1726
1763
|
const path = getUserConfigPath();
|
|
1727
1764
|
const raw = readRawConfig();
|
|
@@ -1738,6 +1775,7 @@ function loadUserConfig() {
|
|
|
1738
1775
|
throw new UserConfigError(`config.json "projectGroups" must be an object: ${path}`);
|
|
1739
1776
|
}
|
|
1740
1777
|
const mode = parseMode(raw, path);
|
|
1778
|
+
const headroom = parseHeadroom(raw, path);
|
|
1741
1779
|
const rawProjects = raw["projects"];
|
|
1742
1780
|
const rawProjectGroups = "projectGroups" in raw ? raw["projectGroups"] : {};
|
|
1743
1781
|
const projectKeys = Object.keys(rawProjects);
|
|
@@ -1788,7 +1826,7 @@ function loadUserConfig() {
|
|
|
1788
1826
|
}
|
|
1789
1827
|
projectGroups[groupName] = members;
|
|
1790
1828
|
}
|
|
1791
|
-
return { mode, projects, projectGroups };
|
|
1829
|
+
return { mode, headroom, projects, projectGroups };
|
|
1792
1830
|
}
|
|
1793
1831
|
var cachedRunMode;
|
|
1794
1832
|
function getRunMode() {
|
|
@@ -1798,18 +1836,35 @@ function getRunMode() {
|
|
|
1798
1836
|
return cachedRunMode;
|
|
1799
1837
|
}
|
|
1800
1838
|
function readRunMode() {
|
|
1839
|
+
const raw = readTopLevelConfig(`using "${DEFAULT_RUN_MODE}" mode`);
|
|
1840
|
+
if (raw === void 0) return DEFAULT_RUN_MODE;
|
|
1841
|
+
return parseMode(raw, getUserConfigPath());
|
|
1842
|
+
}
|
|
1843
|
+
var cachedHeadroom;
|
|
1844
|
+
function getHeadroomEnabled() {
|
|
1845
|
+
if (cachedHeadroom === void 0) {
|
|
1846
|
+
cachedHeadroom = readHeadroom();
|
|
1847
|
+
}
|
|
1848
|
+
return cachedHeadroom;
|
|
1849
|
+
}
|
|
1850
|
+
function readHeadroom() {
|
|
1851
|
+
const raw = readTopLevelConfig(`using headroom=${DEFAULT_HEADROOM}`);
|
|
1852
|
+
if (raw === void 0) return DEFAULT_HEADROOM;
|
|
1853
|
+
return parseHeadroom(raw, getUserConfigPath());
|
|
1854
|
+
}
|
|
1855
|
+
function readTopLevelConfig(fallbackDescription) {
|
|
1801
1856
|
let raw;
|
|
1802
1857
|
try {
|
|
1803
1858
|
raw = readRawConfig();
|
|
1804
1859
|
} catch (err) {
|
|
1805
|
-
console.warn(`[config] failed to read config file,
|
|
1806
|
-
return
|
|
1860
|
+
console.warn(`[config] failed to read config file, ${fallbackDescription}: ${err}`);
|
|
1861
|
+
return void 0;
|
|
1807
1862
|
}
|
|
1808
|
-
if (raw === void 0) return
|
|
1863
|
+
if (raw === void 0) return void 0;
|
|
1809
1864
|
if (typeof raw !== "object" || raw === null || Array.isArray(raw)) {
|
|
1810
|
-
return
|
|
1865
|
+
return void 0;
|
|
1811
1866
|
}
|
|
1812
|
-
return
|
|
1867
|
+
return raw;
|
|
1813
1868
|
}
|
|
1814
1869
|
function findProjectNameByPath(path) {
|
|
1815
1870
|
let config;
|
|
@@ -1945,6 +2000,7 @@ async function runViaHerdr(command, args, id, onComplete, cwd, env) {
|
|
|
1945
2000
|
herdrTasks.set(id, task);
|
|
1946
2001
|
result = await waitForHerdrTask2(task.paneId, {
|
|
1947
2002
|
signal: herdrAbortSignal,
|
|
2003
|
+
headroom: getHeadroomEnabled(),
|
|
1948
2004
|
onBlocked: () => console.warn(`[worker] #${id} is blocked and waiting for input in herdr tab "${label}"`),
|
|
1949
2005
|
onStatus: (status) => {
|
|
1950
2006
|
const task2 = tasks.get(id);
|
|
@@ -2002,7 +2058,8 @@ function run(command, args, id, title, workerName, path, onComplete, cwd, env) {
|
|
|
2002
2058
|
const result = buildTaskResult(
|
|
2003
2059
|
code,
|
|
2004
2060
|
Buffer.concat(outputChunks).toString("utf-8"),
|
|
2005
|
-
Buffer.concat(stderrChunks).toString("utf-8").slice(-STDERR_TAIL_LIMIT)
|
|
2061
|
+
Buffer.concat(stderrChunks).toString("utf-8").slice(-STDERR_TAIL_LIMIT),
|
|
2062
|
+
{ headroom: getHeadroomEnabled() }
|
|
2006
2063
|
);
|
|
2007
2064
|
await finishTask(id, result, onComplete);
|
|
2008
2065
|
childProcesses.delete(id);
|
|
@@ -2711,7 +2768,13 @@ function createIssuePollingWorker(config) {
|
|
|
2711
2768
|
const command = skill || config.command;
|
|
2712
2769
|
const parentNumber = issue.parent?.number;
|
|
2713
2770
|
const mode = getRunMode();
|
|
2714
|
-
const
|
|
2771
|
+
const execution = buildClaudeExecution({
|
|
2772
|
+
mode,
|
|
2773
|
+
prompt: `${command} ${issue.number}`,
|
|
2774
|
+
model,
|
|
2775
|
+
effort,
|
|
2776
|
+
headroom: getHeadroomEnabled()
|
|
2777
|
+
});
|
|
2715
2778
|
let baseBranch = defaultBranch;
|
|
2716
2779
|
if (parentNumber !== void 0) {
|
|
2717
2780
|
baseBranch = `cc-epic-${parentNumber}`;
|
|
@@ -2721,8 +2784,8 @@ function createIssuePollingWorker(config) {
|
|
|
2721
2784
|
const cwd = getWorktreePath(worktreeId);
|
|
2722
2785
|
console.log(`[${config.name}] #${issue.number}: created worktree ${worktreeId} from ${baseBranch}`);
|
|
2723
2786
|
run(
|
|
2724
|
-
|
|
2725
|
-
|
|
2787
|
+
execution.command,
|
|
2788
|
+
execution.args,
|
|
2726
2789
|
issue.number,
|
|
2727
2790
|
issue.title,
|
|
2728
2791
|
config.name,
|
|
@@ -2877,9 +2940,16 @@ function createPrPollingWorker(config) {
|
|
|
2877
2940
|
const { model, effort, skill } = getWorkerConfig(config.name);
|
|
2878
2941
|
const command = skill || config.command;
|
|
2879
2942
|
const mode = getRunMode();
|
|
2943
|
+
const execution = buildClaudeExecution({
|
|
2944
|
+
mode,
|
|
2945
|
+
prompt: `${command} ${pr.number}`,
|
|
2946
|
+
model,
|
|
2947
|
+
effort,
|
|
2948
|
+
headroom: getHeadroomEnabled()
|
|
2949
|
+
});
|
|
2880
2950
|
run(
|
|
2881
|
-
|
|
2882
|
-
|
|
2951
|
+
execution.command,
|
|
2952
|
+
execution.args,
|
|
2883
2953
|
pr.number,
|
|
2884
2954
|
`PR #${pr.number} (${pr.headRefName})`,
|
|
2885
2955
|
config.name,
|
|
@@ -3543,6 +3613,23 @@ async function assertRunModeAvailable() {
|
|
|
3543
3613
|
}
|
|
3544
3614
|
console.log("[worker] run mode: herdr (each task runs as a TUI session in its own herdr tab)");
|
|
3545
3615
|
}
|
|
3616
|
+
async function assertHeadroomAvailable() {
|
|
3617
|
+
if (!getHeadroomEnabled()) return;
|
|
3618
|
+
const { execFile: execFile3 } = await import("node:child_process");
|
|
3619
|
+
const { promisify: promisify4 } = await import("node:util");
|
|
3620
|
+
try {
|
|
3621
|
+
await promisify4(execFile3)(HEADROOM_COMMAND, ["--version"]);
|
|
3622
|
+
} catch (err) {
|
|
3623
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
3624
|
+
console.error(`[worker] config.json has headroom: true but the headroom CLI is unavailable: ${message}`);
|
|
3625
|
+
process.exit(1);
|
|
3626
|
+
}
|
|
3627
|
+
console.log("[worker] headroom: enabled (each task runs as `headroom wrap claude`)");
|
|
3628
|
+
}
|
|
3629
|
+
async function assertRunPrerequisites() {
|
|
3630
|
+
await assertRunModeAvailable();
|
|
3631
|
+
await assertHeadroomAvailable();
|
|
3632
|
+
}
|
|
3546
3633
|
if (!hasProjectFilter()) {
|
|
3547
3634
|
process.on("SIGTERM", async () => {
|
|
3548
3635
|
if (isShuttingDown()) return;
|
|
@@ -3631,7 +3718,7 @@ if (hasProjectFilter()) {
|
|
|
3631
3718
|
const epicFilters = parseEpicFilters();
|
|
3632
3719
|
const labelFilters = parseLabelFilters();
|
|
3633
3720
|
(async () => {
|
|
3634
|
-
await
|
|
3721
|
+
await assertRunPrerequisites();
|
|
3635
3722
|
await removeStaleWorktrees();
|
|
3636
3723
|
await Promise.all([
|
|
3637
3724
|
execIssueWorker({ epicFilters, labelFilters }),
|
|
@@ -3647,7 +3734,7 @@ if (hasProjectFilter()) {
|
|
|
3647
3734
|
const epicFilters = parseEpicFilters();
|
|
3648
3735
|
const labelFilters = parseLabelFilters();
|
|
3649
3736
|
(async () => {
|
|
3650
|
-
await
|
|
3737
|
+
await assertRunPrerequisites();
|
|
3651
3738
|
await removeStaleWorktrees();
|
|
3652
3739
|
await Promise.all([
|
|
3653
3740
|
execIssueWorker({ epicFilters, labelFilters }),
|
|
@@ -3666,7 +3753,7 @@ if (hasProjectFilter()) {
|
|
|
3666
3753
|
const epicFilters = parseEpicFilters();
|
|
3667
3754
|
const labelFilters = parseLabelFilters();
|
|
3668
3755
|
(async () => {
|
|
3669
|
-
await
|
|
3756
|
+
await assertRunPrerequisites();
|
|
3670
3757
|
await removeStaleWorktrees();
|
|
3671
3758
|
await WORKERS[workerType]({ epicFilters, labelFilters });
|
|
3672
3759
|
})();
|