@tarcisiopgs/lisa 1.21.3 → 1.22.1

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 +77 -56
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -545,16 +545,18 @@ function startOverseer(proc, cwd, config2, getSnapshot = getGitSnapshot) {
545
545
  import { spawn } from "child_process";
546
546
  import { platform } from "os";
547
547
  var ANSI_REGEX = /\x1b(?:\[[0-9;?]*[a-zA-Z]|\][^\x07]*\x07|\([A-Z0-9]|[A-Z])/g;
548
+ var CTRL_D_REGEX = /\x04/g;
548
549
  function stripAnsi(text2) {
549
- return text2.replace(ANSI_REGEX, "").replace(/\r\n/g, "\n").replace(/\r/g, "");
550
+ return text2.replace(ANSI_REGEX, "").replace(CTRL_D_REGEX, "").replace(/\r\n/g, "\n").replace(/\r/g, "");
550
551
  }
551
552
  function buildPtyArgs(command, os) {
552
553
  const currentOs = os ?? platform();
554
+ const wrappedCommand = `${command} < /dev/null`;
553
555
  if (currentOs === "darwin") {
554
- return { file: "script", args: ["-qF", "/dev/null", "sh", "-c", command] };
556
+ return { file: "script", args: ["-qF", "/dev/null", "sh", "-c", wrappedCommand] };
555
557
  }
556
558
  if (currentOs === "linux") {
557
- return { file: "script", args: ["-qef", "-c", command, "/dev/null"] };
559
+ return { file: "script", args: ["-qef", "-c", wrappedCommand, "/dev/null"] };
558
560
  }
559
561
  return null;
560
562
  }
@@ -5735,70 +5737,88 @@ import { resolve as resolve9 } from "path";
5735
5737
  async function runWorktreeMultiRepoSession(config2, issue2, logFile, session, models) {
5736
5738
  const workspace = resolve9(config2.workspace);
5737
5739
  const planPath = getPlanPath(workspace, issue2.id);
5738
- cleanupPlanFile(planPath);
5739
5740
  initLogFile(logFile);
5740
5741
  kanbanEmitter.emit("issue:log-file", issue2.id, logFile);
5741
- startSpinner(`${issue2.id} \u2014 analyzing issue...`);
5742
- log(`Multi-repo planning phase for ${issue2.id}`);
5743
- const globalContextMd = readContext(workspace);
5744
- const planPrompt = buildPlanningPrompt(issue2, config2, planPath, globalContextMd);
5745
- const planResult = await runWithFallback(models, planPrompt, {
5746
- logFile,
5747
- cwd: workspace,
5748
- guardrailsDir: workspace,
5749
- issueId: issue2.id,
5750
- overseer: config2.overseer,
5751
- sessionTimeout: config2.loop.session_timeout,
5752
- outputStallTimeout: config2.loop.output_stall_timeout,
5753
- onProcess: (pid) => {
5754
- activeProviderPids.set(issue2.id, pid);
5755
- },
5756
- shouldAbort: () => userKilledSet.has(issue2.id) || userSkippedSet.has(issue2.id)
5757
- });
5758
- stopSpinner();
5759
- try {
5760
- appendFileSync10(
5742
+ const cachedPlan = readPlanFile(planPath);
5743
+ let planProviderUsed = models[0]?.provider ?? "claude";
5744
+ let planFallback = null;
5745
+ let sortedSteps;
5746
+ if (cachedPlan?.steps && cachedPlan.steps.length > 0) {
5747
+ sortedSteps = [...cachedPlan.steps].sort((a, b) => a.order - b.order);
5748
+ ok(
5749
+ `Reusing cached plan for ${issue2.id}: ${sortedSteps.length} step(s) \u2014 ${sortedSteps.map((s) => s.repoPath).join(" \u2192 ")}`
5750
+ );
5751
+ } else {
5752
+ startSpinner(`${issue2.id} \u2014 analyzing issue...`);
5753
+ log(`Multi-repo planning phase for ${issue2.id}`);
5754
+ const globalContextMd = readContext(workspace);
5755
+ const planPrompt = buildPlanningPrompt(issue2, config2, planPath, globalContextMd);
5756
+ const planResult = await runWithFallback(models, planPrompt, {
5761
5757
  logFile,
5762
- `
5758
+ cwd: workspace,
5759
+ guardrailsDir: workspace,
5760
+ issueId: issue2.id,
5761
+ overseer: config2.overseer,
5762
+ sessionTimeout: config2.loop.session_timeout,
5763
+ outputStallTimeout: config2.loop.output_stall_timeout,
5764
+ onProcess: (pid) => {
5765
+ activeProviderPids.set(issue2.id, pid);
5766
+ },
5767
+ shouldAbort: () => userKilledSet.has(issue2.id) || userSkippedSet.has(issue2.id)
5768
+ });
5769
+ stopSpinner();
5770
+ planProviderUsed = planResult.providerUsed;
5771
+ planFallback = planResult;
5772
+ try {
5773
+ appendFileSync10(
5774
+ logFile,
5775
+ `
5763
5776
  ${"=".repeat(80)}
5764
5777
  Planning phase \u2014 provider: ${planResult.providerUsed}
5765
5778
  ${planResult.output}
5766
5779
  `
5780
+ );
5781
+ } catch {
5782
+ }
5783
+ if (!planResult.success) {
5784
+ error(`Planning phase failed for ${issue2.id}. Check ${logFile}`);
5785
+ cleanupPlanFile(planPath);
5786
+ activeProviderPids.delete(issue2.id);
5787
+ return {
5788
+ success: false,
5789
+ providerUsed: planResult.providerUsed,
5790
+ prUrls: [],
5791
+ fallback: planResult
5792
+ };
5793
+ }
5794
+ const plan = readPlanFile(planPath);
5795
+ if (!plan?.steps || plan.steps.length === 0) {
5796
+ error(`Agent did not produce a valid execution plan for ${issue2.id}. Aborting.`);
5797
+ cleanupPlanFile(planPath);
5798
+ activeProviderPids.delete(issue2.id);
5799
+ return {
5800
+ success: false,
5801
+ providerUsed: planResult.providerUsed,
5802
+ prUrls: [],
5803
+ fallback: planResult
5804
+ };
5805
+ }
5806
+ sortedSteps = [...plan.steps].sort((a, b) => a.order - b.order);
5807
+ ok(
5808
+ `Plan produced ${sortedSteps.length} step(s): ${sortedSteps.map((s) => s.repoPath).join(" \u2192 ")}`
5767
5809
  );
5768
- } catch {
5769
- }
5770
- if (!planResult.success) {
5771
- error(`Planning phase failed for ${issue2.id}. Check ${logFile}`);
5772
- cleanupPlanFile(planPath);
5773
- activeProviderPids.delete(issue2.id);
5774
- return {
5775
- success: false,
5776
- providerUsed: planResult.providerUsed,
5777
- prUrls: [],
5778
- fallback: planResult
5779
- };
5780
- }
5781
- const plan = readPlanFile(planPath);
5782
- if (!plan?.steps || plan.steps.length === 0) {
5783
- error(`Agent did not produce a valid execution plan for ${issue2.id}. Aborting.`);
5784
- cleanupPlanFile(planPath);
5785
- activeProviderPids.delete(issue2.id);
5786
- return {
5787
- success: false,
5788
- providerUsed: planResult.providerUsed,
5789
- prUrls: [],
5790
- fallback: planResult
5791
- };
5792
5810
  }
5793
- const sortedSteps = [...plan.steps].sort((a, b) => a.order - b.order);
5794
- ok(
5795
- `Plan produced ${sortedSteps.length} step(s): ${sortedSteps.map((s) => s.repoPath).join(" \u2192 ")}`
5796
- );
5797
- cleanupPlanFile(planPath);
5811
+ const defaultFallback = planFallback ?? {
5812
+ success: true,
5813
+ output: "",
5814
+ duration: 0,
5815
+ providerUsed: planProviderUsed,
5816
+ attempts: []
5817
+ };
5798
5818
  const prUrls = [];
5799
5819
  const previousResults = [];
5800
- let lastFallback = planResult;
5801
- let lastProvider = planResult.providerUsed;
5820
+ let lastFallback = defaultFallback;
5821
+ let lastProvider = planProviderUsed;
5802
5822
  for (const [i, step] of sortedSteps.entries()) {
5803
5823
  const stepNum = i + 1;
5804
5824
  const isLastStep = i === sortedSteps.length - 1;
@@ -5836,6 +5856,7 @@ ${planResult.output}
5836
5856
  });
5837
5857
  }
5838
5858
  activeProviderPids.delete(issue2.id);
5859
+ cleanupPlanFile(planPath);
5839
5860
  ok(`Session ${session} complete for ${issue2.id} \u2014 ${prUrls.length} PR(s) created`);
5840
5861
  return { success: true, providerUsed: lastProvider, prUrls, fallback: lastFallback };
5841
5862
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tarcisiopgs/lisa",
3
- "version": "1.21.3",
3
+ "version": "1.22.1",
4
4
  "description": "Autonomous issue resolver",
5
5
  "keywords": [
6
6
  "loop",