@locusai/cli 0.25.3 → 0.25.4

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/bin/locus.js +57 -13
  2. package/package.json +2 -2
package/bin/locus.js CHANGED
@@ -10529,7 +10529,8 @@ ${green("✓")} Issue #${issueNumber} completed ${dim2(`(${timer.formatted()})`)
10529
10529
  `);
10530
10530
  let prNumber;
10531
10531
  if (config.agent.autoPR && !options.skipPR) {
10532
- prNumber = await createIssuePR(projectRoot, config, issue);
10532
+ const workDir = options.worktreePath ?? projectRoot;
10533
+ prNumber = await createIssuePR(workDir, config, issue);
10533
10534
  }
10534
10535
  if (config.agent.autoLabel) {
10535
10536
  try {
@@ -10610,29 +10611,56 @@ ${aiResult.success ? green("✓") : red2("✗")} Iteration ${aiResult.success ?
10610
10611
  summary: extractSummary(aiResult.output)
10611
10612
  };
10612
10613
  }
10613
- async function createIssuePR(projectRoot, config, issue) {
10614
+ async function createIssuePR(workDir, config, issue) {
10614
10615
  try {
10616
+ try {
10617
+ commitDirtySubmodules(workDir, issue.number, issue.title);
10618
+ const status = execSync14("git status --porcelain", {
10619
+ cwd: workDir,
10620
+ encoding: "utf-8",
10621
+ stdio: ["pipe", "pipe", "pipe"]
10622
+ }).trim();
10623
+ if (status) {
10624
+ execSync14("git add -A", {
10625
+ cwd: workDir,
10626
+ encoding: "utf-8",
10627
+ stdio: ["pipe", "pipe", "pipe"]
10628
+ });
10629
+ const message = `chore: complete #${issue.number} - ${issue.title}
10630
+
10631
+ Co-Authored-By: LocusAgent <agent@locusai.team>`;
10632
+ execSync14("git commit -F -", {
10633
+ input: message,
10634
+ cwd: workDir,
10635
+ encoding: "utf-8",
10636
+ stdio: ["pipe", "pipe", "pipe"]
10637
+ });
10638
+ process.stderr.write(` ${dim2(`Committed uncommitted changes for #${issue.number}`)}
10639
+ `);
10640
+ }
10641
+ } catch {}
10615
10642
  const currentBranch = execSync14("git rev-parse --abbrev-ref HEAD", {
10616
- cwd: projectRoot,
10643
+ cwd: workDir,
10617
10644
  encoding: "utf-8",
10618
10645
  stdio: ["pipe", "pipe", "pipe"]
10619
10646
  }).trim();
10620
10647
  const diff = execSync14(`git diff origin/${config.agent.baseBranch}..HEAD --stat`, {
10621
- cwd: projectRoot,
10648
+ cwd: workDir,
10622
10649
  encoding: "utf-8",
10623
10650
  stdio: ["pipe", "pipe", "pipe"]
10624
10651
  }).trim();
10625
10652
  if (!diff) {
10626
- getLogger().verbose("No changes to create PR for");
10653
+ process.stderr.write(` ${yellow2("⚠")} No changes detected skipping PR creation
10654
+ `);
10627
10655
  return;
10628
10656
  }
10629
- pushSubmoduleBranches(projectRoot);
10657
+ pushSubmoduleBranches(workDir);
10630
10658
  execSync14(`git push -u origin ${currentBranch}`, {
10631
- cwd: projectRoot,
10659
+ cwd: workDir,
10632
10660
  encoding: "utf-8",
10633
10661
  stdio: ["pipe", "pipe", "pipe"]
10634
10662
  });
10635
- const submoduleSummary = getSubmoduleChangeSummary(projectRoot, config.agent.baseBranch);
10663
+ const submoduleSummary = getSubmoduleChangeSummary(workDir, config.agent.baseBranch);
10636
10664
  let prBody = `Closes #${issue.number}`;
10637
10665
  if (submoduleSummary) {
10638
10666
  prBody += `
@@ -10647,7 +10675,7 @@ ${submoduleSummary}`;
10647
10675
  const prTitle = `${issue.title} (#${issue.number})`;
10648
10676
  let prNumber;
10649
10677
  try {
10650
- const existing = execSync14(`gh pr list --head ${currentBranch} --base ${config.agent.baseBranch} --json number --limit 1`, { cwd: projectRoot, encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }).trim();
10678
+ const existing = execSync14(`gh pr list --head ${currentBranch} --base ${config.agent.baseBranch} --json number --limit 1`, { cwd: workDir, encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }).trim();
10651
10679
  const parsed = JSON.parse(existing);
10652
10680
  if (Array.isArray(parsed) && parsed.length > 0) {
10653
10681
  prNumber = parsed[0].number;
@@ -10657,7 +10685,7 @@ ${submoduleSummary}`;
10657
10685
  try {
10658
10686
  execSync14(`gh pr edit ${prNumber} --title ${JSON.stringify(prTitle)} --body-file -`, {
10659
10687
  input: prBody,
10660
- cwd: projectRoot,
10688
+ cwd: workDir,
10661
10689
  encoding: "utf-8",
10662
10690
  stdio: ["pipe", "pipe", "pipe"]
10663
10691
  });
@@ -10667,13 +10695,15 @@ ${submoduleSummary}`;
10667
10695
  getLogger().warn(`Failed to update PR #${prNumber}: ${editErr}`);
10668
10696
  }
10669
10697
  } else {
10670
- prNumber = createPR(prTitle, prBody, currentBranch, config.agent.baseBranch, { cwd: projectRoot });
10698
+ prNumber = createPR(prTitle, prBody, currentBranch, config.agent.baseBranch, { cwd: workDir });
10671
10699
  process.stderr.write(` ${green("✓")} Created PR #${prNumber}
10672
10700
  `);
10673
10701
  }
10674
10702
  return prNumber;
10675
10703
  } catch (e) {
10676
- getLogger().warn(`Failed to create PR: ${e}`);
10704
+ const errorMsg = e instanceof Error ? e.message : String(e);
10705
+ process.stderr.write(` ${red2("✗")} Failed to create PR: ${errorMsg}
10706
+ `);
10677
10707
  return;
10678
10708
  }
10679
10709
  }
@@ -11653,7 +11683,7 @@ async function handleSingleIssue(projectRoot, config, issueNumber, flags, sandbo
11653
11683
  ${bold2("Running sprint issue")} ${cyan2(`#${issueNumber}`)} ${dim2("(sequential)")}
11654
11684
 
11655
11685
  `);
11656
- await executeIssue(projectRoot, {
11686
+ const result2 = await executeIssue(projectRoot, {
11657
11687
  issueNumber,
11658
11688
  provider: execution.provider,
11659
11689
  model: execution.model,
@@ -11662,6 +11692,11 @@ ${bold2("Running sprint issue")} ${cyan2(`#${issueNumber}`)} ${dim2("(sequential
11662
11692
  sandboxName: execution.sandboxName,
11663
11693
  containerWorkdir: execution.containerWorkdir
11664
11694
  });
11695
+ if (!result2.success) {
11696
+ process.stderr.write(`
11697
+ ${red2("✗")} Issue #${issueNumber} execution failed${result2.error ? `: ${result2.error}` : ""}
11698
+ `);
11699
+ }
11665
11700
  return;
11666
11701
  }
11667
11702
  const randomSuffix = Math.random().toString(36).slice(2, 8);
@@ -11704,6 +11739,15 @@ ${bold2("Running issue")} ${cyan2(`#${issueNumber}`)} ${dim2(`(branch: ${branchN
11704
11739
  });
11705
11740
  log.info(`Checked out ${config.agent.baseBranch}`);
11706
11741
  } catch {}
11742
+ if (result.prNumber) {
11743
+ process.stderr.write(`
11744
+ ${green("✓")} Issue #${issueNumber} done — PR #${result.prNumber} opened
11745
+ `);
11746
+ } else if (config.agent.autoPR) {
11747
+ process.stderr.write(`
11748
+ ${yellow2("⚠")} Issue #${issueNumber} done — no PR was created (check errors above)
11749
+ `);
11750
+ }
11707
11751
  } else {
11708
11752
  process.stderr.write(` ${yellow2("⚠")} Branch ${dim2(branchName)} preserved for debugging.
11709
11753
  `);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@locusai/cli",
3
- "version": "0.25.3",
3
+ "version": "0.25.4",
4
4
  "description": "GitHub-native AI engineering assistant",
5
5
  "type": "module",
6
6
  "bin": {
@@ -36,7 +36,7 @@
36
36
  "license": "MIT",
37
37
  "dependencies": {},
38
38
  "devDependencies": {
39
- "@locusai/sdk": "^0.25.3",
39
+ "@locusai/sdk": "^0.25.4",
40
40
  "@types/bun": "latest",
41
41
  "typescript": "^5.8.3"
42
42
  },