claude-task-worker 0.68.0 → 0.69.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 +17 -0
- package/dist/index.js +316 -249
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -185,6 +185,7 @@ claude-task-worker exec-issue --project app-a --epic 100 --label priority-high
|
|
|
185
185
|
{
|
|
186
186
|
"mode": "default",
|
|
187
187
|
"advisor": false,
|
|
188
|
+
"permission": "bypassPermissions",
|
|
188
189
|
"projects": {
|
|
189
190
|
"app-a": "/Users/me/repos/app-a",
|
|
190
191
|
"app-b": "/Users/me/repos/app-b"
|
|
@@ -215,6 +216,7 @@ claude-task-worker exec-issue --project app-a --epic 100 --label priority-high
|
|
|
215
216
|
| `projectGroups` | `{}` | グループ名 → プロジェクト名配列 |
|
|
216
217
|
| `mode` | `"default"` | タスクの実行形態(下記) |
|
|
217
218
|
| `advisor` | `false` | `--advisor` を渡すか(下記) |
|
|
219
|
+
| `permission` | `"bypassPermissions"` | Claude CLI の権限モード(下記) |
|
|
218
220
|
|
|
219
221
|
#### `mode`(タスクの実行形態)
|
|
220
222
|
|
|
@@ -235,6 +237,21 @@ claude-task-worker exec-issue --project app-a --epic 100 --label priority-high
|
|
|
235
237
|
|
|
236
238
|
advisor は main モデル以上の能力が必要(Claude CLI の制約)。全ワーカーの既定 `model` が `opus` なので、`advisorModel` の既定値はすべて空文字(advisor なし)。`model` を `sonnet` 等へ下げたワーカーには `advisorModel: "opus"` を指定できる。
|
|
237
239
|
|
|
240
|
+
#### `permission`(権限モード)
|
|
241
|
+
|
|
242
|
+
タスク起動時に Claude CLI へ渡す[権限モード](https://code.claude.com/docs/ja/permission-modes)。`mode` / `advisor` と同じくトップレベル一括で、プロジェクト単位・ワーカー単位の指定はできない。
|
|
243
|
+
|
|
244
|
+
| `permission` | 挙動 |
|
|
245
|
+
|---|---|
|
|
246
|
+
| `"bypassPermissions"`(既定) | 全許可。承認するユーザーが常駐しない自律実行のため既定 |
|
|
247
|
+
| `"dontAsk"` | 許可されていない操作は確認せずスキップする |
|
|
248
|
+
| `"auto"` | 安全な操作は自動承認、危険な操作のみ確認 |
|
|
249
|
+
| `"acceptEdits"` | ファイル編集は自動承認、それ以外は都度確認 |
|
|
250
|
+
| `"manual"` | 標準の権限確認 |
|
|
251
|
+
| `"plan"` | 読み取りのみ。変更は行わない |
|
|
252
|
+
|
|
253
|
+
値は Claude CLI の `--permission-mode` にそのまま渡される(choices と同じ綴り)。ワーカーには承認するユーザーがいないため、`bypassPermissions` / `dontAsk` 以外ではタスクが承認待ちで止まりうる(`mode: "herdr"` なら herdr のタブを開いて手動で承認できる)。
|
|
254
|
+
|
|
238
255
|
### `claude-task-worker.json`(リポジトリ)
|
|
239
256
|
|
|
240
257
|
| キー | 型 | 既定 | 説明 |
|
package/dist/index.js
CHANGED
|
@@ -16,11 +16,16 @@ __export(table_exports, {
|
|
|
16
16
|
TASK_DISPLAY_LIMIT: () => TASK_DISPLAY_LIMIT,
|
|
17
17
|
buildLogTableLines: () => buildLogTableLines,
|
|
18
18
|
buildTaskTableLines: () => buildTaskTableLines,
|
|
19
|
+
captureConsole: () => captureConsole,
|
|
19
20
|
getDisplayWidth: () => getDisplayWidth,
|
|
21
|
+
logLines: () => logLines,
|
|
20
22
|
padToWidth: () => padToWidth,
|
|
23
|
+
pushLogLine: () => pushLogLine,
|
|
21
24
|
selectRecentTasks: () => selectRecentTasks,
|
|
22
|
-
truncateToWidth: () => truncateToWidth
|
|
25
|
+
truncateToWidth: () => truncateToWidth,
|
|
26
|
+
writeScreen: () => writeScreen
|
|
23
27
|
});
|
|
28
|
+
import { format } from "node:util";
|
|
24
29
|
function getDisplayWidth(str) {
|
|
25
30
|
let width = 0;
|
|
26
31
|
for (const char of str) {
|
|
@@ -132,6 +137,32 @@ function buildTaskTableLines(entries, now = /* @__PURE__ */ new Date()) {
|
|
|
132
137
|
function taskRow(t, title, path2, hasPath, status, time, duration) {
|
|
133
138
|
return hasPath ? [`#${t.id}`, title, t.workerName, path2, status, time, duration] : [`#${t.id}`, title, t.workerName, status, time, duration];
|
|
134
139
|
}
|
|
140
|
+
function pushLogLine(entry) {
|
|
141
|
+
if (entry.text.trim().length === 0) return;
|
|
142
|
+
logLines.push(entry);
|
|
143
|
+
if (logLines.length > LOG_DISPLAY_LIMIT) {
|
|
144
|
+
logLines.splice(0, logLines.length - LOG_DISPLAY_LIMIT);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
function writeScreen(lines) {
|
|
148
|
+
rawClear();
|
|
149
|
+
rawLog(lines.join("\n"));
|
|
150
|
+
}
|
|
151
|
+
function captureConsole() {
|
|
152
|
+
if (consoleCaptured) return;
|
|
153
|
+
consoleCaptured = true;
|
|
154
|
+
process.on("exit", () => {
|
|
155
|
+
if (logLines.length > 0) rawLog(buildLogTableLines(logLines).join("\n"));
|
|
156
|
+
});
|
|
157
|
+
const streams = { log: "stdout", info: "stdout", warn: "stderr", error: "stderr" };
|
|
158
|
+
for (const [method, stream] of Object.entries(streams)) {
|
|
159
|
+
console[method] = (...args) => {
|
|
160
|
+
for (const line of format(...args).split("\n")) {
|
|
161
|
+
pushLogLine({ stream, text: line, time: /* @__PURE__ */ new Date() });
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
}
|
|
135
166
|
function sanitizeLogText(text) {
|
|
136
167
|
return text.replace(CONTROL_CHARS, " ").replace(/\t/g, " ");
|
|
137
168
|
}
|
|
@@ -142,19 +173,23 @@ function buildLogTableLines(entries) {
|
|
|
142
173
|
const text = sanitizeLogText(e.text);
|
|
143
174
|
return [
|
|
144
175
|
formatTime(e.time),
|
|
145
|
-
`#${e.id}`,
|
|
176
|
+
e.id === void 0 ? "-" : `#${e.id}`,
|
|
146
177
|
e.stream,
|
|
147
178
|
getDisplayWidth(text) > maxTextWidth ? truncateToWidth(text, maxTextWidth) : text
|
|
148
179
|
];
|
|
149
180
|
});
|
|
150
181
|
return renderBoxTable(["Time", "#", "Stream", "Log"], [rows]);
|
|
151
182
|
}
|
|
152
|
-
var TASK_DISPLAY_LIMIT, LOG_DISPLAY_LIMIT, CONTROL_CHARS;
|
|
183
|
+
var TASK_DISPLAY_LIMIT, LOG_DISPLAY_LIMIT, logLines, rawLog, rawClear, consoleCaptured, CONTROL_CHARS;
|
|
153
184
|
var init_table = __esm({
|
|
154
185
|
"src/table.ts"() {
|
|
155
186
|
"use strict";
|
|
156
187
|
TASK_DISPLAY_LIMIT = 20;
|
|
157
188
|
LOG_DISPLAY_LIMIT = 20;
|
|
189
|
+
logLines = [];
|
|
190
|
+
rawLog = console.log.bind(console);
|
|
191
|
+
rawClear = console.clear.bind(console);
|
|
192
|
+
consoleCaptured = false;
|
|
158
193
|
CONTROL_CHARS = /\x1b\[[0-9;?]*[ -/]*[@-~]|[\x00-\x08\x0b-\x1f\x7f]/g;
|
|
159
194
|
}
|
|
160
195
|
});
|
|
@@ -1001,7 +1036,11 @@ function formatUptime(start, now) {
|
|
|
1001
1036
|
}
|
|
1002
1037
|
function renderSessionTable(sessions) {
|
|
1003
1038
|
const entries = [...sessions.values()];
|
|
1004
|
-
|
|
1039
|
+
const logTableLines = buildLogTableLines2(logLines2);
|
|
1040
|
+
if (entries.length === 0) {
|
|
1041
|
+
if (logTableLines.length > 0) writeScreen2(["Logs", ...logTableLines]);
|
|
1042
|
+
return;
|
|
1043
|
+
}
|
|
1005
1044
|
const maxProjectWidth = 20;
|
|
1006
1045
|
const rows = entries.map((session) => ({
|
|
1007
1046
|
project: getDisplayWidth2(session.name) > maxProjectWidth ? truncateToWidth2(session.name, maxProjectWidth) : session.name,
|
|
@@ -1028,8 +1067,8 @@ function renderSessionTable(sessions) {
|
|
|
1028
1067
|
lines.push(row(r.project, r.workspace, r.pane, r.status, r.uptime));
|
|
1029
1068
|
}
|
|
1030
1069
|
lines.push(line("\u2514", "\u2534", "\u2518", "\u2500"));
|
|
1031
|
-
|
|
1032
|
-
|
|
1070
|
+
if (logTableLines.length > 0) lines.push("", "Logs", ...logTableLines);
|
|
1071
|
+
writeScreen2(lines);
|
|
1033
1072
|
}
|
|
1034
1073
|
function monitorSessions(sessions, herdr, options) {
|
|
1035
1074
|
const pollIntervalMs = options?.pollIntervalMs ?? POLL_INTERVAL_MS;
|
|
@@ -1179,11 +1218,11 @@ function createDispatcherShutdownHandler(shutdown2) {
|
|
|
1179
1218
|
};
|
|
1180
1219
|
return { handle, isShuttingDown: () => shuttingDown2 };
|
|
1181
1220
|
}
|
|
1182
|
-
var getDisplayWidth2, truncateToWidth2, padToWidth2, POLL_INTERVAL_MS, SHUTDOWN_TIMEOUT_MS, PANE_READY_TIMEOUT_MS2, PANE_READY_POLL_INTERVAL_MS2, WORKER_STARTUP_TIMEOUT_MS, WORKER_STARTUP_POLL_INTERVAL_MS, SEND_MAX_ATTEMPTS, LABEL_PREFIX, SHELL_NAME_PATTERN, SHUTDOWN_RETRY_TIMEOUT_MS, CTRL_C_KEY, shutdownPromise;
|
|
1221
|
+
var getDisplayWidth2, truncateToWidth2, padToWidth2, buildLogTableLines2, logLines2, writeScreen2, POLL_INTERVAL_MS, SHUTDOWN_TIMEOUT_MS, PANE_READY_TIMEOUT_MS2, PANE_READY_POLL_INTERVAL_MS2, WORKER_STARTUP_TIMEOUT_MS, WORKER_STARTUP_POLL_INTERVAL_MS, SEND_MAX_ATTEMPTS, LABEL_PREFIX, SHELL_NAME_PATTERN, SHUTDOWN_RETRY_TIMEOUT_MS, CTRL_C_KEY, shutdownPromise;
|
|
1183
1222
|
var init_dispatcher = __esm({
|
|
1184
1223
|
async "src/dispatcher.ts"() {
|
|
1185
1224
|
"use strict";
|
|
1186
|
-
({ getDisplayWidth: getDisplayWidth2, truncateToWidth: truncateToWidth2, padToWidth: padToWidth2 } = await loadTable());
|
|
1225
|
+
({ getDisplayWidth: getDisplayWidth2, truncateToWidth: truncateToWidth2, padToWidth: padToWidth2, buildLogTableLines: buildLogTableLines2, logLines: logLines2, writeScreen: writeScreen2 } = await loadTable());
|
|
1187
1226
|
POLL_INTERVAL_MS = 7 * 1e3;
|
|
1188
1227
|
SHUTDOWN_TIMEOUT_MS = 10 * 60 * 1e3;
|
|
1189
1228
|
PANE_READY_TIMEOUT_MS2 = 30 * 1e3;
|
|
@@ -1489,6 +1528,244 @@ async function createLabel(name, color, force) {
|
|
|
1489
1528
|
import { mkdirSync, renameSync, writeFileSync } from "node:fs";
|
|
1490
1529
|
import os from "node:os";
|
|
1491
1530
|
import path from "node:path";
|
|
1531
|
+
|
|
1532
|
+
// src/user-config.ts
|
|
1533
|
+
import { readFileSync, statSync } from "node:fs";
|
|
1534
|
+
import { homedir } from "node:os";
|
|
1535
|
+
import { isAbsolute, join, resolve } from "node:path";
|
|
1536
|
+
var RESERVED_ALL = "all";
|
|
1537
|
+
var DEFAULT_RUN_MODE = "default";
|
|
1538
|
+
var DEFAULT_ADVISOR_ENABLED = false;
|
|
1539
|
+
var PERMISSION_MODES = [
|
|
1540
|
+
"manual",
|
|
1541
|
+
"auto",
|
|
1542
|
+
"acceptEdits",
|
|
1543
|
+
"dontAsk",
|
|
1544
|
+
"plan",
|
|
1545
|
+
"bypassPermissions"
|
|
1546
|
+
];
|
|
1547
|
+
var DEFAULT_PERMISSION_MODE = "bypassPermissions";
|
|
1548
|
+
var UserConfigError = class extends Error {
|
|
1549
|
+
constructor(message) {
|
|
1550
|
+
super(message);
|
|
1551
|
+
this.name = "UserConfigError";
|
|
1552
|
+
}
|
|
1553
|
+
};
|
|
1554
|
+
function getConfigDir() {
|
|
1555
|
+
const xdg = process.env.XDG_CONFIG_HOME;
|
|
1556
|
+
const configHome = xdg && xdg.length > 0 ? xdg : join(homedir(), ".config");
|
|
1557
|
+
return join(configHome, "claude-task-worker");
|
|
1558
|
+
}
|
|
1559
|
+
function getUserConfigPath() {
|
|
1560
|
+
return join(getConfigDir(), "config.json");
|
|
1561
|
+
}
|
|
1562
|
+
function isDirectory(path2) {
|
|
1563
|
+
try {
|
|
1564
|
+
return statSync(path2).isDirectory();
|
|
1565
|
+
} catch {
|
|
1566
|
+
return false;
|
|
1567
|
+
}
|
|
1568
|
+
}
|
|
1569
|
+
function parseConfigFile(path2) {
|
|
1570
|
+
let content;
|
|
1571
|
+
try {
|
|
1572
|
+
content = readFileSync(path2, "utf-8");
|
|
1573
|
+
} catch (err) {
|
|
1574
|
+
if (err.code === "ENOENT") return void 0;
|
|
1575
|
+
throw err;
|
|
1576
|
+
}
|
|
1577
|
+
try {
|
|
1578
|
+
return JSON.parse(content);
|
|
1579
|
+
} catch (err) {
|
|
1580
|
+
if (err instanceof SyntaxError) {
|
|
1581
|
+
throw new UserConfigError(`config file contains invalid JSON: ${path2}: ${err.message}`);
|
|
1582
|
+
}
|
|
1583
|
+
throw err;
|
|
1584
|
+
}
|
|
1585
|
+
}
|
|
1586
|
+
function readRawConfig() {
|
|
1587
|
+
return parseConfigFile(getUserConfigPath());
|
|
1588
|
+
}
|
|
1589
|
+
function parseMode(raw, path2) {
|
|
1590
|
+
if (!("mode" in raw)) return DEFAULT_RUN_MODE;
|
|
1591
|
+
const value = raw["mode"];
|
|
1592
|
+
if (value === "default" || value === "herdr") return value;
|
|
1593
|
+
console.warn(`[config] invalid mode: ${JSON.stringify(value)} in ${path2}, using "${DEFAULT_RUN_MODE}"`);
|
|
1594
|
+
return DEFAULT_RUN_MODE;
|
|
1595
|
+
}
|
|
1596
|
+
function parseAdvisor(raw, path2) {
|
|
1597
|
+
if (!("advisor" in raw)) return DEFAULT_ADVISOR_ENABLED;
|
|
1598
|
+
const value = raw["advisor"];
|
|
1599
|
+
if (typeof value === "boolean") return value;
|
|
1600
|
+
console.warn(`[config] invalid advisor: ${JSON.stringify(value)} in ${path2}, using ${DEFAULT_ADVISOR_ENABLED}`);
|
|
1601
|
+
return DEFAULT_ADVISOR_ENABLED;
|
|
1602
|
+
}
|
|
1603
|
+
function parsePermission(raw, path2) {
|
|
1604
|
+
if (!("permission" in raw)) return DEFAULT_PERMISSION_MODE;
|
|
1605
|
+
const value = raw["permission"];
|
|
1606
|
+
if (typeof value === "string" && PERMISSION_MODES.includes(value)) return value;
|
|
1607
|
+
console.warn(`[config] invalid permission: ${JSON.stringify(value)} in ${path2}, using "${DEFAULT_PERMISSION_MODE}"`);
|
|
1608
|
+
return DEFAULT_PERMISSION_MODE;
|
|
1609
|
+
}
|
|
1610
|
+
function loadUserConfig() {
|
|
1611
|
+
const path2 = getUserConfigPath();
|
|
1612
|
+
const raw = readRawConfig();
|
|
1613
|
+
if (raw === void 0) {
|
|
1614
|
+
throw new UserConfigError(`config.json not found: ${path2}`);
|
|
1615
|
+
}
|
|
1616
|
+
if (typeof raw !== "object" || raw === null || Array.isArray(raw)) {
|
|
1617
|
+
throw new UserConfigError(`config.json must contain a JSON object: ${path2}`);
|
|
1618
|
+
}
|
|
1619
|
+
if (!("projects" in raw) || typeof raw["projects"] !== "object" || raw["projects"] === null || Array.isArray(raw["projects"])) {
|
|
1620
|
+
throw new UserConfigError(`config.json must contain a "projects" section as an object: ${path2}`);
|
|
1621
|
+
}
|
|
1622
|
+
if ("projectGroups" in raw && (typeof raw["projectGroups"] !== "object" || raw["projectGroups"] === null || Array.isArray(raw["projectGroups"]))) {
|
|
1623
|
+
throw new UserConfigError(`config.json "projectGroups" must be an object: ${path2}`);
|
|
1624
|
+
}
|
|
1625
|
+
const mode = parseMode(raw, path2);
|
|
1626
|
+
const advisor = parseAdvisor(raw, path2);
|
|
1627
|
+
const permission = parsePermission(raw, path2);
|
|
1628
|
+
const rawProjects = raw["projects"];
|
|
1629
|
+
const rawProjectGroups = "projectGroups" in raw ? raw["projectGroups"] : {};
|
|
1630
|
+
const projectKeys = Object.keys(rawProjects);
|
|
1631
|
+
const groupKeys = Object.keys(rawProjectGroups);
|
|
1632
|
+
if (projectKeys.includes(RESERVED_ALL) || groupKeys.includes(RESERVED_ALL)) {
|
|
1633
|
+
throw new UserConfigError(
|
|
1634
|
+
`"${RESERVED_ALL}" is a reserved word and cannot be used as a key in "projects" or "projectGroups"`
|
|
1635
|
+
);
|
|
1636
|
+
}
|
|
1637
|
+
const groupKeySet = new Set(groupKeys);
|
|
1638
|
+
const duplicateKeys = projectKeys.filter((key) => groupKeySet.has(key));
|
|
1639
|
+
if (duplicateKeys.length > 0) {
|
|
1640
|
+
throw new UserConfigError(
|
|
1641
|
+
`"projects" and "projectGroups" share the same key namespace; duplicate keys are not allowed: ${duplicateKeys.join(", ")}`
|
|
1642
|
+
);
|
|
1643
|
+
}
|
|
1644
|
+
const projects = {};
|
|
1645
|
+
for (const [name, value] of Object.entries(rawProjects)) {
|
|
1646
|
+
if (name === "__proto__") {
|
|
1647
|
+
throw new UserConfigError(`"__proto__" cannot be used as a key in "projects": ${path2}`);
|
|
1648
|
+
}
|
|
1649
|
+
if (typeof value !== "string" || !isAbsolute(value)) {
|
|
1650
|
+
console.warn(`[config] invalid projects.${name}: expected an absolute path, skipping`);
|
|
1651
|
+
continue;
|
|
1652
|
+
}
|
|
1653
|
+
if (!isDirectory(value)) {
|
|
1654
|
+
console.warn(`[config] projects.${name} does not exist as a directory: ${value}, skipping`);
|
|
1655
|
+
continue;
|
|
1656
|
+
}
|
|
1657
|
+
projects[name] = value;
|
|
1658
|
+
}
|
|
1659
|
+
const projectGroups = {};
|
|
1660
|
+
for (const [groupName, value] of Object.entries(rawProjectGroups)) {
|
|
1661
|
+
if (groupName === "__proto__") {
|
|
1662
|
+
throw new UserConfigError(`"__proto__" cannot be used as a key in "projectGroups": ${path2}`);
|
|
1663
|
+
}
|
|
1664
|
+
if (!Array.isArray(value)) {
|
|
1665
|
+
console.warn(`[config] invalid projectGroups.${groupName}: expected an array, skipping`);
|
|
1666
|
+
continue;
|
|
1667
|
+
}
|
|
1668
|
+
const members = [];
|
|
1669
|
+
for (const member of value) {
|
|
1670
|
+
if (typeof member !== "string" || !Object.prototype.hasOwnProperty.call(projects, member)) {
|
|
1671
|
+
console.warn(`[config] projectGroups.${groupName} references unknown project "${String(member)}", skipping`);
|
|
1672
|
+
continue;
|
|
1673
|
+
}
|
|
1674
|
+
members.push(member);
|
|
1675
|
+
}
|
|
1676
|
+
projectGroups[groupName] = members;
|
|
1677
|
+
}
|
|
1678
|
+
return { mode, advisor, permission, projects, projectGroups };
|
|
1679
|
+
}
|
|
1680
|
+
var cachedRunMode;
|
|
1681
|
+
function getRunMode() {
|
|
1682
|
+
if (cachedRunMode === void 0) {
|
|
1683
|
+
cachedRunMode = readRunMode();
|
|
1684
|
+
}
|
|
1685
|
+
return cachedRunMode;
|
|
1686
|
+
}
|
|
1687
|
+
var cachedAdvisorEnabled;
|
|
1688
|
+
function isAdvisorEnabled() {
|
|
1689
|
+
if (cachedAdvisorEnabled === void 0) {
|
|
1690
|
+
cachedAdvisorEnabled = readAdvisorEnabled();
|
|
1691
|
+
}
|
|
1692
|
+
return cachedAdvisorEnabled;
|
|
1693
|
+
}
|
|
1694
|
+
var cachedPermissionMode;
|
|
1695
|
+
function getPermissionMode() {
|
|
1696
|
+
if (cachedPermissionMode === void 0) {
|
|
1697
|
+
cachedPermissionMode = readTopLevel(parsePermission, DEFAULT_PERMISSION_MODE, "permission");
|
|
1698
|
+
}
|
|
1699
|
+
return cachedPermissionMode;
|
|
1700
|
+
}
|
|
1701
|
+
function readTopLevel(parse, fallback, label) {
|
|
1702
|
+
let raw;
|
|
1703
|
+
try {
|
|
1704
|
+
raw = readRawConfig();
|
|
1705
|
+
} catch (err) {
|
|
1706
|
+
console.warn(`[config] failed to read config file, using default ${label}: ${err}`);
|
|
1707
|
+
return fallback;
|
|
1708
|
+
}
|
|
1709
|
+
if (raw === void 0) return fallback;
|
|
1710
|
+
if (typeof raw !== "object" || raw === null || Array.isArray(raw)) {
|
|
1711
|
+
return fallback;
|
|
1712
|
+
}
|
|
1713
|
+
return parse(raw, getUserConfigPath());
|
|
1714
|
+
}
|
|
1715
|
+
function readAdvisorEnabled() {
|
|
1716
|
+
return readTopLevel(parseAdvisor, DEFAULT_ADVISOR_ENABLED, "advisor");
|
|
1717
|
+
}
|
|
1718
|
+
function readRunMode() {
|
|
1719
|
+
return readTopLevel(parseMode, DEFAULT_RUN_MODE, "mode");
|
|
1720
|
+
}
|
|
1721
|
+
function findProjectNameByPath(path2) {
|
|
1722
|
+
let config;
|
|
1723
|
+
try {
|
|
1724
|
+
config = loadUserConfig();
|
|
1725
|
+
} catch {
|
|
1726
|
+
return void 0;
|
|
1727
|
+
}
|
|
1728
|
+
const target = resolve(path2);
|
|
1729
|
+
for (const [name, projectPath] of Object.entries(config.projects)) {
|
|
1730
|
+
if (resolve(projectPath) === target) return name;
|
|
1731
|
+
}
|
|
1732
|
+
return void 0;
|
|
1733
|
+
}
|
|
1734
|
+
function resolveTargetProjects(requested, config) {
|
|
1735
|
+
const resolved = /* @__PURE__ */ new Map();
|
|
1736
|
+
for (const name of requested) {
|
|
1737
|
+
if (name === RESERVED_ALL) {
|
|
1738
|
+
for (const [projectName, projectPath] of Object.entries(config.projects)) {
|
|
1739
|
+
resolved.set(projectName, { name: projectName, path: projectPath });
|
|
1740
|
+
}
|
|
1741
|
+
continue;
|
|
1742
|
+
}
|
|
1743
|
+
if (Object.prototype.hasOwnProperty.call(config.projects, name)) {
|
|
1744
|
+
resolved.set(name, { name, path: config.projects[name] });
|
|
1745
|
+
continue;
|
|
1746
|
+
}
|
|
1747
|
+
if (Object.prototype.hasOwnProperty.call(config.projectGroups, name)) {
|
|
1748
|
+
for (const projectName of config.projectGroups[name]) {
|
|
1749
|
+
const projectPath = config.projects[projectName];
|
|
1750
|
+
if (projectPath === void 0) continue;
|
|
1751
|
+
resolved.set(projectName, { name: projectName, path: projectPath });
|
|
1752
|
+
}
|
|
1753
|
+
continue;
|
|
1754
|
+
}
|
|
1755
|
+
const availableProjects = Object.keys(config.projects).join(", ") || "(none)";
|
|
1756
|
+
const availableGroups = Object.keys(config.projectGroups).join(", ") || "(none)";
|
|
1757
|
+
throw new UserConfigError(
|
|
1758
|
+
`Unknown project or group: "${name}". Available projects: ${availableProjects}. Available groups: ${availableGroups}.`
|
|
1759
|
+
);
|
|
1760
|
+
}
|
|
1761
|
+
const resolvedProjects = Array.from(resolved.values());
|
|
1762
|
+
if (resolvedProjects.length === 0) {
|
|
1763
|
+
throw new UserConfigError(`No projects resolved from requested targets: ${requested.join(", ")}`);
|
|
1764
|
+
}
|
|
1765
|
+
return resolvedProjects;
|
|
1766
|
+
}
|
|
1767
|
+
|
|
1768
|
+
// src/claude-args.ts
|
|
1492
1769
|
var DISALLOWED_TOOLS = [
|
|
1493
1770
|
// 遅延 / yield: 後続ウェイクアップ前提。print モードではウェイクアップが発火せず、
|
|
1494
1771
|
// 呼ぶと処理未完のままプロセスが終了する。
|
|
@@ -1565,12 +1842,21 @@ function systemPromptFilePath(model) {
|
|
|
1565
1842
|
cachedSystemPromptFilePaths.set(variant, target);
|
|
1566
1843
|
return target;
|
|
1567
1844
|
}
|
|
1568
|
-
function buildClaudeArgs({
|
|
1845
|
+
function buildClaudeArgs({
|
|
1846
|
+
mode,
|
|
1847
|
+
prompt,
|
|
1848
|
+
model,
|
|
1849
|
+
effort,
|
|
1850
|
+
advisorModel,
|
|
1851
|
+
permissionMode
|
|
1852
|
+
}) {
|
|
1569
1853
|
const advisor = advisorModel?.trim() ?? "";
|
|
1854
|
+
const permission = permissionMode ?? DEFAULT_PERMISSION_MODE;
|
|
1570
1855
|
return [
|
|
1571
1856
|
...mode === "herdr" ? [] : ["-p"],
|
|
1572
1857
|
prompt,
|
|
1573
|
-
"--
|
|
1858
|
+
"--permission-mode",
|
|
1859
|
+
permission,
|
|
1574
1860
|
"--chrome",
|
|
1575
1861
|
"--disallowedTools",
|
|
1576
1862
|
DISALLOWED_TOOLS_ARG,
|
|
@@ -1593,8 +1879,8 @@ function buildClaudeEnv(mode) {
|
|
|
1593
1879
|
}
|
|
1594
1880
|
|
|
1595
1881
|
// src/config.ts
|
|
1596
|
-
import { readFileSync } from "node:fs";
|
|
1597
|
-
import { isAbsolute, join, normalize, sep as SEP } from "node:path";
|
|
1882
|
+
import { readFileSync as readFileSync2 } from "node:fs";
|
|
1883
|
+
import { isAbsolute as isAbsolute2, join as join2, normalize, sep as SEP } from "node:path";
|
|
1598
1884
|
var DEFAULT_UI_DESIGN_CONFIG = {
|
|
1599
1885
|
enabled: false,
|
|
1600
1886
|
designDir: "designs",
|
|
@@ -1724,7 +2010,7 @@ var DEFAULT_CONFIG = {
|
|
|
1724
2010
|
uiDesign: { ...DEFAULT_UI_DESIGN_CONFIG },
|
|
1725
2011
|
workers: {}
|
|
1726
2012
|
};
|
|
1727
|
-
var CONFIG_PATH =
|
|
2013
|
+
var CONFIG_PATH = join2(process.cwd(), "claude-task-worker.json");
|
|
1728
2014
|
function defaultsFor(name) {
|
|
1729
2015
|
return WORKER_DEFAULTS[name] ?? DEFAULT_WORKER_CONFIG;
|
|
1730
2016
|
}
|
|
@@ -1825,7 +2111,7 @@ function parseUiDesignEntry(val) {
|
|
|
1825
2111
|
}
|
|
1826
2112
|
if ("designDir" in entry) {
|
|
1827
2113
|
const normalized = typeof entry.designDir === "string" && entry.designDir.length > 0 ? normalize(entry.designDir) : null;
|
|
1828
|
-
const isContained = normalized !== null && !
|
|
2114
|
+
const isContained = normalized !== null && !isAbsolute2(normalized) && normalized !== ".." && !normalized.startsWith(`..${SEP}`);
|
|
1829
2115
|
if (isContained) {
|
|
1830
2116
|
result.designDir = normalized;
|
|
1831
2117
|
} else {
|
|
@@ -1840,7 +2126,7 @@ function loadConfig() {
|
|
|
1840
2126
|
const configPath = CONFIG_PATH;
|
|
1841
2127
|
let raw;
|
|
1842
2128
|
try {
|
|
1843
|
-
raw = JSON.parse(
|
|
2129
|
+
raw = JSON.parse(readFileSync2(configPath, "utf-8"));
|
|
1844
2130
|
} catch (err) {
|
|
1845
2131
|
if (err.code === "ENOENT") {
|
|
1846
2132
|
return { ...DEFAULT_CONFIG, uiDesign: { ...DEFAULT_UI_DESIGN_CONFIG }, workers: {} };
|
|
@@ -1951,239 +2237,13 @@ function buildTaskResult(code, stdout, stderrTail) {
|
|
|
1951
2237
|
return { status: completed ? "completed" : "failed", output };
|
|
1952
2238
|
}
|
|
1953
2239
|
|
|
1954
|
-
// src/user-config.ts
|
|
1955
|
-
import { readFileSync as readFileSync2, statSync } from "node:fs";
|
|
1956
|
-
import { homedir } from "node:os";
|
|
1957
|
-
import { isAbsolute as isAbsolute2, join as join2, resolve } from "node:path";
|
|
1958
|
-
var RESERVED_ALL = "all";
|
|
1959
|
-
var DEFAULT_RUN_MODE = "default";
|
|
1960
|
-
var DEFAULT_ADVISOR_ENABLED = false;
|
|
1961
|
-
var UserConfigError = class extends Error {
|
|
1962
|
-
constructor(message) {
|
|
1963
|
-
super(message);
|
|
1964
|
-
this.name = "UserConfigError";
|
|
1965
|
-
}
|
|
1966
|
-
};
|
|
1967
|
-
function getConfigDir() {
|
|
1968
|
-
const xdg = process.env.XDG_CONFIG_HOME;
|
|
1969
|
-
const configHome = xdg && xdg.length > 0 ? xdg : join2(homedir(), ".config");
|
|
1970
|
-
return join2(configHome, "claude-task-worker");
|
|
1971
|
-
}
|
|
1972
|
-
function getUserConfigPath() {
|
|
1973
|
-
return join2(getConfigDir(), "config.json");
|
|
1974
|
-
}
|
|
1975
|
-
function isDirectory(path2) {
|
|
1976
|
-
try {
|
|
1977
|
-
return statSync(path2).isDirectory();
|
|
1978
|
-
} catch {
|
|
1979
|
-
return false;
|
|
1980
|
-
}
|
|
1981
|
-
}
|
|
1982
|
-
function parseConfigFile(path2) {
|
|
1983
|
-
let content;
|
|
1984
|
-
try {
|
|
1985
|
-
content = readFileSync2(path2, "utf-8");
|
|
1986
|
-
} catch (err) {
|
|
1987
|
-
if (err.code === "ENOENT") return void 0;
|
|
1988
|
-
throw err;
|
|
1989
|
-
}
|
|
1990
|
-
try {
|
|
1991
|
-
return JSON.parse(content);
|
|
1992
|
-
} catch (err) {
|
|
1993
|
-
if (err instanceof SyntaxError) {
|
|
1994
|
-
throw new UserConfigError(`config file contains invalid JSON: ${path2}: ${err.message}`);
|
|
1995
|
-
}
|
|
1996
|
-
throw err;
|
|
1997
|
-
}
|
|
1998
|
-
}
|
|
1999
|
-
function readRawConfig() {
|
|
2000
|
-
return parseConfigFile(getUserConfigPath());
|
|
2001
|
-
}
|
|
2002
|
-
function parseMode(raw, path2) {
|
|
2003
|
-
if (!("mode" in raw)) return DEFAULT_RUN_MODE;
|
|
2004
|
-
const value = raw["mode"];
|
|
2005
|
-
if (value === "default" || value === "herdr") return value;
|
|
2006
|
-
console.warn(`[config] invalid mode: ${JSON.stringify(value)} in ${path2}, using "${DEFAULT_RUN_MODE}"`);
|
|
2007
|
-
return DEFAULT_RUN_MODE;
|
|
2008
|
-
}
|
|
2009
|
-
function parseAdvisor(raw, path2) {
|
|
2010
|
-
if (!("advisor" in raw)) return DEFAULT_ADVISOR_ENABLED;
|
|
2011
|
-
const value = raw["advisor"];
|
|
2012
|
-
if (typeof value === "boolean") return value;
|
|
2013
|
-
console.warn(`[config] invalid advisor: ${JSON.stringify(value)} in ${path2}, using ${DEFAULT_ADVISOR_ENABLED}`);
|
|
2014
|
-
return DEFAULT_ADVISOR_ENABLED;
|
|
2015
|
-
}
|
|
2016
|
-
function loadUserConfig() {
|
|
2017
|
-
const path2 = getUserConfigPath();
|
|
2018
|
-
const raw = readRawConfig();
|
|
2019
|
-
if (raw === void 0) {
|
|
2020
|
-
throw new UserConfigError(`config.json not found: ${path2}`);
|
|
2021
|
-
}
|
|
2022
|
-
if (typeof raw !== "object" || raw === null || Array.isArray(raw)) {
|
|
2023
|
-
throw new UserConfigError(`config.json must contain a JSON object: ${path2}`);
|
|
2024
|
-
}
|
|
2025
|
-
if (!("projects" in raw) || typeof raw["projects"] !== "object" || raw["projects"] === null || Array.isArray(raw["projects"])) {
|
|
2026
|
-
throw new UserConfigError(`config.json must contain a "projects" section as an object: ${path2}`);
|
|
2027
|
-
}
|
|
2028
|
-
if ("projectGroups" in raw && (typeof raw["projectGroups"] !== "object" || raw["projectGroups"] === null || Array.isArray(raw["projectGroups"]))) {
|
|
2029
|
-
throw new UserConfigError(`config.json "projectGroups" must be an object: ${path2}`);
|
|
2030
|
-
}
|
|
2031
|
-
const mode = parseMode(raw, path2);
|
|
2032
|
-
const advisor = parseAdvisor(raw, path2);
|
|
2033
|
-
const rawProjects = raw["projects"];
|
|
2034
|
-
const rawProjectGroups = "projectGroups" in raw ? raw["projectGroups"] : {};
|
|
2035
|
-
const projectKeys = Object.keys(rawProjects);
|
|
2036
|
-
const groupKeys = Object.keys(rawProjectGroups);
|
|
2037
|
-
if (projectKeys.includes(RESERVED_ALL) || groupKeys.includes(RESERVED_ALL)) {
|
|
2038
|
-
throw new UserConfigError(
|
|
2039
|
-
`"${RESERVED_ALL}" is a reserved word and cannot be used as a key in "projects" or "projectGroups"`
|
|
2040
|
-
);
|
|
2041
|
-
}
|
|
2042
|
-
const groupKeySet = new Set(groupKeys);
|
|
2043
|
-
const duplicateKeys = projectKeys.filter((key) => groupKeySet.has(key));
|
|
2044
|
-
if (duplicateKeys.length > 0) {
|
|
2045
|
-
throw new UserConfigError(
|
|
2046
|
-
`"projects" and "projectGroups" share the same key namespace; duplicate keys are not allowed: ${duplicateKeys.join(", ")}`
|
|
2047
|
-
);
|
|
2048
|
-
}
|
|
2049
|
-
const projects = {};
|
|
2050
|
-
for (const [name, value] of Object.entries(rawProjects)) {
|
|
2051
|
-
if (name === "__proto__") {
|
|
2052
|
-
throw new UserConfigError(`"__proto__" cannot be used as a key in "projects": ${path2}`);
|
|
2053
|
-
}
|
|
2054
|
-
if (typeof value !== "string" || !isAbsolute2(value)) {
|
|
2055
|
-
console.warn(`[config] invalid projects.${name}: expected an absolute path, skipping`);
|
|
2056
|
-
continue;
|
|
2057
|
-
}
|
|
2058
|
-
if (!isDirectory(value)) {
|
|
2059
|
-
console.warn(`[config] projects.${name} does not exist as a directory: ${value}, skipping`);
|
|
2060
|
-
continue;
|
|
2061
|
-
}
|
|
2062
|
-
projects[name] = value;
|
|
2063
|
-
}
|
|
2064
|
-
const projectGroups = {};
|
|
2065
|
-
for (const [groupName, value] of Object.entries(rawProjectGroups)) {
|
|
2066
|
-
if (groupName === "__proto__") {
|
|
2067
|
-
throw new UserConfigError(`"__proto__" cannot be used as a key in "projectGroups": ${path2}`);
|
|
2068
|
-
}
|
|
2069
|
-
if (!Array.isArray(value)) {
|
|
2070
|
-
console.warn(`[config] invalid projectGroups.${groupName}: expected an array, skipping`);
|
|
2071
|
-
continue;
|
|
2072
|
-
}
|
|
2073
|
-
const members = [];
|
|
2074
|
-
for (const member of value) {
|
|
2075
|
-
if (typeof member !== "string" || !Object.prototype.hasOwnProperty.call(projects, member)) {
|
|
2076
|
-
console.warn(`[config] projectGroups.${groupName} references unknown project "${String(member)}", skipping`);
|
|
2077
|
-
continue;
|
|
2078
|
-
}
|
|
2079
|
-
members.push(member);
|
|
2080
|
-
}
|
|
2081
|
-
projectGroups[groupName] = members;
|
|
2082
|
-
}
|
|
2083
|
-
return { mode, advisor, projects, projectGroups };
|
|
2084
|
-
}
|
|
2085
|
-
var cachedRunMode;
|
|
2086
|
-
function getRunMode() {
|
|
2087
|
-
if (cachedRunMode === void 0) {
|
|
2088
|
-
cachedRunMode = readRunMode();
|
|
2089
|
-
}
|
|
2090
|
-
return cachedRunMode;
|
|
2091
|
-
}
|
|
2092
|
-
var cachedAdvisorEnabled;
|
|
2093
|
-
function isAdvisorEnabled() {
|
|
2094
|
-
if (cachedAdvisorEnabled === void 0) {
|
|
2095
|
-
cachedAdvisorEnabled = readAdvisorEnabled();
|
|
2096
|
-
}
|
|
2097
|
-
return cachedAdvisorEnabled;
|
|
2098
|
-
}
|
|
2099
|
-
function readAdvisorEnabled() {
|
|
2100
|
-
let raw;
|
|
2101
|
-
try {
|
|
2102
|
-
raw = readRawConfig();
|
|
2103
|
-
} catch (err) {
|
|
2104
|
-
console.warn(`[config] failed to read config file, advisor disabled: ${err}`);
|
|
2105
|
-
return DEFAULT_ADVISOR_ENABLED;
|
|
2106
|
-
}
|
|
2107
|
-
if (raw === void 0) return DEFAULT_ADVISOR_ENABLED;
|
|
2108
|
-
if (typeof raw !== "object" || raw === null || Array.isArray(raw)) {
|
|
2109
|
-
return DEFAULT_ADVISOR_ENABLED;
|
|
2110
|
-
}
|
|
2111
|
-
return parseAdvisor(raw, getUserConfigPath());
|
|
2112
|
-
}
|
|
2113
|
-
function readRunMode() {
|
|
2114
|
-
let raw;
|
|
2115
|
-
try {
|
|
2116
|
-
raw = readRawConfig();
|
|
2117
|
-
} catch (err) {
|
|
2118
|
-
console.warn(`[config] failed to read config file, using "${DEFAULT_RUN_MODE}" mode: ${err}`);
|
|
2119
|
-
return DEFAULT_RUN_MODE;
|
|
2120
|
-
}
|
|
2121
|
-
if (raw === void 0) return DEFAULT_RUN_MODE;
|
|
2122
|
-
if (typeof raw !== "object" || raw === null || Array.isArray(raw)) {
|
|
2123
|
-
return DEFAULT_RUN_MODE;
|
|
2124
|
-
}
|
|
2125
|
-
return parseMode(raw, getUserConfigPath());
|
|
2126
|
-
}
|
|
2127
|
-
function findProjectNameByPath(path2) {
|
|
2128
|
-
let config;
|
|
2129
|
-
try {
|
|
2130
|
-
config = loadUserConfig();
|
|
2131
|
-
} catch {
|
|
2132
|
-
return void 0;
|
|
2133
|
-
}
|
|
2134
|
-
const target = resolve(path2);
|
|
2135
|
-
for (const [name, projectPath] of Object.entries(config.projects)) {
|
|
2136
|
-
if (resolve(projectPath) === target) return name;
|
|
2137
|
-
}
|
|
2138
|
-
return void 0;
|
|
2139
|
-
}
|
|
2140
|
-
function resolveTargetProjects(requested, config) {
|
|
2141
|
-
const resolved = /* @__PURE__ */ new Map();
|
|
2142
|
-
for (const name of requested) {
|
|
2143
|
-
if (name === RESERVED_ALL) {
|
|
2144
|
-
for (const [projectName, projectPath] of Object.entries(config.projects)) {
|
|
2145
|
-
resolved.set(projectName, { name: projectName, path: projectPath });
|
|
2146
|
-
}
|
|
2147
|
-
continue;
|
|
2148
|
-
}
|
|
2149
|
-
if (Object.prototype.hasOwnProperty.call(config.projects, name)) {
|
|
2150
|
-
resolved.set(name, { name, path: config.projects[name] });
|
|
2151
|
-
continue;
|
|
2152
|
-
}
|
|
2153
|
-
if (Object.prototype.hasOwnProperty.call(config.projectGroups, name)) {
|
|
2154
|
-
for (const projectName of config.projectGroups[name]) {
|
|
2155
|
-
const projectPath = config.projects[projectName];
|
|
2156
|
-
if (projectPath === void 0) continue;
|
|
2157
|
-
resolved.set(projectName, { name: projectName, path: projectPath });
|
|
2158
|
-
}
|
|
2159
|
-
continue;
|
|
2160
|
-
}
|
|
2161
|
-
const availableProjects = Object.keys(config.projects).join(", ") || "(none)";
|
|
2162
|
-
const availableGroups = Object.keys(config.projectGroups).join(", ") || "(none)";
|
|
2163
|
-
throw new UserConfigError(
|
|
2164
|
-
`Unknown project or group: "${name}". Available projects: ${availableProjects}. Available groups: ${availableGroups}.`
|
|
2165
|
-
);
|
|
2166
|
-
}
|
|
2167
|
-
const resolvedProjects = Array.from(resolved.values());
|
|
2168
|
-
if (resolvedProjects.length === 0) {
|
|
2169
|
-
throw new UserConfigError(`No projects resolved from requested targets: ${requested.join(", ")}`);
|
|
2170
|
-
}
|
|
2171
|
-
return resolvedProjects;
|
|
2172
|
-
}
|
|
2173
|
-
|
|
2174
2240
|
// src/process-manager.ts
|
|
2175
2241
|
var childProcesses = /* @__PURE__ */ new Map();
|
|
2176
2242
|
var herdrTasks = /* @__PURE__ */ new Map();
|
|
2177
2243
|
var herdrAbortSignal = { aborted: false };
|
|
2178
2244
|
var tasks = /* @__PURE__ */ new Map();
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
const trimmed = text.replace(/\r$/, "");
|
|
2182
|
-
if (trimmed.trim().length === 0) return;
|
|
2183
|
-
logLines.push({ id, stream, text: trimmed, time: /* @__PURE__ */ new Date() });
|
|
2184
|
-
if (logLines.length > LOG_DISPLAY_LIMIT) {
|
|
2185
|
-
logLines.splice(0, logLines.length - LOG_DISPLAY_LIMIT);
|
|
2186
|
-
}
|
|
2245
|
+
function pushTaskLogLine(id, stream, text) {
|
|
2246
|
+
pushLogLine({ id, stream, text: text.replace(/\r$/, ""), time: /* @__PURE__ */ new Date() });
|
|
2187
2247
|
}
|
|
2188
2248
|
function makeLogFeeder(id, stream) {
|
|
2189
2249
|
let partial = "";
|
|
@@ -2193,12 +2253,12 @@ function makeLogFeeder(id, stream) {
|
|
|
2193
2253
|
partial += decoder.write(chunk);
|
|
2194
2254
|
const parts = partial.split("\n");
|
|
2195
2255
|
partial = parts.pop() ?? "";
|
|
2196
|
-
for (const part of parts)
|
|
2256
|
+
for (const part of parts) pushTaskLogLine(id, stream, part);
|
|
2197
2257
|
},
|
|
2198
2258
|
flush() {
|
|
2199
2259
|
partial += decoder.end();
|
|
2200
2260
|
if (partial.length > 0) {
|
|
2201
|
-
|
|
2261
|
+
pushTaskLogLine(id, stream, partial);
|
|
2202
2262
|
partial = "";
|
|
2203
2263
|
}
|
|
2204
2264
|
}
|
|
@@ -2245,8 +2305,7 @@ function renderTable() {
|
|
|
2245
2305
|
if (lines.length > 0) lines.push("");
|
|
2246
2306
|
lines.push("Logs", ...logTableLines);
|
|
2247
2307
|
}
|
|
2248
|
-
|
|
2249
|
-
console.log(lines.join("\n"));
|
|
2308
|
+
writeScreen(lines);
|
|
2250
2309
|
}
|
|
2251
2310
|
var renderInterval;
|
|
2252
2311
|
function ensureRenderInterval() {
|
|
@@ -3076,7 +3135,8 @@ function createIssuePollingWorker(config) {
|
|
|
3076
3135
|
model,
|
|
3077
3136
|
effort,
|
|
3078
3137
|
// config.json の advisor が false なら advisorModel の指定に関わらず渡さない。
|
|
3079
|
-
advisorModel: isAdvisorEnabled() ? advisorModel : ""
|
|
3138
|
+
advisorModel: isAdvisorEnabled() ? advisorModel : "",
|
|
3139
|
+
permissionMode: getPermissionMode()
|
|
3080
3140
|
});
|
|
3081
3141
|
let baseBranch = defaultBranch;
|
|
3082
3142
|
if (parentNumber !== void 0) {
|
|
@@ -3249,7 +3309,8 @@ function createPrPollingWorker(config) {
|
|
|
3249
3309
|
model,
|
|
3250
3310
|
effort,
|
|
3251
3311
|
// config.json の advisor が false なら advisorModel の指定に関わらず渡さない。
|
|
3252
|
-
advisorModel: isAdvisorEnabled() ? advisorModel : ""
|
|
3312
|
+
advisorModel: isAdvisorEnabled() ? advisorModel : "",
|
|
3313
|
+
permissionMode: getPermissionMode()
|
|
3253
3314
|
});
|
|
3254
3315
|
run(
|
|
3255
3316
|
execution.command,
|
|
@@ -3707,6 +3768,9 @@ var applyUiDesignWorker = async (opts = {}) => {
|
|
|
3707
3768
|
})();
|
|
3708
3769
|
};
|
|
3709
3770
|
|
|
3771
|
+
// src/index.ts
|
|
3772
|
+
init_table();
|
|
3773
|
+
|
|
3710
3774
|
// src/commands/init.ts
|
|
3711
3775
|
import { mkdir as mkdir2, writeFile as writeFile2, access } from "node:fs/promises";
|
|
3712
3776
|
|
|
@@ -4217,6 +4281,8 @@ async function assertRunModeAvailable() {
|
|
|
4217
4281
|
console.log("[worker] run mode: herdr (each task runs as a TUI session in its own herdr tab)");
|
|
4218
4282
|
}
|
|
4219
4283
|
async function assertRunPrerequisites() {
|
|
4284
|
+
captureConsole();
|
|
4285
|
+
ensureRenderInterval();
|
|
4220
4286
|
await assertRunModeAvailable();
|
|
4221
4287
|
}
|
|
4222
4288
|
if (!hasProjectFilter()) {
|
|
@@ -4254,6 +4320,7 @@ if (hasProjectFilter()) {
|
|
|
4254
4320
|
let monitorHandle;
|
|
4255
4321
|
const herdr = await Promise.resolve().then(() => (init_herdr(), herdr_exports));
|
|
4256
4322
|
const dispatcher = await init_dispatcher().then(() => dispatcher_exports);
|
|
4323
|
+
captureConsole();
|
|
4257
4324
|
const shutdownController = dispatcher.createDispatcherShutdownHandler(
|
|
4258
4325
|
(options) => dispatcher.shutdownDispatcher(sessions, monitorHandle, options)
|
|
4259
4326
|
);
|