claude-task-worker 0.142.3 → 0.142.4

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.
@@ -2140,9 +2140,9 @@ function generateWorktreeName() {
2140
2140
  }
2141
2141
 
2142
2142
  // src/slack.ts
2143
- import { exec } from "node:child_process";
2143
+ import { exec, execFile as execFile2 } from "node:child_process";
2144
2144
  import { readFileSync as readFileSync2, renameSync as renameSync3, writeFileSync as writeFileSync4 } from "node:fs";
2145
- import { homedir as homedir3 } from "node:os";
2145
+ import { homedir as homedir3, tmpdir } from "node:os";
2146
2146
  import { join as join3 } from "node:path";
2147
2147
  import { promisify as promisify2 } from "node:util";
2148
2148
 
@@ -2233,6 +2233,7 @@ function writeRuncatUsage(usage, outFile = RUNCAT_OUT_FILE) {
2233
2233
 
2234
2234
  // src/slack.ts
2235
2235
  var execAsync = promisify2(exec);
2236
+ var execFileAsync2 = promisify2(execFile2);
2236
2237
  var WEBHOOK_URL = process.env.CLAUDE_TASK_WORKER_SLACK_WEBHOOK_URL;
2237
2238
  var USAGE_POLL_INTERVAL_SECONDS = 600;
2238
2239
  var USAGE_BACKOFF_PATH = "/tmp/claude-usage-backoff.json";
@@ -2324,16 +2325,21 @@ async function fetchUsageInfo() {
2324
2325
  const cached = readUsageCache();
2325
2326
  if (cached) return cached;
2326
2327
  try {
2327
- const { token, expiresAt } = await getStoredCredential();
2328
+ let { token, expiresAt } = await getStoredCredential();
2328
2329
  if (!token) {
2329
2330
  console.error("[slack] No OAuth token found (sign in to Claude Code)");
2330
2331
  return null;
2331
2332
  }
2332
- if (expiresAt !== void 0 && expiresAt <= Date.now()) {
2333
+ if (isExpired(expiresAt)) {
2333
2334
  console.error(
2334
- `[slack] OAuth token expired at ${new Date(expiresAt).toISOString()} (it is refreshed when claude runs)`
2335
+ `[slack] OAuth token expired at ${new Date(expiresAt).toISOString()}; running claude to refresh it`
2335
2336
  );
2336
- return null;
2337
+ await refreshTokenByRunningClaude();
2338
+ ({ token, expiresAt } = await getStoredCredential());
2339
+ if (!token || isExpired(expiresAt)) {
2340
+ console.error("[slack] OAuth token is still expired after running claude");
2341
+ return null;
2342
+ }
2337
2343
  }
2338
2344
  const usage = await handleUsageResponse(await requestUsage(token));
2339
2345
  if (usage) writeUsageCache(usage);
@@ -2343,6 +2349,17 @@ async function fetchUsageInfo() {
2343
2349
  return null;
2344
2350
  }
2345
2351
  }
2352
+ function isExpired(expiresAt) {
2353
+ return expiresAt !== void 0 && expiresAt <= Date.now();
2354
+ }
2355
+ async function refreshTokenByRunningClaude() {
2356
+ const { CLAUDE_CODE_OAUTH_TOKEN: _ignored, ...env } = process.env;
2357
+ try {
2358
+ await execFileAsync2("claude", ["-p", "/exit"], { cwd: tmpdir(), env, timeout: 12e4 });
2359
+ } catch (err) {
2360
+ console.error(`[slack] Failed to run claude for token refresh: ${err}`);
2361
+ }
2362
+ }
2346
2363
  function requestUsage(token) {
2347
2364
  return fetch("https://api.anthropic.com/api/oauth/usage", {
2348
2365
  headers: {
@@ -2464,7 +2481,7 @@ import { promisify as promisify3 } from "node:util";
2464
2481
  import { rm, stat } from "node:fs/promises";
2465
2482
  import { basename as basename2, resolve as resolve2, sep } from "node:path";
2466
2483
  var childProcess2 = createRequire2(import.meta.url)("node:child_process");
2467
- var execFileAsync2 = (command, args) => promisify3(childProcess2.execFile)(command, args);
2484
+ var execFileAsync3 = (command, args) => promisify3(childProcess2.execFile)(command, args);
2468
2485
  var WORKTREES_DIR = ".claude/worktrees";
2469
2486
  function isManagedWorktreePath(path2) {
2470
2487
  return resolve2(path2).startsWith(resolve2(WORKTREES_DIR) + sep);
@@ -2491,7 +2508,7 @@ async function forceRemoveIfExists(path2) {
2491
2508
  }
2492
2509
  }
2493
2510
  async function listWorktreeEntries() {
2494
- const { stdout } = await execFileAsync2("git", ["worktree", "list", "--porcelain"]);
2511
+ const { stdout } = await execFileAsync3("git", ["worktree", "list", "--porcelain"]);
2495
2512
  return stdout.replace(/\r\n/g, "\n").trim().split("\n\n").filter(Boolean).map((entry) => {
2496
2513
  const lines = entry.split("\n");
2497
2514
  const worktreeLine = lines.find((l) => l.startsWith("worktree "));
@@ -2505,7 +2522,7 @@ async function listWorktreeEntries() {
2505
2522
  }
2506
2523
  async function removeRegisteredWorktree(worktreePath) {
2507
2524
  try {
2508
- await execFileAsync2("git", ["worktree", "remove", "--force", "--force", worktreePath]);
2525
+ await execFileAsync3("git", ["worktree", "remove", "--force", "--force", worktreePath]);
2509
2526
  } catch (error) {
2510
2527
  console.error(`[worktree] Failed to remove worktree ${worktreePath}:`, error);
2511
2528
  }
@@ -2514,7 +2531,7 @@ async function removeRegisteredWorktree(worktreePath) {
2514
2531
  var PROTECTED_BRANCHES = /* @__PURE__ */ new Set(["main", "master", "develop"]);
2515
2532
  async function getDefaultBranchName() {
2516
2533
  try {
2517
- const { stdout } = await execFileAsync2("git", ["symbolic-ref", "--short", "refs/remotes/origin/HEAD"]);
2534
+ const { stdout } = await execFileAsync3("git", ["symbolic-ref", "--short", "refs/remotes/origin/HEAD"]);
2518
2535
  return stdout.trim().replace(/^origin\//, "");
2519
2536
  } catch {
2520
2537
  return void 0;
@@ -2527,7 +2544,7 @@ async function deleteLocalBranch(branchName) {
2527
2544
  return;
2528
2545
  }
2529
2546
  try {
2530
- await execFileAsync2("git", ["branch", "-D", branchName]);
2547
+ await execFileAsync3("git", ["branch", "-D", branchName]);
2531
2548
  console.log(`[worktree] Deleted local branch: ${branchName}`);
2532
2549
  } catch (error) {
2533
2550
  const stderr = String(error?.stderr ?? "");
@@ -2537,7 +2554,7 @@ async function deleteLocalBranch(branchName) {
2537
2554
  }
2538
2555
  async function localBranchExists(branchName) {
2539
2556
  try {
2540
- await execFileAsync2("git", ["rev-parse", "--verify", "--quiet", `refs/heads/${branchName}`]);
2557
+ await execFileAsync3("git", ["rev-parse", "--verify", "--quiet", `refs/heads/${branchName}`]);
2541
2558
  return true;
2542
2559
  } catch {
2543
2560
  return false;
@@ -2555,7 +2572,7 @@ function createWorktreeFromBranch(worktreeId, baseBranch) {
2555
2572
  }
2556
2573
  async function addWorktree(worktreeId, baseBranch) {
2557
2574
  const worktreePath = getWorktreePath(worktreeId);
2558
- await execFileAsync2("git", ["worktree", "add", "--track", "-B", worktreeId, worktreePath, `origin/${baseBranch}`]);
2575
+ await execFileAsync3("git", ["worktree", "add", "--track", "-B", worktreeId, worktreePath, `origin/${baseBranch}`]);
2559
2576
  }
2560
2577
  async function removeWorktree(worktreeId) {
2561
2578
  const worktreePath = getWorktreePath(worktreeId);
@@ -3001,7 +3018,7 @@ function createPrPollingWorker(config) {
3001
3018
  import { createRequire as createRequire3 } from "node:module";
3002
3019
  import { promisify as promisify4 } from "node:util";
3003
3020
  var childProcess3 = createRequire3(import.meta.url)("node:child_process");
3004
- var execFileAsync3 = (command, args) => promisify4(childProcess3.execFile)(command, args);
3021
+ var execFileAsync4 = (command, args) => promisify4(childProcess3.execFile)(command, args);
3005
3022
  var CONFIG_FILE = "claude-task-worker.json";
3006
3023
  var LABEL_TRIAGE_SCOPE2 = "cc-triage-scope";
3007
3024
  function lastRunBranchName(workerName) {
@@ -3024,7 +3041,7 @@ function lastRunPrBody(workerName, at) {
3024
3041
  ].join("\n");
3025
3042
  }
3026
3043
  async function git(cwd, args) {
3027
- const { stdout } = await execFileAsync3("git", ["-C", cwd, ...args]);
3044
+ const { stdout } = await execFileAsync4("git", ["-C", cwd, ...args]);
3028
3045
  return stdout;
3029
3046
  }
3030
3047
  async function publishLastRunPr(workerName, defaultBranch, at) {
package/dist/index.js CHANGED
@@ -65,7 +65,7 @@ import {
65
65
  shutdown,
66
66
  waitForAllProcesses,
67
67
  writeLastRun
68
- } from "./chunk-QCQA2UJO.js";
68
+ } from "./chunk-WTY7GTRT.js";
69
69
  import {
70
70
  UserConfigError,
71
71
  assertCloudCompatibleCommand,
package/dist/lib.js CHANGED
@@ -55,7 +55,7 @@ import {
55
55
  removeWorktreeByBranch,
56
56
  run,
57
57
  syncDefaultBranch
58
- } from "./chunk-QCQA2UJO.js";
58
+ } from "./chunk-WTY7GTRT.js";
59
59
  import {
60
60
  getPermissionMode,
61
61
  getRunMode,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-task-worker",
3
- "version": "0.142.3",
3
+ "version": "0.142.4",
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",