@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.
Files changed (2) hide show
  1. package/dist/index.js +39 -10
  2. 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
- "- You may create PRs with `gh pr create`. You may push branches and contribute to existing PRs.",
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. If you created a PR or made commits, include the PR URL and branch name."
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 extractPullRequestUrl(stdout) {
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 match2 = text.match(GITHUB_PR_URL_RE);
371
- if (match2) return match2[match2.length - 1];
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 = extractPullRequestUrl(stdout) ?? extractPullRequestUrl(rawOutput);
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
- const summary = resultText;
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) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@groupchatai/claude-runner",
3
- "version": "0.2.1",
3
+ "version": "0.2.3",
4
4
  "description": "Run GroupChat AI agent tasks locally with Claude Code",
5
5
  "type": "module",
6
6
  "bin": {