claude-task-worker 0.15.0 → 0.17.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.
Files changed (2) hide show
  1. package/dist/index.js +18 -9
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -193,6 +193,7 @@ __export(dispatcher_exports, {
193
193
  POLL_INTERVAL_MS: () => POLL_INTERVAL_MS,
194
194
  SHUTDOWN_RETRY_TIMEOUT_MS: () => SHUTDOWN_RETRY_TIMEOUT_MS,
195
195
  SHUTDOWN_TIMEOUT_MS: () => SHUTDOWN_TIMEOUT_MS,
196
+ TAB_LABEL_PREFIX: () => TAB_LABEL_PREFIX,
196
197
  createDispatcherShutdownHandler: () => createDispatcherShutdownHandler,
197
198
  formatUptime: () => formatUptime,
198
199
  monitorSessions: () => monitorSessions,
@@ -200,7 +201,8 @@ __export(dispatcher_exports, {
200
201
  removeSession: () => removeSession,
201
202
  renderSessionTable: () => renderSessionTable,
202
203
  runDispatcher: () => runDispatcher,
203
- shutdownDispatcher: () => shutdownDispatcher
204
+ shutdownDispatcher: () => shutdownDispatcher,
205
+ tabLabelFor: () => tabLabelFor
204
206
  });
205
207
  async function loadHerdr() {
206
208
  return await Promise.resolve().then(() => (init_herdr(), herdr_exports));
@@ -208,6 +210,9 @@ async function loadHerdr() {
208
210
  async function loadTable() {
209
211
  return await Promise.resolve().then(() => (init_table(), table_exports));
210
212
  }
213
+ function tabLabelFor(projectName) {
214
+ return `${TAB_LABEL_PREFIX}${projectName}`;
215
+ }
211
216
  async function runDispatcher(projects, forwardedCommand) {
212
217
  const { checkHerdrAvailable: checkHerdrAvailable2, tabCreate: tabCreate2, tabClose: tabClose2, tabList: tabList2, paneSendText: paneSendText2, paneSendKeys: paneSendKeys2 } = await loadHerdr();
213
218
  try {
@@ -221,13 +226,13 @@ async function runDispatcher(projects, forwardedCommand) {
221
226
  const existingLabels = new Set(existingTabs.map((tab) => tab.label));
222
227
  const sessions = /* @__PURE__ */ new Map();
223
228
  for (const project of projects) {
224
- if (existingLabels.has(project.name)) {
229
+ if (existingLabels.has(tabLabelFor(project.name))) {
225
230
  console.warn(`[dispatcher] project "${project.name}" already has a running tab, skipping`);
226
231
  continue;
227
232
  }
228
233
  let createdTabId;
229
234
  try {
230
- const { paneId, tabId } = await tabCreate2({ label: project.name, cwd: project.path });
235
+ const { paneId, tabId } = await tabCreate2({ label: tabLabelFor(project.name), cwd: project.path });
231
236
  createdTabId = tabId;
232
237
  sessions.set(project.name, {
233
238
  name: project.name,
@@ -462,13 +467,14 @@ function createDispatcherShutdownHandler(shutdown2) {
462
467
  };
463
468
  return { handle, isShuttingDown: () => shuttingDown2 };
464
469
  }
465
- var getDisplayWidth2, truncateToWidth2, padToWidth2, POLL_INTERVAL_MS, SHUTDOWN_TIMEOUT_MS, SHUTDOWN_RETRY_TIMEOUT_MS, CTRL_C_KEY, shutdownPromise;
470
+ var getDisplayWidth2, truncateToWidth2, padToWidth2, POLL_INTERVAL_MS, SHUTDOWN_TIMEOUT_MS, TAB_LABEL_PREFIX, SHUTDOWN_RETRY_TIMEOUT_MS, CTRL_C_KEY, shutdownPromise;
466
471
  var init_dispatcher = __esm({
467
472
  async "src/dispatcher.ts"() {
468
473
  "use strict";
469
474
  ({ getDisplayWidth: getDisplayWidth2, truncateToWidth: truncateToWidth2, padToWidth: padToWidth2 } = await loadTable());
470
475
  POLL_INTERVAL_MS = 7 * 1e3;
471
476
  SHUTDOWN_TIMEOUT_MS = 10 * 60 * 1e3;
477
+ TAB_LABEL_PREFIX = "ctw:";
472
478
  SHUTDOWN_RETRY_TIMEOUT_MS = 90 * 1e3;
473
479
  CTRL_C_KEY = "ctrl+c";
474
480
  }
@@ -512,7 +518,7 @@ async function getRepoInfo() {
512
518
  const parsed = JSON.parse(output);
513
519
  return { owner: parsed.owner.login, name: parsed.name, defaultBranch: parsed.defaultBranchRef.name };
514
520
  }
515
- async function listIssuesByLabel(assignee, labels, excludeLabels = [], epicFilter) {
521
+ async function listIssuesByLabel(assignee, labels, excludeLabels = [], epicFilter, limit = 10) {
516
522
  const labelArgs = labels.flatMap((label) => ["--label", label]);
517
523
  const searchTerms = ["sort:created-asc", "-is:blocked", ...excludeLabels.map((label) => `-label:"${label}"`)];
518
524
  if (epicFilter && epicFilter.numbers.length > 0) {
@@ -532,7 +538,7 @@ async function listIssuesByLabel(assignee, labels, excludeLabels = [], epicFilte
532
538
  "--search",
533
539
  search,
534
540
  "--limit",
535
- "10"
541
+ String(limit)
536
542
  ]);
537
543
  return JSON.parse(output);
538
544
  }
@@ -616,7 +622,7 @@ async function fetchPRChecks(prNumber) {
616
622
  if (!output) return [];
617
623
  return JSON.parse(output);
618
624
  }
619
- async function listPullRequestsWithChecks(assignee, label, excludeLabels = []) {
625
+ async function listPullRequestsWithChecks(assignee, label, excludeLabels = [], limit = 5) {
620
626
  const search = ["sort:created-asc", ...excludeLabels.map((l) => `-label:"${l}"`)].join(" ");
621
627
  const args = [
622
628
  "pr",
@@ -628,7 +634,7 @@ async function listPullRequestsWithChecks(assignee, label, excludeLabels = []) {
628
634
  "--search",
629
635
  search,
630
636
  "--limit",
631
- "10"
637
+ String(limit)
632
638
  ];
633
639
  if (assignee) {
634
640
  args.push("--assignee", assignee);
@@ -1700,6 +1706,7 @@ async function removeStaleWorktrees() {
1700
1706
 
1701
1707
  // src/workers/issue-worker.ts
1702
1708
  var LABEL_TRIAGE_SCOPE = "cc-triage-scope";
1709
+ var PREFLIGHT_SEARCH_LIMIT = 5;
1703
1710
  function createIssuePollingWorker(config) {
1704
1711
  return async () => {
1705
1712
  const { owner, name, defaultBranch } = await getRepoInfo();
@@ -1718,7 +1725,9 @@ function createIssuePollingWorker(config) {
1718
1725
  const excludeLabels = ["cc-in-progress", "cc-need-human-check", ...config.excludeLabels ?? []];
1719
1726
  const epicFilter = config.epicFilters && config.epicFilters.length > 0 ? { owner, repo: name, numbers: config.epicFilters } : void 0;
1720
1727
  const labels = config.labelFilters && config.labelFilters.length > 0 ? [...config.triggerLabels, ...config.labelFilters] : config.triggerLabels;
1721
- const candidates = config.ownNumberFilters && config.ownNumberFilters.length > 0 ? await listIssuesByNumbers(user, labels, excludeLabels, config.ownNumberFilters) : await listIssuesByLabel(user, labels, excludeLabels, epicFilter);
1728
+ const { maxConcurrentTasks } = getWorkerConfig(config.name);
1729
+ const searchLimit = config.preflight ? PREFLIGHT_SEARCH_LIMIT : maxConcurrentTasks;
1730
+ const candidates = config.ownNumberFilters && config.ownNumberFilters.length > 0 ? await listIssuesByNumbers(user, labels, excludeLabels, config.ownNumberFilters) : await listIssuesByLabel(user, labels, excludeLabels, epicFilter, searchLimit);
1722
1731
  for (const issue of candidates) {
1723
1732
  if (isRunning(issue.number)) continue;
1724
1733
  if (isWorkerAtCapacity(config.name)) break;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-task-worker",
3
- "version": "0.15.0",
3
+ "version": "0.17.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",