@tarcisiopgs/lisa 0.8.2 → 0.9.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.
Files changed (2) hide show
  1. package/dist/index.js +42 -36
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -968,9 +968,11 @@ function determineRepoPath(repos, issue, workspace) {
968
968
  }
969
969
  return join4(workspace, repos[0].path);
970
970
  }
971
- async function detectFeatureBranch(repos, issueId, workspace, globalBaseBranch) {
971
+ async function detectFeatureBranches(repos, issueId, workspace, globalBaseBranch) {
972
972
  const entries = repos.length > 0 ? repos.map((r) => ({ path: resolve3(workspace, r.path), baseBranch: r.base_branch })) : [{ path: workspace, baseBranch: globalBaseBranch }];
973
973
  const needle = issueId.toLowerCase();
974
+ const results = [];
975
+ const matched = /* @__PURE__ */ new Set();
974
976
  const currentBranches = [];
975
977
  for (const entry of entries) {
976
978
  try {
@@ -978,23 +980,26 @@ async function detectFeatureBranch(repos, issueId, workspace, globalBaseBranch)
978
980
  const current = stdout.trim();
979
981
  currentBranches.push({ ...entry, current });
980
982
  if (current && current.toLowerCase().includes(needle)) {
981
- return { repoPath: entry.path, branch: current };
983
+ results.push({ repoPath: entry.path, branch: current });
984
+ matched.add(entry.path);
982
985
  }
983
986
  } catch {
984
987
  }
985
988
  }
986
989
  for (const entry of currentBranches) {
987
- if (entry.current && entry.current !== entry.baseBranch) {
988
- return { repoPath: entry.path, branch: entry.current };
990
+ if (!matched.has(entry.path) && entry.current && entry.current !== entry.baseBranch) {
991
+ results.push({ repoPath: entry.path, branch: entry.current });
992
+ matched.add(entry.path);
989
993
  }
990
994
  }
991
995
  for (const entry of entries) {
996
+ if (matched.has(entry.path)) continue;
992
997
  const branch = await findBranchByIssueId(entry.path, issueId);
993
998
  if (branch) {
994
- return { repoPath: entry.path, branch };
999
+ results.push({ repoPath: entry.path, branch });
995
1000
  }
996
1001
  }
997
- return void 0;
1002
+ return results;
998
1003
  }
999
1004
 
1000
1005
  // src/loop.ts
@@ -1047,8 +1052,8 @@ async function runLoop(config2, opts) {
1047
1052
  } catch (err) {
1048
1053
  warn(`Failed to update status: ${err instanceof Error ? err.message : String(err)}`);
1049
1054
  }
1050
- const prUrl = config2.workflow === "worktree" ? await runWorktreeSession(config2, issue, logFile, session) : await runBranchSession(config2, issue, logFile, session);
1051
- if (prUrl) {
1055
+ const prUrls = config2.workflow === "worktree" ? await runWorktreeSession(config2, issue, logFile, session) : await runBranchSession(config2, issue, logFile, session);
1056
+ for (const prUrl of prUrls) {
1052
1057
  try {
1053
1058
  await source.attachPullRequest(issue.id, prUrl);
1054
1059
  ok(`Attached PR to ${issue.id}`);
@@ -1095,7 +1100,7 @@ async function runWorktreeSession(config2, issue, logFile, session) {
1095
1100
  worktreePath = await createWorktree(repoPath, branchName, defaultBranch);
1096
1101
  } catch (err) {
1097
1102
  error(`Failed to create worktree: ${err instanceof Error ? err.message : String(err)}`);
1098
- return;
1103
+ return [];
1099
1104
  }
1100
1105
  ok(`Worktree created at ${worktreePath}`);
1101
1106
  const prompt = buildImplementPrompt(issue, config2);
@@ -1113,9 +1118,9 @@ ${result.output}
1113
1118
  if (!result.success) {
1114
1119
  error(`Session ${session} failed for ${issue.id}. Check ${logFile}`);
1115
1120
  await cleanupWorktree(repoPath, worktreePath);
1116
- return void 0;
1121
+ return [];
1117
1122
  }
1118
- let prUrl;
1123
+ const prUrls = [];
1119
1124
  try {
1120
1125
  const repoInfo = await getRepoInfo(worktreePath);
1121
1126
  const pr = await createPullRequest({
@@ -1129,13 +1134,13 @@ ${result.output}
1129
1134
  Implemented by [lisa](https://github.com/tarcisiopgs/lisa).`
1130
1135
  }, config2.github);
1131
1136
  ok(`PR created: ${pr.html_url}`);
1132
- prUrl = pr.html_url;
1137
+ prUrls.push(pr.html_url);
1133
1138
  } catch (err) {
1134
1139
  error(`Failed to create PR: ${err instanceof Error ? err.message : String(err)}`);
1135
1140
  }
1136
1141
  await cleanupWorktree(repoPath, worktreePath);
1137
1142
  ok(`Session ${session} complete for ${issue.id}`);
1138
- return prUrl;
1143
+ return prUrls;
1139
1144
  }
1140
1145
  async function runBranchSession(config2, issue, logFile, session) {
1141
1146
  const provider = createProvider(config2.provider);
@@ -1154,37 +1159,38 @@ ${result.output}
1154
1159
  }
1155
1160
  if (!result.success) {
1156
1161
  error(`Session ${session} failed for ${issue.id}. Check ${logFile}`);
1157
- return void 0;
1162
+ return [];
1158
1163
  }
1159
- const detected = await detectFeatureBranch(config2.repos, issue.id, workspace, config2.base_branch);
1160
- const repoPath = detected?.repoPath ?? (determineRepoPath(config2.repos, issue, workspace) ?? workspace);
1161
- const baseBranch = resolveBaseBranch(config2, repoPath);
1162
- const headBranch = detected?.branch;
1163
- if (!headBranch || headBranch === baseBranch) {
1164
+ const detected = await detectFeatureBranches(config2.repos, issue.id, workspace, config2.base_branch);
1165
+ if (detected.length === 0) {
1164
1166
  error(`Could not detect feature branch for ${issue.id} \u2014 skipping PR creation`);
1165
1167
  ok(`Session ${session} complete for ${issue.id}`);
1166
- return void 0;
1168
+ return [];
1167
1169
  }
1168
- let prUrl;
1169
- try {
1170
- const repoInfo = await getRepoInfo(repoPath);
1171
- const pr = await createPullRequest({
1172
- owner: repoInfo.owner,
1173
- repo: repoInfo.repo,
1174
- head: headBranch,
1175
- base: baseBranch,
1176
- title: issue.title,
1177
- body: `Closes ${issue.url}
1170
+ const prUrls = [];
1171
+ for (const { repoPath, branch } of detected) {
1172
+ const baseBranch = resolveBaseBranch(config2, repoPath);
1173
+ if (branch === baseBranch) continue;
1174
+ try {
1175
+ const repoInfo = await getRepoInfo(repoPath);
1176
+ const pr = await createPullRequest({
1177
+ owner: repoInfo.owner,
1178
+ repo: repoInfo.repo,
1179
+ head: branch,
1180
+ base: baseBranch,
1181
+ title: issue.title,
1182
+ body: `Closes ${issue.url}
1178
1183
 
1179
1184
  Implemented by [lisa](https://github.com/tarcisiopgs/lisa).`
1180
- }, config2.github);
1181
- ok(`PR created: ${pr.html_url}`);
1182
- prUrl = pr.html_url;
1183
- } catch (err) {
1184
- error(`Failed to create PR: ${err instanceof Error ? err.message : String(err)}`);
1185
+ }, config2.github);
1186
+ ok(`PR created: ${pr.html_url}`);
1187
+ prUrls.push(pr.html_url);
1188
+ } catch (err) {
1189
+ error(`Failed to create PR: ${err instanceof Error ? err.message : String(err)}`);
1190
+ }
1185
1191
  }
1186
1192
  ok(`Session ${session} complete for ${issue.id}`);
1187
- return prUrl;
1193
+ return prUrls;
1188
1194
  }
1189
1195
  async function cleanupWorktree(repoRoot, worktreePath) {
1190
1196
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tarcisiopgs/lisa",
3
- "version": "0.8.2",
3
+ "version": "0.9.0",
4
4
  "description": "Autonomous issue resolver — AI agent loop for Linear/Trello",
5
5
  "type": "module",
6
6
  "bin": {