claude-task-worker 0.84.0 → 0.86.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 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
- ...mode === "herdr" ? [] : ["-p"],
1879
- prompt,
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 { command: CLAUDE_COMMAND, args: buildClaudeArgs(invocation) };
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, {
@@ -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}`);
@@ -3488,7 +3504,8 @@ function createPrPollingWorker(config) {
3488
3504
  }
3489
3505
  },
3490
3506
  cwd,
3491
- buildClaudeEnv(mode)
3507
+ buildClaudeEnv(mode),
3508
+ execution.prompt
3492
3509
  );
3493
3510
  } catch (err) {
3494
3511
  console.error(`[${config.name}] setup error for PR #${pr.number}: ${err}`);
@@ -4046,7 +4063,8 @@ function createScheduledWorker(config) {
4046
4063
  }
4047
4064
  },
4048
4065
  cwd,
4049
- buildClaudeEnv(mode)
4066
+ buildClaudeEnv(mode),
4067
+ execution.prompt
4050
4068
  );
4051
4069
  } catch (err) {
4052
4070
  console.error(`[${config.name}] setup error: ${err}`);
@@ -4089,7 +4107,7 @@ var updateDesignMdWorker = createScheduledWorker({
4089
4107
  init_table();
4090
4108
 
4091
4109
  // src/commands/init.ts
4092
- 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";
4093
4111
 
4094
4112
  // src/commands/codegraph.ts
4095
4113
  import { mkdir, readFile, writeFile } from "node:fs/promises";
@@ -4177,6 +4195,111 @@ async function ensureCodegraphGitIgnore(logPrefix) {
4177
4195
  }
4178
4196
  }
4179
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
+ var GLOBAL_NPM_PACKAGES = [PLUGIN_NAME, CODEGRAPH_PACKAGE, DESIGN_MD_PACKAGE, PEN_PACKAGE];
4247
+ async function printGlobalPackageVersions(logPrefix) {
4248
+ console.log(`[${logPrefix}] Installed versions:`);
4249
+ try {
4250
+ await runCommand("npm", ["ls", "-g", "--depth=0", ...GLOBAL_NPM_PACKAGES]);
4251
+ } catch (err) {
4252
+ console.error(`[${logPrefix}] Some packages are missing from the global install: ${err.message}`);
4253
+ }
4254
+ }
4255
+ async function addMarketplace() {
4256
+ console.log(`[install] Adding marketplace: ${MARKETPLACE_SOURCE}...`);
4257
+ try {
4258
+ await runCommand("claude", ["plugin", "marketplace", "add", MARKETPLACE_SOURCE]);
4259
+ console.log("[install] Marketplace added.");
4260
+ } catch (err) {
4261
+ console.error(
4262
+ `[install] Failed to add marketplace (already added is expected and safe to ignore): ${err.message}`
4263
+ );
4264
+ }
4265
+ }
4266
+ async function installPlugin() {
4267
+ console.log(`[install] Installing plugin: ${PLUGIN_NAME}@${MARKETPLACE_NAME}...`);
4268
+ try {
4269
+ await runCommand("claude", ["plugin", "install", `${PLUGIN_NAME}@${MARKETPLACE_NAME}`]);
4270
+ console.log("[install] Plugin installed. Restart your Claude Code session to apply.");
4271
+ return true;
4272
+ } catch (err) {
4273
+ console.error(`[install] Failed to install plugin: ${err.message}`);
4274
+ return false;
4275
+ }
4276
+ }
4277
+ async function installCli() {
4278
+ console.log("[install] Installing claude-task-worker CLI (npm install -g claude-task-worker@latest)...");
4279
+ try {
4280
+ await runCommand("npm", ["install", "-g", "claude-task-worker@latest"]);
4281
+ console.log("[install] claude-task-worker CLI installed.");
4282
+ return true;
4283
+ } catch (err) {
4284
+ console.error(`[install] Failed to install claude-task-worker CLI: ${err.message}`);
4285
+ return false;
4286
+ }
4287
+ }
4288
+ async function install() {
4289
+ console.log("[install] Starting install...");
4290
+ await addMarketplace();
4291
+ const pluginOk = await installPlugin();
4292
+ const cliOk = await installCli();
4293
+ const codegraphOk = await installCodegraphCli("install");
4294
+ const designMdOk = await installDesignMdCli("install");
4295
+ const penOk = await installPenCli("install");
4296
+ await printGlobalPackageVersions("install");
4297
+ if (!pluginOk || !cliOk || !codegraphOk || !designMdOk || !penOk) {
4298
+ process.exitCode = 1;
4299
+ }
4300
+ console.log("[install] Done.");
4301
+ }
4302
+
4180
4303
  // src/commands/init.ts
4181
4304
  var LABELS = [
4182
4305
  { name: "cc-need-human-check", color: "eb1700" },
@@ -4276,6 +4399,45 @@ async function createConfig(force) {
4276
4399
  const result = await writeFileWithMode(CONFIG_PATH, JSON.stringify(initialConfig, null, 2), force);
4277
4400
  logWriteResult(result, CONFIG_PATH);
4278
4401
  }
4402
+ var PROJECT_SETTINGS_PATH = ".claude/settings.json";
4403
+ function mergePluginSettings(current) {
4404
+ const marketplaces = { ...current.extraKnownMarketplaces ?? {} };
4405
+ marketplaces[MARKETPLACE_NAME] = { source: { source: "github", repo: MARKETPLACE_SOURCE } };
4406
+ const plugins = { ...current.enabledPlugins ?? {} };
4407
+ plugins[`${PLUGIN_NAME}@${MARKETPLACE_NAME}`] = true;
4408
+ return { ...current, extraKnownMarketplaces: marketplaces, enabledPlugins: plugins };
4409
+ }
4410
+ async function registerPluginInSettings() {
4411
+ let current = {};
4412
+ try {
4413
+ const raw = await readFile2(PROJECT_SETTINGS_PATH, "utf-8");
4414
+ const parsed = JSON.parse(raw);
4415
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
4416
+ console.log(`[init] Skipped: ${PROJECT_SETTINGS_PATH} is not a JSON object`);
4417
+ return;
4418
+ }
4419
+ current = parsed;
4420
+ } catch (err) {
4421
+ if (err.code !== "ENOENT") {
4422
+ console.log(`[init] Skipped: failed to read ${PROJECT_SETTINGS_PATH}: ${err.message}`);
4423
+ return;
4424
+ }
4425
+ }
4426
+ const merged = mergePluginSettings(current);
4427
+ if (JSON.stringify(merged) === JSON.stringify(current)) {
4428
+ console.log(`[init] Already registered: ${PLUGIN_NAME}@${MARKETPLACE_NAME} in ${PROJECT_SETTINGS_PATH}`);
4429
+ return;
4430
+ }
4431
+ try {
4432
+ await mkdir2(".claude", { recursive: true });
4433
+ await writeFile2(PROJECT_SETTINGS_PATH, `${JSON.stringify(merged, null, 2)}
4434
+ `, "utf-8");
4435
+ } catch (err) {
4436
+ console.log(`[init] Skipped: failed to write ${PROJECT_SETTINGS_PATH}: ${err.message}`);
4437
+ return;
4438
+ }
4439
+ console.log(`[init] Registered ${PLUGIN_NAME}@${MARKETPLACE_NAME} in ${PROJECT_SETTINGS_PATH}`);
4440
+ }
4279
4441
  async function init(options = {}) {
4280
4442
  const force = options.force ?? false;
4281
4443
  console.log(`[init] Creating labels...${force ? " (force mode)" : ""}`);
@@ -4295,6 +4457,8 @@ async function init(options = {}) {
4295
4457
  await mkdir2(".github/workflows", { recursive: true });
4296
4458
  const workflowPath = ".github/workflows/assign-creator-on-cc-triage-scope.yml";
4297
4459
  logWriteResult(await writeFileWithMode(workflowPath, ASSIGN_CREATOR_WORKFLOW, force), workflowPath);
4460
+ console.log("[init] Registering the plugin in project settings...");
4461
+ await registerPluginInSettings();
4298
4462
  console.log("[init] Creating config file...");
4299
4463
  await createConfig(force);
4300
4464
  console.log("[init] Setting up CodeGraph...");
@@ -4303,75 +4467,6 @@ async function init(options = {}) {
4303
4467
  console.log("[init] Done.");
4304
4468
  }
4305
4469
 
4306
- // src/commands/design-md.ts
4307
- async function loadRunCommand2() {
4308
- return await Promise.resolve().then(() => (init_run_command(), run_command_exports));
4309
- }
4310
- var DESIGN_MD_PACKAGE = "@google/design.md";
4311
- async function installDesignMdCli(logPrefix) {
4312
- console.log(`[${logPrefix}] Installing DESIGN.md CLI (npm install -g ${DESIGN_MD_PACKAGE}@latest)...`);
4313
- try {
4314
- const { runCommand: runCommand2 } = await loadRunCommand2();
4315
- await runCommand2("npm", ["install", "-g", `${DESIGN_MD_PACKAGE}@latest`]);
4316
- console.log(`[${logPrefix}] DESIGN.md CLI installed.`);
4317
- return true;
4318
- } catch (err) {
4319
- console.error(`[${logPrefix}] Failed to install DESIGN.md CLI: ${err.message}`);
4320
- return false;
4321
- }
4322
- }
4323
-
4324
- // src/commands/install.ts
4325
- init_run_command();
4326
- var PLUGIN_NAME = "claude-task-worker";
4327
- var MARKETPLACE_NAME = "claude-task-worker";
4328
- var MARKETPLACE_SOURCE = "getty104/claude-task-worker";
4329
- async function addMarketplace() {
4330
- console.log(`[install] Adding marketplace: ${MARKETPLACE_SOURCE}...`);
4331
- try {
4332
- await runCommand("claude", ["plugin", "marketplace", "add", MARKETPLACE_SOURCE]);
4333
- console.log("[install] Marketplace added.");
4334
- } catch (err) {
4335
- console.error(
4336
- `[install] Failed to add marketplace (already added is expected and safe to ignore): ${err.message}`
4337
- );
4338
- }
4339
- }
4340
- async function installPlugin() {
4341
- console.log(`[install] Installing plugin: ${PLUGIN_NAME}@${MARKETPLACE_NAME}...`);
4342
- try {
4343
- await runCommand("claude", ["plugin", "install", `${PLUGIN_NAME}@${MARKETPLACE_NAME}`]);
4344
- console.log("[install] Plugin installed. Restart your Claude Code session to apply.");
4345
- return true;
4346
- } catch (err) {
4347
- console.error(`[install] Failed to install plugin: ${err.message}`);
4348
- return false;
4349
- }
4350
- }
4351
- async function installCli() {
4352
- console.log("[install] Installing claude-task-worker CLI (npm install -g claude-task-worker@latest)...");
4353
- try {
4354
- await runCommand("npm", ["install", "-g", "claude-task-worker@latest"]);
4355
- console.log("[install] claude-task-worker CLI installed.");
4356
- return true;
4357
- } catch (err) {
4358
- console.error(`[install] Failed to install claude-task-worker CLI: ${err.message}`);
4359
- return false;
4360
- }
4361
- }
4362
- async function install() {
4363
- console.log("[install] Starting install...");
4364
- await addMarketplace();
4365
- const pluginOk = await installPlugin();
4366
- const cliOk = await installCli();
4367
- const codegraphOk = await installCodegraphCli("install");
4368
- const designMdOk = await installDesignMdCli("install");
4369
- if (!pluginOk || !cliOk || !codegraphOk || !designMdOk) {
4370
- process.exitCode = 1;
4371
- }
4372
- console.log("[install] Done.");
4373
- }
4374
-
4375
4470
  // src/commands/update.ts
4376
4471
  init_run_command();
4377
4472
  var PLUGIN_NAME2 = "claude-task-worker";
@@ -4416,7 +4511,9 @@ async function update() {
4416
4511
  const cliOk = await updateCli();
4417
4512
  const codegraphOk = await upgradeCodegraphCli("update");
4418
4513
  const designMdOk = await installDesignMdCli("update");
4419
- if (!marketplaceOk || !pluginOk || !cliOk || !codegraphOk || !designMdOk) {
4514
+ const penOk = await installPenCli("update");
4515
+ await printGlobalPackageVersions("update");
4516
+ if (!marketplaceOk || !pluginOk || !cliOk || !codegraphOk || !designMdOk || !penOk) {
4420
4517
  process.exitCode = 1;
4421
4518
  }
4422
4519
  console.log("[update] Done.");
@@ -4438,8 +4535,34 @@ function version() {
4438
4535
  }
4439
4536
  }
4440
4537
 
4538
+ // src/commands/pencil.ts
4539
+ import { spawn as spawn3 } from "node:child_process";
4540
+ import { dirname as dirname4, join as join9 } from "node:path";
4541
+ import { fileURLToPath as fileURLToPath2, pathToFileURL } from "node:url";
4542
+ var HOOK_FILE = "pen-baseuri-fix.mjs";
4543
+ function buildPencilNodeOptions(existing, hookUrl) {
4544
+ return [`--import ${hookUrl}`, existing?.trim()].filter(Boolean).join(" ");
4545
+ }
4546
+ function pencil(args) {
4547
+ const hookPath = join9(dirname4(fileURLToPath2(import.meta.url)), HOOK_FILE);
4548
+ const child = spawn3("pencil", args, {
4549
+ stdio: "inherit",
4550
+ env: {
4551
+ ...process.env,
4552
+ NODE_OPTIONS: buildPencilNodeOptions(process.env.NODE_OPTIONS, pathToFileURL(hookPath).href)
4553
+ }
4554
+ });
4555
+ child.on("error", (err) => {
4556
+ console.error(`[pencil] Failed to run pencil: ${err.message}`);
4557
+ process.exit(127);
4558
+ });
4559
+ child.on("exit", (code, signal) => {
4560
+ process.exit(signal ? 1 : code ?? 1);
4561
+ });
4562
+ }
4563
+
4441
4564
  // src/dispatch-args.ts
4442
- var PROJECT_INCOMPATIBLE_COMMANDS = ["init", "install", "update", "usage", "version"];
4565
+ var PROJECT_INCOMPATIBLE_COMMANDS = ["init", "install", "update", "usage", "version", "pencil"];
4443
4566
  function collectFlagValues(argv, flag) {
4444
4567
  const values = [];
4445
4568
  for (let i = 0; i < argv.length; i++) {
@@ -4507,6 +4630,7 @@ Commands:
4507
4630
  install Add the claude-task-worker marketplace, install the plugin, and install/update the CLI
4508
4631
  update Update the claude-task-worker plugin/marketplace and the CLI itself
4509
4632
  usage Notify current usage to Slack
4633
+ pencil <args...> Run the Pencil CLI with the asset base-URI fix loaded (passes every argument and stdin through)
4510
4634
  version Print the installed claude-task-worker CLI version (aliases: --version, -v)
4511
4635
 
4512
4636
  Workers:
@@ -4554,7 +4678,7 @@ if (!workerType) {
4554
4678
  printUsage();
4555
4679
  process.exit(1);
4556
4680
  }
4557
- if (workerType !== "all" && workerType !== "yolo" && workerType !== "init" && workerType !== "install" && workerType !== "update" && workerType !== "usage" && !WORKERS[workerType]) {
4681
+ if (workerType !== "all" && workerType !== "yolo" && workerType !== "init" && workerType !== "install" && workerType !== "update" && workerType !== "usage" && workerType !== "pencil" && !WORKERS[workerType]) {
4558
4682
  console.error(`Unknown command: ${workerType}`);
4559
4683
  printUsage();
4560
4684
  process.exit(1);
@@ -4685,6 +4809,8 @@ if (hasProjectFilter()) {
4685
4809
  (async () => {
4686
4810
  await update();
4687
4811
  })();
4812
+ } else if (workerType === "pencil") {
4813
+ pencil(process.argv.slice(3));
4688
4814
  } else if (workerType === "usage") {
4689
4815
  (async () => {
4690
4816
  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.84.0",
3
+ "version": "0.86.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",