claude-task-worker 0.83.0 → 0.85.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 +15 -1
- package/dist/index.js +212 -86
- package/dist/pen-baseuri-fix.mjs +31 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -66,7 +66,7 @@ CLI が GitHub ラベルを検知してタスクを起動し、プラグイン
|
|
|
66
66
|
| [Git](https://git-scm.com/) | worktree の作成・ブランチ操作 |
|
|
67
67
|
| [jq](https://jqlang.org/) | プラグインスキル内での JSON 加工 |
|
|
68
68
|
| [CodeGraph](https://www.npmjs.com/package/@colbymchenry/codegraph) | コード探索用インデックス。任意(未導入でも探索がテキスト検索に落ちるだけ) |
|
|
69
|
-
| [Pencil CLI](https://docs.pencil.dev/for-developers/pencil-cli) | `.pen` デザインファイルの編集・参照。UI
|
|
69
|
+
| [Pencil CLI](https://docs.pencil.dev/for-developers/pencil-cli) | `.pen` デザインファイルの編集・参照。UIデザイン先行ワークフロー使用時のみ(呼び出しは `claude-task-worker pencil` 経由) |
|
|
70
70
|
| [herdr](https://herdr.dev) | `--project` / `mode: "herdr"` 使用時のみ |
|
|
71
71
|
|
|
72
72
|
CLI 本体に npm の実行時依存はない(esbuild で `dist/index.js` に単一バンドルされ、Node.js 標準モジュールのみで動作する)。
|
|
@@ -149,8 +149,22 @@ claude-task-worker <command> [--epic <issue-number>]... [--label <label>]... [--
|
|
|
149
149
|
| `init` | ラベル・テンプレート・設定ファイルの作成と CodeGraph セットアップ |
|
|
150
150
|
| `install` / `update` | 上記「セットアップ」を参照 |
|
|
151
151
|
| `usage` | Claude API 使用状況(5時間/7日間の利用率とリセット時刻)を表示し、Slack にも通知 |
|
|
152
|
+
| `pencil <args...>` | Pencil CLI をアセット URI 修正パッチ付きで実行するラッパー(下記参照) |
|
|
152
153
|
| `version` | CLI のバージョンを表示(`--version` / `-v` も可) |
|
|
153
154
|
|
|
155
|
+
### `pencil <args...>`
|
|
156
|
+
|
|
157
|
+
`@pen.dev/cli`(`pencil`)にはアセットのベース URI を絶対 URI として解決できないバグがあり、`.pen` を開くと `Base URI must be absolute!` で失敗する。本コマンドはその修正を Node の loader hook(`dist/pen-baseuri-fix.mjs`)として `NODE_OPTIONS` 経由で注入したうえで `pencil` を実行するラッパー。
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
claude-task-worker pencil version
|
|
161
|
+
claude-task-worker pencil interactive -i designs/login.pen -o designs/login.pen <<'EOF'
|
|
162
|
+
...
|
|
163
|
+
EOF
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
引数・stdin・stdout・stderr・終了コードはすべて素通しするため、使い方は `pencil` と同じ。`.pen` を扱うスキル・エージェント(`edit-pencil-design` / `inspect-pencil-node` / `resolve-pencil-conflict` / `pencil-design-updater` など)はすべてこのラッパー経由で `pencil` を呼ぶ。
|
|
167
|
+
|
|
154
168
|
### `--epic <issue-number>`
|
|
155
169
|
|
|
156
170
|
指定したエピック Issue のサブ Issue のみを処理対象に絞る。`all` / `yolo` と Issue 系ワーカーで有効。複数指定するといずれかのエピックを親に持つサブ Issue が対象になる(OR)。
|
package/dist/index.js
CHANGED
|
@@ -266,6 +266,7 @@ __export(herdr_exports, {
|
|
|
266
266
|
HerdrError: () => HerdrError,
|
|
267
267
|
HerdrUnavailableError: () => HerdrUnavailableError,
|
|
268
268
|
agentGet: () => agentGet,
|
|
269
|
+
agentPrompt: () => agentPrompt,
|
|
269
270
|
agentStart: () => agentStart,
|
|
270
271
|
checkHerdrAvailable: () => checkHerdrAvailable,
|
|
271
272
|
getCurrentWorkspaceId: () => getCurrentWorkspaceId,
|
|
@@ -452,6 +453,9 @@ async function agentStart(paneId, {
|
|
|
452
453
|
}
|
|
453
454
|
return toAgentInfo(agent);
|
|
454
455
|
}
|
|
456
|
+
async function agentPrompt(paneId, text) {
|
|
457
|
+
await execHerdr(["agent", "prompt", paneId, text], { allowEmptyResult: true });
|
|
458
|
+
}
|
|
455
459
|
async function agentGet(target) {
|
|
456
460
|
const result = await execHerdr(["agent", "get", target]);
|
|
457
461
|
const agent = result?.agent;
|
|
@@ -635,6 +639,7 @@ async function startHerdrTask({
|
|
|
635
639
|
label,
|
|
636
640
|
cwd,
|
|
637
641
|
args,
|
|
642
|
+
prompt,
|
|
638
643
|
env,
|
|
639
644
|
workspaceId,
|
|
640
645
|
herdr,
|
|
@@ -651,6 +656,7 @@ async function startHerdrTask({
|
|
|
651
656
|
console.warn(`[herdr-runner] pane ${paneId} produced no prompt before the timeout, launching anyway`);
|
|
652
657
|
}
|
|
653
658
|
await mod.agentStart(paneId, { name: toAgentName(label), args, readyTimeoutMs: timing?.agentStartReadyTimeoutMs });
|
|
659
|
+
await mod.agentPrompt(paneId, prompt);
|
|
654
660
|
} catch (err) {
|
|
655
661
|
await mod.tabClose(tabId).catch(() => {
|
|
656
662
|
});
|
|
@@ -1875,8 +1881,12 @@ function buildClaudeArgs({
|
|
|
1875
1881
|
const advisor = advisorModel?.trim() ?? "";
|
|
1876
1882
|
const permission = permissionMode ?? DEFAULT_PERMISSION_MODE;
|
|
1877
1883
|
return [
|
|
1878
|
-
|
|
1879
|
-
|
|
1884
|
+
// default モードはプロンプトを引数で渡す(print モード)。herdr モードでは渡さない:
|
|
1885
|
+
// 引数で渡すと claude が起動と同時に作業を始めてしまい、`herdr agent start` が
|
|
1886
|
+
// 「入力待ちになるまで」ブロックする仕様と噛み合わない(タスクが終わるまで返らず、
|
|
1887
|
+
// 2分を超えると timeout で落ちる)。プロンプトは起動後に `herdr agent prompt` で
|
|
1888
|
+
// 投入し、herdr にターンを追跡させる(herdr-runner.ts の startHerdrTask 参照)。
|
|
1889
|
+
...mode === "herdr" ? [] : ["-p", prompt],
|
|
1880
1890
|
"--permission-mode",
|
|
1881
1891
|
permission,
|
|
1882
1892
|
"--chrome",
|
|
@@ -1894,7 +1904,11 @@ function buildClaudeArgs({
|
|
|
1894
1904
|
];
|
|
1895
1905
|
}
|
|
1896
1906
|
function buildClaudeExecution(invocation) {
|
|
1897
|
-
return {
|
|
1907
|
+
return {
|
|
1908
|
+
command: CLAUDE_COMMAND,
|
|
1909
|
+
args: buildClaudeArgs(invocation),
|
|
1910
|
+
...invocation.mode === "herdr" ? { prompt: invocation.prompt } : {}
|
|
1911
|
+
};
|
|
1898
1912
|
}
|
|
1899
1913
|
function buildClaudeEnv(mode) {
|
|
1900
1914
|
return mode === "herdr" ? { CLAUDE_CODE_DISABLE_BACKGROUND_TASKS: CLAUDE_SPAWN_ENV.CLAUDE_CODE_DISABLE_BACKGROUND_TASKS } : { ...CLAUDE_SPAWN_ENV };
|
|
@@ -2446,7 +2460,7 @@ function resolveProjectName(cwd = process.cwd()) {
|
|
|
2446
2460
|
if (injected && injected.length > 0) return injected;
|
|
2447
2461
|
return findProjectNameByPath(cwd) ?? basename(cwd);
|
|
2448
2462
|
}
|
|
2449
|
-
async function runViaHerdr(args, id, onComplete, cwd, env) {
|
|
2463
|
+
async function runViaHerdr(args, prompt, id, onComplete, cwd, env) {
|
|
2450
2464
|
const { startHerdrTask: startHerdrTask2, stopHerdrTask: stopHerdrTask2, taskTabLabel: taskTabLabel2, waitForHerdrTask: waitForHerdrTask2 } = await Promise.resolve().then(() => (init_herdr_runner(), herdr_runner_exports));
|
|
2451
2465
|
const { getCurrentWorkspaceId: getCurrentWorkspaceId2 } = await Promise.resolve().then(() => (init_herdr(), herdr_exports));
|
|
2452
2466
|
const label = taskTabLabel2(resolveProjectName(), id);
|
|
@@ -2458,6 +2472,7 @@ async function runViaHerdr(args, id, onComplete, cwd, env) {
|
|
|
2458
2472
|
label,
|
|
2459
2473
|
cwd: cwd ?? process.cwd(),
|
|
2460
2474
|
args,
|
|
2475
|
+
prompt,
|
|
2461
2476
|
env,
|
|
2462
2477
|
workspaceId: getCurrentWorkspaceId2()
|
|
2463
2478
|
});
|
|
@@ -2481,7 +2496,7 @@ async function runViaHerdr(args, id, onComplete, cwd, env) {
|
|
|
2481
2496
|
await finishTask(id, result, onComplete);
|
|
2482
2497
|
herdrTasks.delete(id);
|
|
2483
2498
|
}
|
|
2484
|
-
function run(command, args, id, title, workerName, path2, onComplete, cwd, env) {
|
|
2499
|
+
function run(command, args, id, title, workerName, path2, onComplete, cwd, env, prompt) {
|
|
2485
2500
|
tasks.delete(id);
|
|
2486
2501
|
tasks.set(id, {
|
|
2487
2502
|
id,
|
|
@@ -2494,7 +2509,7 @@ function run(command, args, id, title, workerName, path2, onComplete, cwd, env)
|
|
|
2494
2509
|
ensureRenderInterval();
|
|
2495
2510
|
renderTable();
|
|
2496
2511
|
if (getRunMode() === "herdr") {
|
|
2497
|
-
void runViaHerdr(args, id, onComplete, cwd, env);
|
|
2512
|
+
void runViaHerdr(args, prompt ?? "", id, onComplete, cwd, env);
|
|
2498
2513
|
return;
|
|
2499
2514
|
}
|
|
2500
2515
|
const child = spawn(command, args, {
|
|
@@ -3287,7 +3302,7 @@ function createIssuePollingWorker(config) {
|
|
|
3287
3302
|
}
|
|
3288
3303
|
try {
|
|
3289
3304
|
if (status === "completed") {
|
|
3290
|
-
const verified = await config.onCompleted?.(issue.number, worktreeId) ?? true;
|
|
3305
|
+
const verified = await config.onCompleted?.(issue.number, worktreeId, output) ?? true;
|
|
3291
3306
|
if (verified === false) {
|
|
3292
3307
|
await notifyTaskFailed(config.name, name, issue.number, issue.title, issueUrl, output);
|
|
3293
3308
|
} else {
|
|
@@ -3311,7 +3326,8 @@ function createIssuePollingWorker(config) {
|
|
|
3311
3326
|
}
|
|
3312
3327
|
},
|
|
3313
3328
|
cwd,
|
|
3314
|
-
buildClaudeEnv(mode)
|
|
3329
|
+
buildClaudeEnv(mode),
|
|
3330
|
+
execution.prompt
|
|
3315
3331
|
);
|
|
3316
3332
|
} catch (err) {
|
|
3317
3333
|
console.error(`[${config.name}] setup error for #${issue.number}: ${err}`);
|
|
@@ -3333,11 +3349,22 @@ function createIssuePollingWorker(config) {
|
|
|
3333
3349
|
}
|
|
3334
3350
|
|
|
3335
3351
|
// src/workers/exec-issue.ts
|
|
3336
|
-
|
|
3352
|
+
var REPORT_TAIL_LIMIT = 3e3;
|
|
3353
|
+
function formatSessionReport(output) {
|
|
3354
|
+
const trimmed = output.trim();
|
|
3355
|
+
if (trimmed === "") return "\uFF08\u30BB\u30C3\u30B7\u30E7\u30F3\u306E\u51FA\u529B\u306F\u3042\u308A\u307E\u305B\u3093\u3067\u3057\u305F\uFF09";
|
|
3356
|
+
const tail = trimmed.length > REPORT_TAIL_LIMIT ? `\u2026\uFF08\u5148\u982D\u3092\u7701\u7565\uFF09
|
|
3357
|
+
${trimmed.slice(-REPORT_TAIL_LIMIT)}` : trimmed;
|
|
3358
|
+
return ["```", tail, "```"].join("\n");
|
|
3359
|
+
}
|
|
3360
|
+
function prMissingComment(worktreeId, output) {
|
|
3337
3361
|
return [
|
|
3338
3362
|
"## PR\u672A\u4F5C\u6210\u306E\u307E\u307E\u81EA\u52D5\u5B9F\u884C\u304C\u7D42\u4E86\u3057\u307E\u3057\u305F\uFF08\u8981\u4EBA\u624B\u78BA\u8A8D\uFF09",
|
|
3339
3363
|
`exec-issue \u306E\u30BB\u30C3\u30B7\u30E7\u30F3\u306F\u6B63\u5E38\u7D42\u4E86\uFF08exit 0\uFF09\u3057\u307E\u3057\u305F\u304C\u3001\u3053\u306E\u5B9F\u884C\u306E\u4F5C\u696D\u30D6\u30E9\u30F3\u30C1\uFF08\`${worktreeId}\`\uFF09\u3092 head \u3068\u3059\u308BPR\u3082\u3001\u672CIssue\u3092 closing \u53C2\u7167\u3059\u308BPR\u3082\u898B\u3064\u304B\u308A\u307E\u305B\u3093\u3067\u3057\u305F\u3002PR\u4F5C\u6210\u524D\u306B\u30BB\u30C3\u30B7\u30E7\u30F3\u304C\u7D42\u4E86\u3057\u305F\u53EF\u80FD\u6027\u304C\u3042\u308A\u307E\u3059\u3002`,
|
|
3340
3364
|
"",
|
|
3365
|
+
"## PR\u3092\u4F5C\u6210\u3057\u306A\u304B\u3063\u305F\u7406\u7531\uFF08\u30BB\u30C3\u30B7\u30E7\u30F3\u306E\u6700\u7D42\u5831\u544A\uFF09",
|
|
3366
|
+
formatSessionReport(output),
|
|
3367
|
+
"",
|
|
3341
3368
|
"## \u72B6\u614B\u306E\u78BA\u8A8D",
|
|
3342
3369
|
`- \u5909\u66F4\u304C push \u6E08\u307F\u306E\u5834\u5408\u306F\u30EA\u30E2\u30FC\u30C8\u30D6\u30E9\u30F3\u30C1 \`${worktreeId}\` \u304C\u6B8B\u3063\u3066\u3044\u307E\u3059\u3002\u5185\u5BB9\u3092\u78BA\u8A8D\u3057\u3001\u5FC5\u8981\u306A\u3089\u624B\u52D5\u3067PR\u3092\u4F5C\u6210\u3057\u3066\u304F\u3060\u3055\u3044`,
|
|
3343
3370
|
"",
|
|
@@ -3352,7 +3379,7 @@ var execIssueWorker = (opts = {}) => createIssuePollingWorker({
|
|
|
3352
3379
|
triggerLabels: ["cc-exec-issue"],
|
|
3353
3380
|
epicFilters: opts.epicFilters,
|
|
3354
3381
|
labelFilters: opts.labelFilters,
|
|
3355
|
-
onCompleted: async (issueNumber, worktreeId) => {
|
|
3382
|
+
onCompleted: async (issueNumber, worktreeId, output) => {
|
|
3356
3383
|
if (await hasLabel("issue", issueNumber, "cc-need-human-check")) {
|
|
3357
3384
|
console.log(`[exec-issue] #${issueNumber}: cc-need-human-check present, skip cc-pr-created`);
|
|
3358
3385
|
return false;
|
|
@@ -3370,7 +3397,7 @@ var execIssueWorker = (opts = {}) => createIssuePollingWorker({
|
|
|
3370
3397
|
`[exec-issue] #${issueNumber}: session exited without a PR (branch: ${worktreeId}); marking cc-need-human-check`
|
|
3371
3398
|
);
|
|
3372
3399
|
await addLabel("issue", issueNumber, "cc-need-human-check");
|
|
3373
|
-
await commentOnIssue(issueNumber, prMissingComment(worktreeId)).catch(
|
|
3400
|
+
await commentOnIssue(issueNumber, prMissingComment(worktreeId, output)).catch(
|
|
3374
3401
|
(err) => console.error(`[exec-issue] commentOnIssue failed for #${issueNumber}: ${err}`)
|
|
3375
3402
|
);
|
|
3376
3403
|
return false;
|
|
@@ -3477,7 +3504,8 @@ function createPrPollingWorker(config) {
|
|
|
3477
3504
|
}
|
|
3478
3505
|
},
|
|
3479
3506
|
cwd,
|
|
3480
|
-
buildClaudeEnv(mode)
|
|
3507
|
+
buildClaudeEnv(mode),
|
|
3508
|
+
execution.prompt
|
|
3481
3509
|
);
|
|
3482
3510
|
} catch (err) {
|
|
3483
3511
|
console.error(`[${config.name}] setup error for PR #${pr.number}: ${err}`);
|
|
@@ -4035,7 +4063,8 @@ function createScheduledWorker(config) {
|
|
|
4035
4063
|
}
|
|
4036
4064
|
},
|
|
4037
4065
|
cwd,
|
|
4038
|
-
buildClaudeEnv(mode)
|
|
4066
|
+
buildClaudeEnv(mode),
|
|
4067
|
+
execution.prompt
|
|
4039
4068
|
);
|
|
4040
4069
|
} catch (err) {
|
|
4041
4070
|
console.error(`[${config.name}] setup error: ${err}`);
|
|
@@ -4078,7 +4107,7 @@ var updateDesignMdWorker = createScheduledWorker({
|
|
|
4078
4107
|
init_table();
|
|
4079
4108
|
|
|
4080
4109
|
// src/commands/init.ts
|
|
4081
|
-
import { mkdir as mkdir2, writeFile as writeFile2, access } from "node:fs/promises";
|
|
4110
|
+
import { mkdir as mkdir2, writeFile as writeFile2, readFile as readFile2, access } from "node:fs/promises";
|
|
4082
4111
|
|
|
4083
4112
|
// src/commands/codegraph.ts
|
|
4084
4113
|
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
@@ -4166,6 +4195,101 @@ async function ensureCodegraphGitIgnore(logPrefix) {
|
|
|
4166
4195
|
}
|
|
4167
4196
|
}
|
|
4168
4197
|
|
|
4198
|
+
// src/commands/design-md.ts
|
|
4199
|
+
async function loadRunCommand2() {
|
|
4200
|
+
return await Promise.resolve().then(() => (init_run_command(), run_command_exports));
|
|
4201
|
+
}
|
|
4202
|
+
var DESIGN_MD_PACKAGE = "@google/design.md";
|
|
4203
|
+
async function installDesignMdCli(logPrefix) {
|
|
4204
|
+
console.log(`[${logPrefix}] Installing DESIGN.md CLI (npm install -g ${DESIGN_MD_PACKAGE}@latest)...`);
|
|
4205
|
+
try {
|
|
4206
|
+
const { runCommand: runCommand2 } = await loadRunCommand2();
|
|
4207
|
+
await runCommand2("npm", ["install", "-g", `${DESIGN_MD_PACKAGE}@latest`]);
|
|
4208
|
+
console.log(`[${logPrefix}] DESIGN.md CLI installed.`);
|
|
4209
|
+
return true;
|
|
4210
|
+
} catch (err) {
|
|
4211
|
+
console.error(`[${logPrefix}] Failed to install DESIGN.md CLI: ${err.message}`);
|
|
4212
|
+
return false;
|
|
4213
|
+
}
|
|
4214
|
+
}
|
|
4215
|
+
|
|
4216
|
+
// src/commands/pen.ts
|
|
4217
|
+
async function loadRunCommand3() {
|
|
4218
|
+
return await Promise.resolve().then(() => (init_run_command(), run_command_exports));
|
|
4219
|
+
}
|
|
4220
|
+
var PEN_PACKAGE = "@pen.dev/cli";
|
|
4221
|
+
var LEGACY_PEN_PACKAGE = "@pencil.dev/cli";
|
|
4222
|
+
async function installPenCli(logPrefix) {
|
|
4223
|
+
console.log(`[${logPrefix}] Removing legacy Pen CLI (npm uninstall -g ${LEGACY_PEN_PACKAGE})...`);
|
|
4224
|
+
const { runCommand: runCommand2 } = await loadRunCommand3();
|
|
4225
|
+
try {
|
|
4226
|
+
await runCommand2("npm", ["uninstall", "-g", LEGACY_PEN_PACKAGE]);
|
|
4227
|
+
} catch (err) {
|
|
4228
|
+
console.error(`[${logPrefix}] Skipped removing legacy Pen CLI: ${err.message}`);
|
|
4229
|
+
}
|
|
4230
|
+
console.log(`[${logPrefix}] Installing Pen CLI (npm install -g ${PEN_PACKAGE}@latest)...`);
|
|
4231
|
+
try {
|
|
4232
|
+
await runCommand2("npm", ["install", "-g", `${PEN_PACKAGE}@latest`]);
|
|
4233
|
+
console.log(`[${logPrefix}] Pen CLI installed.`);
|
|
4234
|
+
return true;
|
|
4235
|
+
} catch (err) {
|
|
4236
|
+
console.error(`[${logPrefix}] Failed to install Pen CLI: ${err.message}`);
|
|
4237
|
+
return false;
|
|
4238
|
+
}
|
|
4239
|
+
}
|
|
4240
|
+
|
|
4241
|
+
// src/commands/install.ts
|
|
4242
|
+
init_run_command();
|
|
4243
|
+
var PLUGIN_NAME = "claude-task-worker";
|
|
4244
|
+
var MARKETPLACE_NAME = "claude-task-worker";
|
|
4245
|
+
var MARKETPLACE_SOURCE = "getty104/claude-task-worker";
|
|
4246
|
+
async function addMarketplace() {
|
|
4247
|
+
console.log(`[install] Adding marketplace: ${MARKETPLACE_SOURCE}...`);
|
|
4248
|
+
try {
|
|
4249
|
+
await runCommand("claude", ["plugin", "marketplace", "add", MARKETPLACE_SOURCE]);
|
|
4250
|
+
console.log("[install] Marketplace added.");
|
|
4251
|
+
} catch (err) {
|
|
4252
|
+
console.error(
|
|
4253
|
+
`[install] Failed to add marketplace (already added is expected and safe to ignore): ${err.message}`
|
|
4254
|
+
);
|
|
4255
|
+
}
|
|
4256
|
+
}
|
|
4257
|
+
async function installPlugin() {
|
|
4258
|
+
console.log(`[install] Installing plugin: ${PLUGIN_NAME}@${MARKETPLACE_NAME}...`);
|
|
4259
|
+
try {
|
|
4260
|
+
await runCommand("claude", ["plugin", "install", `${PLUGIN_NAME}@${MARKETPLACE_NAME}`]);
|
|
4261
|
+
console.log("[install] Plugin installed. Restart your Claude Code session to apply.");
|
|
4262
|
+
return true;
|
|
4263
|
+
} catch (err) {
|
|
4264
|
+
console.error(`[install] Failed to install plugin: ${err.message}`);
|
|
4265
|
+
return false;
|
|
4266
|
+
}
|
|
4267
|
+
}
|
|
4268
|
+
async function installCli() {
|
|
4269
|
+
console.log("[install] Installing claude-task-worker CLI (npm install -g claude-task-worker@latest)...");
|
|
4270
|
+
try {
|
|
4271
|
+
await runCommand("npm", ["install", "-g", "claude-task-worker@latest"]);
|
|
4272
|
+
console.log("[install] claude-task-worker CLI installed.");
|
|
4273
|
+
return true;
|
|
4274
|
+
} catch (err) {
|
|
4275
|
+
console.error(`[install] Failed to install claude-task-worker CLI: ${err.message}`);
|
|
4276
|
+
return false;
|
|
4277
|
+
}
|
|
4278
|
+
}
|
|
4279
|
+
async function install() {
|
|
4280
|
+
console.log("[install] Starting install...");
|
|
4281
|
+
await addMarketplace();
|
|
4282
|
+
const pluginOk = await installPlugin();
|
|
4283
|
+
const cliOk = await installCli();
|
|
4284
|
+
const codegraphOk = await installCodegraphCli("install");
|
|
4285
|
+
const designMdOk = await installDesignMdCli("install");
|
|
4286
|
+
const penOk = await installPenCli("install");
|
|
4287
|
+
if (!pluginOk || !cliOk || !codegraphOk || !designMdOk || !penOk) {
|
|
4288
|
+
process.exitCode = 1;
|
|
4289
|
+
}
|
|
4290
|
+
console.log("[install] Done.");
|
|
4291
|
+
}
|
|
4292
|
+
|
|
4169
4293
|
// src/commands/init.ts
|
|
4170
4294
|
var LABELS = [
|
|
4171
4295
|
{ name: "cc-need-human-check", color: "eb1700" },
|
|
@@ -4265,6 +4389,45 @@ async function createConfig(force) {
|
|
|
4265
4389
|
const result = await writeFileWithMode(CONFIG_PATH, JSON.stringify(initialConfig, null, 2), force);
|
|
4266
4390
|
logWriteResult(result, CONFIG_PATH);
|
|
4267
4391
|
}
|
|
4392
|
+
var PROJECT_SETTINGS_PATH = ".claude/settings.json";
|
|
4393
|
+
function mergePluginSettings(current) {
|
|
4394
|
+
const marketplaces = { ...current.extraKnownMarketplaces ?? {} };
|
|
4395
|
+
marketplaces[MARKETPLACE_NAME] = { source: { source: "github", repo: MARKETPLACE_SOURCE } };
|
|
4396
|
+
const plugins = { ...current.enabledPlugins ?? {} };
|
|
4397
|
+
plugins[`${PLUGIN_NAME}@${MARKETPLACE_NAME}`] = true;
|
|
4398
|
+
return { ...current, extraKnownMarketplaces: marketplaces, enabledPlugins: plugins };
|
|
4399
|
+
}
|
|
4400
|
+
async function registerPluginInSettings() {
|
|
4401
|
+
let current = {};
|
|
4402
|
+
try {
|
|
4403
|
+
const raw = await readFile2(PROJECT_SETTINGS_PATH, "utf-8");
|
|
4404
|
+
const parsed = JSON.parse(raw);
|
|
4405
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
4406
|
+
console.log(`[init] Skipped: ${PROJECT_SETTINGS_PATH} is not a JSON object`);
|
|
4407
|
+
return;
|
|
4408
|
+
}
|
|
4409
|
+
current = parsed;
|
|
4410
|
+
} catch (err) {
|
|
4411
|
+
if (err.code !== "ENOENT") {
|
|
4412
|
+
console.log(`[init] Skipped: failed to read ${PROJECT_SETTINGS_PATH}: ${err.message}`);
|
|
4413
|
+
return;
|
|
4414
|
+
}
|
|
4415
|
+
}
|
|
4416
|
+
const merged = mergePluginSettings(current);
|
|
4417
|
+
if (JSON.stringify(merged) === JSON.stringify(current)) {
|
|
4418
|
+
console.log(`[init] Already registered: ${PLUGIN_NAME}@${MARKETPLACE_NAME} in ${PROJECT_SETTINGS_PATH}`);
|
|
4419
|
+
return;
|
|
4420
|
+
}
|
|
4421
|
+
try {
|
|
4422
|
+
await mkdir2(".claude", { recursive: true });
|
|
4423
|
+
await writeFile2(PROJECT_SETTINGS_PATH, `${JSON.stringify(merged, null, 2)}
|
|
4424
|
+
`, "utf-8");
|
|
4425
|
+
} catch (err) {
|
|
4426
|
+
console.log(`[init] Skipped: failed to write ${PROJECT_SETTINGS_PATH}: ${err.message}`);
|
|
4427
|
+
return;
|
|
4428
|
+
}
|
|
4429
|
+
console.log(`[init] Registered ${PLUGIN_NAME}@${MARKETPLACE_NAME} in ${PROJECT_SETTINGS_PATH}`);
|
|
4430
|
+
}
|
|
4268
4431
|
async function init(options = {}) {
|
|
4269
4432
|
const force = options.force ?? false;
|
|
4270
4433
|
console.log(`[init] Creating labels...${force ? " (force mode)" : ""}`);
|
|
@@ -4284,6 +4447,8 @@ async function init(options = {}) {
|
|
|
4284
4447
|
await mkdir2(".github/workflows", { recursive: true });
|
|
4285
4448
|
const workflowPath = ".github/workflows/assign-creator-on-cc-triage-scope.yml";
|
|
4286
4449
|
logWriteResult(await writeFileWithMode(workflowPath, ASSIGN_CREATOR_WORKFLOW, force), workflowPath);
|
|
4450
|
+
console.log("[init] Registering the plugin in project settings...");
|
|
4451
|
+
await registerPluginInSettings();
|
|
4287
4452
|
console.log("[init] Creating config file...");
|
|
4288
4453
|
await createConfig(force);
|
|
4289
4454
|
console.log("[init] Setting up CodeGraph...");
|
|
@@ -4292,75 +4457,6 @@ async function init(options = {}) {
|
|
|
4292
4457
|
console.log("[init] Done.");
|
|
4293
4458
|
}
|
|
4294
4459
|
|
|
4295
|
-
// src/commands/design-md.ts
|
|
4296
|
-
async function loadRunCommand2() {
|
|
4297
|
-
return await Promise.resolve().then(() => (init_run_command(), run_command_exports));
|
|
4298
|
-
}
|
|
4299
|
-
var DESIGN_MD_PACKAGE = "@google/design.md";
|
|
4300
|
-
async function installDesignMdCli(logPrefix) {
|
|
4301
|
-
console.log(`[${logPrefix}] Installing DESIGN.md CLI (npm install -g ${DESIGN_MD_PACKAGE}@latest)...`);
|
|
4302
|
-
try {
|
|
4303
|
-
const { runCommand: runCommand2 } = await loadRunCommand2();
|
|
4304
|
-
await runCommand2("npm", ["install", "-g", `${DESIGN_MD_PACKAGE}@latest`]);
|
|
4305
|
-
console.log(`[${logPrefix}] DESIGN.md CLI installed.`);
|
|
4306
|
-
return true;
|
|
4307
|
-
} catch (err) {
|
|
4308
|
-
console.error(`[${logPrefix}] Failed to install DESIGN.md CLI: ${err.message}`);
|
|
4309
|
-
return false;
|
|
4310
|
-
}
|
|
4311
|
-
}
|
|
4312
|
-
|
|
4313
|
-
// src/commands/install.ts
|
|
4314
|
-
init_run_command();
|
|
4315
|
-
var PLUGIN_NAME = "claude-task-worker";
|
|
4316
|
-
var MARKETPLACE_NAME = "claude-task-worker";
|
|
4317
|
-
var MARKETPLACE_SOURCE = "getty104/claude-task-worker";
|
|
4318
|
-
async function addMarketplace() {
|
|
4319
|
-
console.log(`[install] Adding marketplace: ${MARKETPLACE_SOURCE}...`);
|
|
4320
|
-
try {
|
|
4321
|
-
await runCommand("claude", ["plugin", "marketplace", "add", MARKETPLACE_SOURCE]);
|
|
4322
|
-
console.log("[install] Marketplace added.");
|
|
4323
|
-
} catch (err) {
|
|
4324
|
-
console.error(
|
|
4325
|
-
`[install] Failed to add marketplace (already added is expected and safe to ignore): ${err.message}`
|
|
4326
|
-
);
|
|
4327
|
-
}
|
|
4328
|
-
}
|
|
4329
|
-
async function installPlugin() {
|
|
4330
|
-
console.log(`[install] Installing plugin: ${PLUGIN_NAME}@${MARKETPLACE_NAME}...`);
|
|
4331
|
-
try {
|
|
4332
|
-
await runCommand("claude", ["plugin", "install", `${PLUGIN_NAME}@${MARKETPLACE_NAME}`]);
|
|
4333
|
-
console.log("[install] Plugin installed. Restart your Claude Code session to apply.");
|
|
4334
|
-
return true;
|
|
4335
|
-
} catch (err) {
|
|
4336
|
-
console.error(`[install] Failed to install plugin: ${err.message}`);
|
|
4337
|
-
return false;
|
|
4338
|
-
}
|
|
4339
|
-
}
|
|
4340
|
-
async function installCli() {
|
|
4341
|
-
console.log("[install] Installing claude-task-worker CLI (npm install -g claude-task-worker@latest)...");
|
|
4342
|
-
try {
|
|
4343
|
-
await runCommand("npm", ["install", "-g", "claude-task-worker@latest"]);
|
|
4344
|
-
console.log("[install] claude-task-worker CLI installed.");
|
|
4345
|
-
return true;
|
|
4346
|
-
} catch (err) {
|
|
4347
|
-
console.error(`[install] Failed to install claude-task-worker CLI: ${err.message}`);
|
|
4348
|
-
return false;
|
|
4349
|
-
}
|
|
4350
|
-
}
|
|
4351
|
-
async function install() {
|
|
4352
|
-
console.log("[install] Starting install...");
|
|
4353
|
-
await addMarketplace();
|
|
4354
|
-
const pluginOk = await installPlugin();
|
|
4355
|
-
const cliOk = await installCli();
|
|
4356
|
-
const codegraphOk = await installCodegraphCli("install");
|
|
4357
|
-
const designMdOk = await installDesignMdCli("install");
|
|
4358
|
-
if (!pluginOk || !cliOk || !codegraphOk || !designMdOk) {
|
|
4359
|
-
process.exitCode = 1;
|
|
4360
|
-
}
|
|
4361
|
-
console.log("[install] Done.");
|
|
4362
|
-
}
|
|
4363
|
-
|
|
4364
4460
|
// src/commands/update.ts
|
|
4365
4461
|
init_run_command();
|
|
4366
4462
|
var PLUGIN_NAME2 = "claude-task-worker";
|
|
@@ -4405,7 +4501,8 @@ async function update() {
|
|
|
4405
4501
|
const cliOk = await updateCli();
|
|
4406
4502
|
const codegraphOk = await upgradeCodegraphCli("update");
|
|
4407
4503
|
const designMdOk = await installDesignMdCli("update");
|
|
4408
|
-
|
|
4504
|
+
const penOk = await installPenCli("update");
|
|
4505
|
+
if (!marketplaceOk || !pluginOk || !cliOk || !codegraphOk || !designMdOk || !penOk) {
|
|
4409
4506
|
process.exitCode = 1;
|
|
4410
4507
|
}
|
|
4411
4508
|
console.log("[update] Done.");
|
|
@@ -4427,8 +4524,34 @@ function version() {
|
|
|
4427
4524
|
}
|
|
4428
4525
|
}
|
|
4429
4526
|
|
|
4527
|
+
// src/commands/pencil.ts
|
|
4528
|
+
import { spawn as spawn3 } from "node:child_process";
|
|
4529
|
+
import { dirname as dirname4, join as join9 } from "node:path";
|
|
4530
|
+
import { fileURLToPath as fileURLToPath2, pathToFileURL } from "node:url";
|
|
4531
|
+
var HOOK_FILE = "pen-baseuri-fix.mjs";
|
|
4532
|
+
function buildPencilNodeOptions(existing, hookUrl) {
|
|
4533
|
+
return [`--import ${hookUrl}`, existing?.trim()].filter(Boolean).join(" ");
|
|
4534
|
+
}
|
|
4535
|
+
function pencil(args) {
|
|
4536
|
+
const hookPath = join9(dirname4(fileURLToPath2(import.meta.url)), HOOK_FILE);
|
|
4537
|
+
const child = spawn3("pencil", args, {
|
|
4538
|
+
stdio: "inherit",
|
|
4539
|
+
env: {
|
|
4540
|
+
...process.env,
|
|
4541
|
+
NODE_OPTIONS: buildPencilNodeOptions(process.env.NODE_OPTIONS, pathToFileURL(hookPath).href)
|
|
4542
|
+
}
|
|
4543
|
+
});
|
|
4544
|
+
child.on("error", (err) => {
|
|
4545
|
+
console.error(`[pencil] Failed to run pencil: ${err.message}`);
|
|
4546
|
+
process.exit(127);
|
|
4547
|
+
});
|
|
4548
|
+
child.on("exit", (code, signal) => {
|
|
4549
|
+
process.exit(signal ? 1 : code ?? 1);
|
|
4550
|
+
});
|
|
4551
|
+
}
|
|
4552
|
+
|
|
4430
4553
|
// src/dispatch-args.ts
|
|
4431
|
-
var PROJECT_INCOMPATIBLE_COMMANDS = ["init", "install", "update", "usage", "version"];
|
|
4554
|
+
var PROJECT_INCOMPATIBLE_COMMANDS = ["init", "install", "update", "usage", "version", "pencil"];
|
|
4432
4555
|
function collectFlagValues(argv, flag) {
|
|
4433
4556
|
const values = [];
|
|
4434
4557
|
for (let i = 0; i < argv.length; i++) {
|
|
@@ -4496,6 +4619,7 @@ Commands:
|
|
|
4496
4619
|
install Add the claude-task-worker marketplace, install the plugin, and install/update the CLI
|
|
4497
4620
|
update Update the claude-task-worker plugin/marketplace and the CLI itself
|
|
4498
4621
|
usage Notify current usage to Slack
|
|
4622
|
+
pencil <args...> Run the Pencil CLI with the asset base-URI fix loaded (passes every argument and stdin through)
|
|
4499
4623
|
version Print the installed claude-task-worker CLI version (aliases: --version, -v)
|
|
4500
4624
|
|
|
4501
4625
|
Workers:
|
|
@@ -4543,7 +4667,7 @@ if (!workerType) {
|
|
|
4543
4667
|
printUsage();
|
|
4544
4668
|
process.exit(1);
|
|
4545
4669
|
}
|
|
4546
|
-
if (workerType !== "all" && workerType !== "yolo" && workerType !== "init" && workerType !== "install" && workerType !== "update" && workerType !== "usage" && !WORKERS[workerType]) {
|
|
4670
|
+
if (workerType !== "all" && workerType !== "yolo" && workerType !== "init" && workerType !== "install" && workerType !== "update" && workerType !== "usage" && workerType !== "pencil" && !WORKERS[workerType]) {
|
|
4547
4671
|
console.error(`Unknown command: ${workerType}`);
|
|
4548
4672
|
printUsage();
|
|
4549
4673
|
process.exit(1);
|
|
@@ -4674,6 +4798,8 @@ if (hasProjectFilter()) {
|
|
|
4674
4798
|
(async () => {
|
|
4675
4799
|
await update();
|
|
4676
4800
|
})();
|
|
4801
|
+
} else if (workerType === "pencil") {
|
|
4802
|
+
pencil(process.argv.slice(3));
|
|
4677
4803
|
} else if (workerType === "usage") {
|
|
4678
4804
|
(async () => {
|
|
4679
4805
|
const text = await buildTokenLimitText();
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// src/pen-baseuri-fix.ts
|
|
2
|
+
import { registerHooks } from "node:module";
|
|
3
|
+
import { resolve } from "node:path";
|
|
4
|
+
var BASE_URI_GETTER = /\[(_0x[0-9a-f]+)\((0x[0-9a-f]+)\)\]\(\)\{return this\[\1\((0x[0-9a-f]+)\)\]\|\|this\[\1\((0x[0-9a-f]+)\)\];\}/;
|
|
5
|
+
var PEN_CLI_MODULE = /@pen\.dev\/cli\/dist\/[^/]*\.mjs$/;
|
|
6
|
+
var ABSOLUTE_URI = /^[a-zA-Z][a-zA-Z0-9+.-]*:\/\//;
|
|
7
|
+
function toAbsoluteUri(path) {
|
|
8
|
+
if (!path || ABSOLUTE_URI.test(path)) return path;
|
|
9
|
+
return `file://${resolve(path)}`;
|
|
10
|
+
}
|
|
11
|
+
globalThis.__penAbsURI = toAbsoluteUri;
|
|
12
|
+
registerHooks({
|
|
13
|
+
load(url, ctx, next) {
|
|
14
|
+
const loaded = next(url, ctx);
|
|
15
|
+
if (!PEN_CLI_MODULE.test(url) || !loaded.source) return loaded;
|
|
16
|
+
const source = String(loaded.source);
|
|
17
|
+
const match = BASE_URI_GETTER.exec(source);
|
|
18
|
+
if (!match) return loaded;
|
|
19
|
+
const [all, decode, methodKey, primaryKey, fallbackKey] = match;
|
|
20
|
+
return {
|
|
21
|
+
...loaded,
|
|
22
|
+
source: source.replace(
|
|
23
|
+
all,
|
|
24
|
+
`[${decode}(${methodKey})](){return globalThis.__penAbsURI(this[${decode}(${primaryKey})]||this[${decode}(${fallbackKey})]);}`
|
|
25
|
+
)
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
export {
|
|
30
|
+
toAbsoluteUri
|
|
31
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-task-worker",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.85.0",
|
|
4
4
|
"description": "CLI tool that polls GitHub Issues/PRs and delegates work to Claude CLI",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"claude-task-worker": "dist/index.js"
|
|
9
9
|
},
|
|
10
10
|
"scripts": {
|
|
11
|
-
"build": "tsc --noEmit && esbuild src/index.ts --bundle --platform=node --format=esm --outfile=dist/index.js",
|
|
11
|
+
"build": "tsc --noEmit && esbuild src/index.ts --bundle --platform=node --format=esm --outfile=dist/index.js && esbuild src/pen-baseuri-fix.ts --bundle --platform=node --format=esm --outfile=dist/pen-baseuri-fix.mjs",
|
|
12
12
|
"dev": "tsc --noEmit --watch",
|
|
13
13
|
"lint": "eslint .",
|
|
14
14
|
"lint:fix": "eslint . --fix",
|