claude-task-worker 0.27.0 → 0.28.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/index.js +172 -83
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -65,7 +65,6 @@ __export(herdr_exports, {
|
|
|
65
65
|
getCurrentWorkspaceId: () => getCurrentWorkspaceId,
|
|
66
66
|
paneClose: () => paneClose,
|
|
67
67
|
paneGet: () => paneGet,
|
|
68
|
-
paneMoveToNewTab: () => paneMoveToNewTab,
|
|
69
68
|
paneProcessInfo: () => paneProcessInfo,
|
|
70
69
|
paneRead: () => paneRead,
|
|
71
70
|
paneSendKeys: () => paneSendKeys,
|
|
@@ -79,6 +78,7 @@ __export(herdr_exports, {
|
|
|
79
78
|
workspaceList: () => workspaceList
|
|
80
79
|
});
|
|
81
80
|
import { createRequire as createRequire2 } from "node:module";
|
|
81
|
+
import { resolve as resolvePath } from "node:path";
|
|
82
82
|
function runHerdr(args) {
|
|
83
83
|
return new Promise((resolve3) => {
|
|
84
84
|
childProcess2.execFile(
|
|
@@ -86,24 +86,30 @@ function runHerdr(args) {
|
|
|
86
86
|
args,
|
|
87
87
|
{ timeout: HERDR_TIMEOUT_MS, killSignal: "SIGKILL" },
|
|
88
88
|
(error, stdout, stderr) => {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
} catch {
|
|
93
|
-
parsed = void 0;
|
|
94
|
-
}
|
|
95
|
-
resolve3({ execError: error, parsed, stdout, stderr });
|
|
89
|
+
const parsed = parseHerdrResponse(stdout);
|
|
90
|
+
const stderrError = parsed?.error ? void 0 : parseHerdrResponse(stderr)?.error;
|
|
91
|
+
resolve3({ execError: error, parsed, stderrError, stdout, stderr });
|
|
96
92
|
}
|
|
97
93
|
);
|
|
98
94
|
});
|
|
99
95
|
}
|
|
96
|
+
function parseHerdrResponse(output) {
|
|
97
|
+
try {
|
|
98
|
+
const parsed = JSON.parse(output);
|
|
99
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) return void 0;
|
|
100
|
+
return parsed;
|
|
101
|
+
} catch {
|
|
102
|
+
return void 0;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
100
105
|
async function execHerdr(args, options) {
|
|
101
|
-
const { execError, parsed, stdout, stderr } = await runHerdr(args);
|
|
106
|
+
const { execError, parsed, stderrError, stdout, stderr } = await runHerdr(args);
|
|
102
107
|
const stderrSuffix = stderr.trim() ? `: ${stderr.trim()}` : "";
|
|
103
|
-
|
|
108
|
+
const errorPayload = parsed?.error ?? stderrError;
|
|
109
|
+
if (errorPayload) {
|
|
104
110
|
throw new HerdrError(
|
|
105
|
-
`herdr ${args.join(" ")} failed: [${
|
|
106
|
-
|
|
111
|
+
`herdr ${args.join(" ")} failed: [${errorPayload.code}] ${errorPayload.message}`,
|
|
112
|
+
errorPayload.code
|
|
107
113
|
);
|
|
108
114
|
}
|
|
109
115
|
if (execError) {
|
|
@@ -121,6 +127,9 @@ function envArgs(env) {
|
|
|
121
127
|
if (!env) return [];
|
|
122
128
|
return Object.entries(env).flatMap(([key, value]) => ["--env", `${key}=${value}`]);
|
|
123
129
|
}
|
|
130
|
+
function cwdArgs(cwd) {
|
|
131
|
+
return ["--cwd", resolvePath(cwd)];
|
|
132
|
+
}
|
|
124
133
|
async function tabCreate({
|
|
125
134
|
label,
|
|
126
135
|
cwd,
|
|
@@ -133,8 +142,7 @@ async function tabCreate({
|
|
|
133
142
|
...workspaceId ? ["--workspace", workspaceId] : [],
|
|
134
143
|
"--label",
|
|
135
144
|
label,
|
|
136
|
-
|
|
137
|
-
cwd,
|
|
145
|
+
...cwdArgs(cwd),
|
|
138
146
|
...envArgs(env),
|
|
139
147
|
"--no-focus"
|
|
140
148
|
]);
|
|
@@ -183,8 +191,7 @@ async function workspaceCreate({
|
|
|
183
191
|
"create",
|
|
184
192
|
"--label",
|
|
185
193
|
label,
|
|
186
|
-
|
|
187
|
-
cwd,
|
|
194
|
+
...cwdArgs(cwd),
|
|
188
195
|
...envArgs(env),
|
|
189
196
|
"--no-focus"
|
|
190
197
|
]);
|
|
@@ -214,6 +221,7 @@ async function agentStart({
|
|
|
214
221
|
cwd,
|
|
215
222
|
argv,
|
|
216
223
|
workspaceId,
|
|
224
|
+
tabId: targetTabId,
|
|
217
225
|
env
|
|
218
226
|
}) {
|
|
219
227
|
const result = await execHerdr([
|
|
@@ -221,8 +229,8 @@ async function agentStart({
|
|
|
221
229
|
"start",
|
|
222
230
|
name,
|
|
223
231
|
...workspaceId ? ["--workspace", workspaceId] : [],
|
|
224
|
-
"--
|
|
225
|
-
cwd,
|
|
232
|
+
...targetTabId ? ["--tab", targetTabId] : [],
|
|
233
|
+
...cwdArgs(cwd),
|
|
226
234
|
...envArgs(env),
|
|
227
235
|
"--no-focus",
|
|
228
236
|
"--",
|
|
@@ -235,23 +243,6 @@ async function agentStart({
|
|
|
235
243
|
}
|
|
236
244
|
return { paneId, tabId };
|
|
237
245
|
}
|
|
238
|
-
async function paneMoveToNewTab(paneId, { label, workspaceId }) {
|
|
239
|
-
const result = await execHerdr([
|
|
240
|
-
"pane",
|
|
241
|
-
"move",
|
|
242
|
-
paneId,
|
|
243
|
-
"--new-tab",
|
|
244
|
-
...workspaceId ? ["--workspace", workspaceId] : [],
|
|
245
|
-
"--label",
|
|
246
|
-
label,
|
|
247
|
-
"--no-focus"
|
|
248
|
-
]);
|
|
249
|
-
const tabId = result?.move_result?.created_tab?.tab_id;
|
|
250
|
-
if (!tabId) {
|
|
251
|
-
throw new Error("Failed to move pane to a new tab: invalid response structure from herdr");
|
|
252
|
-
}
|
|
253
|
-
return { tabId };
|
|
254
|
-
}
|
|
255
246
|
function toAgentStatus(value) {
|
|
256
247
|
return value === "working" || value === "idle" || value === "blocked" ? value : "unknown";
|
|
257
248
|
}
|
|
@@ -430,15 +421,19 @@ async function startHerdrTask({
|
|
|
430
421
|
herdr
|
|
431
422
|
}) {
|
|
432
423
|
const mod = herdr ?? await loadHerdr();
|
|
433
|
-
const { paneId } = await mod.
|
|
424
|
+
const { tabId, paneId: shellPaneId } = await mod.tabCreate({ label, cwd, workspaceId, env });
|
|
425
|
+
let paneId;
|
|
434
426
|
try {
|
|
435
|
-
|
|
436
|
-
return { paneId, tabId };
|
|
427
|
+
({ paneId } = await mod.agentStart({ name: label, cwd, argv, env, workspaceId, tabId }));
|
|
437
428
|
} catch (err) {
|
|
438
|
-
await mod.
|
|
429
|
+
await mod.tabClose(tabId).catch(() => {
|
|
439
430
|
});
|
|
440
431
|
throw err;
|
|
441
432
|
}
|
|
433
|
+
await mod.paneClose(shellPaneId).catch((err) => {
|
|
434
|
+
console.error(`[herdr-runner] failed to close the placeholder shell pane ${shellPaneId}: ${err}`);
|
|
435
|
+
});
|
|
436
|
+
return { paneId, tabId };
|
|
442
437
|
}
|
|
443
438
|
async function waitForHerdrTask(paneId, options) {
|
|
444
439
|
const mod = options?.herdr ?? await loadHerdr();
|
|
@@ -534,6 +529,49 @@ var init_herdr_runner = __esm({
|
|
|
534
529
|
}
|
|
535
530
|
});
|
|
536
531
|
|
|
532
|
+
// src/commands/run-command.ts
|
|
533
|
+
var run_command_exports = {};
|
|
534
|
+
__export(run_command_exports, {
|
|
535
|
+
runCommand: () => runCommand
|
|
536
|
+
});
|
|
537
|
+
import { spawn as spawn2 } from "node:child_process";
|
|
538
|
+
function runCommand(command, args) {
|
|
539
|
+
return new Promise((resolve3, reject) => {
|
|
540
|
+
const child = spawn2(command, args, {
|
|
541
|
+
stdio: "inherit",
|
|
542
|
+
shell: process.platform === "win32"
|
|
543
|
+
});
|
|
544
|
+
const forwardSignal = (signal) => {
|
|
545
|
+
child.kill(signal);
|
|
546
|
+
};
|
|
547
|
+
const onSigint = () => forwardSignal("SIGINT");
|
|
548
|
+
const onSigterm = () => forwardSignal("SIGTERM");
|
|
549
|
+
const cleanup = () => {
|
|
550
|
+
process.removeListener("SIGINT", onSigint);
|
|
551
|
+
process.removeListener("SIGTERM", onSigterm);
|
|
552
|
+
};
|
|
553
|
+
process.once("SIGINT", onSigint);
|
|
554
|
+
process.once("SIGTERM", onSigterm);
|
|
555
|
+
child.on("error", (err) => {
|
|
556
|
+
cleanup();
|
|
557
|
+
reject(err);
|
|
558
|
+
});
|
|
559
|
+
child.on("close", (code) => {
|
|
560
|
+
cleanup();
|
|
561
|
+
if (code === 0) {
|
|
562
|
+
resolve3();
|
|
563
|
+
} else {
|
|
564
|
+
reject(new Error(`${command} ${args.join(" ")} exited with code ${code}`));
|
|
565
|
+
}
|
|
566
|
+
});
|
|
567
|
+
});
|
|
568
|
+
}
|
|
569
|
+
var init_run_command = __esm({
|
|
570
|
+
"src/commands/run-command.ts"() {
|
|
571
|
+
"use strict";
|
|
572
|
+
}
|
|
573
|
+
});
|
|
574
|
+
|
|
537
575
|
// src/dispatcher.ts
|
|
538
576
|
var dispatcher_exports = {};
|
|
539
577
|
__export(dispatcher_exports, {
|
|
@@ -2997,7 +3035,85 @@ var epicIssueWorker = (opts = {}) => createIssuePollingWorker({
|
|
|
2997
3035
|
})();
|
|
2998
3036
|
|
|
2999
3037
|
// src/commands/init.ts
|
|
3000
|
-
import { mkdir, writeFile, access } from "node:fs/promises";
|
|
3038
|
+
import { mkdir as mkdir2, writeFile as writeFile2, access } from "node:fs/promises";
|
|
3039
|
+
|
|
3040
|
+
// src/commands/codegraph.ts
|
|
3041
|
+
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
3042
|
+
import { homedir as homedir4 } from "node:os";
|
|
3043
|
+
import { dirname as dirname2, join as join5 } from "node:path";
|
|
3044
|
+
async function loadRunCommand() {
|
|
3045
|
+
return await Promise.resolve().then(() => (init_run_command(), run_command_exports));
|
|
3046
|
+
}
|
|
3047
|
+
var CODEGRAPH_PACKAGE = "@colbymchenry/codegraph";
|
|
3048
|
+
var CODEGRAPH_IGNORE_ENTRY = ".codegraph/";
|
|
3049
|
+
function globalGitIgnorePath(env = process.env, home = homedir4()) {
|
|
3050
|
+
const xdg = env.XDG_CONFIG_HOME?.trim();
|
|
3051
|
+
const base = xdg ? xdg : join5(home, ".config");
|
|
3052
|
+
return join5(base, "git", "ignore");
|
|
3053
|
+
}
|
|
3054
|
+
function appendIgnoreEntry(current, entry) {
|
|
3055
|
+
const bare = entry.replace(/\/$/, "");
|
|
3056
|
+
const alreadyListed = current.split("\n").map((line) => line.trim()).some((line) => line === entry || line === bare);
|
|
3057
|
+
if (alreadyListed) return null;
|
|
3058
|
+
if (current === "") return `${entry}
|
|
3059
|
+
`;
|
|
3060
|
+
return current.endsWith("\n") ? `${current}${entry}
|
|
3061
|
+
` : `${current}
|
|
3062
|
+
${entry}
|
|
3063
|
+
`;
|
|
3064
|
+
}
|
|
3065
|
+
async function installCodegraphCli(logPrefix, mode) {
|
|
3066
|
+
const progressive = mode === "install" ? "Installing" : "Updating";
|
|
3067
|
+
const past = mode === "install" ? "installed" : "updated";
|
|
3068
|
+
console.log(`[${logPrefix}] ${progressive} CodeGraph CLI (npm install -g ${CODEGRAPH_PACKAGE}@latest)...`);
|
|
3069
|
+
try {
|
|
3070
|
+
const { runCommand: runCommand2 } = await loadRunCommand();
|
|
3071
|
+
await runCommand2("npm", ["install", "-g", `${CODEGRAPH_PACKAGE}@latest`]);
|
|
3072
|
+
console.log(`[${logPrefix}] CodeGraph CLI ${past}.`);
|
|
3073
|
+
return true;
|
|
3074
|
+
} catch (err) {
|
|
3075
|
+
console.error(`[${logPrefix}] Failed to ${mode} CodeGraph CLI: ${err.message}`);
|
|
3076
|
+
return false;
|
|
3077
|
+
}
|
|
3078
|
+
}
|
|
3079
|
+
async function runCodegraphInit(logPrefix) {
|
|
3080
|
+
console.log(`[${logPrefix}] Initializing CodeGraph index (codegraph init)...`);
|
|
3081
|
+
try {
|
|
3082
|
+
const { runCommand: runCommand2 } = await loadRunCommand();
|
|
3083
|
+
await runCommand2("codegraph", ["init"]);
|
|
3084
|
+
console.log(`[${logPrefix}] CodeGraph index initialized.`);
|
|
3085
|
+
return true;
|
|
3086
|
+
} catch (err) {
|
|
3087
|
+
console.error(
|
|
3088
|
+
`[${logPrefix}] Failed to run codegraph init (install it with \`claude-task-worker install\`): ${err.message}`
|
|
3089
|
+
);
|
|
3090
|
+
return false;
|
|
3091
|
+
}
|
|
3092
|
+
}
|
|
3093
|
+
async function ensureCodegraphGitIgnore(logPrefix) {
|
|
3094
|
+
const path = globalGitIgnorePath();
|
|
3095
|
+
try {
|
|
3096
|
+
let current = "";
|
|
3097
|
+
try {
|
|
3098
|
+
current = await readFile(path, "utf-8");
|
|
3099
|
+
} catch {
|
|
3100
|
+
}
|
|
3101
|
+
const next = appendIgnoreEntry(current, CODEGRAPH_IGNORE_ENTRY);
|
|
3102
|
+
if (next === null) {
|
|
3103
|
+
console.log(`[${logPrefix}] Already ignored: ${CODEGRAPH_IGNORE_ENTRY} (${path})`);
|
|
3104
|
+
return true;
|
|
3105
|
+
}
|
|
3106
|
+
await mkdir(dirname2(path), { recursive: true });
|
|
3107
|
+
await writeFile(path, next, "utf-8");
|
|
3108
|
+
console.log(`[${logPrefix}] Added ${CODEGRAPH_IGNORE_ENTRY} to ${path}`);
|
|
3109
|
+
return true;
|
|
3110
|
+
} catch (err) {
|
|
3111
|
+
console.error(`[${logPrefix}] Failed to update ${path}: ${err.message}`);
|
|
3112
|
+
return false;
|
|
3113
|
+
}
|
|
3114
|
+
}
|
|
3115
|
+
|
|
3116
|
+
// src/commands/init.ts
|
|
3001
3117
|
var LABELS = [
|
|
3002
3118
|
{ name: "cc-update-issue", color: "e4e669" },
|
|
3003
3119
|
{ name: "cc-answer-issue-questions", color: "5319e7" },
|
|
@@ -3053,10 +3169,10 @@ async function writeFileWithMode(path, content, force) {
|
|
|
3053
3169
|
try {
|
|
3054
3170
|
await access(path);
|
|
3055
3171
|
if (!force) return "skipped";
|
|
3056
|
-
await
|
|
3172
|
+
await writeFile2(path, content, "utf-8");
|
|
3057
3173
|
return "overwritten";
|
|
3058
3174
|
} catch {
|
|
3059
|
-
await
|
|
3175
|
+
await writeFile2(path, content, "utf-8");
|
|
3060
3176
|
return "created";
|
|
3061
3177
|
}
|
|
3062
3178
|
}
|
|
@@ -3082,53 +3198,23 @@ async function init(options = {}) {
|
|
|
3082
3198
|
}
|
|
3083
3199
|
}
|
|
3084
3200
|
console.log("[init] Creating issue template...");
|
|
3085
|
-
await
|
|
3201
|
+
await mkdir2(".github/ISSUE_TEMPLATE", { recursive: true });
|
|
3086
3202
|
const templatePath = ".github/ISSUE_TEMPLATE/cc-triage-scope.yml";
|
|
3087
3203
|
logWriteResult(await writeFileWithMode(templatePath, ISSUE_TEMPLATE, force), templatePath);
|
|
3088
3204
|
console.log("[init] Creating GitHub Actions workflow...");
|
|
3089
|
-
await
|
|
3205
|
+
await mkdir2(".github/workflows", { recursive: true });
|
|
3090
3206
|
const workflowPath = ".github/workflows/assign-creator-on-cc-triage-scope.yml";
|
|
3091
3207
|
logWriteResult(await writeFileWithMode(workflowPath, ASSIGN_CREATOR_WORKFLOW, force), workflowPath);
|
|
3092
3208
|
console.log("[init] Creating config file...");
|
|
3093
3209
|
await createConfig(force);
|
|
3210
|
+
console.log("[init] Setting up CodeGraph...");
|
|
3211
|
+
await ensureCodegraphGitIgnore("init");
|
|
3212
|
+
await runCodegraphInit("init");
|
|
3094
3213
|
console.log("[init] Done.");
|
|
3095
3214
|
}
|
|
3096
3215
|
|
|
3097
|
-
// src/commands/run-command.ts
|
|
3098
|
-
import { spawn as spawn2 } from "node:child_process";
|
|
3099
|
-
function runCommand(command, args) {
|
|
3100
|
-
return new Promise((resolve3, reject) => {
|
|
3101
|
-
const child = spawn2(command, args, {
|
|
3102
|
-
stdio: "inherit",
|
|
3103
|
-
shell: process.platform === "win32"
|
|
3104
|
-
});
|
|
3105
|
-
const forwardSignal = (signal) => {
|
|
3106
|
-
child.kill(signal);
|
|
3107
|
-
};
|
|
3108
|
-
const onSigint = () => forwardSignal("SIGINT");
|
|
3109
|
-
const onSigterm = () => forwardSignal("SIGTERM");
|
|
3110
|
-
const cleanup = () => {
|
|
3111
|
-
process.removeListener("SIGINT", onSigint);
|
|
3112
|
-
process.removeListener("SIGTERM", onSigterm);
|
|
3113
|
-
};
|
|
3114
|
-
process.once("SIGINT", onSigint);
|
|
3115
|
-
process.once("SIGTERM", onSigterm);
|
|
3116
|
-
child.on("error", (err) => {
|
|
3117
|
-
cleanup();
|
|
3118
|
-
reject(err);
|
|
3119
|
-
});
|
|
3120
|
-
child.on("close", (code) => {
|
|
3121
|
-
cleanup();
|
|
3122
|
-
if (code === 0) {
|
|
3123
|
-
resolve3();
|
|
3124
|
-
} else {
|
|
3125
|
-
reject(new Error(`${command} ${args.join(" ")} exited with code ${code}`));
|
|
3126
|
-
}
|
|
3127
|
-
});
|
|
3128
|
-
});
|
|
3129
|
-
}
|
|
3130
|
-
|
|
3131
3216
|
// src/commands/install.ts
|
|
3217
|
+
init_run_command();
|
|
3132
3218
|
var PLUGIN_NAME = "claude-task-worker";
|
|
3133
3219
|
var MARKETPLACE_NAME = "claude-task-worker";
|
|
3134
3220
|
var MARKETPLACE_SOURCE = "getty104/claude-task-worker";
|
|
@@ -3170,13 +3256,15 @@ async function install() {
|
|
|
3170
3256
|
await addMarketplace();
|
|
3171
3257
|
const pluginOk = await installPlugin();
|
|
3172
3258
|
const cliOk = await installCli();
|
|
3173
|
-
|
|
3259
|
+
const codegraphOk = await installCodegraphCli("install", "install");
|
|
3260
|
+
if (!pluginOk || !cliOk || !codegraphOk) {
|
|
3174
3261
|
process.exitCode = 1;
|
|
3175
3262
|
}
|
|
3176
3263
|
console.log("[install] Done.");
|
|
3177
3264
|
}
|
|
3178
3265
|
|
|
3179
3266
|
// src/commands/update.ts
|
|
3267
|
+
init_run_command();
|
|
3180
3268
|
var PLUGIN_NAME2 = "claude-task-worker";
|
|
3181
3269
|
var MARKETPLACE_NAME2 = "claude-task-worker";
|
|
3182
3270
|
async function updateMarketplace() {
|
|
@@ -3217,7 +3305,8 @@ async function update() {
|
|
|
3217
3305
|
const marketplaceOk = await updateMarketplace();
|
|
3218
3306
|
const pluginOk = await updatePlugin();
|
|
3219
3307
|
const cliOk = await updateCli();
|
|
3220
|
-
|
|
3308
|
+
const codegraphOk = await installCodegraphCli("update", "update");
|
|
3309
|
+
if (!marketplaceOk || !pluginOk || !cliOk || !codegraphOk) {
|
|
3221
3310
|
process.exitCode = 1;
|
|
3222
3311
|
}
|
|
3223
3312
|
console.log("[update] Done.");
|
|
@@ -3225,11 +3314,11 @@ async function update() {
|
|
|
3225
3314
|
|
|
3226
3315
|
// src/commands/version.ts
|
|
3227
3316
|
import { readFileSync as readFileSync4 } from "node:fs";
|
|
3228
|
-
import { dirname as
|
|
3317
|
+
import { dirname as dirname3, join as join6 } from "node:path";
|
|
3229
3318
|
import { fileURLToPath } from "node:url";
|
|
3230
3319
|
function version() {
|
|
3231
|
-
const here =
|
|
3232
|
-
const pkgPath =
|
|
3320
|
+
const here = dirname3(fileURLToPath(import.meta.url));
|
|
3321
|
+
const pkgPath = join6(here, "..", "package.json");
|
|
3233
3322
|
try {
|
|
3234
3323
|
const pkg = JSON.parse(readFileSync4(pkgPath, "utf8"));
|
|
3235
3324
|
console.log(pkg.version ?? "unknown");
|