claude-task-worker 0.123.0 → 0.124.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/dist/chunk-HFU27QHT.js +579 -0
- package/dist/{chunk-HZHIQMAQ.js → chunk-XJCZF5SA.js} +45 -372
- package/dist/{dispatcher-JKUMXTJ2.js → dispatcher-CIAW3Z6X.js} +1 -1
- package/dist/{herdr-runner-33D6C2KI.js → herdr-runner-TNX2W4G6.js} +1 -1
- package/dist/index.js +15 -15
- package/dist/lib.js +6 -5
- package/dist/{table-DWVMNDS3.js → table-OOKBQVW5.js} +7 -1
- package/dist/table.d.ts +7 -0
- package/dist/user-config.d.ts +1 -0
- package/package.json +1 -1
- package/dist/chunk-N42YU3GJ.js +0 -184
|
@@ -1,41 +1,50 @@
|
|
|
1
1
|
import {
|
|
2
2
|
CLOUD_WORKTREE_LABEL,
|
|
3
|
+
DEFAULT_PERMISSION_MODE,
|
|
4
|
+
INHERIT_CONFIG_FLAG,
|
|
3
5
|
TASK_DISPLAY_LIMIT,
|
|
4
6
|
buildLogTableLines,
|
|
5
7
|
buildTaskTableLines,
|
|
8
|
+
findProjectNameByPath,
|
|
9
|
+
getInheritConfigPath,
|
|
10
|
+
getPermissionMode,
|
|
11
|
+
getRunMode,
|
|
12
|
+
hasCloudFlag,
|
|
13
|
+
hasDebugFlag,
|
|
14
|
+
isAdvisorEnabled,
|
|
6
15
|
logLines,
|
|
7
16
|
pushLogLine,
|
|
8
17
|
selectRecentTasks,
|
|
9
18
|
writeScreen
|
|
10
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-HFU27QHT.js";
|
|
11
20
|
|
|
12
21
|
// src/gh.ts
|
|
13
22
|
import { createRequire } from "node:module";
|
|
14
23
|
var childProcess = createRequire(import.meta.url)("node:child_process");
|
|
15
24
|
function execGh(args) {
|
|
16
|
-
return new Promise((
|
|
25
|
+
return new Promise((resolve3, reject) => {
|
|
17
26
|
childProcess.execFile("gh", args, (error, stdout, stderr) => {
|
|
18
27
|
if (error) {
|
|
19
28
|
reject(new Error(`gh ${args.join(" ")} failed: ${stderr || error.message}`));
|
|
20
29
|
return;
|
|
21
30
|
}
|
|
22
|
-
|
|
31
|
+
resolve3(stdout.trim());
|
|
23
32
|
});
|
|
24
33
|
});
|
|
25
34
|
}
|
|
26
35
|
function execGhAllowExit(args, allowedCodes) {
|
|
27
|
-
return new Promise((
|
|
36
|
+
return new Promise((resolve3, reject) => {
|
|
28
37
|
childProcess.execFile("gh", args, (error, stdout, stderr) => {
|
|
29
38
|
if (error) {
|
|
30
39
|
const code = error.code;
|
|
31
40
|
if (typeof code === "number" && allowedCodes.includes(code)) {
|
|
32
|
-
|
|
41
|
+
resolve3(stdout.trim());
|
|
33
42
|
return;
|
|
34
43
|
}
|
|
35
44
|
reject(new Error(`gh ${args.join(" ")} failed: ${stderr || error.message}`));
|
|
36
45
|
return;
|
|
37
46
|
}
|
|
38
|
-
|
|
47
|
+
resolve3(stdout.trim());
|
|
39
48
|
});
|
|
40
49
|
});
|
|
41
50
|
}
|
|
@@ -369,7 +378,7 @@ async function withRetry(fn, maxRetries = 5, baseDelayMs = 1e3) {
|
|
|
369
378
|
if (attempt === maxRetries) throw err;
|
|
370
379
|
const delayMs = baseDelayMs * Math.pow(2, attempt - 1);
|
|
371
380
|
console.error(`[gh] Attempt ${attempt}/${maxRetries} failed, retrying in ${delayMs}ms...`);
|
|
372
|
-
await new Promise((
|
|
381
|
+
await new Promise((resolve3) => setTimeout(resolve3, delayMs));
|
|
373
382
|
}
|
|
374
383
|
}
|
|
375
384
|
throw new Error("unreachable");
|
|
@@ -468,97 +477,10 @@ async function createLabel(name, color, force) {
|
|
|
468
477
|
}
|
|
469
478
|
}
|
|
470
479
|
|
|
471
|
-
// src/dispatch-args.ts
|
|
472
|
-
import { resolve } from "node:path";
|
|
473
|
-
var FLAG_INCOMPATIBLE_COMMANDS = [
|
|
474
|
-
"init",
|
|
475
|
-
"apply-labels",
|
|
476
|
-
"install",
|
|
477
|
-
"update",
|
|
478
|
-
"cloud-setup",
|
|
479
|
-
"usage",
|
|
480
|
-
"version",
|
|
481
|
-
"list-workers"
|
|
482
|
-
];
|
|
483
|
-
function collectFlagValues(argv, flag) {
|
|
484
|
-
const values = [];
|
|
485
|
-
for (let i = 0; i < argv.length; i++) {
|
|
486
|
-
if (argv[i] !== flag) continue;
|
|
487
|
-
const raw = argv[i + 1];
|
|
488
|
-
if (!raw || raw.startsWith("--")) {
|
|
489
|
-
console.error(`[dispatcher] ${flag} requires a value`);
|
|
490
|
-
process.exit(1);
|
|
491
|
-
}
|
|
492
|
-
values.push(raw);
|
|
493
|
-
}
|
|
494
|
-
return values;
|
|
495
|
-
}
|
|
496
|
-
function parseProjectFilters() {
|
|
497
|
-
return collectFlagValues(process.argv, "--project");
|
|
498
|
-
}
|
|
499
|
-
function hasProjectFilter() {
|
|
500
|
-
return process.argv.includes("--project");
|
|
501
|
-
}
|
|
502
|
-
function assertProjectCompatibleCommand(command) {
|
|
503
|
-
if (FLAG_INCOMPATIBLE_COMMANDS.includes(command)) {
|
|
504
|
-
console.error(`[dispatcher] --project cannot be used with the "${command}" command`);
|
|
505
|
-
process.exit(1);
|
|
506
|
-
}
|
|
507
|
-
}
|
|
508
|
-
var cachedCloudFlag;
|
|
509
|
-
function hasCloudFlag() {
|
|
510
|
-
if (cachedCloudFlag === void 0) {
|
|
511
|
-
cachedCloudFlag = process.argv.includes("--cloud");
|
|
512
|
-
}
|
|
513
|
-
return cachedCloudFlag;
|
|
514
|
-
}
|
|
515
|
-
var cachedDebugFlag;
|
|
516
|
-
function hasDebugFlag() {
|
|
517
|
-
if (cachedDebugFlag === void 0) {
|
|
518
|
-
cachedDebugFlag = process.argv.includes("--debug");
|
|
519
|
-
}
|
|
520
|
-
return cachedDebugFlag;
|
|
521
|
-
}
|
|
522
|
-
var INHERIT_CONFIG_FLAG = "--inherit-config";
|
|
523
|
-
var cachedInheritConfigPath;
|
|
524
|
-
function getInheritConfigPath() {
|
|
525
|
-
if (cachedInheritConfigPath === void 0) {
|
|
526
|
-
const values = collectFlagValues(process.argv, INHERIT_CONFIG_FLAG);
|
|
527
|
-
cachedInheritConfigPath = values.length > 0 ? resolve(values[values.length - 1]) : null;
|
|
528
|
-
}
|
|
529
|
-
return cachedInheritConfigPath;
|
|
530
|
-
}
|
|
531
|
-
function assertCloudCompatibleCommand(command) {
|
|
532
|
-
if (FLAG_INCOMPATIBLE_COMMANDS.includes(command)) {
|
|
533
|
-
console.error(`[worker] --cloud cannot be used with the "${command}" command`);
|
|
534
|
-
process.exit(1);
|
|
535
|
-
}
|
|
536
|
-
}
|
|
537
|
-
function shellQuote(value) {
|
|
538
|
-
if (value === "") return "''";
|
|
539
|
-
return `'${value.replace(/'/g, "'\\''")}'`;
|
|
540
|
-
}
|
|
541
|
-
function buildForwardedCommand(argv) {
|
|
542
|
-
const tokens = [];
|
|
543
|
-
for (let i = 0; i < argv.length; i++) {
|
|
544
|
-
if (argv[i] === "--project") {
|
|
545
|
-
i++;
|
|
546
|
-
continue;
|
|
547
|
-
}
|
|
548
|
-
if (argv[i] === INHERIT_CONFIG_FLAG && i + 1 < argv.length) {
|
|
549
|
-
tokens.push(argv[i], resolve(argv[i + 1]));
|
|
550
|
-
i++;
|
|
551
|
-
continue;
|
|
552
|
-
}
|
|
553
|
-
tokens.push(argv[i]);
|
|
554
|
-
}
|
|
555
|
-
return ["claude-task-worker", ...tokens.map(shellQuote)].join(" ");
|
|
556
|
-
}
|
|
557
|
-
|
|
558
480
|
// src/config.ts
|
|
559
481
|
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
560
482
|
import { homedir } from "node:os";
|
|
561
|
-
import { dirname, isAbsolute, join, normalize, relative, resolve
|
|
483
|
+
import { dirname, isAbsolute, join, normalize, relative, resolve, sep as SEP } from "node:path";
|
|
562
484
|
var DEFAULT_UI_DESIGN_CONFIG = {
|
|
563
485
|
enabled: false,
|
|
564
486
|
designDir: "designs",
|
|
@@ -960,8 +882,8 @@ function parseWorkerFilesEntry(val) {
|
|
|
960
882
|
}
|
|
961
883
|
function resolveWorkerFilePath(entry, configDir, home) {
|
|
962
884
|
if (entry === "~") return home;
|
|
963
|
-
if (entry.startsWith("~/")) return
|
|
964
|
-
return
|
|
885
|
+
if (entry.startsWith("~/")) return resolve(home, entry.slice(2));
|
|
886
|
+
return resolve(configDir, entry);
|
|
965
887
|
}
|
|
966
888
|
function isPlainObject(val) {
|
|
967
889
|
return typeof val === "object" && val !== null && !Array.isArray(val);
|
|
@@ -998,13 +920,13 @@ function resolveInheritedRelativePaths(raw, configDir, repoRoot) {
|
|
|
998
920
|
if (isPlainObject(uiDesign) && typeof uiDesign.designDir === "string" && uiDesign.designDir.length > 0) {
|
|
999
921
|
result["uiDesign"] = {
|
|
1000
922
|
...uiDesign,
|
|
1001
|
-
designDir: relative(repoRoot,
|
|
923
|
+
designDir: relative(repoRoot, resolve(configDir, uiDesign.designDir)) || "."
|
|
1002
924
|
};
|
|
1003
925
|
}
|
|
1004
926
|
const workerFiles = raw["workerFiles"];
|
|
1005
927
|
if (Array.isArray(workerFiles)) {
|
|
1006
928
|
result["workerFiles"] = workerFiles.map(
|
|
1007
|
-
(entry) => typeof entry === "string" && entry.trim().length > 0 && !entry.trim().startsWith("~") ?
|
|
929
|
+
(entry) => typeof entry === "string" && entry.trim().length > 0 && !entry.trim().startsWith("~") ? resolve(configDir, entry.trim()) : entry
|
|
1008
930
|
);
|
|
1009
931
|
}
|
|
1010
932
|
return result;
|
|
@@ -1160,242 +1082,6 @@ function getUiDesignConfig() {
|
|
|
1160
1082
|
}
|
|
1161
1083
|
}
|
|
1162
1084
|
|
|
1163
|
-
// src/user-config.ts
|
|
1164
|
-
import { readFileSync as readFileSync2, statSync } from "node:fs";
|
|
1165
|
-
import { homedir as homedir2 } from "node:os";
|
|
1166
|
-
import { isAbsolute as isAbsolute2, join as join2, resolve as resolve3 } from "node:path";
|
|
1167
|
-
var RESERVED_ALL = "all";
|
|
1168
|
-
var DEFAULT_RUN_MODE = "default";
|
|
1169
|
-
var DEFAULT_ADVISOR_ENABLED = false;
|
|
1170
|
-
var PERMISSION_MODES = [
|
|
1171
|
-
"manual",
|
|
1172
|
-
"auto",
|
|
1173
|
-
"acceptEdits",
|
|
1174
|
-
"dontAsk",
|
|
1175
|
-
"plan",
|
|
1176
|
-
"bypassPermissions"
|
|
1177
|
-
];
|
|
1178
|
-
var DEFAULT_PERMISSION_MODE = "bypassPermissions";
|
|
1179
|
-
var UserConfigError = class extends Error {
|
|
1180
|
-
constructor(message) {
|
|
1181
|
-
super(message);
|
|
1182
|
-
this.name = "UserConfigError";
|
|
1183
|
-
}
|
|
1184
|
-
};
|
|
1185
|
-
function getConfigDir() {
|
|
1186
|
-
const xdg = process.env.XDG_CONFIG_HOME;
|
|
1187
|
-
const configHome = xdg && xdg.length > 0 ? xdg : join2(homedir2(), ".config");
|
|
1188
|
-
return join2(configHome, "claude-task-worker");
|
|
1189
|
-
}
|
|
1190
|
-
function getUserConfigPath() {
|
|
1191
|
-
return join2(getConfigDir(), "config.json");
|
|
1192
|
-
}
|
|
1193
|
-
function isDirectory(path2) {
|
|
1194
|
-
try {
|
|
1195
|
-
return statSync(path2).isDirectory();
|
|
1196
|
-
} catch {
|
|
1197
|
-
return false;
|
|
1198
|
-
}
|
|
1199
|
-
}
|
|
1200
|
-
function parseConfigFile(path2) {
|
|
1201
|
-
let content;
|
|
1202
|
-
try {
|
|
1203
|
-
content = readFileSync2(path2, "utf-8");
|
|
1204
|
-
} catch (err) {
|
|
1205
|
-
if (err.code === "ENOENT") return void 0;
|
|
1206
|
-
throw err;
|
|
1207
|
-
}
|
|
1208
|
-
try {
|
|
1209
|
-
return JSON.parse(content);
|
|
1210
|
-
} catch (err) {
|
|
1211
|
-
if (err instanceof SyntaxError) {
|
|
1212
|
-
throw new UserConfigError(`config file contains invalid JSON: ${path2}: ${err.message}`);
|
|
1213
|
-
}
|
|
1214
|
-
throw err;
|
|
1215
|
-
}
|
|
1216
|
-
}
|
|
1217
|
-
function readRawConfig2() {
|
|
1218
|
-
return parseConfigFile(getUserConfigPath());
|
|
1219
|
-
}
|
|
1220
|
-
function parseMode(raw, path2) {
|
|
1221
|
-
if (!("mode" in raw)) return DEFAULT_RUN_MODE;
|
|
1222
|
-
const value = raw["mode"];
|
|
1223
|
-
if (value === "default" || value === "herdr") return value;
|
|
1224
|
-
console.warn(`[config] invalid mode: ${JSON.stringify(value)} in ${path2}, using "${DEFAULT_RUN_MODE}"`);
|
|
1225
|
-
return DEFAULT_RUN_MODE;
|
|
1226
|
-
}
|
|
1227
|
-
function parseAdvisor(raw, path2) {
|
|
1228
|
-
if (!("advisor" in raw)) return DEFAULT_ADVISOR_ENABLED;
|
|
1229
|
-
const value = raw["advisor"];
|
|
1230
|
-
if (typeof value === "boolean") return value;
|
|
1231
|
-
console.warn(`[config] invalid advisor: ${JSON.stringify(value)} in ${path2}, using ${DEFAULT_ADVISOR_ENABLED}`);
|
|
1232
|
-
return DEFAULT_ADVISOR_ENABLED;
|
|
1233
|
-
}
|
|
1234
|
-
function parsePermission(raw, path2) {
|
|
1235
|
-
if (!("permission" in raw)) return DEFAULT_PERMISSION_MODE;
|
|
1236
|
-
const value = raw["permission"];
|
|
1237
|
-
if (typeof value === "string" && PERMISSION_MODES.includes(value)) return value;
|
|
1238
|
-
console.warn(`[config] invalid permission: ${JSON.stringify(value)} in ${path2}, using "${DEFAULT_PERMISSION_MODE}"`);
|
|
1239
|
-
return DEFAULT_PERMISSION_MODE;
|
|
1240
|
-
}
|
|
1241
|
-
function loadUserConfig() {
|
|
1242
|
-
const path2 = getUserConfigPath();
|
|
1243
|
-
const raw = readRawConfig2();
|
|
1244
|
-
if (raw === void 0) {
|
|
1245
|
-
throw new UserConfigError(`config.json not found: ${path2}`);
|
|
1246
|
-
}
|
|
1247
|
-
if (typeof raw !== "object" || raw === null || Array.isArray(raw)) {
|
|
1248
|
-
throw new UserConfigError(`config.json must contain a JSON object: ${path2}`);
|
|
1249
|
-
}
|
|
1250
|
-
if (!("projects" in raw) || typeof raw["projects"] !== "object" || raw["projects"] === null || Array.isArray(raw["projects"])) {
|
|
1251
|
-
throw new UserConfigError(`config.json must contain a "projects" section as an object: ${path2}`);
|
|
1252
|
-
}
|
|
1253
|
-
if ("projectGroups" in raw && (typeof raw["projectGroups"] !== "object" || raw["projectGroups"] === null || Array.isArray(raw["projectGroups"]))) {
|
|
1254
|
-
throw new UserConfigError(`config.json "projectGroups" must be an object: ${path2}`);
|
|
1255
|
-
}
|
|
1256
|
-
const mode = parseMode(raw, path2);
|
|
1257
|
-
const advisor = parseAdvisor(raw, path2);
|
|
1258
|
-
const permission = parsePermission(raw, path2);
|
|
1259
|
-
const rawProjects = raw["projects"];
|
|
1260
|
-
const rawProjectGroups = "projectGroups" in raw ? raw["projectGroups"] : {};
|
|
1261
|
-
const projectKeys = Object.keys(rawProjects);
|
|
1262
|
-
const groupKeys = Object.keys(rawProjectGroups);
|
|
1263
|
-
if (projectKeys.includes(RESERVED_ALL) || groupKeys.includes(RESERVED_ALL)) {
|
|
1264
|
-
throw new UserConfigError(
|
|
1265
|
-
`"${RESERVED_ALL}" is a reserved word and cannot be used as a key in "projects" or "projectGroups"`
|
|
1266
|
-
);
|
|
1267
|
-
}
|
|
1268
|
-
const groupKeySet = new Set(groupKeys);
|
|
1269
|
-
const duplicateKeys = projectKeys.filter((key) => groupKeySet.has(key));
|
|
1270
|
-
if (duplicateKeys.length > 0) {
|
|
1271
|
-
throw new UserConfigError(
|
|
1272
|
-
`"projects" and "projectGroups" share the same key namespace; duplicate keys are not allowed: ${duplicateKeys.join(", ")}`
|
|
1273
|
-
);
|
|
1274
|
-
}
|
|
1275
|
-
const projects = {};
|
|
1276
|
-
for (const [name, value] of Object.entries(rawProjects)) {
|
|
1277
|
-
if (name === "__proto__") {
|
|
1278
|
-
throw new UserConfigError(`"__proto__" cannot be used as a key in "projects": ${path2}`);
|
|
1279
|
-
}
|
|
1280
|
-
if (typeof value !== "string" || !isAbsolute2(value)) {
|
|
1281
|
-
console.warn(`[config] invalid projects.${name}: expected an absolute path, skipping`);
|
|
1282
|
-
continue;
|
|
1283
|
-
}
|
|
1284
|
-
if (!isDirectory(value)) {
|
|
1285
|
-
console.warn(`[config] projects.${name} does not exist as a directory: ${value}, skipping`);
|
|
1286
|
-
continue;
|
|
1287
|
-
}
|
|
1288
|
-
projects[name] = value;
|
|
1289
|
-
}
|
|
1290
|
-
const projectGroups = {};
|
|
1291
|
-
for (const [groupName, value] of Object.entries(rawProjectGroups)) {
|
|
1292
|
-
if (groupName === "__proto__") {
|
|
1293
|
-
throw new UserConfigError(`"__proto__" cannot be used as a key in "projectGroups": ${path2}`);
|
|
1294
|
-
}
|
|
1295
|
-
if (!Array.isArray(value)) {
|
|
1296
|
-
console.warn(`[config] invalid projectGroups.${groupName}: expected an array, skipping`);
|
|
1297
|
-
continue;
|
|
1298
|
-
}
|
|
1299
|
-
const members = [];
|
|
1300
|
-
for (const member of value) {
|
|
1301
|
-
if (typeof member !== "string" || !Object.prototype.hasOwnProperty.call(projects, member)) {
|
|
1302
|
-
console.warn(`[config] projectGroups.${groupName} references unknown project "${String(member)}", skipping`);
|
|
1303
|
-
continue;
|
|
1304
|
-
}
|
|
1305
|
-
members.push(member);
|
|
1306
|
-
}
|
|
1307
|
-
projectGroups[groupName] = members;
|
|
1308
|
-
}
|
|
1309
|
-
return { mode, advisor, permission, projects, projectGroups };
|
|
1310
|
-
}
|
|
1311
|
-
var cachedRunMode;
|
|
1312
|
-
function getRunMode() {
|
|
1313
|
-
if (cachedRunMode === void 0) {
|
|
1314
|
-
cachedRunMode = readRunMode();
|
|
1315
|
-
}
|
|
1316
|
-
return cachedRunMode;
|
|
1317
|
-
}
|
|
1318
|
-
var cachedAdvisorEnabled;
|
|
1319
|
-
function isAdvisorEnabled() {
|
|
1320
|
-
if (cachedAdvisorEnabled === void 0) {
|
|
1321
|
-
cachedAdvisorEnabled = readAdvisorEnabled();
|
|
1322
|
-
}
|
|
1323
|
-
return cachedAdvisorEnabled;
|
|
1324
|
-
}
|
|
1325
|
-
var cachedPermissionMode;
|
|
1326
|
-
function getPermissionMode() {
|
|
1327
|
-
if (cachedPermissionMode === void 0) {
|
|
1328
|
-
cachedPermissionMode = readTopLevel(parsePermission, DEFAULT_PERMISSION_MODE, "permission");
|
|
1329
|
-
}
|
|
1330
|
-
return cachedPermissionMode;
|
|
1331
|
-
}
|
|
1332
|
-
function readTopLevel(parse, fallback, label) {
|
|
1333
|
-
let raw;
|
|
1334
|
-
try {
|
|
1335
|
-
raw = readRawConfig2();
|
|
1336
|
-
} catch (err) {
|
|
1337
|
-
console.warn(`[config] failed to read config file, using default ${label}: ${err}`);
|
|
1338
|
-
return fallback;
|
|
1339
|
-
}
|
|
1340
|
-
if (raw === void 0) return fallback;
|
|
1341
|
-
if (typeof raw !== "object" || raw === null || Array.isArray(raw)) {
|
|
1342
|
-
return fallback;
|
|
1343
|
-
}
|
|
1344
|
-
return parse(raw, getUserConfigPath());
|
|
1345
|
-
}
|
|
1346
|
-
function readAdvisorEnabled() {
|
|
1347
|
-
return readTopLevel(parseAdvisor, DEFAULT_ADVISOR_ENABLED, "advisor");
|
|
1348
|
-
}
|
|
1349
|
-
function readRunMode() {
|
|
1350
|
-
return readTopLevel(parseMode, DEFAULT_RUN_MODE, "mode");
|
|
1351
|
-
}
|
|
1352
|
-
function findProjectNameByPath(path2) {
|
|
1353
|
-
let config;
|
|
1354
|
-
try {
|
|
1355
|
-
config = loadUserConfig();
|
|
1356
|
-
} catch {
|
|
1357
|
-
return void 0;
|
|
1358
|
-
}
|
|
1359
|
-
const target = resolve3(path2);
|
|
1360
|
-
for (const [name, projectPath] of Object.entries(config.projects)) {
|
|
1361
|
-
if (resolve3(projectPath) === target) return name;
|
|
1362
|
-
}
|
|
1363
|
-
return void 0;
|
|
1364
|
-
}
|
|
1365
|
-
function resolveTargetProjects(requested, config) {
|
|
1366
|
-
const resolved = /* @__PURE__ */ new Map();
|
|
1367
|
-
for (const name of requested) {
|
|
1368
|
-
if (name === RESERVED_ALL) {
|
|
1369
|
-
for (const [projectName, projectPath] of Object.entries(config.projects)) {
|
|
1370
|
-
resolved.set(projectName, { name: projectName, path: projectPath });
|
|
1371
|
-
}
|
|
1372
|
-
continue;
|
|
1373
|
-
}
|
|
1374
|
-
if (Object.prototype.hasOwnProperty.call(config.projects, name)) {
|
|
1375
|
-
resolved.set(name, { name, path: config.projects[name] });
|
|
1376
|
-
continue;
|
|
1377
|
-
}
|
|
1378
|
-
if (Object.prototype.hasOwnProperty.call(config.projectGroups, name)) {
|
|
1379
|
-
for (const projectName of config.projectGroups[name]) {
|
|
1380
|
-
const projectPath = config.projects[projectName];
|
|
1381
|
-
if (projectPath === void 0) continue;
|
|
1382
|
-
resolved.set(projectName, { name: projectName, path: projectPath });
|
|
1383
|
-
}
|
|
1384
|
-
continue;
|
|
1385
|
-
}
|
|
1386
|
-
const availableProjects = Object.keys(config.projects).join(", ") || "(none)";
|
|
1387
|
-
const availableGroups = Object.keys(config.projectGroups).join(", ") || "(none)";
|
|
1388
|
-
throw new UserConfigError(
|
|
1389
|
-
`Unknown project or group: "${name}". Available projects: ${availableProjects}. Available groups: ${availableGroups}.`
|
|
1390
|
-
);
|
|
1391
|
-
}
|
|
1392
|
-
const resolvedProjects = Array.from(resolved.values());
|
|
1393
|
-
if (resolvedProjects.length === 0) {
|
|
1394
|
-
throw new UserConfigError(`No projects resolved from requested targets: ${requested.join(", ")}`);
|
|
1395
|
-
}
|
|
1396
|
-
return resolvedProjects;
|
|
1397
|
-
}
|
|
1398
|
-
|
|
1399
1085
|
// src/claude-args.ts
|
|
1400
1086
|
import { mkdirSync, renameSync, writeFileSync as writeFileSync2 } from "node:fs";
|
|
1401
1087
|
import os from "node:os";
|
|
@@ -1603,7 +1289,7 @@ ${buildCloudGitHubAccessInstruction()}`;
|
|
|
1603
1289
|
${principles}`;
|
|
1604
1290
|
return target ? appendCloudDoneInstruction(withPrinciples, target, debug) : withPrinciples;
|
|
1605
1291
|
}
|
|
1606
|
-
function
|
|
1292
|
+
function shellQuote(value) {
|
|
1607
1293
|
return `'${value.replace(/'/g, "'\\''")}'`;
|
|
1608
1294
|
}
|
|
1609
1295
|
function buildScriptCommand(command, args, platform = process.platform) {
|
|
@@ -1611,7 +1297,7 @@ function buildScriptCommand(command, args, platform = process.platform) {
|
|
|
1611
1297
|
return { command: "script", args: ["-q", "/dev/null", command, ...args] };
|
|
1612
1298
|
}
|
|
1613
1299
|
if (platform === "linux") {
|
|
1614
|
-
return { command: "script", args: ["-qec", [command, ...args].map(
|
|
1300
|
+
return { command: "script", args: ["-qec", [command, ...args].map(shellQuote).join(" "), "/dev/null"] };
|
|
1615
1301
|
}
|
|
1616
1302
|
throw new Error(`unsupported platform for script(1): ${platform}`);
|
|
1617
1303
|
}
|
|
@@ -1709,7 +1395,7 @@ var herdrTasks = /* @__PURE__ */ new Map();
|
|
|
1709
1395
|
var herdrAbortSignal = { aborted: false };
|
|
1710
1396
|
var tasks = /* @__PURE__ */ new Map();
|
|
1711
1397
|
function pushTaskLogLine(id, stream, text) {
|
|
1712
|
-
pushLogLine({ id, stream, text: text.replace(/\r$/, ""), time: /* @__PURE__ */ new Date() });
|
|
1398
|
+
pushLogLine({ id, stream, text: text.replace(/\r$/, ""), time: /* @__PURE__ */ new Date(), path: tasks.get(id)?.path });
|
|
1713
1399
|
}
|
|
1714
1400
|
function makeLogFeeder(id, stream) {
|
|
1715
1401
|
let partial = "";
|
|
@@ -1820,7 +1506,7 @@ function resolveProjectName(cwd = process.cwd()) {
|
|
|
1820
1506
|
return findProjectNameByPath(cwd) ?? basename(cwd);
|
|
1821
1507
|
}
|
|
1822
1508
|
async function runViaHerdr(args, prompt, id, onComplete, cwd, env) {
|
|
1823
|
-
const { startHerdrTask, stopHerdrTask, taskTabLabel, waitForHerdrTask } = await import("./herdr-runner-
|
|
1509
|
+
const { startHerdrTask, stopHerdrTask, taskTabLabel, waitForHerdrTask } = await import("./herdr-runner-TNX2W4G6.js");
|
|
1824
1510
|
const { getCurrentWorkspaceId } = await import("./herdr-NDLUM6JF.js");
|
|
1825
1511
|
const label = taskTabLabel(resolveProjectName(), id);
|
|
1826
1512
|
let task;
|
|
@@ -1904,17 +1590,17 @@ async function pollCloudWaiters() {
|
|
|
1904
1590
|
if (cloudWaiters.size === 0) break;
|
|
1905
1591
|
for (let waited = 0; waited < CLOUD_POLL_INTERVAL_MS; waited += 1e3) {
|
|
1906
1592
|
if (herdrAbortSignal.aborted) break;
|
|
1907
|
-
await new Promise((
|
|
1593
|
+
await new Promise((resolve3) => setTimeout(resolve3, 1e3));
|
|
1908
1594
|
}
|
|
1909
1595
|
}
|
|
1910
1596
|
}
|
|
1911
1597
|
function waitForCloudTask(id, target) {
|
|
1912
|
-
return new Promise((
|
|
1598
|
+
return new Promise((resolve3) => {
|
|
1913
1599
|
cloudWaiters.set(`${target.type}:${target.number}:${id}`, {
|
|
1914
1600
|
type: target.type,
|
|
1915
1601
|
number: target.number,
|
|
1916
1602
|
deadline: Date.now() + CLOUD_TASK_TIMEOUT_MS,
|
|
1917
|
-
settle:
|
|
1603
|
+
settle: resolve3
|
|
1918
1604
|
});
|
|
1919
1605
|
ensureCloudPollLoop();
|
|
1920
1606
|
});
|
|
@@ -1939,7 +1625,7 @@ async function flagOrphanedCloudSession(target, reason, cloudSessionId) {
|
|
|
1939
1625
|
});
|
|
1940
1626
|
}
|
|
1941
1627
|
async function createCloudSession(args, initialPrompt, cwd, env) {
|
|
1942
|
-
const { extractCloudSessionId, normalizePtyOutput } = await import("./herdr-runner-
|
|
1628
|
+
const { extractCloudSessionId, normalizePtyOutput } = await import("./herdr-runner-TNX2W4G6.js");
|
|
1943
1629
|
const spec = buildScriptCommand("claude", buildCloudCreateArgs(args, initialPrompt));
|
|
1944
1630
|
const child = spawn(spec.command, spec.args, {
|
|
1945
1631
|
stdio: ["ignore", "pipe", "pipe"],
|
|
@@ -1947,7 +1633,7 @@ async function createCloudSession(args, initialPrompt, cwd, env) {
|
|
|
1947
1633
|
...env ? { env: { ...process.env, ...env } } : {}
|
|
1948
1634
|
});
|
|
1949
1635
|
let output = "";
|
|
1950
|
-
return await new Promise((
|
|
1636
|
+
return await new Promise((resolve3, reject) => {
|
|
1951
1637
|
let settled = false;
|
|
1952
1638
|
const finish = (err, sessionId) => {
|
|
1953
1639
|
if (settled) return;
|
|
@@ -1958,7 +1644,7 @@ async function createCloudSession(args, initialPrompt, cwd, env) {
|
|
|
1958
1644
|
child.kill();
|
|
1959
1645
|
reject(err);
|
|
1960
1646
|
} else {
|
|
1961
|
-
|
|
1647
|
+
resolve3(sessionId);
|
|
1962
1648
|
}
|
|
1963
1649
|
};
|
|
1964
1650
|
const scan = () => {
|
|
@@ -2124,10 +1810,10 @@ function run(command, args, id, title, workerName, path2, onComplete, cwd, env,
|
|
|
2124
1810
|
});
|
|
2125
1811
|
}
|
|
2126
1812
|
function waitForAllProcesses() {
|
|
2127
|
-
return new Promise((
|
|
1813
|
+
return new Promise((resolve3) => {
|
|
2128
1814
|
const check = () => {
|
|
2129
1815
|
if (childProcesses.size === 0 && herdrTasks.size === 0) {
|
|
2130
|
-
|
|
1816
|
+
resolve3();
|
|
2131
1817
|
} else {
|
|
2132
1818
|
setTimeout(check, 500);
|
|
2133
1819
|
}
|
|
@@ -2401,16 +2087,16 @@ function isGeneratedWorktreeName(name) {
|
|
|
2401
2087
|
|
|
2402
2088
|
// src/slack.ts
|
|
2403
2089
|
import { exec } from "node:child_process";
|
|
2404
|
-
import { readFileSync as
|
|
2405
|
-
import { homedir as
|
|
2406
|
-
import { join as
|
|
2090
|
+
import { readFileSync as readFileSync2, writeFileSync as writeFileSync4 } from "node:fs";
|
|
2091
|
+
import { homedir as homedir3 } from "node:os";
|
|
2092
|
+
import { join as join3 } from "node:path";
|
|
2407
2093
|
import { promisify as promisify2 } from "node:util";
|
|
2408
2094
|
|
|
2409
2095
|
// src/runcat.ts
|
|
2410
2096
|
import { mkdirSync as mkdirSync2, renameSync as renameSync2, rmSync, writeFileSync as writeFileSync3 } from "node:fs";
|
|
2411
|
-
import { homedir as
|
|
2412
|
-
import { dirname as dirname2, join as
|
|
2413
|
-
var RUNCAT_OUT_FILE = process.env.RUNCAT_OUT_FILE ??
|
|
2097
|
+
import { homedir as homedir2 } from "node:os";
|
|
2098
|
+
import { dirname as dirname2, join as join2 } from "node:path";
|
|
2099
|
+
var RUNCAT_OUT_FILE = process.env.RUNCAT_OUT_FILE ?? join2(process.env.HOME ?? homedir2(), ".claude", "runcat-usage.json");
|
|
2414
2100
|
var JST = "Asia/Tokyo";
|
|
2415
2101
|
function formatG(value) {
|
|
2416
2102
|
return String(Number(value.toPrecision(6)));
|
|
@@ -2474,7 +2160,7 @@ function buildRuncatSnapshot(usage, now = /* @__PURE__ */ new Date()) {
|
|
|
2474
2160
|
function writeRuncatUsage(usage, outFile = RUNCAT_OUT_FILE) {
|
|
2475
2161
|
const snapshot = buildRuncatSnapshot(usage);
|
|
2476
2162
|
const dir = dirname2(outFile);
|
|
2477
|
-
const tmp =
|
|
2163
|
+
const tmp = join2(dir, `.runcat-${process.pid}-${Date.now()}.json`);
|
|
2478
2164
|
try {
|
|
2479
2165
|
mkdirSync2(dir, { recursive: true });
|
|
2480
2166
|
writeFileSync3(tmp, JSON.stringify(snapshot), "utf-8");
|
|
@@ -2511,13 +2197,13 @@ async function getOAuthToken() {
|
|
|
2511
2197
|
const { stdout } = await execAsync('security find-generic-password -s "Claude Code-credentials" -w');
|
|
2512
2198
|
return extractToken(JSON.parse(stdout.trim()));
|
|
2513
2199
|
} catch {
|
|
2514
|
-
const raw =
|
|
2200
|
+
const raw = readFileSync2(join3(homedir3(), ".claude", ".credentials.json"), "utf-8");
|
|
2515
2201
|
return extractToken(JSON.parse(raw));
|
|
2516
2202
|
}
|
|
2517
2203
|
}
|
|
2518
2204
|
function readUsageCache() {
|
|
2519
2205
|
try {
|
|
2520
|
-
const raw =
|
|
2206
|
+
const raw = readFileSync2(USAGE_CACHE_PATH, "utf-8");
|
|
2521
2207
|
const cached = JSON.parse(raw);
|
|
2522
2208
|
if (Date.now() - cached.timestamp < USAGE_CACHE_TTL_SECONDS * 1e3) {
|
|
2523
2209
|
return cached.data;
|
|
@@ -2656,12 +2342,12 @@ async function notifyError(workerName, repoName, error) {
|
|
|
2656
2342
|
import { createRequire as createRequire2 } from "node:module";
|
|
2657
2343
|
import { promisify as promisify3 } from "node:util";
|
|
2658
2344
|
import { readdir, rm, stat } from "node:fs/promises";
|
|
2659
|
-
import { basename as basename2, resolve as
|
|
2345
|
+
import { basename as basename2, resolve as resolve2, sep } from "node:path";
|
|
2660
2346
|
var childProcess2 = createRequire2(import.meta.url)("node:child_process");
|
|
2661
2347
|
var execFileAsync2 = (command, args) => promisify3(childProcess2.execFile)(command, args);
|
|
2662
2348
|
var WORKTREES_DIR = ".claude/worktrees";
|
|
2663
2349
|
function isManagedWorktreePath(path2) {
|
|
2664
|
-
return
|
|
2350
|
+
return resolve2(path2).startsWith(resolve2(WORKTREES_DIR) + sep);
|
|
2665
2351
|
}
|
|
2666
2352
|
async function pathExists(path2) {
|
|
2667
2353
|
try {
|
|
@@ -2755,7 +2441,7 @@ async function removeWorktree(worktreeId) {
|
|
|
2755
2441
|
const worktreePath = getWorktreePath(worktreeId);
|
|
2756
2442
|
let entry;
|
|
2757
2443
|
try {
|
|
2758
|
-
entry = (await listWorktreeEntries()).find((e) =>
|
|
2444
|
+
entry = (await listWorktreeEntries()).find((e) => resolve2(e.path) === resolve2(worktreePath));
|
|
2759
2445
|
} catch (error) {
|
|
2760
2446
|
console.error(`[worktree] Failed to list worktrees:`, error);
|
|
2761
2447
|
}
|
|
@@ -3402,13 +3088,6 @@ export {
|
|
|
3402
3088
|
commentOnIssue,
|
|
3403
3089
|
createPullRequest,
|
|
3404
3090
|
createLabel,
|
|
3405
|
-
parseProjectFilters,
|
|
3406
|
-
hasProjectFilter,
|
|
3407
|
-
assertProjectCompatibleCommand,
|
|
3408
|
-
hasCloudFlag,
|
|
3409
|
-
getInheritConfigPath,
|
|
3410
|
-
assertCloudCompatibleCommand,
|
|
3411
|
-
buildForwardedCommand,
|
|
3412
3091
|
DEFAULT_UI_DESIGN_CONFIG,
|
|
3413
3092
|
SCHEDULED_WORKER_NAMES,
|
|
3414
3093
|
CLOUD_DONE_LABEL,
|
|
@@ -3429,12 +3108,6 @@ export {
|
|
|
3429
3108
|
writeLastRun,
|
|
3430
3109
|
getRemoteEnvId,
|
|
3431
3110
|
getUiDesignConfig,
|
|
3432
|
-
UserConfigError,
|
|
3433
|
-
loadUserConfig,
|
|
3434
|
-
getRunMode,
|
|
3435
|
-
isAdvisorEnabled,
|
|
3436
|
-
getPermissionMode,
|
|
3437
|
-
resolveTargetProjects,
|
|
3438
3111
|
buildScriptCommand,
|
|
3439
3112
|
buildClaudeExecution,
|
|
3440
3113
|
buildClaudeEnv,
|
|
@@ -3,7 +3,7 @@ async function loadHerdr() {
|
|
|
3
3
|
return await import("./herdr-NDLUM6JF.js");
|
|
4
4
|
}
|
|
5
5
|
async function loadTable() {
|
|
6
|
-
return await import("./table-
|
|
6
|
+
return await import("./table-OOKBQVW5.js");
|
|
7
7
|
}
|
|
8
8
|
var { getDisplayWidth, truncateToWidth, padToWidth, buildLogTableLines, logLines, writeScreen } = await loadTable();
|
|
9
9
|
var POLL_INTERVAL_MS = 7 * 1e3;
|