claude-task-worker 0.39.1 → 0.39.2
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/dist/index.js +76 -61
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -109,7 +109,7 @@ function buildTaskTableLines(entries, now = /* @__PURE__ */ new Date()) {
|
|
|
109
109
|
colWidths.duration
|
|
110
110
|
] : [colWidths.id, colWidths.title, colWidths.worker, colWidths.status, colWidths.time, colWidths.duration];
|
|
111
111
|
const line = (l, m, r, f) => `${l}${cols.map((w) => f.repeat(w + 2)).join(m)}${r}`;
|
|
112
|
-
const row = (id, title, worker,
|
|
112
|
+
const row = (id, title, worker, path2, status, time, duration) => hasPath ? `\u2502 ${pad(id, colWidths.id)} \u2502 ${pad(title, colWidths.title, true)} \u2502 ${pad(worker, colWidths.worker)} \u2502 ${pad(path2, colWidths.path)} \u2502 ${pad(status, colWidths.status)} \u2502 ${pad(time, colWidths.time)} \u2502 ${pad(duration, colWidths.duration)} \u2502` : `\u2502 ${pad(id, colWidths.id)} \u2502 ${pad(title, colWidths.title, true)} \u2502 ${pad(worker, colWidths.worker)} \u2502 ${pad(status, colWidths.status)} \u2502 ${pad(time, colWidths.time)} \u2502 ${pad(duration, colWidths.duration)} \u2502`;
|
|
113
113
|
const lines = [];
|
|
114
114
|
lines.push(line("\u250C", "\u252C", "\u2510", "\u2500"));
|
|
115
115
|
lines.push(row("#", "Title", "Worker", "Worktree", "Status", "Time", "Duration"));
|
|
@@ -180,12 +180,12 @@ function extractFinalAssistantText(jsonl) {
|
|
|
180
180
|
}
|
|
181
181
|
function readFinalReport(sessionId, root = transcriptRoot()) {
|
|
182
182
|
if (!sessionId) return "";
|
|
183
|
-
const
|
|
184
|
-
if (!
|
|
183
|
+
const path2 = findTranscriptPath(sessionId, root);
|
|
184
|
+
if (!path2) return "";
|
|
185
185
|
try {
|
|
186
|
-
return extractFinalAssistantText(readFileSync3(
|
|
186
|
+
return extractFinalAssistantText(readFileSync3(path2, "utf-8"));
|
|
187
187
|
} catch (err) {
|
|
188
|
-
console.error(`[transcript] failed to read ${
|
|
188
|
+
console.error(`[transcript] failed to read ${path2}: ${err}`);
|
|
189
189
|
return "";
|
|
190
190
|
}
|
|
191
191
|
}
|
|
@@ -1459,6 +1459,9 @@ async function createLabel(name, color, force) {
|
|
|
1459
1459
|
}
|
|
1460
1460
|
|
|
1461
1461
|
// src/claude-args.ts
|
|
1462
|
+
import { mkdirSync, renameSync, writeFileSync } from "node:fs";
|
|
1463
|
+
import os from "node:os";
|
|
1464
|
+
import path from "node:path";
|
|
1462
1465
|
var DISALLOWED_TOOLS = [
|
|
1463
1466
|
// 遅延 / yield: 後続ウェイクアップ前提。print モードではウェイクアップが発火せず、
|
|
1464
1467
|
// 呼ぶと処理未完のままプロセスが終了する。
|
|
@@ -1500,6 +1503,18 @@ var SYSTEM_PROMPT = `\u3053\u306E\u30BB\u30C3\u30B7\u30E7\u30F3\u306F \`claude-t
|
|
|
1500
1503
|
- \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
|
|
1501
1504
|
- \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`;
|
|
1502
1505
|
var CLAUDE_COMMAND = "claude";
|
|
1506
|
+
var cachedSystemPromptFilePath;
|
|
1507
|
+
function systemPromptFilePath() {
|
|
1508
|
+
if (cachedSystemPromptFilePath) return cachedSystemPromptFilePath;
|
|
1509
|
+
const dir = path.join(os.tmpdir(), "claude-task-worker");
|
|
1510
|
+
mkdirSync(dir, { recursive: true });
|
|
1511
|
+
const target = path.join(dir, `append-system-prompt-${process.pid}.txt`);
|
|
1512
|
+
const tmp = `${target}.tmp`;
|
|
1513
|
+
writeFileSync(tmp, SYSTEM_PROMPT, "utf8");
|
|
1514
|
+
renameSync(tmp, target);
|
|
1515
|
+
cachedSystemPromptFilePath = target;
|
|
1516
|
+
return target;
|
|
1517
|
+
}
|
|
1503
1518
|
function buildClaudeArgs({ mode, prompt, model, effort }) {
|
|
1504
1519
|
return [
|
|
1505
1520
|
...mode === "herdr" ? [] : ["-p"],
|
|
@@ -1508,8 +1523,8 @@ function buildClaudeArgs({ mode, prompt, model, effort }) {
|
|
|
1508
1523
|
"--chrome",
|
|
1509
1524
|
"--disallowedTools",
|
|
1510
1525
|
DISALLOWED_TOOLS_ARG,
|
|
1511
|
-
"--append-system-prompt",
|
|
1512
|
-
|
|
1526
|
+
"--append-system-prompt-file",
|
|
1527
|
+
systemPromptFilePath(),
|
|
1513
1528
|
"--model",
|
|
1514
1529
|
model,
|
|
1515
1530
|
"--effort",
|
|
@@ -1869,17 +1884,17 @@ function getConfigDir() {
|
|
|
1869
1884
|
function getUserConfigPath() {
|
|
1870
1885
|
return join2(getConfigDir(), "config.json");
|
|
1871
1886
|
}
|
|
1872
|
-
function isDirectory(
|
|
1887
|
+
function isDirectory(path2) {
|
|
1873
1888
|
try {
|
|
1874
|
-
return statSync(
|
|
1889
|
+
return statSync(path2).isDirectory();
|
|
1875
1890
|
} catch {
|
|
1876
1891
|
return false;
|
|
1877
1892
|
}
|
|
1878
1893
|
}
|
|
1879
|
-
function parseConfigFile(
|
|
1894
|
+
function parseConfigFile(path2) {
|
|
1880
1895
|
let content;
|
|
1881
1896
|
try {
|
|
1882
|
-
content = readFileSync2(
|
|
1897
|
+
content = readFileSync2(path2, "utf-8");
|
|
1883
1898
|
} catch (err) {
|
|
1884
1899
|
if (err.code === "ENOENT") return void 0;
|
|
1885
1900
|
throw err;
|
|
@@ -1888,7 +1903,7 @@ function parseConfigFile(path) {
|
|
|
1888
1903
|
return JSON.parse(content);
|
|
1889
1904
|
} catch (err) {
|
|
1890
1905
|
if (err instanceof SyntaxError) {
|
|
1891
|
-
throw new UserConfigError(`config file contains invalid JSON: ${
|
|
1906
|
+
throw new UserConfigError(`config file contains invalid JSON: ${path2}: ${err.message}`);
|
|
1892
1907
|
}
|
|
1893
1908
|
throw err;
|
|
1894
1909
|
}
|
|
@@ -1896,29 +1911,29 @@ function parseConfigFile(path) {
|
|
|
1896
1911
|
function readRawConfig() {
|
|
1897
1912
|
return parseConfigFile(getUserConfigPath());
|
|
1898
1913
|
}
|
|
1899
|
-
function parseMode(raw,
|
|
1914
|
+
function parseMode(raw, path2) {
|
|
1900
1915
|
if (!("mode" in raw)) return DEFAULT_RUN_MODE;
|
|
1901
1916
|
const value = raw["mode"];
|
|
1902
1917
|
if (value === "default" || value === "herdr") return value;
|
|
1903
|
-
console.warn(`[config] invalid mode: ${JSON.stringify(value)} in ${
|
|
1918
|
+
console.warn(`[config] invalid mode: ${JSON.stringify(value)} in ${path2}, using "${DEFAULT_RUN_MODE}"`);
|
|
1904
1919
|
return DEFAULT_RUN_MODE;
|
|
1905
1920
|
}
|
|
1906
1921
|
function loadUserConfig() {
|
|
1907
|
-
const
|
|
1922
|
+
const path2 = getUserConfigPath();
|
|
1908
1923
|
const raw = readRawConfig();
|
|
1909
1924
|
if (raw === void 0) {
|
|
1910
|
-
throw new UserConfigError(`config.json not found: ${
|
|
1925
|
+
throw new UserConfigError(`config.json not found: ${path2}`);
|
|
1911
1926
|
}
|
|
1912
1927
|
if (typeof raw !== "object" || raw === null || Array.isArray(raw)) {
|
|
1913
|
-
throw new UserConfigError(`config.json must contain a JSON object: ${
|
|
1928
|
+
throw new UserConfigError(`config.json must contain a JSON object: ${path2}`);
|
|
1914
1929
|
}
|
|
1915
1930
|
if (!("projects" in raw) || typeof raw["projects"] !== "object" || raw["projects"] === null || Array.isArray(raw["projects"])) {
|
|
1916
|
-
throw new UserConfigError(`config.json must contain a "projects" section as an object: ${
|
|
1931
|
+
throw new UserConfigError(`config.json must contain a "projects" section as an object: ${path2}`);
|
|
1917
1932
|
}
|
|
1918
1933
|
if ("projectGroups" in raw && (typeof raw["projectGroups"] !== "object" || raw["projectGroups"] === null || Array.isArray(raw["projectGroups"]))) {
|
|
1919
|
-
throw new UserConfigError(`config.json "projectGroups" must be an object: ${
|
|
1934
|
+
throw new UserConfigError(`config.json "projectGroups" must be an object: ${path2}`);
|
|
1920
1935
|
}
|
|
1921
|
-
const mode = parseMode(raw,
|
|
1936
|
+
const mode = parseMode(raw, path2);
|
|
1922
1937
|
const rawProjects = raw["projects"];
|
|
1923
1938
|
const rawProjectGroups = "projectGroups" in raw ? raw["projectGroups"] : {};
|
|
1924
1939
|
const projectKeys = Object.keys(rawProjects);
|
|
@@ -1938,7 +1953,7 @@ function loadUserConfig() {
|
|
|
1938
1953
|
const projects = {};
|
|
1939
1954
|
for (const [name, value] of Object.entries(rawProjects)) {
|
|
1940
1955
|
if (name === "__proto__") {
|
|
1941
|
-
throw new UserConfigError(`"__proto__" cannot be used as a key in "projects": ${
|
|
1956
|
+
throw new UserConfigError(`"__proto__" cannot be used as a key in "projects": ${path2}`);
|
|
1942
1957
|
}
|
|
1943
1958
|
if (typeof value !== "string" || !isAbsolute2(value)) {
|
|
1944
1959
|
console.warn(`[config] invalid projects.${name}: expected an absolute path, skipping`);
|
|
@@ -1953,7 +1968,7 @@ function loadUserConfig() {
|
|
|
1953
1968
|
const projectGroups = {};
|
|
1954
1969
|
for (const [groupName, value] of Object.entries(rawProjectGroups)) {
|
|
1955
1970
|
if (groupName === "__proto__") {
|
|
1956
|
-
throw new UserConfigError(`"__proto__" cannot be used as a key in "projectGroups": ${
|
|
1971
|
+
throw new UserConfigError(`"__proto__" cannot be used as a key in "projectGroups": ${path2}`);
|
|
1957
1972
|
}
|
|
1958
1973
|
if (!Array.isArray(value)) {
|
|
1959
1974
|
console.warn(`[config] invalid projectGroups.${groupName}: expected an array, skipping`);
|
|
@@ -1992,14 +2007,14 @@ function readRunMode() {
|
|
|
1992
2007
|
}
|
|
1993
2008
|
return parseMode(raw, getUserConfigPath());
|
|
1994
2009
|
}
|
|
1995
|
-
function findProjectNameByPath(
|
|
2010
|
+
function findProjectNameByPath(path2) {
|
|
1996
2011
|
let config;
|
|
1997
2012
|
try {
|
|
1998
2013
|
config = loadUserConfig();
|
|
1999
2014
|
} catch {
|
|
2000
2015
|
return void 0;
|
|
2001
2016
|
}
|
|
2002
|
-
const target = resolve(
|
|
2017
|
+
const target = resolve(path2);
|
|
2003
2018
|
for (const [name, projectPath] of Object.entries(config.projects)) {
|
|
2004
2019
|
if (resolve(projectPath) === target) return name;
|
|
2005
2020
|
}
|
|
@@ -2143,13 +2158,13 @@ async function runViaHerdr(args, id, onComplete, cwd, env) {
|
|
|
2143
2158
|
await finishTask(id, result, onComplete);
|
|
2144
2159
|
herdrTasks.delete(id);
|
|
2145
2160
|
}
|
|
2146
|
-
function run(command, args, id, title, workerName,
|
|
2161
|
+
function run(command, args, id, title, workerName, path2, onComplete, cwd, env) {
|
|
2147
2162
|
tasks.set(id, {
|
|
2148
2163
|
id,
|
|
2149
2164
|
title,
|
|
2150
2165
|
status: "running",
|
|
2151
2166
|
workerName,
|
|
2152
|
-
path,
|
|
2167
|
+
path: path2,
|
|
2153
2168
|
startedAt: /* @__PURE__ */ new Date()
|
|
2154
2169
|
});
|
|
2155
2170
|
ensureRenderInterval();
|
|
@@ -2472,13 +2487,13 @@ function isGeneratedWorktreeName(name) {
|
|
|
2472
2487
|
|
|
2473
2488
|
// src/slack.ts
|
|
2474
2489
|
import { exec } from "node:child_process";
|
|
2475
|
-
import { readFileSync as readFileSync4, writeFileSync as
|
|
2490
|
+
import { readFileSync as readFileSync4, writeFileSync as writeFileSync3 } from "node:fs";
|
|
2476
2491
|
import { homedir as homedir4 } from "node:os";
|
|
2477
2492
|
import { join as join5 } from "node:path";
|
|
2478
2493
|
import { promisify as promisify2 } from "node:util";
|
|
2479
2494
|
|
|
2480
2495
|
// src/runcat.ts
|
|
2481
|
-
import { mkdirSync, renameSync, rmSync, writeFileSync } from "node:fs";
|
|
2496
|
+
import { mkdirSync as mkdirSync2, renameSync as renameSync2, rmSync, writeFileSync as writeFileSync2 } from "node:fs";
|
|
2482
2497
|
import { homedir as homedir3 } from "node:os";
|
|
2483
2498
|
import { dirname, join as join4 } from "node:path";
|
|
2484
2499
|
var RUNCAT_OUT_FILE = process.env.RUNCAT_OUT_FILE ?? join4(process.env.HOME ?? homedir3(), ".claude", "runcat-usage.json");
|
|
@@ -2547,9 +2562,9 @@ function writeRuncatUsage(usage, outFile = RUNCAT_OUT_FILE) {
|
|
|
2547
2562
|
const dir = dirname(outFile);
|
|
2548
2563
|
const tmp = join4(dir, `.runcat-${process.pid}-${Date.now()}.json`);
|
|
2549
2564
|
try {
|
|
2550
|
-
|
|
2551
|
-
|
|
2552
|
-
|
|
2565
|
+
mkdirSync2(dir, { recursive: true });
|
|
2566
|
+
writeFileSync2(tmp, JSON.stringify(snapshot), "utf-8");
|
|
2567
|
+
renameSync2(tmp, outFile);
|
|
2553
2568
|
} catch (err) {
|
|
2554
2569
|
rmSync(tmp, { force: true });
|
|
2555
2570
|
console.error(`[runcat] Failed to write ${outFile}: ${err}`);
|
|
@@ -2599,7 +2614,7 @@ function readUsageCache() {
|
|
|
2599
2614
|
}
|
|
2600
2615
|
function writeUsageCache(data) {
|
|
2601
2616
|
try {
|
|
2602
|
-
|
|
2617
|
+
writeFileSync3(USAGE_CACHE_PATH, JSON.stringify({ timestamp: Date.now(), data }));
|
|
2603
2618
|
} catch {
|
|
2604
2619
|
}
|
|
2605
2620
|
}
|
|
@@ -2693,28 +2708,28 @@ import { readdir, rm, stat } from "node:fs/promises";
|
|
|
2693
2708
|
import { basename as basename2, resolve as resolve2, sep } from "node:path";
|
|
2694
2709
|
var execFileAsync2 = promisify3(execFile2);
|
|
2695
2710
|
var WORKTREES_DIR = ".claude/worktrees";
|
|
2696
|
-
function isManagedWorktreePath(
|
|
2697
|
-
return resolve2(
|
|
2711
|
+
function isManagedWorktreePath(path2) {
|
|
2712
|
+
return resolve2(path2).startsWith(resolve2(WORKTREES_DIR) + sep);
|
|
2698
2713
|
}
|
|
2699
|
-
async function pathExists(
|
|
2714
|
+
async function pathExists(path2) {
|
|
2700
2715
|
try {
|
|
2701
|
-
await stat(
|
|
2716
|
+
await stat(path2);
|
|
2702
2717
|
return true;
|
|
2703
2718
|
} catch {
|
|
2704
2719
|
return false;
|
|
2705
2720
|
}
|
|
2706
2721
|
}
|
|
2707
|
-
async function forceRemoveIfExists(
|
|
2708
|
-
if (!isManagedWorktreePath(
|
|
2709
|
-
console.error(`[worktree] Refusing to remove path outside ${WORKTREES_DIR}: ${
|
|
2722
|
+
async function forceRemoveIfExists(path2) {
|
|
2723
|
+
if (!isManagedWorktreePath(path2)) {
|
|
2724
|
+
console.error(`[worktree] Refusing to remove path outside ${WORKTREES_DIR}: ${path2}`);
|
|
2710
2725
|
return;
|
|
2711
2726
|
}
|
|
2712
|
-
if (!await pathExists(
|
|
2727
|
+
if (!await pathExists(path2)) return;
|
|
2713
2728
|
try {
|
|
2714
|
-
await rm(
|
|
2715
|
-
console.log(`[worktree] Force removed remaining directory: ${
|
|
2729
|
+
await rm(path2, { recursive: true, force: true });
|
|
2730
|
+
console.log(`[worktree] Force removed remaining directory: ${path2}`);
|
|
2716
2731
|
} catch (error) {
|
|
2717
|
-
console.error(`[worktree] Failed to remove directory ${
|
|
2732
|
+
console.error(`[worktree] Failed to remove directory ${path2}:`, error);
|
|
2718
2733
|
}
|
|
2719
2734
|
}
|
|
2720
2735
|
async function listWorktreeEntries() {
|
|
@@ -3293,9 +3308,9 @@ function extractDesignFilePath(body) {
|
|
|
3293
3308
|
if (section === null) return null;
|
|
3294
3309
|
const match = DESIGN_FILE_LINE.exec(section);
|
|
3295
3310
|
if (match === null) return null;
|
|
3296
|
-
const
|
|
3297
|
-
if (
|
|
3298
|
-
return
|
|
3311
|
+
const path2 = match[1].trim();
|
|
3312
|
+
if (path2.length === 0 || path2.includes("<") || path2.includes(">") || !path2.endsWith(".pen")) return null;
|
|
3313
|
+
return path2;
|
|
3299
3314
|
}
|
|
3300
3315
|
function classifyDesignPr(pr) {
|
|
3301
3316
|
if (pr === null) return "needs-human";
|
|
@@ -3566,24 +3581,24 @@ async function runCodegraphInit(logPrefix) {
|
|
|
3566
3581
|
}
|
|
3567
3582
|
}
|
|
3568
3583
|
async function ensureCodegraphGitIgnore(logPrefix) {
|
|
3569
|
-
const
|
|
3584
|
+
const path2 = globalGitIgnorePath();
|
|
3570
3585
|
try {
|
|
3571
3586
|
let current = "";
|
|
3572
3587
|
try {
|
|
3573
|
-
current = await readFile(
|
|
3588
|
+
current = await readFile(path2, "utf-8");
|
|
3574
3589
|
} catch {
|
|
3575
3590
|
}
|
|
3576
3591
|
const next = appendIgnoreEntry(current, CODEGRAPH_IGNORE_ENTRY);
|
|
3577
3592
|
if (next === null) {
|
|
3578
|
-
console.log(`[${logPrefix}] Already ignored: ${CODEGRAPH_IGNORE_ENTRY} (${
|
|
3593
|
+
console.log(`[${logPrefix}] Already ignored: ${CODEGRAPH_IGNORE_ENTRY} (${path2})`);
|
|
3579
3594
|
return true;
|
|
3580
3595
|
}
|
|
3581
|
-
await mkdir(dirname2(
|
|
3582
|
-
await writeFile(
|
|
3583
|
-
console.log(`[${logPrefix}] Added ${CODEGRAPH_IGNORE_ENTRY} to ${
|
|
3596
|
+
await mkdir(dirname2(path2), { recursive: true });
|
|
3597
|
+
await writeFile(path2, next, "utf-8");
|
|
3598
|
+
console.log(`[${logPrefix}] Added ${CODEGRAPH_IGNORE_ENTRY} to ${path2}`);
|
|
3584
3599
|
return true;
|
|
3585
3600
|
} catch (err) {
|
|
3586
|
-
console.error(`[${logPrefix}] Failed to update ${
|
|
3601
|
+
console.error(`[${logPrefix}] Failed to update ${path2}: ${err.message}`);
|
|
3587
3602
|
return false;
|
|
3588
3603
|
}
|
|
3589
3604
|
}
|
|
@@ -3644,21 +3659,21 @@ jobs:
|
|
|
3644
3659
|
assignees: [context.payload.issue.user.login]
|
|
3645
3660
|
});
|
|
3646
3661
|
`;
|
|
3647
|
-
async function writeFileWithMode(
|
|
3662
|
+
async function writeFileWithMode(path2, content, force) {
|
|
3648
3663
|
try {
|
|
3649
|
-
await access(
|
|
3664
|
+
await access(path2);
|
|
3650
3665
|
if (!force) return "skipped";
|
|
3651
|
-
await writeFile2(
|
|
3666
|
+
await writeFile2(path2, content, "utf-8");
|
|
3652
3667
|
return "overwritten";
|
|
3653
3668
|
} catch {
|
|
3654
|
-
await writeFile2(
|
|
3669
|
+
await writeFile2(path2, content, "utf-8");
|
|
3655
3670
|
return "created";
|
|
3656
3671
|
}
|
|
3657
3672
|
}
|
|
3658
|
-
function logWriteResult(result,
|
|
3659
|
-
if (result === "created") console.log(`[init] Created: ${
|
|
3660
|
-
else if (result === "overwritten") console.log(`[init] Overwritten: ${
|
|
3661
|
-
else console.log(`[init] Already exists: ${
|
|
3673
|
+
function logWriteResult(result, path2) {
|
|
3674
|
+
if (result === "created") console.log(`[init] Created: ${path2}`);
|
|
3675
|
+
else if (result === "overwritten") console.log(`[init] Overwritten: ${path2}`);
|
|
3676
|
+
else console.log(`[init] Already exists: ${path2}`);
|
|
3662
3677
|
}
|
|
3663
3678
|
async function createConfig(force) {
|
|
3664
3679
|
const initialConfig = { ...DEFAULT_CONFIG, workers: { ...WORKER_DEFAULTS } };
|