@groupchatai/claude-runner 0.1.0 → 0.2.1
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 +48 -20
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -120,13 +120,40 @@ Due: ${new Date(detail.task.dueDate).toLocaleDateString()}`);
|
|
|
120
120
|
);
|
|
121
121
|
return parts.join("\n");
|
|
122
122
|
}
|
|
123
|
+
var C = {
|
|
124
|
+
reset: "\x1B[0m",
|
|
125
|
+
dim: "\x1B[2m",
|
|
126
|
+
white: "\x1B[97m",
|
|
127
|
+
grey: "\x1B[90m",
|
|
128
|
+
lightGrey: "\x1B[37m",
|
|
129
|
+
green: "\x1B[32m",
|
|
130
|
+
red: "\x1B[31m",
|
|
131
|
+
pid: "\x1B[38;2;193;95;60m"
|
|
132
|
+
};
|
|
133
|
+
function pidTag(pid) {
|
|
134
|
+
return ` ${C.pid}[pid ${pid}]${C.reset}`;
|
|
135
|
+
}
|
|
136
|
+
function padForTag(pid) {
|
|
137
|
+
const tagLen = ` [pid ${pid}] `.length;
|
|
138
|
+
return " ".repeat(tagLen);
|
|
139
|
+
}
|
|
140
|
+
function wrapLines(tag, pad, text, color) {
|
|
141
|
+
const lines = text.split("\n").filter((l) => l.trim());
|
|
142
|
+
if (lines.length === 0) return "";
|
|
143
|
+
const first = `${tag} ${color}${lines[0]}${C.reset}`;
|
|
144
|
+
if (lines.length === 1) return first;
|
|
145
|
+
const rest = lines.slice(1).map((l) => `${pad}${color}${l}${C.reset}`);
|
|
146
|
+
return [first, ...rest].join("\n");
|
|
147
|
+
}
|
|
123
148
|
function formatStreamEvent(event, pid) {
|
|
124
|
-
const
|
|
149
|
+
const tag = pidTag(pid);
|
|
150
|
+
const pad = padForTag(pid);
|
|
125
151
|
switch (event.type) {
|
|
126
152
|
case "system":
|
|
127
153
|
if (event.subtype === "init") {
|
|
128
|
-
let line = `${
|
|
154
|
+
let line = `${tag} ${C.dim}session started`;
|
|
129
155
|
if (event.session_id) line += ` (${event.session_id})`;
|
|
156
|
+
line += C.reset;
|
|
130
157
|
return line;
|
|
131
158
|
}
|
|
132
159
|
return null;
|
|
@@ -136,21 +163,20 @@ function formatStreamEvent(event, pid) {
|
|
|
136
163
|
const parts = [];
|
|
137
164
|
for (const block of blocks) {
|
|
138
165
|
if (block.type === "text" && block.text) {
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
}
|
|
166
|
+
const wrapped = wrapLines(tag, pad, block.text, C.white);
|
|
167
|
+
if (wrapped) parts.push(wrapped);
|
|
142
168
|
} else if (block.type === "tool_use" && block.name) {
|
|
143
169
|
let detail = block.name;
|
|
144
170
|
const input = block.input;
|
|
145
171
|
if (input) {
|
|
146
172
|
if (typeof input.file_path === "string") {
|
|
147
|
-
detail += ` \u2192 ${input.file_path}`;
|
|
173
|
+
detail += ` ${C.grey}\u2192${C.lightGrey} ${input.file_path}`;
|
|
148
174
|
} else if (typeof input.command === "string") {
|
|
149
175
|
const cmd = input.command.length > 80 ? input.command.slice(0, 77) + "\u2026" : input.command;
|
|
150
|
-
detail += ` \u2192 ${cmd}`;
|
|
176
|
+
detail += ` ${C.grey}\u2192${C.lightGrey} ${cmd}`;
|
|
151
177
|
}
|
|
152
178
|
}
|
|
153
|
-
parts.push(`${
|
|
179
|
+
parts.push(`${tag} ${C.grey}${detail}${C.reset}`);
|
|
154
180
|
}
|
|
155
181
|
}
|
|
156
182
|
return parts.length > 0 ? parts.join("\n") : null;
|
|
@@ -161,11 +187,11 @@ function formatStreamEvent(event, pid) {
|
|
|
161
187
|
const lines = [];
|
|
162
188
|
if (event.cost_usd !== void 0 || event.total_cost_usd !== void 0) {
|
|
163
189
|
const cost = event.cost_usd ?? event.total_cost_usd;
|
|
164
|
-
lines.push(`${
|
|
190
|
+
lines.push(`${tag} ${C.dim}cost: $${cost?.toFixed(4)}${C.reset}`);
|
|
165
191
|
}
|
|
166
192
|
if (event.result) {
|
|
167
|
-
const
|
|
168
|
-
lines.push(
|
|
193
|
+
const wrapped = wrapLines(tag, pad, `\u2713 ${event.result}`, C.green);
|
|
194
|
+
if (wrapped) lines.push(wrapped);
|
|
169
195
|
}
|
|
170
196
|
return lines.length > 0 ? lines.join("\n") : null;
|
|
171
197
|
}
|
|
@@ -257,7 +283,7 @@ function spawnClaudeCode(prompt, config, runOptions) {
|
|
|
257
283
|
const formatted = formatStreamEvent(event, pid);
|
|
258
284
|
if (formatted) console.log(formatted);
|
|
259
285
|
} catch {
|
|
260
|
-
console.log(
|
|
286
|
+
console.log(`${pidTag(pid)} ${C.dim}${trimmed}${C.reset}`);
|
|
261
287
|
}
|
|
262
288
|
}
|
|
263
289
|
});
|
|
@@ -265,7 +291,7 @@ function spawnClaudeCode(prompt, config, runOptions) {
|
|
|
265
291
|
errChunks.push(data);
|
|
266
292
|
if (config.verbose) {
|
|
267
293
|
const text = data.toString("utf-8").trimEnd();
|
|
268
|
-
if (text) console.error(
|
|
294
|
+
if (text) console.error(`${pidTag(pid)} ${C.dim}${text}${C.reset}`);
|
|
269
295
|
}
|
|
270
296
|
});
|
|
271
297
|
child.on("error", (err) => reject(new Error(`Failed to spawn claude: ${err.message}`)));
|
|
@@ -277,7 +303,7 @@ function spawnClaudeCode(prompt, config, runOptions) {
|
|
|
277
303
|
const formatted = formatStreamEvent(event, pid);
|
|
278
304
|
if (formatted) console.log(formatted);
|
|
279
305
|
} catch {
|
|
280
|
-
console.log(
|
|
306
|
+
console.log(`${pidTag(pid)} ${C.dim}${lineBuf.trim()}${C.reset}`);
|
|
281
307
|
}
|
|
282
308
|
}
|
|
283
309
|
const rawOutput = Buffer.concat(chunks).toString("utf-8");
|
|
@@ -349,7 +375,9 @@ function extractPullRequestUrl(stdout) {
|
|
|
349
375
|
return void 0;
|
|
350
376
|
}
|
|
351
377
|
async function processRun(client, run, config) {
|
|
352
|
-
const
|
|
378
|
+
const runTag = ` ${C.pid}[${run.id.slice(-8)}]${C.reset}`;
|
|
379
|
+
const log = (msg) => console.log(`${runTag} ${msg}`);
|
|
380
|
+
const logGreen = (msg) => console.log(`${runTag} ${C.green}${msg}${C.reset}`);
|
|
353
381
|
const detail = await client.getRunDetail(run.id);
|
|
354
382
|
const ownerName = run.owner?.name ?? detail.owner?.name ?? "unknown";
|
|
355
383
|
log(`\u{1F4CB} "${run.taskTitle}" \u2014 delegated by ${ownerName}`);
|
|
@@ -402,15 +430,15 @@ async function processRun(client, run, config) {
|
|
|
402
430
|
${stdout.slice(0, 2e3)}
|
|
403
431
|
\`\`\``;
|
|
404
432
|
await client.errorRun(run.id, errorMsg, { pullRequestUrl });
|
|
405
|
-
log(
|
|
433
|
+
log(`${C.red}\u274C Run errored (exit code ${exitCode})${C.reset}`);
|
|
406
434
|
return;
|
|
407
435
|
}
|
|
408
436
|
const resultText = extractResultText(stdout);
|
|
409
437
|
const cost = extractCost(stdout);
|
|
410
438
|
const summary = resultText;
|
|
411
439
|
await client.completeRun(run.id, summary, { ...cost, pullRequestUrl });
|
|
412
|
-
if (pullRequestUrl)
|
|
413
|
-
|
|
440
|
+
if (pullRequestUrl) logGreen(`\u{1F517} PR: ${pullRequestUrl}`);
|
|
441
|
+
logGreen(`\u2705 Run completed`);
|
|
414
442
|
} catch (err) {
|
|
415
443
|
const message = err instanceof Error ? err.message : String(err);
|
|
416
444
|
const errorBody = `Claude Code runner error:
|
|
@@ -420,9 +448,9 @@ ${message.slice(0, 2e3)}
|
|
|
420
448
|
try {
|
|
421
449
|
await client.errorRun(run.id, errorBody);
|
|
422
450
|
} catch {
|
|
423
|
-
log(
|
|
451
|
+
log(`${C.dim}\u26A0 Failed to report error to API${C.reset}`);
|
|
424
452
|
}
|
|
425
|
-
log(
|
|
453
|
+
log(`${C.red}\u274C Error: ${message}${C.reset}`);
|
|
426
454
|
}
|
|
427
455
|
}
|
|
428
456
|
function loadEnvFile() {
|