@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.
- package/bin/locus.js +57 -13
- 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
|
-
|
|
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(
|
|
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:
|
|
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:
|
|
10648
|
+
cwd: workDir,
|
|
10622
10649
|
encoding: "utf-8",
|
|
10623
10650
|
stdio: ["pipe", "pipe", "pipe"]
|
|
10624
10651
|
}).trim();
|
|
10625
10652
|
if (!diff) {
|
|
10626
|
-
|
|
10653
|
+
process.stderr.write(` ${yellow2("⚠")} No changes detected — skipping PR creation
|
|
10654
|
+
`);
|
|
10627
10655
|
return;
|
|
10628
10656
|
}
|
|
10629
|
-
pushSubmoduleBranches(
|
|
10657
|
+
pushSubmoduleBranches(workDir);
|
|
10630
10658
|
execSync14(`git push -u origin ${currentBranch}`, {
|
|
10631
|
-
cwd:
|
|
10659
|
+
cwd: workDir,
|
|
10632
10660
|
encoding: "utf-8",
|
|
10633
10661
|
stdio: ["pipe", "pipe", "pipe"]
|
|
10634
10662
|
});
|
|
10635
|
-
const submoduleSummary = getSubmoduleChangeSummary(
|
|
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:
|
|
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:
|
|
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:
|
|
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
|
-
|
|
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
|
+
"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.
|
|
39
|
+
"@locusai/sdk": "^0.25.4",
|
|
40
40
|
"@types/bun": "latest",
|
|
41
41
|
"typescript": "^5.8.3"
|
|
42
42
|
},
|