claude-task-worker 0.107.0 → 0.108.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 +14 -1
- package/dist/index.js +44 -13
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -122,7 +122,7 @@ claude-task-worker init --force # 強制上書き
|
|
|
122
122
|
## コマンド
|
|
123
123
|
|
|
124
124
|
```bash
|
|
125
|
-
claude-task-worker <command> [--epic <issue-number>]... [--label <label>]... [--project <name>]... [--cloud]
|
|
125
|
+
claude-task-worker <command> [--epic <issue-number>]... [--label <label>]... [--project <name>]... [--cloud] [--debug]
|
|
126
126
|
```
|
|
127
127
|
|
|
128
128
|
| コマンド | 内容 |
|
|
@@ -210,6 +210,19 @@ npx claude-task-worker cloud-setup
|
|
|
210
210
|
|
|
211
211
|
詳細は [`docs/prd-cloud-worker-execution.md`](./docs/prd-cloud-worker-execution.md) を参照。
|
|
212
212
|
|
|
213
|
+
### `--debug`
|
|
214
|
+
|
|
215
|
+
各タスクの最終報告を対象 Issue/PR へコメントとして残す。ローカル実行(`default` / `herdr`)でもクラウド実行(`--cloud`)でも使える。
|
|
216
|
+
|
|
217
|
+
```bash
|
|
218
|
+
claude-task-worker exec-issue --debug
|
|
219
|
+
claude-task-worker exec-issue --cloud --debug
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
既定(`--debug` なし)では最終報告は Slack 通知にのみ載り、Issue/PR にはコメントされない。毎タスク投稿すると Issue/PR がワーカーの実行ログで埋まるため。
|
|
223
|
+
|
|
224
|
+
投稿の担当は実行形態で違う。ローカルはワーカーが報告そのもの(`claude -p` の stdout / transcript)を持っているのでワーカーが投稿し、クラウドはワーカーに報告が届かないのでセッション自身に投稿させる(ワーカーはそれを回収して Slack へ載せる)。定期ワーカー(`update-*`)の投稿先は実行記録PR(`ctw-last-run-<ワーカー名>`)。クラウド実行の完了検知(`cc-cloud-done`)はフラグの有無に関わらず従来どおり動く。
|
|
225
|
+
|
|
213
226
|
### Pen CLI のログイン
|
|
214
227
|
|
|
215
228
|
`.pen` を扱うスキルは Pen CLI の認証を必要とする。UIデザイン先行ワークフローを使うなら一度ログインしておく。
|
package/dist/index.js
CHANGED
|
@@ -1732,6 +1732,13 @@ function hasCloudFlag() {
|
|
|
1732
1732
|
}
|
|
1733
1733
|
return cachedCloudFlag;
|
|
1734
1734
|
}
|
|
1735
|
+
var cachedDebugFlag;
|
|
1736
|
+
function hasDebugFlag() {
|
|
1737
|
+
if (cachedDebugFlag === void 0) {
|
|
1738
|
+
cachedDebugFlag = process.argv.includes("--debug");
|
|
1739
|
+
}
|
|
1740
|
+
return cachedDebugFlag;
|
|
1741
|
+
}
|
|
1735
1742
|
function assertCloudCompatibleCommand(command) {
|
|
1736
1743
|
if (FLAG_INCOMPATIBLE_COMMANDS.includes(command)) {
|
|
1737
1744
|
console.error(`[worker] --cloud cannot be used with the "${command}" command`);
|
|
@@ -2585,12 +2592,12 @@ function buildClaudeArgs({
|
|
|
2585
2592
|
function buildCloudCreateArgs(commonArgs, prompt) {
|
|
2586
2593
|
return ["--cloud", prompt, ...commonArgs];
|
|
2587
2594
|
}
|
|
2588
|
-
function appendCloudDoneInstruction(prompt, target) {
|
|
2595
|
+
function appendCloudDoneInstruction(prompt, target, debug = false) {
|
|
2589
2596
|
const targetLabel = target.type === "issue" ? `Issue #${target.number}` : `PR #${target.number}`;
|
|
2590
2597
|
const checkoutInstruction = buildCloudCheckoutInstruction(target);
|
|
2591
2598
|
const worktreeInstruction = buildCloudWorktreeInstruction(prompt);
|
|
2592
|
-
const reportInstruction = `\`${CLOUD_DONE_LABEL}\` \u30E9\u30D9\u30EB\u3092\u4ED8\u3051\u308B\u76F4\u524D\u306B\u3001${targetLabel} \u3078 \`${CLOUD_REPORT_HEADING}\` \u3092\u898B\u51FA\u3057\u3068\u3059\u308B\u30B3\u30E1\u30F3\u30C8\u30921\u4EF6\u6295\u7A3F\u3057\u3001\u672C\u6587\u306B\u6700\u7D42\u5831\u544A\uFF08\u5B8C\u4E86\u30FB\u4E2D\u65AD\u306B\u304B\u304B\u308F\u3089\u305A\uFF09\u3092\u66F8\u304F\u3053\u3068\u3002GitHub MCP\uFF08\`add_issue_comment\`\uFF09\u3092\u512A\u5148\u3057\u3001\u5931\u6557\u3057\u305F\u5834\u5408\u306E\u307F \`gh ${target.type} comment ${target.number} --body-file -\` \u3078\u30D5\u30A9\u30FC\u30EB\u30D0\u30C3\u30AF\u3059\u308B\u3053\u3068\uFF08\u30D5\u30A9\u30FC\u30EB\u30D0\u30C3\u30AF\u306F1\u56DE\u307E\u3067\uFF09\u3002\u30EF\u30FC\u30AB\u30FC\u306F\u3053\u306E\u30B3\u30E1\u30F3\u30C8\u3092\u6700\u7D42\u30EC\u30DD\u30FC\u30C8\u3068\u3057\u3066\u56DE\u53CE\u3057 Slack \u901A\u77E5\u306B\u8F09\u305B\u308B\u3002
|
|
2593
|
-
const labelInstruction =
|
|
2599
|
+
const reportInstruction = debug ? `\`${CLOUD_DONE_LABEL}\` \u30E9\u30D9\u30EB\u3092\u4ED8\u3051\u308B\u76F4\u524D\u306B\u3001${targetLabel} \u3078 \`${CLOUD_REPORT_HEADING}\` \u3092\u898B\u51FA\u3057\u3068\u3059\u308B\u30B3\u30E1\u30F3\u30C8\u30921\u4EF6\u6295\u7A3F\u3057\u3001\u672C\u6587\u306B\u6700\u7D42\u5831\u544A\uFF08\u5B8C\u4E86\u30FB\u4E2D\u65AD\u306B\u304B\u304B\u308F\u3089\u305A\uFF09\u3092\u66F8\u304F\u3053\u3068\u3002GitHub MCP\uFF08\`add_issue_comment\`\uFF09\u3092\u512A\u5148\u3057\u3001\u5931\u6557\u3057\u305F\u5834\u5408\u306E\u307F \`gh ${target.type} comment ${target.number} --body-file -\` \u3078\u30D5\u30A9\u30FC\u30EB\u30D0\u30C3\u30AF\u3059\u308B\u3053\u3068\uFF08\u30D5\u30A9\u30FC\u30EB\u30D0\u30C3\u30AF\u306F1\u56DE\u307E\u3067\uFF09\u3002\u30EF\u30FC\u30AB\u30FC\u306F\u3053\u306E\u30B3\u30E1\u30F3\u30C8\u3092\u6700\u7D42\u30EC\u30DD\u30FC\u30C8\u3068\u3057\u3066\u56DE\u53CE\u3057 Slack \u901A\u77E5\u306B\u8F09\u305B\u308B\u3002` : "";
|
|
2600
|
+
const labelInstruction = `${debug ? "\u4E0A\u8A18\u30B3\u30E1\u30F3\u30C8\u306E\u6295\u7A3F\u5F8C\u3001" : ""}\u3053\u306E\u30BB\u30C3\u30B7\u30E7\u30F3\u306E\u6700\u5F8C\u306E\u64CD\u4F5C\u3068\u3057\u3066 ${targetLabel} \u306B \`${CLOUD_DONE_LABEL}\` \u30E9\u30D9\u30EB\u3092\u4ED8\u4E0E\u3059\u308B\u3053\u3068\u3002GitHub MCP\uFF08\`issue_write\` / method: \`update\`\uFF09\u3092\u512A\u5148\u3057\u3001\u5931\u6557\u3057\u305F\u5834\u5408\u306E\u307F \`gh ${target.type} edit ${target.number} --add-label ${CLOUD_DONE_LABEL}\` \u3078\u30D5\u30A9\u30FC\u30EB\u30D0\u30C3\u30AF\u3059\u308B\u3053\u3068\uFF08\u30D5\u30A9\u30FC\u30EB\u30D0\u30C3\u30AF\u306F1\u56DE\u307E\u3067\uFF09\u3002\u30EF\u30FC\u30AB\u30FC\u306F\u3053\u306E\u30E9\u30D9\u30EB\u3067\u30BF\u30B9\u30AF\u306E\u7D42\u4E86\u3092\u691C\u77E5\u3057\u3066\u304A\u308A\u3001\u4ED8\u4E0E\u3055\u308C\u306A\u3044\u3068\u30BF\u30A4\u30E0\u30A2\u30A6\u30C8\u307E\u3067\u5B8C\u4E86\u6271\u3044\u306B\u306A\u3089\u306A\u3044\u3002`;
|
|
2594
2601
|
return [prompt, checkoutInstruction, worktreeInstruction, reportInstruction, labelInstruction].filter((part) => part !== "").join("\n\n");
|
|
2595
2602
|
}
|
|
2596
2603
|
var CLOUD_WORKTREE_EXEMPT_SKILLS = ["exec-issue", "fix-review-point", "create-ui-design"];
|
|
@@ -2609,7 +2616,7 @@ function buildCloudGitHubAccessInstruction() {
|
|
|
2609
2616
|
function buildCloudToolRestriction() {
|
|
2610
2617
|
return `\u30AF\u30E9\u30A6\u30C9\u5B9F\u884C\u3067\u306F \`--disallowedTools\` \u30D5\u30E9\u30B0\u306B\u3088\u308B\u30C4\u30FC\u30EB\u5236\u9650\u304C\u53CD\u6620\u3055\u308C\u306A\u3044\u305F\u3081\u3001\u4EE5\u4E0B\u306E\u30C4\u30FC\u30EB\u3092\u4F7F\u308F\u306A\u3044\u3053\u3068: ${DISALLOWED_TOOLS.join(", ")}`;
|
|
2611
2618
|
}
|
|
2612
|
-
function buildCloudPrompt(prompt, model, target) {
|
|
2619
|
+
function buildCloudPrompt(prompt, model, target, debug = false) {
|
|
2613
2620
|
const principles = `\u4EE5\u4E0B\u306F\u3053\u306E\u30BB\u30C3\u30B7\u30E7\u30F3\u306E\u5B9F\u884C\u539F\u5247\u3067\u3042\u308B\u3002\u30AF\u30E9\u30A6\u30C9\u5B9F\u884C\u3067\u306F\u30B7\u30B9\u30C6\u30E0\u30D7\u30ED\u30F3\u30D7\u30C8\u306B\u3088\u308B\u6CE8\u5165\u304C\u53CD\u6620\u3055\u308C\u306A\u3044\u305F\u3081\u3001\u30D7\u30ED\u30F3\u30D7\u30C8\u672C\u6587\u3068\u3057\u3066\u6E21\u3057\u3066\u3044\u308B\u3002
|
|
2614
2621
|
|
|
2615
2622
|
${systemPromptFor(model)}
|
|
@@ -2620,7 +2627,7 @@ ${buildCloudGitHubAccessInstruction()}`;
|
|
|
2620
2627
|
const withPrinciples = `${prompt}
|
|
2621
2628
|
|
|
2622
2629
|
${principles}`;
|
|
2623
|
-
return target ? appendCloudDoneInstruction(withPrinciples, target) : withPrinciples;
|
|
2630
|
+
return target ? appendCloudDoneInstruction(withPrinciples, target, debug) : withPrinciples;
|
|
2624
2631
|
}
|
|
2625
2632
|
function shellQuote2(value) {
|
|
2626
2633
|
return `'${value.replace(/'/g, "'\\''")}'`;
|
|
@@ -2819,6 +2826,21 @@ async function finishTask(id, result, onComplete) {
|
|
|
2819
2826
|
pruneTaskHistory();
|
|
2820
2827
|
renderTable();
|
|
2821
2828
|
}
|
|
2829
|
+
function onCompleteWithDebugReport(onComplete, target) {
|
|
2830
|
+
if (!target || !hasDebugFlag()) return onComplete;
|
|
2831
|
+
return async (status, output, cloudSessionId) => {
|
|
2832
|
+
const body = output.trim();
|
|
2833
|
+
if (body !== "") {
|
|
2834
|
+
const comment = target.type === "issue" ? commentOnIssue : commentOnPR;
|
|
2835
|
+
await comment(target.number, `${CLOUD_REPORT_HEADING}
|
|
2836
|
+
|
|
2837
|
+
${body}`).catch(
|
|
2838
|
+
(err) => console.error(`[worker] failed to post the debug report to ${target.type} #${target.number}: ${err}`)
|
|
2839
|
+
);
|
|
2840
|
+
}
|
|
2841
|
+
await onComplete?.(status, output, cloudSessionId);
|
|
2842
|
+
};
|
|
2843
|
+
}
|
|
2822
2844
|
function resolveProjectName(cwd = process.cwd()) {
|
|
2823
2845
|
const injected = process.env.CTW_PROJECT_NAME;
|
|
2824
2846
|
if (injected && injected.length > 0) return injected;
|
|
@@ -2992,7 +3014,8 @@ async function createCloudSession(args, initialPrompt, cwd, env) {
|
|
|
2992
3014
|
}
|
|
2993
3015
|
async function runViaCloud(args, prompt, id, onComplete, cwd, env, cloudTarget, model) {
|
|
2994
3016
|
herdrTasks.set(id, { paneId: "", tabId: "" });
|
|
2995
|
-
const
|
|
3017
|
+
const debug = hasDebugFlag();
|
|
3018
|
+
const initialPrompt = buildCloudPrompt(prompt, model ?? "", cloudTarget, debug);
|
|
2996
3019
|
let result;
|
|
2997
3020
|
let cloudSessionId;
|
|
2998
3021
|
try {
|
|
@@ -3010,7 +3033,7 @@ async function runViaCloud(args, prompt, id, onComplete, cwd, env, cloudTarget,
|
|
|
3010
3033
|
});
|
|
3011
3034
|
let reportBody = null;
|
|
3012
3035
|
const startedAt = tasks.get(id)?.startedAt;
|
|
3013
|
-
if (startedAt) {
|
|
3036
|
+
if (debug && startedAt) {
|
|
3014
3037
|
try {
|
|
3015
3038
|
reportBody = await findCommentSince(targetNumber, startedAt, CLOUD_REPORT_HEADING);
|
|
3016
3039
|
} catch (err) {
|
|
@@ -3080,8 +3103,9 @@ function run(command, args, id, title, workerName, path2, onComplete, cwd, env,
|
|
|
3080
3103
|
void runViaCloud(args, prompt ?? "", id, onComplete, cwd, env, cloudTarget, model);
|
|
3081
3104
|
return;
|
|
3082
3105
|
}
|
|
3106
|
+
const onCompleteWithReport = onCompleteWithDebugReport(onComplete, cloudTarget);
|
|
3083
3107
|
if (getRunMode() === "herdr") {
|
|
3084
|
-
void runViaHerdr(args, prompt ?? "", id,
|
|
3108
|
+
void runViaHerdr(args, prompt ?? "", id, onCompleteWithReport, cwd, env);
|
|
3085
3109
|
return;
|
|
3086
3110
|
}
|
|
3087
3111
|
const child = spawn(command, args, {
|
|
@@ -3117,12 +3141,12 @@ function run(command, args, id, title, workerName, path2, onComplete, cwd, env,
|
|
|
3117
3141
|
Buffer.concat(outputChunks).toString("utf-8"),
|
|
3118
3142
|
Buffer.concat(stderrChunks).toString("utf-8").slice(-STDERR_TAIL_LIMIT)
|
|
3119
3143
|
);
|
|
3120
|
-
await finishTask(id, result,
|
|
3144
|
+
await finishTask(id, result, onCompleteWithReport);
|
|
3121
3145
|
childProcesses.delete(id);
|
|
3122
3146
|
});
|
|
3123
3147
|
child.on("error", async (err) => {
|
|
3124
3148
|
console.error(`[worker] failed to spawn process for #${id}: ${err.message}`);
|
|
3125
|
-
await finishTask(id, { status: "failed", output: err.message },
|
|
3149
|
+
await finishTask(id, { status: "failed", output: err.message }, onCompleteWithReport);
|
|
3126
3150
|
childProcesses.delete(id);
|
|
3127
3151
|
});
|
|
3128
3152
|
}
|
|
@@ -3984,7 +4008,9 @@ function createIssuePollingWorker(config) {
|
|
|
3984
4008
|
buildClaudeEnv(mode, cloud),
|
|
3985
4009
|
execution.prompt,
|
|
3986
4010
|
cloud,
|
|
3987
|
-
|
|
4011
|
+
// クラウドでは cc-cloud-done の探索先、ローカルでは --debug の報告コメントの
|
|
4012
|
+
// 投稿先。どちらも対象は同じ Issue なので実行形態で出し分けない。
|
|
4013
|
+
{ type: "issue", number: issue.number },
|
|
3988
4014
|
model
|
|
3989
4015
|
);
|
|
3990
4016
|
} catch (err) {
|
|
@@ -4241,7 +4267,9 @@ function createPrPollingWorker(config) {
|
|
|
4241
4267
|
buildClaudeEnv(mode, isCloud),
|
|
4242
4268
|
execution.prompt,
|
|
4243
4269
|
isCloud,
|
|
4244
|
-
|
|
4270
|
+
// クラウドでは cc-cloud-done の探索先、ローカルでは --debug の報告コメントの
|
|
4271
|
+
// 投稿先。onBranch は `--on-branch` を渡したか(=クラウドのみ)を表す。
|
|
4272
|
+
{ type: "pr", number: pr.number, onBranch: isCloud },
|
|
4245
4273
|
model
|
|
4246
4274
|
);
|
|
4247
4275
|
} catch (err) {
|
|
@@ -4837,7 +4865,9 @@ function createScheduledWorker(config) {
|
|
|
4837
4865
|
buildClaudeEnv(mode, cloud),
|
|
4838
4866
|
execution.prompt,
|
|
4839
4867
|
cloud,
|
|
4840
|
-
|
|
4868
|
+
// 定期ワーカーは Issue/PR を起点に走らないため、クラウドの cc-cloud-done も
|
|
4869
|
+
// ローカル --debug の報告コメントも実行記録PRを置き先にする。
|
|
4870
|
+
lastRunPr !== null ? { type: "pr", number: lastRunPr } : void 0,
|
|
4841
4871
|
model
|
|
4842
4872
|
);
|
|
4843
4873
|
} catch (err) {
|
|
@@ -5543,6 +5573,7 @@ Workers:
|
|
|
5543
5573
|
|
|
5544
5574
|
Options:
|
|
5545
5575
|
--project <name> Dispatch to project(s) via herdr instead of running the worker locally. Accepts a project name, a project group name, or "all". Repeatable.
|
|
5576
|
+
--debug Post each task's final report as a comment on the target Issue/PR (off by default; the report is only sent to Slack). Works in both local and --cloud runs.
|
|
5546
5577
|
--epic <number> Limit issue-based workers to sub-issues of the specified epic issue. Repeatable: any matching parent (OR).
|
|
5547
5578
|
--label <name> Limit issue-based workers to issues that also carry the specified label. Repeatable: all must be present (AND).
|
|
5548
5579
|
|