@tarcisiopgs/lisa 1.38.4 → 1.39.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.
- package/dist/{chunk-UA22HIYE.js → chunk-5O3ECNWK.js} +33 -3
- package/dist/{chunk-BKKDHLUA.js → chunk-RZ53EOAY.js} +2 -2
- package/dist/{chunk-LR2GREZS.js → chunk-SOV2YONG.js} +5 -0
- package/dist/{chunk-246P5Z5G.js → chunk-YTUZFCU2.js} +3 -2
- package/dist/index.js +14 -8
- package/dist/{kanban-6WPOGFK5.js → kanban-XCQ6QNOL.js} +17 -3
- package/dist/{loop-CHG2SZUB.js → loop-OLYIVX3B.js} +3 -3
- package/dist/{tui-bridge-HNJ5ADCJ.js → tui-bridge-GGH36LIH.js} +3 -3
- package/package.json +1 -1
|
@@ -19,10 +19,10 @@ import {
|
|
|
19
19
|
readContext,
|
|
20
20
|
resolveModels,
|
|
21
21
|
runWithFallback
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-YTUZFCU2.js";
|
|
23
23
|
import {
|
|
24
24
|
kanbanEmitter
|
|
25
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-SOV2YONG.js";
|
|
26
26
|
import {
|
|
27
27
|
appendPlatformAttribution,
|
|
28
28
|
appendPlatformProofOfWork,
|
|
@@ -1188,6 +1188,27 @@ function emptyCommitFailure(result) {
|
|
|
1188
1188
|
]
|
|
1189
1189
|
});
|
|
1190
1190
|
}
|
|
1191
|
+
async function pullBaseBranch(config) {
|
|
1192
|
+
const workspace = resolve3(config.workspace);
|
|
1193
|
+
const baseBranch = config.base_branch;
|
|
1194
|
+
const repoPaths = [workspace];
|
|
1195
|
+
if (config.repos.length > 0) {
|
|
1196
|
+
for (const repo of config.repos) {
|
|
1197
|
+
repoPaths.push(resolve3(workspace, repo.path));
|
|
1198
|
+
}
|
|
1199
|
+
}
|
|
1200
|
+
for (const repoPath of repoPaths) {
|
|
1201
|
+
try {
|
|
1202
|
+
await execa("git", ["pull", "--ff-only", "origin", baseBranch], {
|
|
1203
|
+
cwd: repoPath,
|
|
1204
|
+
reject: true,
|
|
1205
|
+
timeout: 3e4
|
|
1206
|
+
});
|
|
1207
|
+
} catch (err) {
|
|
1208
|
+
warn(`Failed to pull ${baseBranch} in ${repoPath}: ${formatError(err)}`);
|
|
1209
|
+
}
|
|
1210
|
+
}
|
|
1211
|
+
}
|
|
1191
1212
|
function appendSessionLog(logFile, result) {
|
|
1192
1213
|
try {
|
|
1193
1214
|
appendFileSync(
|
|
@@ -2092,6 +2113,7 @@ async function monitorCi(branch, config, issue, models, cwd, logFile, workspace,
|
|
|
2092
2113
|
let retriesLeft = maxRetries;
|
|
2093
2114
|
while (true) {
|
|
2094
2115
|
startSpinner(`${issue.id} \u2014 waiting for CI...`);
|
|
2116
|
+
kanbanEmitter.emit("issue:ci-status", issue.id, "pending");
|
|
2095
2117
|
const startTime = Date.now();
|
|
2096
2118
|
let lastRun = null;
|
|
2097
2119
|
while (Date.now() - startTime < pollTimeout) {
|
|
@@ -2103,10 +2125,12 @@ async function monitorCi(branch, config, issue, models, cwd, logFile, workspace,
|
|
|
2103
2125
|
}
|
|
2104
2126
|
if (lastRun.status === "success") {
|
|
2105
2127
|
stopSpinner();
|
|
2128
|
+
kanbanEmitter.emit("issue:ci-status", issue.id, "passing");
|
|
2106
2129
|
ok(`CI passed: ${lastRun.name}`);
|
|
2107
2130
|
return { passed: true, skipped: false, attempts: maxRetries - retriesLeft };
|
|
2108
2131
|
}
|
|
2109
2132
|
if (lastRun.status === "failure") {
|
|
2133
|
+
kanbanEmitter.emit("issue:ci-status", issue.id, "failing");
|
|
2110
2134
|
break;
|
|
2111
2135
|
}
|
|
2112
2136
|
await sleep2(pollInterval);
|
|
@@ -2656,7 +2680,11 @@ function cleanupManifest(cwd, issueId) {
|
|
|
2656
2680
|
function readManifestFile(filePath) {
|
|
2657
2681
|
if (!existsSync6(filePath)) return null;
|
|
2658
2682
|
try {
|
|
2659
|
-
|
|
2683
|
+
const parsed = JSON.parse(readFileSync6(filePath, "utf-8").trim());
|
|
2684
|
+
if (Array.isArray(parsed)) {
|
|
2685
|
+
return parsed.find((m) => m.prUrl) ?? null;
|
|
2686
|
+
}
|
|
2687
|
+
return parsed;
|
|
2660
2688
|
} catch {
|
|
2661
2689
|
return null;
|
|
2662
2690
|
}
|
|
@@ -3505,6 +3533,7 @@ async function runConcurrentLoop(config, source, models, workspace, opts) {
|
|
|
3505
3533
|
kanbanEmitter.emit("issue:started", issue.id);
|
|
3506
3534
|
await moveToInProgress(issue, source, config);
|
|
3507
3535
|
activeCleanups.set(issue.id, { previousStatus, source, sourceConfig: config.source_config });
|
|
3536
|
+
await pullBaseBranch(config);
|
|
3508
3537
|
let sessionResult;
|
|
3509
3538
|
try {
|
|
3510
3539
|
sessionResult = await runWorktreeSession(
|
|
@@ -4145,6 +4174,7 @@ async function runSequentialLoop(config, source, models, workspace, opts) {
|
|
|
4145
4174
|
kanbanEmitter.emit("issue:started", issue.id);
|
|
4146
4175
|
await moveToInProgress(issue, source, config);
|
|
4147
4176
|
activeCleanups.set(issue.id, { previousStatus, source, sourceConfig: config.source_config });
|
|
4177
|
+
await pullBaseBranch(config);
|
|
4148
4178
|
let sessionResult;
|
|
4149
4179
|
try {
|
|
4150
4180
|
sessionResult = config.workflow === "worktree" ? await runWorktreeSession(config, issue, logFile, session, models, source) : await runBranchSession(config, issue, logFile, session, models, source);
|
|
@@ -891,6 +891,9 @@ function useKanbanState(bellEnabled, initialCards = []) {
|
|
|
891
891
|
const onSubstatus = (issueId, substatus) => {
|
|
892
892
|
setCards((prev) => prev.map((c) => c.id === issueId ? { ...c, substatus } : c));
|
|
893
893
|
};
|
|
894
|
+
const onCiStatus = (issueId, ciStatus) => {
|
|
895
|
+
setCards((prev) => prev.map((c) => c.id === issueId ? { ...c, ciStatus } : c));
|
|
896
|
+
};
|
|
894
897
|
const onReviewersUpdated = (issueId, reviewers) => {
|
|
895
898
|
setCards((prev) => prev.map((c) => c.id === issueId ? { ...c, reviewers } : c));
|
|
896
899
|
};
|
|
@@ -947,6 +950,7 @@ function useKanbanState(bellEnabled, initialCards = []) {
|
|
|
947
950
|
kanbanEmitter.on("provider:resumed", onProviderResumed);
|
|
948
951
|
kanbanEmitter.on("issue:log-file", onLogFile);
|
|
949
952
|
kanbanEmitter.on("issue:substatus", onSubstatus);
|
|
953
|
+
kanbanEmitter.on("issue:ci-status", onCiStatus);
|
|
950
954
|
kanbanEmitter.on("issue:reviewers-updated", onReviewersUpdated);
|
|
951
955
|
kanbanEmitter.on("issue:available-reviewers", onAvailableReviewers);
|
|
952
956
|
kanbanEmitter.on("issue:output", onOutput);
|
|
@@ -995,6 +999,7 @@ function useKanbanState(bellEnabled, initialCards = []) {
|
|
|
995
999
|
kanbanEmitter.off("provider:resumed", onProviderResumed);
|
|
996
1000
|
kanbanEmitter.off("issue:log-file", onLogFile);
|
|
997
1001
|
kanbanEmitter.off("issue:substatus", onSubstatus);
|
|
1002
|
+
kanbanEmitter.off("issue:ci-status", onCiStatus);
|
|
998
1003
|
kanbanEmitter.off("issue:reviewers-updated", onReviewersUpdated);
|
|
999
1004
|
kanbanEmitter.off("issue:available-reviewers", onAvailableReviewers);
|
|
1000
1005
|
kanbanEmitter.off("issue:output", onOutput);
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
createApiClient,
|
|
7
7
|
kanbanEmitter,
|
|
8
8
|
normalizeLabels
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-SOV2YONG.js";
|
|
10
10
|
import {
|
|
11
11
|
buildPrCreateInstruction
|
|
12
12
|
} from "./chunk-ZOVVFU7B.js";
|
|
@@ -500,7 +500,8 @@ function buildValidateStep(testRunner, pm = "npm") {
|
|
|
500
500
|
` : "";
|
|
501
501
|
return `**Validate**: Confirm all quality gates before committing:
|
|
502
502
|
${testLine} - Run lint/typecheck scripts if available (e.g., \`npm run lint\`, \`npm run typecheck\`).
|
|
503
|
-
- Fix every error. Do NOT commit with failing tests or lint errors
|
|
503
|
+
- Fix every error. Do NOT commit with failing tests or lint errors.
|
|
504
|
+
- Run the **full** test suite, not just the files you changed \u2014 your changes may break existing tests that import or mock the same modules.`;
|
|
504
505
|
}
|
|
505
506
|
function buildPreCommitHookInstructions() {
|
|
506
507
|
return `
|
package/dist/index.js
CHANGED
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
runLoop,
|
|
15
15
|
saveConfig,
|
|
16
16
|
validateConfig
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-5O3ECNWK.js";
|
|
18
18
|
import {
|
|
19
19
|
CliError,
|
|
20
20
|
buildExecutionWaves,
|
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
parseStructuredOutput,
|
|
25
25
|
runPlanWizard,
|
|
26
26
|
savePlan
|
|
27
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-RZ53EOAY.js";
|
|
28
28
|
import {
|
|
29
29
|
buildContextMdBlock,
|
|
30
30
|
createProvider,
|
|
@@ -34,10 +34,10 @@ import {
|
|
|
34
34
|
readContext,
|
|
35
35
|
resolveModels,
|
|
36
36
|
runWithFallback
|
|
37
|
-
} from "./chunk-
|
|
37
|
+
} from "./chunk-YTUZFCU2.js";
|
|
38
38
|
import {
|
|
39
39
|
kanbanEmitter
|
|
40
|
-
} from "./chunk-
|
|
40
|
+
} from "./chunk-SOV2YONG.js";
|
|
41
41
|
import {
|
|
42
42
|
isProofOfWorkEnabled,
|
|
43
43
|
isSpecComplianceEnabled,
|
|
@@ -1850,7 +1850,7 @@ async function reviewAndCreate(plan2, planPath, opts) {
|
|
|
1850
1850
|
log("Run `lisa run` when ready.");
|
|
1851
1851
|
return;
|
|
1852
1852
|
}
|
|
1853
|
-
const { runLoop: runLoop2 } = await import("./loop-
|
|
1853
|
+
const { runLoop: runLoop2 } = await import("./loop-OLYIVX3B.js");
|
|
1854
1854
|
const waves = buildExecutionWaves(plan2.issues);
|
|
1855
1855
|
const maxWaveSize = Math.max(...waves.map((w) => w.length));
|
|
1856
1856
|
await runLoop2(config2, {
|
|
@@ -1945,6 +1945,7 @@ function resolveCard(card) {
|
|
|
1945
1945
|
finishedAt: card.finishedAt ?? Date.now(),
|
|
1946
1946
|
prUrls: card.prUrls,
|
|
1947
1947
|
merged: card.merged,
|
|
1948
|
+
ciStatus: card.ciStatus,
|
|
1948
1949
|
logFile: card.logFile,
|
|
1949
1950
|
outputLog: card.outputLogTail.join("\n")
|
|
1950
1951
|
};
|
|
@@ -1971,6 +1972,7 @@ function resolveCard(card) {
|
|
|
1971
1972
|
skipped: card.skipped,
|
|
1972
1973
|
killed: card.killed,
|
|
1973
1974
|
merged: card.merged,
|
|
1975
|
+
ciStatus: card.ciStatus,
|
|
1974
1976
|
logFile: card.logFile,
|
|
1975
1977
|
outputLog: card.outputLogTail.join("\n")
|
|
1976
1978
|
};
|
|
@@ -2055,6 +2057,10 @@ var KanbanPersistence = class {
|
|
|
2055
2057
|
this.updateCard(issueId, { substatus });
|
|
2056
2058
|
this.scheduleFlush();
|
|
2057
2059
|
});
|
|
2060
|
+
on("issue:ci-status", (issueId, ciStatus) => {
|
|
2061
|
+
this.updateCard(issueId, { ciStatus });
|
|
2062
|
+
this.scheduleFlush();
|
|
2063
|
+
});
|
|
2058
2064
|
on("issue:reconcile-remove", (issueId) => {
|
|
2059
2065
|
this.removeCard(issueId);
|
|
2060
2066
|
this.scheduleFlush();
|
|
@@ -2220,7 +2226,7 @@ async function executeRun(args) {
|
|
|
2220
2226
|
if (isTTY) {
|
|
2221
2227
|
const { render } = await import("ink");
|
|
2222
2228
|
const { createElement } = await import("react");
|
|
2223
|
-
const { KanbanApp } = await import("./kanban-
|
|
2229
|
+
const { KanbanApp } = await import("./kanban-XCQ6QNOL.js");
|
|
2224
2230
|
const demoConfig = {
|
|
2225
2231
|
provider: "claude",
|
|
2226
2232
|
source: "linear",
|
|
@@ -2320,7 +2326,7 @@ Add them to your ${shell} and run: source ${shell}`));
|
|
|
2320
2326
|
const initialCards = persistence.load();
|
|
2321
2327
|
persistedCards = initialCards;
|
|
2322
2328
|
persistence.start();
|
|
2323
|
-
const { registerPlanBridge } = await import("./tui-bridge-
|
|
2329
|
+
const { registerPlanBridge } = await import("./tui-bridge-GGH36LIH.js");
|
|
2324
2330
|
const cleanupPlan = registerPlanBridge(merged);
|
|
2325
2331
|
onBeforeExit = () => {
|
|
2326
2332
|
persistence.stop();
|
|
@@ -2328,7 +2334,7 @@ Add them to your ${shell} and run: source ${shell}`));
|
|
|
2328
2334
|
};
|
|
2329
2335
|
const { render } = await import("ink");
|
|
2330
2336
|
const { createElement } = await import("react");
|
|
2331
|
-
const { KanbanApp } = await import("./kanban-
|
|
2337
|
+
const { KanbanApp } = await import("./kanban-XCQ6QNOL.js");
|
|
2332
2338
|
render(createElement(KanbanApp, { config: merged, initialCards }), { exitOnCtrlC: false });
|
|
2333
2339
|
}
|
|
2334
2340
|
await runLoop(merged, {
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import {
|
|
3
3
|
kanbanEmitter,
|
|
4
4
|
useKanbanState
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-SOV2YONG.js";
|
|
6
6
|
import {
|
|
7
7
|
resetTitle,
|
|
8
8
|
startSpinner,
|
|
@@ -141,7 +141,10 @@ function Card({
|
|
|
141
141
|
"\u2714 ",
|
|
142
142
|
formatElapsed(card.finishedAt - card.startedAt)
|
|
143
143
|
] }),
|
|
144
|
-
card.prUrls.length > 0 && /* @__PURE__ */
|
|
144
|
+
card.prUrls.length > 0 && /* @__PURE__ */ jsxs(Text, { color: card.merged ? "magenta" : "yellow", dimColor: true, children: [
|
|
145
|
+
card.merged ? "PR\u2714" : "PR",
|
|
146
|
+
card.ciStatus === "pending" ? "\u23F3" : card.ciStatus === "passing" ? "\u2714" : card.ciStatus === "failing" ? "\u2716" : ""
|
|
147
|
+
] })
|
|
145
148
|
] }) : card.killed ? /* @__PURE__ */ jsx(Text, { color: "red", children: "KILLED" }) : card.skipped ? /* @__PURE__ */ jsx(Text, { color: "gray", children: "SKIPPED" }) : card.hasError && !card.killed && !card.skipped ? /* @__PURE__ */ jsx(Text, { color: "red", children: "FAILED" }) : (
|
|
146
149
|
// Empty row for backlog and done-without-timing — maintains CARD_HEIGHT
|
|
147
150
|
/* @__PURE__ */ jsx(Text, { children: " ".repeat(cardWidth) })
|
|
@@ -530,7 +533,8 @@ function IssueDetail({
|
|
|
530
533
|
const hasPrMeta = card.prUrls.length > 0 && (cardReviewers.length > 0 || assignees?.length);
|
|
531
534
|
const prMetaRow = hasPrMeta ? 1 : 0;
|
|
532
535
|
const pickerRows = showReviewerPicker ? Math.min((card.availableReviewers ?? []).length + 2, 12) : 0;
|
|
533
|
-
const
|
|
536
|
+
const ciRow = card.ciStatus ? 1 : 0;
|
|
537
|
+
const headerOverhead = 6 + prCount + logFileRow + ciRow + prMetaRow + pickerRows;
|
|
534
538
|
const bodyRows = Math.max(1, terminalRows - headerOverhead);
|
|
535
539
|
const lines = useMemo(() => processOutputLines(card.outputLog), [card.outputLog]);
|
|
536
540
|
const startLine = Math.max(0, lines.length - bodyRows - logScrollOffset);
|
|
@@ -595,6 +599,16 @@ function IssueDetail({
|
|
|
595
599
|
/* @__PURE__ */ jsx4(Text4, { color: "yellow", dimColor: true, children: card.prUrls.length === 1 ? "PR: " : `PR ${i + 1}: ` }),
|
|
596
600
|
/* @__PURE__ */ jsx4(Text4, { color: "yellow", wrap: "truncate", children: hyperlink(url, truncateLine(url, maxLineWidth - 5)) })
|
|
597
601
|
] }, url)),
|
|
602
|
+
card.ciStatus && /* @__PURE__ */ jsxs4(Box4, { marginTop: 0, children: [
|
|
603
|
+
/* @__PURE__ */ jsx4(Text4, { color: "gray", dimColor: true, children: "CI: " }),
|
|
604
|
+
/* @__PURE__ */ jsx4(
|
|
605
|
+
Text4,
|
|
606
|
+
{
|
|
607
|
+
color: card.ciStatus === "passing" ? "green" : card.ciStatus === "failing" ? "red" : "yellow",
|
|
608
|
+
children: card.ciStatus === "passing" ? "\u2714 passing" : card.ciStatus === "failing" ? "\u2716 failing" : "\u23F3 pending"
|
|
609
|
+
}
|
|
610
|
+
)
|
|
611
|
+
] }),
|
|
598
612
|
hasPrMeta && /* @__PURE__ */ jsxs4(Box4, { marginTop: 0, flexDirection: "row", children: [
|
|
599
613
|
cardReviewers.length > 0 ? /* @__PURE__ */ jsxs4(Fragment2, { children: [
|
|
600
614
|
/* @__PURE__ */ jsx4(Text4, { color: "cyan", dimColor: true, children: "REVIEWERS: " }),
|
|
@@ -4,11 +4,11 @@ import {
|
|
|
4
4
|
cleanupEventListeners,
|
|
5
5
|
runDemoLoop,
|
|
6
6
|
runLoop
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-5O3ECNWK.js";
|
|
8
8
|
import {
|
|
9
9
|
WATCH_POLL_INTERVAL_MS
|
|
10
|
-
} from "./chunk-
|
|
11
|
-
import "./chunk-
|
|
10
|
+
} from "./chunk-YTUZFCU2.js";
|
|
11
|
+
import "./chunk-SOV2YONG.js";
|
|
12
12
|
import "./chunk-ZOVVFU7B.js";
|
|
13
13
|
import "./chunk-3EOEDL3T.js";
|
|
14
14
|
import "./chunk-7OCDGYDM.js";
|
|
@@ -6,15 +6,15 @@ import {
|
|
|
6
6
|
markdownToIssue,
|
|
7
7
|
parseStructuredOutput,
|
|
8
8
|
savePlan
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-RZ53EOAY.js";
|
|
10
10
|
import {
|
|
11
11
|
createSource,
|
|
12
12
|
resolveModels,
|
|
13
13
|
runWithFallback
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-YTUZFCU2.js";
|
|
15
15
|
import {
|
|
16
16
|
kanbanEmitter
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-SOV2YONG.js";
|
|
18
18
|
import "./chunk-ZOVVFU7B.js";
|
|
19
19
|
import "./chunk-3EOEDL3T.js";
|
|
20
20
|
import "./chunk-7OCDGYDM.js";
|