@tarcisiopgs/lisa 1.39.2 → 1.40.0

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.
@@ -1138,6 +1138,13 @@ async function checkoutBaseBranches(config, workspace) {
1138
1138
  function sleep(ms) {
1139
1139
  return new Promise((resolve12) => setTimeout(resolve12, ms));
1140
1140
  }
1141
+ async function interruptibleSleep(ms) {
1142
+ const end = Date.now() + ms;
1143
+ while (Date.now() < end) {
1144
+ if (isShuttingDown() || hasUserQuitFromWatchPrompt()) return;
1145
+ await sleep(Math.min(1e3, end - Date.now()));
1146
+ }
1147
+ }
1141
1148
  async function waitIfPaused() {
1142
1149
  while (isLoopPaused()) {
1143
1150
  await sleep(500);
@@ -1229,6 +1236,18 @@ async function pullBaseBranch(config) {
1229
1236
  }
1230
1237
  }
1231
1238
  }
1239
+ async function autoMergePr(prUrl, issueId, config) {
1240
+ if (!config.pr?.auto_merge) return;
1241
+ log(`Auto-merging PR for ${issueId}...`);
1242
+ const { mergePr } = await import("./merge-NWSEV3FR.js");
1243
+ const result = await mergePr(prUrl);
1244
+ if (result.success) {
1245
+ ok(`Auto-merged: ${prUrl}`);
1246
+ kanbanEmitter.emit("issue:merged", issueId);
1247
+ } else {
1248
+ warn(`Auto-merge failed for ${issueId}: ${result.error}`);
1249
+ }
1250
+ }
1232
1251
  function appendSessionLog(logFile, result) {
1233
1252
  try {
1234
1253
  appendFileSync(
@@ -3234,6 +3253,7 @@ async function runNativeWorktreeSession(config, issue, logFile, session, models,
3234
3253
  }
3235
3254
  }
3236
3255
  if (worktreePath) await cleanupWorktree(repoPath, worktreePath);
3256
+ await autoMergePr(prUrl, issue.id, config);
3237
3257
  await reporter.finish([prUrl]);
3238
3258
  ok(`Session ${session} complete for ${issue.id}`);
3239
3259
  return {
@@ -3511,6 +3531,7 @@ async function runManualWorktreeSession(config, issue, logFile, session, models,
3511
3531
  }
3512
3532
  await executeHook("before_remove", config.hooks, worktreePath, hookEnv);
3513
3533
  await cleanupWorktree(repoPath, worktreePath);
3534
+ await autoMergePr(prUrl, issue.id, config);
3514
3535
  await reporter.finish([prUrl]);
3515
3536
  updateSessionState(workspace, issue.id, "done");
3516
3537
  removeSessionRecord(workspace, issue.id);
@@ -3669,7 +3690,11 @@ async function runConcurrentLoop(config, source, models, workspace, opts) {
3669
3690
  );
3670
3691
  kanbanEmitter.emit("work:watching");
3671
3692
  setTitle("Lisa \u2014 watching...");
3672
- await sleep(WATCH_POLL_INTERVAL_MS);
3693
+ await interruptibleSleep(WATCH_POLL_INTERVAL_MS);
3694
+ if (hasUserQuitFromWatchPrompt() || isShuttingDown()) {
3695
+ noMoreIssues = true;
3696
+ break;
3697
+ }
3673
3698
  kanbanEmitter.emit("work:watch-resume");
3674
3699
  }
3675
3700
  break;
@@ -4040,6 +4065,7 @@ async function runBranchSession(config, issue, logFile, session, models, source,
4040
4065
  }
4041
4066
  }
4042
4067
  }
4068
+ await autoMergePr(prUrl, issue.id, config);
4043
4069
  await reporter.finish([prUrl]);
4044
4070
  ok(`Session ${session} complete for ${issue.id}`);
4045
4071
  return {
@@ -4142,7 +4168,10 @@ async function runSequentialLoop(config, source, models, workspace, opts) {
4142
4168
  ok(`Resuming watch mode (polling every ${WATCH_POLL_INTERVAL_MS / 1e3}s)...`);
4143
4169
  kanbanEmitter.emit("work:watching");
4144
4170
  setTitle("Lisa \u2014 watching...");
4145
- await sleep(WATCH_POLL_INTERVAL_MS);
4171
+ await interruptibleSleep(WATCH_POLL_INTERVAL_MS);
4172
+ if (hasUserQuitFromWatchPrompt() || isShuttingDown()) {
4173
+ break;
4174
+ }
4146
4175
  kanbanEmitter.emit("work:watch-resume");
4147
4176
  session--;
4148
4177
  continue;
@@ -4152,7 +4181,10 @@ async function runSequentialLoop(config, source, models, workspace, opts) {
4152
4181
  );
4153
4182
  kanbanEmitter.emit("work:watching");
4154
4183
  setTitle("Lisa \u2014 watching...");
4155
- await sleep(WATCH_POLL_INTERVAL_MS);
4184
+ await interruptibleSleep(WATCH_POLL_INTERVAL_MS);
4185
+ if (hasUserQuitFromWatchPrompt() || isShuttingDown()) {
4186
+ break;
4187
+ }
4156
4188
  kanbanEmitter.emit("work:watch-resume");
4157
4189
  session--;
4158
4190
  continue;
package/dist/index.js CHANGED
@@ -14,7 +14,7 @@ import {
14
14
  runLoop,
15
15
  saveConfig,
16
16
  validateConfig
17
- } from "./chunk-FJ6YGFS2.js";
17
+ } from "./chunk-C2Y2NO6I.js";
18
18
  import {
19
19
  CliError,
20
20
  buildExecutionWaves,
@@ -708,6 +708,12 @@ This will cause Lisa to re-pick the issue on recovery. Consider using a differen
708
708
  });
709
709
  prReviewers = Array.isArray(reviewerValue) ? reviewerValue : reviewerValue.split(",").map((s) => s.trim()).filter(Boolean);
710
710
  }
711
+ const wantAutoMerge = await clack.confirm({
712
+ message: "Auto-merge PRs after CI passes?",
713
+ initialValue: initial?.pr?.auto_merge ?? false
714
+ });
715
+ if (clack.isCancel(wantAutoMerge)) return process.exit(0);
716
+ const autoMerge = wantAutoMerge === true;
711
717
  const cfg = {
712
718
  provider: providerName,
713
719
  provider_options: {
@@ -734,7 +740,12 @@ This will cause Lisa to re-pick the issue on recovery. Consider using a differen
734
740
  repos,
735
741
  loop: { cooldown: 10, max_sessions: 0 },
736
742
  ...reviewMonitorEnabled ? { review_monitor: { enabled: true } } : {},
737
- ...prReviewers.length ? { pr: { reviewers: prReviewers } } : {}
743
+ ...prReviewers.length || autoMerge ? {
744
+ pr: {
745
+ ...prReviewers.length ? { reviewers: prReviewers } : {},
746
+ ...autoMerge ? { auto_merge: true } : {}
747
+ }
748
+ } : {}
738
749
  };
739
750
  saveConfig(cfg);
740
751
  clack.outro(
@@ -1850,7 +1861,7 @@ async function reviewAndCreate(plan2, planPath, opts) {
1850
1861
  log("Run `lisa run` when ready.");
1851
1862
  return;
1852
1863
  }
1853
- const { runLoop: runLoop2 } = await import("./loop-XXHTAE2N.js");
1864
+ const { runLoop: runLoop2 } = await import("./loop-Y6YS76TH.js");
1854
1865
  const waves = buildExecutionWaves(plan2.issues);
1855
1866
  const maxWaveSize = Math.max(...waves.map((w) => w.length));
1856
1867
  await runLoop2(config2, {
@@ -4,7 +4,7 @@ import {
4
4
  cleanupEventListeners,
5
5
  runDemoLoop,
6
6
  runLoop
7
- } from "./chunk-FJ6YGFS2.js";
7
+ } from "./chunk-C2Y2NO6I.js";
8
8
  import {
9
9
  WATCH_POLL_INTERVAL_MS
10
10
  } from "./chunk-YTUZFCU2.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tarcisiopgs/lisa",
3
- "version": "1.39.2",
3
+ "version": "1.40.0",
4
4
  "description": "Autonomous issue resolver",
5
5
  "keywords": [
6
6
  "loop",