@groupchatai/claude-runner 0.2.1 → 0.2.3
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 +39 -10
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -111,11 +111,12 @@ Due: ${new Date(detail.task.dueDate).toLocaleDateString()}`);
|
|
|
111
111
|
[
|
|
112
112
|
"\n---",
|
|
113
113
|
"RULES:",
|
|
114
|
-
"-
|
|
114
|
+
"- When you have made code changes, you MUST create a new branch, commit your changes, push to the remote, and open a PR using `gh pr create`. Do NOT skip PR creation \u2014 always open a real PR.",
|
|
115
|
+
"- You may push to existing branches and contribute to existing PRs.",
|
|
115
116
|
"- NEVER run `gh pr merge`. Do NOT merge any PR.",
|
|
116
117
|
"- NEVER run `gh pr close`. Do NOT close any PR.",
|
|
117
118
|
"- NEVER run `git push --force` or `git push -f`. No force pushes.",
|
|
118
|
-
"- When you are done, provide a clear summary of what you accomplished
|
|
119
|
+
"- When you are done, provide a clear summary of what you accomplished including the PR URL and branch name."
|
|
119
120
|
].join("\n")
|
|
120
121
|
);
|
|
121
122
|
return parts.join("\n");
|
|
@@ -363,17 +364,46 @@ function extractCost(stdout) {
|
|
|
363
364
|
return void 0;
|
|
364
365
|
}
|
|
365
366
|
var GITHUB_PR_URL_RE = /https:\/\/github\.com\/[^\s"'<>]+\/pull\/\d+/g;
|
|
366
|
-
function
|
|
367
|
+
function extractPullRequestUrlFromText(text) {
|
|
368
|
+
const match = text.match(GITHUB_PR_URL_RE);
|
|
369
|
+
if (match) return match[match.length - 1];
|
|
370
|
+
return void 0;
|
|
371
|
+
}
|
|
372
|
+
function extractPullRequestUrlFromOutput(stdout) {
|
|
367
373
|
const event = findResultEvent(stdout);
|
|
368
374
|
if (event) {
|
|
369
375
|
const text = typeof event.result === "string" ? event.result : typeof event.text === "string" ? event.text : "";
|
|
370
|
-
const
|
|
371
|
-
if (
|
|
376
|
+
const found = extractPullRequestUrlFromText(text);
|
|
377
|
+
if (found) return found;
|
|
378
|
+
}
|
|
379
|
+
return extractPullRequestUrlFromText(stdout);
|
|
380
|
+
}
|
|
381
|
+
async function detectPullRequestUrl(workDir) {
|
|
382
|
+
try {
|
|
383
|
+
const branch = await runShellCommand("git", ["rev-parse", "--abbrev-ref", "HEAD"], workDir);
|
|
384
|
+
if (!branch || branch === "main" || branch === "master") return void 0;
|
|
385
|
+
const prUrl = await runShellCommand(
|
|
386
|
+
"gh",
|
|
387
|
+
["pr", "view", branch, "--json", "url", "--jq", ".url"],
|
|
388
|
+
workDir
|
|
389
|
+
);
|
|
390
|
+
if (prUrl && prUrl.includes("github.com")) return prUrl;
|
|
391
|
+
} catch {
|
|
372
392
|
}
|
|
373
|
-
const match = stdout.match(GITHUB_PR_URL_RE);
|
|
374
|
-
if (match) return match[match.length - 1];
|
|
375
393
|
return void 0;
|
|
376
394
|
}
|
|
395
|
+
function runShellCommand(cmd, args, cwd) {
|
|
396
|
+
return new Promise((resolve, reject) => {
|
|
397
|
+
const child = spawn(cmd, args, { cwd, stdio: ["ignore", "pipe", "pipe"] });
|
|
398
|
+
const chunks = [];
|
|
399
|
+
child.stdout?.on("data", (d) => chunks.push(d));
|
|
400
|
+
child.on("error", reject);
|
|
401
|
+
child.on("close", (code) => {
|
|
402
|
+
if (code !== 0) return reject(new Error(`${cmd} exited with ${code}`));
|
|
403
|
+
resolve(Buffer.concat(chunks).toString("utf-8").trim());
|
|
404
|
+
});
|
|
405
|
+
});
|
|
406
|
+
}
|
|
377
407
|
async function processRun(client, run, config) {
|
|
378
408
|
const runTag = ` ${C.pid}[${run.id.slice(-8)}]${C.reset}`;
|
|
379
409
|
const log = (msg) => console.log(`${runTag} ${msg}`);
|
|
@@ -423,7 +453,7 @@ async function processRun(client, run, config) {
|
|
|
423
453
|
const { process: child, output } = spawnClaudeCode(prompt, config, runOptions);
|
|
424
454
|
log(`\u{1F916} Claude Code spawned (pid ${child.pid})`);
|
|
425
455
|
const { stdout, rawOutput, exitCode } = await output;
|
|
426
|
-
const pullRequestUrl =
|
|
456
|
+
const pullRequestUrl = await detectPullRequestUrl(config.workDir) ?? extractPullRequestUrlFromOutput(stdout) ?? extractPullRequestUrlFromOutput(rawOutput);
|
|
427
457
|
if (exitCode !== 0) {
|
|
428
458
|
const errorMsg = `Claude Code exited with code ${exitCode}:
|
|
429
459
|
\`\`\`
|
|
@@ -435,8 +465,7 @@ ${stdout.slice(0, 2e3)}
|
|
|
435
465
|
}
|
|
436
466
|
const resultText = extractResultText(stdout);
|
|
437
467
|
const cost = extractCost(stdout);
|
|
438
|
-
|
|
439
|
-
await client.completeRun(run.id, summary, { ...cost, pullRequestUrl });
|
|
468
|
+
await client.completeRun(run.id, resultText, { ...cost, pullRequestUrl });
|
|
440
469
|
if (pullRequestUrl) logGreen(`\u{1F517} PR: ${pullRequestUrl}`);
|
|
441
470
|
logGreen(`\u2705 Run completed`);
|
|
442
471
|
} catch (err) {
|