claude-task-worker 0.105.0 → 0.107.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 +2 -1
- package/dist/index.js +115 -48
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -105,7 +105,8 @@ claude-task-worker init --force # 強制上書き
|
|
|
105
105
|
|
|
106
106
|
| ラベル | 用途 |
|
|
107
107
|
|---|---|
|
|
108
|
-
| `cc-triage-scope` | トリアージ対象マーク(Issue/PR
|
|
108
|
+
| `cc-triage-scope` | トリアージ対象マーク(Issue/PR)=ワーカーのキュー合流口 |
|
|
109
|
+
| `cc-issue-request` | 人が Issue テンプレートから作成を依頼した印。起票者を assignee に自動設定するワークフローの発火条件(`cc-triage-scope` と役割を分けてあり、ワーカーの自動起票では付かない) |
|
|
109
110
|
| `cc-issue-created` | `create-issue` 由来の Issue マーク |
|
|
110
111
|
| `cc-update-issue` / `cc-answer-issue-questions` / `cc-exec-issue` | Issue の更新 / 確認事項回答 / 実行トリガー |
|
|
111
112
|
| `cc-fix-onetime` / `cc-resolve-conflict` | PR の修正 / コンフリクト解消トリガー |
|
package/dist/index.js
CHANGED
|
@@ -1917,9 +1917,8 @@ var SCHEDULED_WORKER_NAMES = [
|
|
|
1917
1917
|
"update-design-md"
|
|
1918
1918
|
];
|
|
1919
1919
|
var CLOUD_DONE_LABEL = "cc-cloud-done";
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
return hasCloudFlag() && CLOUD_ALLOWED_WORKERS.includes(name);
|
|
1920
|
+
function isCloudWorker(_name) {
|
|
1921
|
+
return hasCloudFlag();
|
|
1923
1922
|
}
|
|
1924
1923
|
function checkCloudAuth(input) {
|
|
1925
1924
|
if (input.status.kind === "unknown") return [];
|
|
@@ -2594,14 +2593,14 @@ function appendCloudDoneInstruction(prompt, target) {
|
|
|
2594
2593
|
const labelInstruction = `\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`;
|
|
2595
2594
|
return [prompt, checkoutInstruction, worktreeInstruction, reportInstruction, labelInstruction].filter((part) => part !== "").join("\n\n");
|
|
2596
2595
|
}
|
|
2597
|
-
var CLOUD_WORKTREE_EXEMPT_SKILLS = ["exec-issue", "fix-review-point"];
|
|
2596
|
+
var CLOUD_WORKTREE_EXEMPT_SKILLS = ["exec-issue", "fix-review-point", "create-ui-design"];
|
|
2598
2597
|
function buildCloudWorktreeInstruction(prompt) {
|
|
2599
2598
|
const skill = prompt.trim().split(/\s+/)[0] ?? "";
|
|
2600
2599
|
if (!CLOUD_WORKTREE_EXEMPT_SKILLS.some((name) => skill.endsWith(`:${name}`))) return "";
|
|
2601
2600
|
return "\u3053\u306E\u30BB\u30C3\u30B7\u30E7\u30F3\u306F\u30AF\u30E9\u30A6\u30C9\u5B9F\u884C\u306E\u305F\u3081 worktree \u3092\u6301\u305F\u305A\u3001cwd \u306F\u30EA\u30DD\u30B8\u30C8\u30EA\u30EB\u30FC\u30C8\u3067\u3042\u308B\uFF08\u30EF\u30FC\u30AB\u30FC\u306F\u30AF\u30E9\u30A6\u30C9\u5B9F\u884C\u6642\u306B worktree \u3092\u4F5C\u3089\u306A\u3044\uFF09\u3002\u30B9\u30AD\u30EB\u672C\u6587\u306E\u30D5\u30A7\u30FC\u30BA0\u306B\u3042\u308B\u300C`pwd` \u304C `.claude/worktrees/` \u914D\u4E0B\u3067\u306A\u3051\u308C\u3070\u4E2D\u65AD\u3059\u308B\u300D\u78BA\u8A8D\u306F\u3001\u3053\u306E\u6307\u793A\u304C\u3042\u308B\u5834\u5408\u306B\u9650\u308A\u9069\u7528\u3057\u306A\u3044\u3053\u3068\u3002\u305F\u3060\u3057\u30AC\u30FC\u30C9\u306E\u76EE\u7684\u3067\u3042\u308B\u300C\u30C7\u30D5\u30A9\u30EB\u30C8\u30D6\u30E9\u30F3\u30C1\u3067\u4F5C\u696D\u3057\u306A\u3044\u300D\u306F\u7DAD\u6301\u3059\u308B\u3053\u3068 \u2014 \u540C\u3058\u30D5\u30A7\u30FC\u30BA0\u306E\u300C\u30C7\u30D5\u30A9\u30EB\u30C8\u30D6\u30E9\u30F3\u30C1\u540D\u3092\u53D6\u5F97\u3057\u3001\u73FE\u5728\u30D6\u30E9\u30F3\u30C1\u3068\u4E00\u81F4\u3059\u308B\u5834\u5408\u306F\u4E2D\u65AD\u3059\u308B\uFF08\u53D6\u5F97\u5931\u6557\u3082\u4E2D\u65AD\uFF09\u300D\u306F\u5FC5\u305A\u5B9F\u884C\u3057\u3001\u4E00\u81F4\u3057\u305F\u5834\u5408\u306F\u5F93\u6765\u3069\u304A\u308A\u4E2D\u65AD\u3059\u308B\u3053\u3068\u3002";
|
|
2602
2601
|
}
|
|
2603
2602
|
function buildCloudCheckoutInstruction(target) {
|
|
2604
|
-
if (target.type !== "pr") return "";
|
|
2603
|
+
if (target.type !== "pr" || !target.onBranch) return "";
|
|
2605
2604
|
return `\u3053\u306E\u30BB\u30C3\u30B7\u30E7\u30F3\u306F PR #${target.number} \u306E head \u30D6\u30E9\u30F3\u30C1\u4E0A\u3067\u958B\u59CB\u3057\u3066\u3044\u308B\uFF08\u30EF\u30FC\u30AB\u30FC\u304C \`--on-branch\` \u3067\u6307\u5B9A\u6E08\u307F\uFF09\u3002\u30B9\u30AD\u30EB\u672C\u6587\u304C\u6307\u793A\u3059\u308B \`gh pr checkout\` \u306F\u5B9F\u884C\u3057\u306A\u3044\u3053\u3068\uFF08\u30AF\u30E9\u30A6\u30C9\u3067\u306F GraphQL \u30B2\u30FC\u30C8\u306B\u3088\u308A 403 \u3067\u5931\u6557\u3057\u3001\u304B\u3064\u65E2\u306B\u30D6\u30E9\u30F3\u30C1\u4E0A\u306B\u3044\u308B\u306E\u3067\u4E0D\u8981\uFF09\u3002\u30D6\u30E9\u30F3\u30C1\u306E\u78BA\u8A8D\u304C\u8981\u308B\u5834\u5408\u306F \`git rev-parse --abbrev-ref HEAD\` \u3092\u4F7F\u3046\u3053\u3068\u3002`;
|
|
2606
2605
|
}
|
|
2607
2606
|
function buildCloudGitHubAccessInstruction() {
|
|
@@ -2899,8 +2898,7 @@ async function pollCloudWaiters() {
|
|
|
2899
2898
|
const now = Date.now();
|
|
2900
2899
|
for (const [key, waiter] of [...cloudWaiters.entries()]) {
|
|
2901
2900
|
const done = doneKeys.get(waiter.type);
|
|
2902
|
-
|
|
2903
|
-
if (done?.has(number)) {
|
|
2901
|
+
if (done?.has(waiter.number)) {
|
|
2904
2902
|
waiter.settle("completed");
|
|
2905
2903
|
cloudWaiters.delete(key);
|
|
2906
2904
|
} else if (now >= waiter.deadline) {
|
|
@@ -2915,19 +2913,21 @@ async function pollCloudWaiters() {
|
|
|
2915
2913
|
}
|
|
2916
2914
|
}
|
|
2917
2915
|
}
|
|
2918
|
-
function waitForCloudTask(id,
|
|
2916
|
+
function waitForCloudTask(id, target) {
|
|
2919
2917
|
return new Promise((resolve3) => {
|
|
2920
|
-
cloudWaiters.set(`${type}:${id}`, {
|
|
2921
|
-
type,
|
|
2918
|
+
cloudWaiters.set(`${target.type}:${target.number}:${id}`, {
|
|
2919
|
+
type: target.type,
|
|
2920
|
+
number: target.number,
|
|
2922
2921
|
deadline: Date.now() + CLOUD_TASK_TIMEOUT_MS,
|
|
2923
2922
|
settle: resolve3
|
|
2924
2923
|
});
|
|
2925
2924
|
ensureCloudPollLoop();
|
|
2926
2925
|
});
|
|
2927
2926
|
}
|
|
2928
|
-
async function flagOrphanedCloudSession(target,
|
|
2929
|
-
|
|
2930
|
-
|
|
2927
|
+
async function flagOrphanedCloudSession(target, reason, cloudSessionId) {
|
|
2928
|
+
const { type, number: id } = target;
|
|
2929
|
+
await addLabel(type, id, "cc-need-human-check").catch((err) => {
|
|
2930
|
+
console.error(`[worker] failed to add cc-need-human-check to ${type} #${id}: ${err}`);
|
|
2931
2931
|
});
|
|
2932
2932
|
const causeLine = reason === "session-id" ? "\u30BB\u30C3\u30B7\u30E7\u30F3ID\u306E\u62BD\u51FA\u306B\u5931\u6557\u3057\u3066\u5F85\u6A5F\u3092\u6253\u3061\u5207\u308A\u307E\u3057\u305F\u3002\u30D7\u30ED\u30F3\u30D7\u30C8\u306F\u6295\u5165\u6E08\u307F\u3067\u3001\u30AF\u30E9\u30A6\u30C9\u30BB\u30C3\u30B7\u30E7\u30F3\u306F\u72EC\u7ACB\u3057\u3066\u7A3C\u50CD\u3057\u3066\u3044\u308B\u53EF\u80FD\u6027\u304C\u3042\u308A\u307E\u3059\u3002" : "\u30EF\u30FC\u30AB\u30FC\u306E\u30B7\u30E3\u30C3\u30C8\u30C0\u30A6\u30F3\u3067\u5F85\u6A5F\u3092\u6253\u3061\u5207\u308A\u307E\u3057\u305F\u3002\u30AF\u30E9\u30A6\u30C9\u30BB\u30C3\u30B7\u30E7\u30F3\u306F\u7D99\u7D9A\u3057\u3066\u3044\u308B\u53EF\u80FD\u6027\u304C\u9AD8\u3044\u3067\u3059\u3002";
|
|
2933
2933
|
const sessionLine = cloudSessionId ? `https://claude.ai/code/${cloudSessionId}` : "\u30BB\u30C3\u30B7\u30E7\u30F3URL\u4E0D\u660E\uFF08ID\u62BD\u51FA\u306B\u5931\u6557\uFF09";
|
|
@@ -2938,9 +2938,9 @@ async function flagOrphanedCloudSession(target, id, reason, cloudSessionId) {
|
|
|
2938
2938
|
**\u30BB\u30C3\u30B7\u30E7\u30F3URL**: ${sessionLine}
|
|
2939
2939
|
|
|
2940
2940
|
**\u518D\u958B\u65B9\u6CD5**: \u5B64\u7ACB\u30BB\u30C3\u30B7\u30E7\u30F3\u306E\u6210\u679C\u7269\u304C\u5C4A\u3044\u3066\u3044\u306A\u3044\u304B\u78BA\u8A8D\u3057\u305F\u3046\u3048\u3067\u3001\`cc-need-human-check\` \u30E9\u30D9\u30EB\u3092\u5916\u3059\u3068\u30DD\u30FC\u30EA\u30F3\u30B0\u5BFE\u8C61\u306B\u623B\u308A\u307E\u3059\u3002`;
|
|
2941
|
-
const commentFn =
|
|
2941
|
+
const commentFn = type === "issue" ? commentOnIssue : commentOnPR;
|
|
2942
2942
|
await commentFn(id, body).catch((err) => {
|
|
2943
|
-
console.error(`[worker] failed to comment on ${
|
|
2943
|
+
console.error(`[worker] failed to comment on ${type} #${id} about the orphaned cloud session: ${err}`);
|
|
2944
2944
|
});
|
|
2945
2945
|
}
|
|
2946
2946
|
async function createCloudSession(args, initialPrompt, cwd, env) {
|
|
@@ -2992,11 +2992,7 @@ async function createCloudSession(args, initialPrompt, cwd, env) {
|
|
|
2992
2992
|
}
|
|
2993
2993
|
async function runViaCloud(args, prompt, id, onComplete, cwd, env, cloudTarget, model) {
|
|
2994
2994
|
herdrTasks.set(id, { paneId: "", tabId: "" });
|
|
2995
|
-
const initialPrompt = buildCloudPrompt(
|
|
2996
|
-
prompt,
|
|
2997
|
-
model ?? "",
|
|
2998
|
-
cloudTarget ? { type: cloudTarget, number: id } : void 0
|
|
2999
|
-
);
|
|
2995
|
+
const initialPrompt = buildCloudPrompt(prompt, model ?? "", cloudTarget);
|
|
3000
2996
|
let result;
|
|
3001
2997
|
let cloudSessionId;
|
|
3002
2998
|
try {
|
|
@@ -3007,17 +3003,20 @@ async function runViaCloud(args, prompt, id, onComplete, cwd, env, cloudTarget,
|
|
|
3007
3003
|
result = { status: "completed", output: createOutput };
|
|
3008
3004
|
} else {
|
|
3009
3005
|
const outcome = await waitForCloudTask(id, cloudTarget);
|
|
3006
|
+
const { type: targetType, number: targetNumber } = cloudTarget;
|
|
3010
3007
|
if (outcome === "completed") {
|
|
3011
|
-
await removeLabel(
|
|
3012
|
-
console.error(`[worker] failed to remove ${CLOUD_DONE_LABEL} from ${
|
|
3008
|
+
await removeLabel(targetType, targetNumber, CLOUD_DONE_LABEL).catch((err) => {
|
|
3009
|
+
console.error(`[worker] failed to remove ${CLOUD_DONE_LABEL} from ${targetType} #${targetNumber}: ${err}`);
|
|
3013
3010
|
});
|
|
3014
3011
|
let reportBody = null;
|
|
3015
3012
|
const startedAt = tasks.get(id)?.startedAt;
|
|
3016
3013
|
if (startedAt) {
|
|
3017
3014
|
try {
|
|
3018
|
-
reportBody = await findCommentSince(
|
|
3015
|
+
reportBody = await findCommentSince(targetNumber, startedAt, CLOUD_REPORT_HEADING);
|
|
3019
3016
|
} catch (err) {
|
|
3020
|
-
console.error(
|
|
3017
|
+
console.error(
|
|
3018
|
+
`[worker] failed to fetch the cloud report comment for ${targetType} #${targetNumber}: ${err}`
|
|
3019
|
+
);
|
|
3021
3020
|
}
|
|
3022
3021
|
}
|
|
3023
3022
|
result = {
|
|
@@ -3026,8 +3025,8 @@ async function runViaCloud(args, prompt, id, onComplete, cwd, env, cloudTarget,
|
|
|
3026
3025
|
[worker] detected completion via the ${CLOUD_DONE_LABEL} label`
|
|
3027
3026
|
};
|
|
3028
3027
|
} else if (outcome === "timeout") {
|
|
3029
|
-
await addLabel(
|
|
3030
|
-
console.error(`[worker] failed to add cc-need-human-check to ${
|
|
3028
|
+
await addLabel(targetType, targetNumber, "cc-need-human-check").catch((err) => {
|
|
3029
|
+
console.error(`[worker] failed to add cc-need-human-check to ${targetType} #${targetNumber}: ${err}`);
|
|
3031
3030
|
});
|
|
3032
3031
|
result = {
|
|
3033
3032
|
status: "failed",
|
|
@@ -3035,7 +3034,7 @@ async function runViaCloud(args, prompt, id, onComplete, cwd, env, cloudTarget,
|
|
|
3035
3034
|
[worker] timed out waiting for the ${CLOUD_DONE_LABEL} label after ${CLOUD_TASK_TIMEOUT_MS / 1e3 / 60} minutes. Possible causes: the session stopped on AskUserQuestion, the cloud VM crashed, the plugin was not installed, or label assignment itself failed.`
|
|
3036
3035
|
};
|
|
3037
3036
|
} else {
|
|
3038
|
-
await flagOrphanedCloudSession(cloudTarget,
|
|
3037
|
+
await flagOrphanedCloudSession(cloudTarget, "shutdown", cloudSessionId);
|
|
3039
3038
|
result = {
|
|
3040
3039
|
status: "failed",
|
|
3041
3040
|
output: `${createOutput}
|
|
@@ -3049,7 +3048,7 @@ async function runViaCloud(args, prompt, id, onComplete, cwd, env, cloudTarget,
|
|
|
3049
3048
|
let orphanNote = "[worker] note: with the 1-command launch, the cloud session may already have started working independently even though this task is being reported as failed locally (orphaned session).";
|
|
3050
3049
|
if (cloudTarget) {
|
|
3051
3050
|
const reason = herdrAbortSignal.aborted ? "shutdown" : "session-id";
|
|
3052
|
-
await flagOrphanedCloudSession(cloudTarget,
|
|
3051
|
+
await flagOrphanedCloudSession(cloudTarget, reason, cloudSessionId);
|
|
3053
3052
|
orphanNote += " added cc-need-human-check so a human can verify whether it completed on its own.";
|
|
3054
3053
|
}
|
|
3055
3054
|
result = {
|
|
@@ -3985,7 +3984,7 @@ function createIssuePollingWorker(config) {
|
|
|
3985
3984
|
buildClaudeEnv(mode, cloud),
|
|
3986
3985
|
execution.prompt,
|
|
3987
3986
|
cloud,
|
|
3988
|
-
cloud ? "issue" : void 0,
|
|
3987
|
+
cloud ? { type: "issue", number: issue.number } : void 0,
|
|
3989
3988
|
model
|
|
3990
3989
|
);
|
|
3991
3990
|
} catch (err) {
|
|
@@ -4242,7 +4241,7 @@ function createPrPollingWorker(config) {
|
|
|
4242
4241
|
buildClaudeEnv(mode, isCloud),
|
|
4243
4242
|
execution.prompt,
|
|
4244
4243
|
isCloud,
|
|
4245
|
-
isCloud ? "pr" : void 0,
|
|
4244
|
+
isCloud ? { type: "pr", number: pr.number, onBranch: true } : void 0,
|
|
4246
4245
|
model
|
|
4247
4246
|
);
|
|
4248
4247
|
} catch (err) {
|
|
@@ -4715,7 +4714,7 @@ async function publishLastRunPr(workerName, defaultBranch, at) {
|
|
|
4715
4714
|
writeLastRun(cwd, workerName, at);
|
|
4716
4715
|
if (!hasLastRunChange(await git(cwd, ["status", "--porcelain", CONFIG_FILE]))) {
|
|
4717
4716
|
console.log(`[${workerName}] lastRun unchanged, skipping PR`);
|
|
4718
|
-
return;
|
|
4717
|
+
return null;
|
|
4719
4718
|
}
|
|
4720
4719
|
await git(cwd, ["add", CONFIG_FILE]);
|
|
4721
4720
|
await git(cwd, ["commit", "-m", lastRunPrTitle(workerName)]);
|
|
@@ -4723,7 +4722,7 @@ async function publishLastRunPr(workerName, defaultBranch, at) {
|
|
|
4723
4722
|
const existing = await findOpenPrNumberByHeadRef(branch);
|
|
4724
4723
|
if (existing !== null) {
|
|
4725
4724
|
console.log(`[${workerName}] updated lastRun PR #${existing}`);
|
|
4726
|
-
return;
|
|
4725
|
+
return existing;
|
|
4727
4726
|
}
|
|
4728
4727
|
const prNumber = await createPullRequest(
|
|
4729
4728
|
defaultBranch,
|
|
@@ -4733,6 +4732,7 @@ async function publishLastRunPr(workerName, defaultBranch, at) {
|
|
|
4733
4732
|
{ labels: [LABEL_TRIAGE_SCOPE2], assignee: await getCurrentUser() }
|
|
4734
4733
|
);
|
|
4735
4734
|
console.log(`[${workerName}] opened lastRun PR #${prNumber}`);
|
|
4735
|
+
return prNumber;
|
|
4736
4736
|
} finally {
|
|
4737
4737
|
await removeWorktree(branch).catch((err) => console.error(`[${workerName}] removeWorktree failed: ${err}`));
|
|
4738
4738
|
}
|
|
@@ -4742,6 +4742,7 @@ async function publishLastRunPr(workerName, defaultBranch, at) {
|
|
|
4742
4742
|
var SCHEDULE_INTERVAL_HOURS = 24;
|
|
4743
4743
|
var SCHEDULE_INTERVAL_MS = SCHEDULE_INTERVAL_HOURS * 60 * 60 * 1e3;
|
|
4744
4744
|
var SCOPE_DAYS = SCHEDULE_INTERVAL_HOURS / 24;
|
|
4745
|
+
var LABEL_IN_PROGRESS2 = "cc-in-progress";
|
|
4745
4746
|
function createScheduledWorker(config) {
|
|
4746
4747
|
return async () => {
|
|
4747
4748
|
const { owner, name: repoName, defaultBranch } = await getRepoInfo();
|
|
@@ -4775,9 +4776,23 @@ function createScheduledWorker(config) {
|
|
|
4775
4776
|
permissionMode: getPermissionMode(),
|
|
4776
4777
|
...cloud ? { cloud: true, baseRef: defaultBranch, remoteEnvId: getRemoteEnvId() ?? "" } : {}
|
|
4777
4778
|
});
|
|
4778
|
-
await publishLastRunPr(config.name, defaultBranch, new Date(now)).catch(
|
|
4779
|
-
|
|
4780
|
-
|
|
4779
|
+
const lastRunPr = await publishLastRunPr(config.name, defaultBranch, new Date(now)).catch((err) => {
|
|
4780
|
+
console.error(`[${config.name}] publishLastRunPr failed: ${err}`);
|
|
4781
|
+
return null;
|
|
4782
|
+
});
|
|
4783
|
+
if (cloud && lastRunPr === null) {
|
|
4784
|
+
console.warn(
|
|
4785
|
+
`[${config.name}] no lastRun PR to carry the cc-cloud-done label; the cloud session will be reported as completed as soon as it is created`
|
|
4786
|
+
);
|
|
4787
|
+
}
|
|
4788
|
+
if (cloud && lastRunPr !== null) {
|
|
4789
|
+
await removeLabel("pr", lastRunPr, CLOUD_DONE_LABEL).catch(
|
|
4790
|
+
(err) => console.error(`[${config.name}] removeLabel ${CLOUD_DONE_LABEL} failed for PR #${lastRunPr}: ${err}`)
|
|
4791
|
+
);
|
|
4792
|
+
await addLabel("pr", lastRunPr, LABEL_IN_PROGRESS2).catch(
|
|
4793
|
+
(err) => console.error(`[${config.name}] addLabel ${LABEL_IN_PROGRESS2} failed for PR #${lastRunPr}: ${err}`)
|
|
4794
|
+
);
|
|
4795
|
+
}
|
|
4781
4796
|
let cwd;
|
|
4782
4797
|
if (cloud) {
|
|
4783
4798
|
console.log(`[${config.name}] cloud execution, running without worktree on ${defaultBranch}`);
|
|
@@ -4804,6 +4819,13 @@ function createScheduledWorker(config) {
|
|
|
4804
4819
|
} catch (err) {
|
|
4805
4820
|
console.error(`[${config.name}] post-task error: ${err}`);
|
|
4806
4821
|
} finally {
|
|
4822
|
+
if (cloud && lastRunPr !== null) {
|
|
4823
|
+
await removeLabel("pr", lastRunPr, LABEL_IN_PROGRESS2).catch(
|
|
4824
|
+
(err) => console.error(
|
|
4825
|
+
`[${config.name}] removeLabel ${LABEL_IN_PROGRESS2} failed for PR #${lastRunPr}: ${err}`
|
|
4826
|
+
)
|
|
4827
|
+
);
|
|
4828
|
+
}
|
|
4807
4829
|
if (!cloud) {
|
|
4808
4830
|
await removeWorktree(worktreeId).catch(
|
|
4809
4831
|
(err) => console.error(`[${config.name}] removeWorktree failed: ${err}`)
|
|
@@ -4815,7 +4837,7 @@ function createScheduledWorker(config) {
|
|
|
4815
4837
|
buildClaudeEnv(mode, cloud),
|
|
4816
4838
|
execution.prompt,
|
|
4817
4839
|
cloud,
|
|
4818
|
-
void 0,
|
|
4840
|
+
cloud && lastRunPr !== null ? { type: "pr", number: lastRunPr } : void 0,
|
|
4819
4841
|
model
|
|
4820
4842
|
);
|
|
4821
4843
|
} catch (err) {
|
|
@@ -4861,7 +4883,7 @@ var updateDesignMdWorker = createScheduledWorker({
|
|
|
4861
4883
|
init_table();
|
|
4862
4884
|
|
|
4863
4885
|
// src/commands/init.ts
|
|
4864
|
-
import { mkdir as mkdir2, readFile as readFile2, writeFile as writeFile2, access } from "node:fs/promises";
|
|
4886
|
+
import { mkdir as mkdir2, readFile as readFile2, rm as rm2, writeFile as writeFile2, access } from "node:fs/promises";
|
|
4865
4887
|
import { basename as basename3 } from "node:path";
|
|
4866
4888
|
|
|
4867
4889
|
// src/commands/codegraph.ts
|
|
@@ -4984,14 +5006,20 @@ var LABELS = [
|
|
|
4984
5006
|
// vivid bronze (H46 S100 L29 / L*50 C*56)
|
|
4985
5007
|
{ name: "cc-ui-design-ready", color: "0c73e9" },
|
|
4986
5008
|
// vivid azure (H212 S90 L48 / L*50 C*69)
|
|
4987
|
-
{ name: CLOUD_DONE_LABEL, color: "33cfff" }
|
|
5009
|
+
{ name: CLOUD_DONE_LABEL, color: "33cfff" },
|
|
4988
5010
|
// vivid sky blue (H194 S100 L60 / L*78 C*42)
|
|
5011
|
+
// 追加時点で有彩色ラベルが色相環をほぼ埋めており、上記6点を全て満たす色は残っていない。
|
|
5012
|
+
// 最寄り色相との差は27°が上限(H185 が最大)で、その相手は cc-cloud-done(クラウド実行中だけ
|
|
5013
|
+
// 現れる短命なマーカー・L*78 と明度が倍近く違う)=見分けたい相手ではない側に倒してある。
|
|
5014
|
+
{ name: "cc-issue-request", color: "03656d" }
|
|
5015
|
+
// vivid deep teal (H185 S95 L22 / L*39 C*24)
|
|
4989
5016
|
];
|
|
4990
5017
|
var ISSUE_TEMPLATE = `name: "[claude-task-worker] Issue\u4F5C\u6210\u4F9D\u983C"
|
|
4991
5018
|
description: claude-task-worker\u3067GitHub Issue\u3092\u4F5C\u6210\u3059\u308B
|
|
4992
5019
|
title: "[claude-task-worker] Issue\u4F5C\u6210\u4F9D\u983C"
|
|
4993
5020
|
labels:
|
|
4994
5021
|
- cc-triage-scope
|
|
5022
|
+
- cc-issue-request
|
|
4995
5023
|
body:
|
|
4996
5024
|
- type: textarea
|
|
4997
5025
|
id: request
|
|
@@ -5001,7 +5029,7 @@ body:
|
|
|
5001
5029
|
validations:
|
|
5002
5030
|
required: true
|
|
5003
5031
|
`;
|
|
5004
|
-
var ASSIGN_CREATOR_WORKFLOW = `name: Assign creator on
|
|
5032
|
+
var ASSIGN_CREATOR_WORKFLOW = `name: Assign creator on issue request
|
|
5005
5033
|
|
|
5006
5034
|
on:
|
|
5007
5035
|
issues:
|
|
@@ -5009,7 +5037,7 @@ on:
|
|
|
5009
5037
|
|
|
5010
5038
|
jobs:
|
|
5011
5039
|
assign:
|
|
5012
|
-
if: contains(github.event.issue.labels.*.name, 'cc-
|
|
5040
|
+
if: contains(github.event.issue.labels.*.name, 'cc-issue-request')
|
|
5013
5041
|
runs-on: ubuntu-latest
|
|
5014
5042
|
permissions:
|
|
5015
5043
|
issues: write
|
|
@@ -5067,6 +5095,25 @@ async function ensureLocalConfigGitIgnore() {
|
|
|
5067
5095
|
await writeFile2(path2, next, "utf-8");
|
|
5068
5096
|
console.log(`[init] Added ${entry} to ${path2}`);
|
|
5069
5097
|
}
|
|
5098
|
+
var LEGACY_PATHS = [
|
|
5099
|
+
".github/ISSUE_TEMPLATE/cc-triage-scope.yml",
|
|
5100
|
+
".github/workflows/assign-creator-on-cc-triage-scope.yml"
|
|
5101
|
+
];
|
|
5102
|
+
function isContentMismatch(result, expected, actual) {
|
|
5103
|
+
return result === "skipped" && actual !== expected;
|
|
5104
|
+
}
|
|
5105
|
+
async function removeLegacyIssueRequestFiles() {
|
|
5106
|
+
for (const path2 of LEGACY_PATHS) {
|
|
5107
|
+
try {
|
|
5108
|
+
await rm2(path2);
|
|
5109
|
+
console.log(`[init] Removed legacy file: ${path2}`);
|
|
5110
|
+
} catch (err) {
|
|
5111
|
+
if (err.code !== "ENOENT") {
|
|
5112
|
+
throw err;
|
|
5113
|
+
}
|
|
5114
|
+
}
|
|
5115
|
+
}
|
|
5116
|
+
}
|
|
5070
5117
|
async function init(options = {}) {
|
|
5071
5118
|
const force = options.force ?? false;
|
|
5072
5119
|
console.log(`[init] Creating labels...${force ? " (force mode)" : ""}`);
|
|
@@ -5080,12 +5127,25 @@ async function init(options = {}) {
|
|
|
5080
5127
|
}
|
|
5081
5128
|
console.log("[init] Creating issue template...");
|
|
5082
5129
|
await mkdir2(".github/ISSUE_TEMPLATE", { recursive: true });
|
|
5083
|
-
const templatePath = ".github/ISSUE_TEMPLATE/cc-
|
|
5084
|
-
|
|
5130
|
+
const templatePath = ".github/ISSUE_TEMPLATE/cc-issue-request.yml";
|
|
5131
|
+
const templateResult = await writeFileWithMode(templatePath, ISSUE_TEMPLATE, force);
|
|
5132
|
+
logWriteResult(templateResult, templatePath);
|
|
5085
5133
|
console.log("[init] Creating GitHub Actions workflow...");
|
|
5086
5134
|
await mkdir2(".github/workflows", { recursive: true });
|
|
5087
|
-
const workflowPath = ".github/workflows/assign-creator-on-
|
|
5088
|
-
|
|
5135
|
+
const workflowPath = ".github/workflows/assign-creator-on-issue-request.yml";
|
|
5136
|
+
const workflowResult = await writeFileWithMode(workflowPath, ASSIGN_CREATOR_WORKFLOW, force);
|
|
5137
|
+
logWriteResult(workflowResult, workflowPath);
|
|
5138
|
+
if (isContentMismatch(templateResult, ISSUE_TEMPLATE, await readFile2(templatePath, "utf-8"))) {
|
|
5139
|
+
throw new Error(
|
|
5140
|
+
`[init] ${templatePath} \u306F\u65E2\u5B58\u306E\u5185\u5BB9\u304C\u6700\u65B0\u306E\u30C6\u30F3\u30D7\u30EC\u30FC\u30C8\u3068\u4E00\u81F4\u3057\u307E\u305B\u3093\u3002--force \u3067\u518D\u5B9F\u884C\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u65E7\u30D5\u30A1\u30A4\u30EB\u306F\u524A\u9664\u3057\u3066\u3044\u307E\u305B\u3093\u3002`
|
|
5141
|
+
);
|
|
5142
|
+
}
|
|
5143
|
+
if (isContentMismatch(workflowResult, ASSIGN_CREATOR_WORKFLOW, await readFile2(workflowPath, "utf-8"))) {
|
|
5144
|
+
throw new Error(
|
|
5145
|
+
`[init] ${workflowPath} \u306F\u65E2\u5B58\u306E\u5185\u5BB9\u304C\u6700\u65B0\u306E\u30EF\u30FC\u30AF\u30D5\u30ED\u30FC\u3068\u4E00\u81F4\u3057\u307E\u305B\u3093\u3002--force \u3067\u518D\u5B9F\u884C\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u65E7\u30D5\u30A1\u30A4\u30EB\u306F\u524A\u9664\u3057\u3066\u3044\u307E\u305B\u3093\u3002`
|
|
5146
|
+
);
|
|
5147
|
+
}
|
|
5148
|
+
await removeLegacyIssueRequestFiles();
|
|
5089
5149
|
console.log("[init] Creating config file...");
|
|
5090
5150
|
await createConfig(force);
|
|
5091
5151
|
await ensureLocalConfigGitIgnore();
|
|
@@ -5259,6 +5319,9 @@ var CLOUD_SETTINGS_DEFAULTS = {
|
|
|
5259
5319
|
outputStyle: "Proactive",
|
|
5260
5320
|
language: "Japanese"
|
|
5261
5321
|
};
|
|
5322
|
+
var CLOUD_SETTINGS_ENV = {
|
|
5323
|
+
CLAUDE_CODE_DISABLE_BACKGROUND_TASKS: "1"
|
|
5324
|
+
};
|
|
5262
5325
|
function claudeSettingsPath() {
|
|
5263
5326
|
const dir = process.env.CLAUDE_CONFIG_DIR;
|
|
5264
5327
|
return join8(dir && dir.length > 0 ? dir : join8(homedir6(), ".claude"), "settings.json");
|
|
@@ -5274,6 +5337,11 @@ function withCloudDefaults(existing, force) {
|
|
|
5274
5337
|
throw new Error("`permissions` is not an object");
|
|
5275
5338
|
}
|
|
5276
5339
|
const permissions = { ...current };
|
|
5340
|
+
const currentEnv = settings["env"] ?? {};
|
|
5341
|
+
if (typeof currentEnv !== "object" || currentEnv === null || Array.isArray(currentEnv)) {
|
|
5342
|
+
throw new Error("`env` is not an object");
|
|
5343
|
+
}
|
|
5344
|
+
const env = { ...currentEnv };
|
|
5277
5345
|
let changed = false;
|
|
5278
5346
|
const set = (target, key, value) => {
|
|
5279
5347
|
if (key in target && !force) return;
|
|
@@ -5283,8 +5351,9 @@ function withCloudDefaults(existing, force) {
|
|
|
5283
5351
|
};
|
|
5284
5352
|
set(permissions, "defaultMode", CLOUD_DEFAULT_PERMISSION_MODE);
|
|
5285
5353
|
for (const [key, value] of Object.entries(CLOUD_SETTINGS_DEFAULTS)) set(settings, key, value);
|
|
5354
|
+
for (const [key, value] of Object.entries(CLOUD_SETTINGS_ENV)) set(env, key, value);
|
|
5286
5355
|
if (!changed) return null;
|
|
5287
|
-
return `${JSON.stringify({ ...settings, permissions }, null, 2)}
|
|
5356
|
+
return `${JSON.stringify({ ...settings, permissions, env }, null, 2)}
|
|
5288
5357
|
`;
|
|
5289
5358
|
}
|
|
5290
5359
|
async function writeClaudeSettings(force) {
|
|
@@ -5612,9 +5681,7 @@ async function assertCloudAvailable() {
|
|
|
5612
5681
|
process.exit(1);
|
|
5613
5682
|
}
|
|
5614
5683
|
if (cloud) {
|
|
5615
|
-
console.log(
|
|
5616
|
-
`[worker] cloud execution enabled (--cloud); only these workers run in the cloud: ${CLOUD_ALLOWED_WORKERS.join(", ")} (all others stay local)`
|
|
5617
|
-
);
|
|
5684
|
+
console.log("[worker] cloud execution enabled (--cloud); every worker started by this process runs in the cloud");
|
|
5618
5685
|
}
|
|
5619
5686
|
}
|
|
5620
5687
|
async function assertRunPrerequisites() {
|