@tarcisiopgs/lisa 1.40.2 → 1.42.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/README.md +2 -2
- package/dist/{chunk-RZ53EOAY.js → chunk-6ZWVYPR5.js} +2 -2
- package/dist/{chunk-MC4SAOF2.js → chunk-JALGARX3.js} +11 -0
- package/dist/{chunk-BI6MR2UP.js → chunk-VVYGYOPG.js} +84 -43
- package/dist/{chunk-YTUZFCU2.js → chunk-YSFHP3A3.js} +31 -3
- package/dist/{chunk-SOV2YONG.js → chunk-ZHB4S7SP.js} +7 -0
- package/dist/{detection-2Z6TXYHU.js → detection-TGAZED6Q.js} +3 -1
- package/dist/index.js +26 -12
- package/dist/{kanban-XCQ6QNOL.js → kanban-QQ47VJUY.js} +21 -6
- package/dist/{loop-RWZJG7BG.js → loop-3OBNPSYF.js} +3 -3
- package/dist/{tui-bridge-GGH36LIH.js → tui-bridge-HVSZNVDO.js} +3 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -38,7 +38,7 @@ If something fails — pre-push hooks, quota limits, stuck processes — Lisa ha
|
|
|
38
38
|
## Features
|
|
39
39
|
|
|
40
40
|
- **7 issue trackers** — Linear, GitHub Issues, GitLab Issues, Jira, Trello, Plane, Shortcut
|
|
41
|
-
- **
|
|
41
|
+
- **10 AI agents** — Claude Code, Gemini CLI, GitHub Copilot CLI, Cursor Agent, Aider, Goose, OpenCode, Codex, Kilo Code, MiMo Code
|
|
42
42
|
- **AI planning** — describe a goal, the AI brainstorms with you, decomposes it into issues with dependencies, created in your tracker
|
|
43
43
|
- **Language-aware** — responds in the same language you write your goal in
|
|
44
44
|
- **Spec compliance** — LLM-verified acceptance criteria check before PR creation, with auto-retry
|
|
@@ -67,7 +67,7 @@ If something fails — pre-push hooks, quota limits, stuck processes — Lisa ha
|
|
|
67
67
|
| Gemini CLI | `gemini` | Goose | `goose` |
|
|
68
68
|
| GitHub Copilot CLI | `copilot` | Aider | `aider` |
|
|
69
69
|
| OpenCode | `opencode` | OpenAI Codex | `codex` |
|
|
70
|
-
| Kilo Code | `kilo` | | |
|
|
70
|
+
| Kilo Code | `kilo` | MiMo Code | `mimo` |
|
|
71
71
|
|
|
72
72
|
Configure models and provider-specific options:
|
|
73
73
|
|
|
@@ -111,6 +111,16 @@ function fetchOpenCodeModels() {
|
|
|
111
111
|
return [];
|
|
112
112
|
}
|
|
113
113
|
}
|
|
114
|
+
function fetchMimoModels() {
|
|
115
|
+
try {
|
|
116
|
+
const raw = execSync("mimo models", { encoding: "utf-8", timeout: 1e4 });
|
|
117
|
+
const clean = raw.replace(/\x1b\[[0-9;]*[mGKHFA-Z]/g, "");
|
|
118
|
+
return clean.split("\n").map((l) => l.trim()).filter((m) => /^[a-z0-9][\w.-]*\/.+/i.test(m));
|
|
119
|
+
} catch (err) {
|
|
120
|
+
verbose(`Failed to fetch MiMo models: ${formatError(err)}`);
|
|
121
|
+
return [];
|
|
122
|
+
}
|
|
123
|
+
}
|
|
114
124
|
function detectPlatformFromRemoteUrl(remoteUrl) {
|
|
115
125
|
if (/github\.com/.test(remoteUrl)) return "cli";
|
|
116
126
|
if (/gitlab\./.test(remoteUrl)) return "gitlab";
|
|
@@ -267,6 +277,7 @@ export {
|
|
|
267
277
|
fetchCursorModels,
|
|
268
278
|
fetchCopilotModels,
|
|
269
279
|
fetchOpenCodeModels,
|
|
280
|
+
fetchMimoModels,
|
|
270
281
|
detectPlatformFromRemoteUrl,
|
|
271
282
|
detectPlatform,
|
|
272
283
|
verifyPlatformCredential,
|
|
@@ -19,10 +19,10 @@ import {
|
|
|
19
19
|
readContext,
|
|
20
20
|
resolveModels,
|
|
21
21
|
runWithFallback
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-YSFHP3A3.js";
|
|
23
23
|
import {
|
|
24
24
|
kanbanEmitter
|
|
25
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-ZHB4S7SP.js";
|
|
26
26
|
import {
|
|
27
27
|
appendPlatformAttribution,
|
|
28
28
|
appendPlatformProofOfWork,
|
|
@@ -91,7 +91,8 @@ var VALID_PROVIDERS = [
|
|
|
91
91
|
"goose",
|
|
92
92
|
"aider",
|
|
93
93
|
"codex",
|
|
94
|
-
"kilo"
|
|
94
|
+
"kilo",
|
|
95
|
+
"mimo"
|
|
95
96
|
];
|
|
96
97
|
var VALID_SOURCES = [
|
|
97
98
|
"linear",
|
|
@@ -1240,46 +1241,52 @@ async function pullBaseBranch(config) {
|
|
|
1240
1241
|
}
|
|
1241
1242
|
var AUTO_MERGE_CI_TIMEOUT_MS = 10 * 60 * 1e3;
|
|
1242
1243
|
var AUTO_MERGE_POLL_MS = 15e3;
|
|
1243
|
-
async function
|
|
1244
|
-
if (!config.pr?.auto_merge) return;
|
|
1244
|
+
async function autoMergeAllPrs(prUrls, issueId, config) {
|
|
1245
|
+
if (!config.pr?.auto_merge || prUrls.length === 0) return;
|
|
1245
1246
|
const { checkPrCiStatus, mergePr } = await import("./merge-NWSEV3FR.js");
|
|
1246
|
-
|
|
1247
|
+
kanbanEmitter.emit("issue:auto-merge-status", issueId, "waiting");
|
|
1247
1248
|
kanbanEmitter.emit("issue:ci-status", issueId, "pending");
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
if (result.success) {
|
|
1257
|
-
ok(`Auto-merged: ${prUrl}`);
|
|
1258
|
-
kanbanEmitter.emit("issue:merged", issueId);
|
|
1259
|
-
} else {
|
|
1260
|
-
warn(`Auto-merge failed for ${issueId}: ${result.error}`);
|
|
1249
|
+
log(
|
|
1250
|
+
`Waiting for CI before auto-merge of ${issueId} (${prUrls.length} PR${prUrls.length > 1 ? "s" : ""})...`
|
|
1251
|
+
);
|
|
1252
|
+
const mergeOnePr = async (prUrl) => {
|
|
1253
|
+
const deadline = Date.now() + AUTO_MERGE_CI_TIMEOUT_MS;
|
|
1254
|
+
while (Date.now() < deadline) {
|
|
1255
|
+
if (isShuttingDown() || hasUserQuitFromWatchPrompt()) {
|
|
1256
|
+
return { url: prUrl, success: false, error: "shutdown" };
|
|
1261
1257
|
}
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
log(`No CI checks found for ${issueId}. Auto-merging...`);
|
|
1271
|
-
const result = await mergePr(prUrl);
|
|
1272
|
-
if (result.success) {
|
|
1273
|
-
ok(`Auto-merged: ${prUrl}`);
|
|
1274
|
-
kanbanEmitter.emit("issue:merged", issueId);
|
|
1275
|
-
} else {
|
|
1276
|
-
warn(`Auto-merge failed for ${issueId}: ${result.error}`);
|
|
1258
|
+
const ciStatus = await checkPrCiStatus(prUrl);
|
|
1259
|
+
if (ciStatus === "passing" || ciStatus === "unknown") {
|
|
1260
|
+
const result = await mergePr(prUrl);
|
|
1261
|
+
if (result.success) {
|
|
1262
|
+
ok(`Merged: ${prUrl}`);
|
|
1263
|
+
return { url: prUrl, success: true };
|
|
1264
|
+
}
|
|
1265
|
+
return { url: prUrl, success: false, error: result.error };
|
|
1277
1266
|
}
|
|
1278
|
-
|
|
1267
|
+
if (ciStatus === "failing") {
|
|
1268
|
+
return { url: prUrl, success: false, error: "CI failed" };
|
|
1269
|
+
}
|
|
1270
|
+
await sleep(AUTO_MERGE_POLL_MS);
|
|
1271
|
+
}
|
|
1272
|
+
return { url: prUrl, success: false, error: "CI timeout" };
|
|
1273
|
+
};
|
|
1274
|
+
kanbanEmitter.emit("issue:auto-merge-status", issueId, "merging");
|
|
1275
|
+
const results = await Promise.all(prUrls.map(mergeOnePr));
|
|
1276
|
+
const allMerged = results.every((r) => r.success);
|
|
1277
|
+
const failed = results.filter((r) => !r.success);
|
|
1278
|
+
if (allMerged) {
|
|
1279
|
+
kanbanEmitter.emit("issue:ci-status", issueId, "passing");
|
|
1280
|
+
kanbanEmitter.emit("issue:auto-merge-status", issueId, "merged");
|
|
1281
|
+
kanbanEmitter.emit("issue:merged", issueId);
|
|
1282
|
+
ok(`All ${prUrls.length} PRs auto-merged for ${issueId}`);
|
|
1283
|
+
} else {
|
|
1284
|
+
kanbanEmitter.emit("issue:ci-status", issueId, "failing");
|
|
1285
|
+
kanbanEmitter.emit("issue:auto-merge-status", issueId, "failed");
|
|
1286
|
+
for (const f of failed) {
|
|
1287
|
+
warn(`Auto-merge failed for ${f.url}: ${f.error}`);
|
|
1279
1288
|
}
|
|
1280
|
-
await sleep(AUTO_MERGE_POLL_MS);
|
|
1281
1289
|
}
|
|
1282
|
-
warn(`CI did not complete within timeout for ${issueId}. Skipping auto-merge.`);
|
|
1283
1290
|
}
|
|
1284
1291
|
function appendSessionLog(logFile, result) {
|
|
1285
1292
|
try {
|
|
@@ -2774,6 +2781,33 @@ function extractPrUrlFromOutput(output) {
|
|
|
2774
2781
|
}
|
|
2775
2782
|
return null;
|
|
2776
2783
|
}
|
|
2784
|
+
function extractAllPrUrlsFromOutput(output) {
|
|
2785
|
+
const patterns = [
|
|
2786
|
+
/https?:\/\/github\.com\/[^/]+\/[^/]+\/pull\/\d+/g,
|
|
2787
|
+
/https?:\/\/[^/]*gitlab[^/]*\/[^/].+?\/-\/merge_requests\/\d+/g,
|
|
2788
|
+
/https?:\/\/bitbucket\.org\/[^/]+\/[^/]+\/pull-requests\/\d+/g
|
|
2789
|
+
];
|
|
2790
|
+
const urls = /* @__PURE__ */ new Set();
|
|
2791
|
+
for (const pattern of patterns) {
|
|
2792
|
+
for (const match of output.matchAll(pattern)) {
|
|
2793
|
+
urls.add(match[0]);
|
|
2794
|
+
}
|
|
2795
|
+
}
|
|
2796
|
+
return [...urls];
|
|
2797
|
+
}
|
|
2798
|
+
function readAllManifestPrUrls(filePath) {
|
|
2799
|
+
if (!existsSync6(filePath)) return [];
|
|
2800
|
+
try {
|
|
2801
|
+
const parsed = JSON.parse(readFileSync6(filePath, "utf-8").trim());
|
|
2802
|
+
if (Array.isArray(parsed)) {
|
|
2803
|
+
return parsed.map((m) => m.prUrl).filter((url) => !!url);
|
|
2804
|
+
}
|
|
2805
|
+
const single = parsed;
|
|
2806
|
+
return single.prUrl ? [single.prUrl] : [];
|
|
2807
|
+
} catch {
|
|
2808
|
+
return [];
|
|
2809
|
+
}
|
|
2810
|
+
}
|
|
2777
2811
|
function readPlanFile(filePath) {
|
|
2778
2812
|
if (!existsSync6(filePath)) return null;
|
|
2779
2813
|
try {
|
|
@@ -3286,7 +3320,7 @@ async function runNativeWorktreeSession(config, issue, logFile, session, models,
|
|
|
3286
3320
|
}
|
|
3287
3321
|
}
|
|
3288
3322
|
if (worktreePath) await cleanupWorktree(repoPath, worktreePath);
|
|
3289
|
-
await
|
|
3323
|
+
await autoMergeAllPrs([prUrl], issue.id, config);
|
|
3290
3324
|
await reporter.finish([prUrl]);
|
|
3291
3325
|
ok(`Session ${session} complete for ${issue.id}`);
|
|
3292
3326
|
return {
|
|
@@ -3564,7 +3598,7 @@ async function runManualWorktreeSession(config, issue, logFile, session, models,
|
|
|
3564
3598
|
}
|
|
3565
3599
|
await executeHook("before_remove", config.hooks, worktreePath, hookEnv);
|
|
3566
3600
|
await cleanupWorktree(repoPath, worktreePath);
|
|
3567
|
-
await
|
|
3601
|
+
await autoMergeAllPrs([prUrl], issue.id, config);
|
|
3568
3602
|
await reporter.finish([prUrl]);
|
|
3569
3603
|
updateSessionState(workspace, issue.id, "done");
|
|
3570
3604
|
removeSessionRecord(workspace, issue.id);
|
|
@@ -3999,11 +4033,12 @@ async function runBranchSession(config, issue, logFile, session, models, source,
|
|
|
3999
4033
|
return failureResult(result.providerUsed, result);
|
|
4000
4034
|
}
|
|
4001
4035
|
const manifest = readManifestFile(manifestPath);
|
|
4036
|
+
const allManifestPrUrls = readAllManifestPrUrls(manifestPath);
|
|
4002
4037
|
try {
|
|
4003
4038
|
unlinkSync4(manifestPath);
|
|
4004
4039
|
} catch {
|
|
4005
4040
|
}
|
|
4006
|
-
let prUrl = manifest?.prUrl;
|
|
4041
|
+
let prUrl = manifest?.prUrl ?? allManifestPrUrls[0];
|
|
4007
4042
|
if (!prUrl) {
|
|
4008
4043
|
const extractedUrl = extractPrUrlFromOutput(result.output);
|
|
4009
4044
|
if (extractedUrl) {
|
|
@@ -4011,6 +4046,12 @@ async function runBranchSession(config, issue, logFile, session, models, source,
|
|
|
4011
4046
|
prUrl = extractedUrl;
|
|
4012
4047
|
}
|
|
4013
4048
|
}
|
|
4049
|
+
const allPrUrls = new Set(allManifestPrUrls);
|
|
4050
|
+
for (const url of extractAllPrUrlsFromOutput(result.output)) {
|
|
4051
|
+
allPrUrls.add(url);
|
|
4052
|
+
}
|
|
4053
|
+
if (prUrl) allPrUrls.add(prUrl);
|
|
4054
|
+
const prUrls = [...allPrUrls];
|
|
4014
4055
|
if (!prUrl) {
|
|
4015
4056
|
const hasChanges = await hasCodeChanges(workspace, config.base_branch);
|
|
4016
4057
|
if (!hasChanges) {
|
|
@@ -4098,13 +4139,13 @@ async function runBranchSession(config, issue, logFile, session, models, source,
|
|
|
4098
4139
|
}
|
|
4099
4140
|
}
|
|
4100
4141
|
}
|
|
4101
|
-
await
|
|
4102
|
-
await reporter.finish(
|
|
4142
|
+
await autoMergeAllPrs(prUrls, issue.id, config);
|
|
4143
|
+
await reporter.finish(prUrls);
|
|
4103
4144
|
ok(`Session ${session} complete for ${issue.id}`);
|
|
4104
4145
|
return {
|
|
4105
4146
|
success: true,
|
|
4106
4147
|
providerUsed: result.providerUsed,
|
|
4107
|
-
prUrls
|
|
4148
|
+
prUrls,
|
|
4108
4149
|
fallback: result
|
|
4109
4150
|
};
|
|
4110
4151
|
}
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
createApiClient,
|
|
7
7
|
kanbanEmitter,
|
|
8
8
|
normalizeLabels
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-ZHB4S7SP.js";
|
|
10
10
|
import {
|
|
11
11
|
buildPrCreateInstruction
|
|
12
12
|
} from "./chunk-ZOVVFU7B.js";
|
|
@@ -2105,6 +2105,32 @@ var KiloProvider = class {
|
|
|
2105
2105
|
}
|
|
2106
2106
|
};
|
|
2107
2107
|
|
|
2108
|
+
// src/providers/mimo.ts
|
|
2109
|
+
var MIMO_ERROR_PATTERN = /^Error /;
|
|
2110
|
+
var MimoProvider = class {
|
|
2111
|
+
name = "mimo";
|
|
2112
|
+
async isAvailable() {
|
|
2113
|
+
return isCommandAvailable("mimo");
|
|
2114
|
+
}
|
|
2115
|
+
async run(prompt, opts) {
|
|
2116
|
+
try {
|
|
2117
|
+
if (opts.model) validateShellArg(opts.model, "model");
|
|
2118
|
+
const modelFlag = opts.model ? `--model ${opts.model}` : "";
|
|
2119
|
+
const config = {
|
|
2120
|
+
name: "mimo",
|
|
2121
|
+
buildCommand: (promptCatExpr) => `mimo run --dangerously-skip-permissions ${modelFlag} ${promptCatExpr}`,
|
|
2122
|
+
logLine: `mimo run --dangerously-skip-permissions ${modelFlag || "(default model)"}`,
|
|
2123
|
+
kanbanLine: `$ mimo run --dangerously-skip-permissions ${modelFlag || "(default model)"} <prompt: ${prompt.length} chars>
|
|
2124
|
+
`,
|
|
2125
|
+
errorPattern: MIMO_ERROR_PATTERN
|
|
2126
|
+
};
|
|
2127
|
+
return await runProviderProcess(config, prompt, opts);
|
|
2128
|
+
} catch (err) {
|
|
2129
|
+
return { success: false, output: formatError(err), duration: 0 };
|
|
2130
|
+
}
|
|
2131
|
+
}
|
|
2132
|
+
};
|
|
2133
|
+
|
|
2108
2134
|
// src/providers/opencode.ts
|
|
2109
2135
|
var OpenCodeProvider = class {
|
|
2110
2136
|
name = "opencode";
|
|
@@ -2140,7 +2166,8 @@ var providers = {
|
|
|
2140
2166
|
goose: () => new GooseProvider(),
|
|
2141
2167
|
aider: () => new AiderProvider(),
|
|
2142
2168
|
codex: () => new CodexProvider(),
|
|
2143
|
-
kilo: () => new KiloProvider()
|
|
2169
|
+
kilo: () => new KiloProvider(),
|
|
2170
|
+
mimo: () => new MimoProvider()
|
|
2144
2171
|
};
|
|
2145
2172
|
async function getAllProvidersWithAvailability() {
|
|
2146
2173
|
const all = Object.values(providers).map((f) => f());
|
|
@@ -4146,7 +4173,8 @@ function resolveModels(config) {
|
|
|
4146
4173
|
"goose",
|
|
4147
4174
|
"aider",
|
|
4148
4175
|
"codex",
|
|
4149
|
-
"kilo"
|
|
4176
|
+
"kilo",
|
|
4177
|
+
"mimo"
|
|
4150
4178
|
]);
|
|
4151
4179
|
for (const m of providerModels) {
|
|
4152
4180
|
if (knownProviders.has(m) && m !== config.provider) {
|
|
@@ -894,6 +894,11 @@ function useKanbanState(bellEnabled, initialCards = []) {
|
|
|
894
894
|
const onCiStatus = (issueId, ciStatus) => {
|
|
895
895
|
setCards((prev) => prev.map((c) => c.id === issueId ? { ...c, ciStatus } : c));
|
|
896
896
|
};
|
|
897
|
+
const onAutoMergeStatus = (issueId, status) => {
|
|
898
|
+
setCards(
|
|
899
|
+
(prev) => prev.map((c) => c.id === issueId ? { ...c, autoMergeStatus: status } : c)
|
|
900
|
+
);
|
|
901
|
+
};
|
|
897
902
|
const onReviewersUpdated = (issueId, reviewers) => {
|
|
898
903
|
setCards((prev) => prev.map((c) => c.id === issueId ? { ...c, reviewers } : c));
|
|
899
904
|
};
|
|
@@ -951,6 +956,7 @@ function useKanbanState(bellEnabled, initialCards = []) {
|
|
|
951
956
|
kanbanEmitter.on("issue:log-file", onLogFile);
|
|
952
957
|
kanbanEmitter.on("issue:substatus", onSubstatus);
|
|
953
958
|
kanbanEmitter.on("issue:ci-status", onCiStatus);
|
|
959
|
+
kanbanEmitter.on("issue:auto-merge-status", onAutoMergeStatus);
|
|
954
960
|
kanbanEmitter.on("issue:reviewers-updated", onReviewersUpdated);
|
|
955
961
|
kanbanEmitter.on("issue:available-reviewers", onAvailableReviewers);
|
|
956
962
|
kanbanEmitter.on("issue:output", onOutput);
|
|
@@ -1000,6 +1006,7 @@ function useKanbanState(bellEnabled, initialCards = []) {
|
|
|
1000
1006
|
kanbanEmitter.off("issue:log-file", onLogFile);
|
|
1001
1007
|
kanbanEmitter.off("issue:substatus", onSubstatus);
|
|
1002
1008
|
kanbanEmitter.off("issue:ci-status", onCiStatus);
|
|
1009
|
+
kanbanEmitter.off("issue:auto-merge-status", onAutoMergeStatus);
|
|
1003
1010
|
kanbanEmitter.off("issue:reviewers-updated", onReviewersUpdated);
|
|
1004
1011
|
kanbanEmitter.off("issue:available-reviewers", onAvailableReviewers);
|
|
1005
1012
|
kanbanEmitter.off("issue:output", onOutput);
|
|
@@ -6,13 +6,14 @@ import {
|
|
|
6
6
|
detectPlatformFromRemoteUrl,
|
|
7
7
|
fetchCopilotModels,
|
|
8
8
|
fetchCursorModels,
|
|
9
|
+
fetchMimoModels,
|
|
9
10
|
fetchOpenCodeModels,
|
|
10
11
|
getGitRepoName,
|
|
11
12
|
getMissingEnvVars,
|
|
12
13
|
getVersion,
|
|
13
14
|
isCursorFreePlan,
|
|
14
15
|
verifyPlatformCredential
|
|
15
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-JALGARX3.js";
|
|
16
17
|
import "./chunk-YBM6JNRO.js";
|
|
17
18
|
import "./chunk-HPWL5JRW.js";
|
|
18
19
|
import "./chunk-4MZ2565Y.js";
|
|
@@ -23,6 +24,7 @@ export {
|
|
|
23
24
|
detectPlatformFromRemoteUrl,
|
|
24
25
|
fetchCopilotModels,
|
|
25
26
|
fetchCursorModels,
|
|
27
|
+
fetchMimoModels,
|
|
26
28
|
fetchOpenCodeModels,
|
|
27
29
|
getGitRepoName,
|
|
28
30
|
getMissingEnvVars,
|
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-VVYGYOPG.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-6ZWVYPR5.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-YSFHP3A3.js";
|
|
38
38
|
import {
|
|
39
39
|
kanbanEmitter
|
|
40
|
-
} from "./chunk-
|
|
40
|
+
} from "./chunk-ZHB4S7SP.js";
|
|
41
41
|
import {
|
|
42
42
|
isProofOfWorkEnabled,
|
|
43
43
|
isSpecComplianceEnabled,
|
|
@@ -55,11 +55,12 @@ import {
|
|
|
55
55
|
detectPlatform,
|
|
56
56
|
fetchCopilotModels,
|
|
57
57
|
fetchCursorModels,
|
|
58
|
+
fetchMimoModels,
|
|
58
59
|
fetchOpenCodeModels,
|
|
59
60
|
getMissingEnvVars,
|
|
60
61
|
getVersion,
|
|
61
62
|
isCursorFreePlan
|
|
62
|
-
} from "./chunk-
|
|
63
|
+
} from "./chunk-JALGARX3.js";
|
|
63
64
|
import {
|
|
64
65
|
isGhCliAvailable
|
|
65
66
|
} from "./chunk-YBM6JNRO.js";
|
|
@@ -251,7 +252,8 @@ async function runConfigWizard(existing) {
|
|
|
251
252
|
goose: "Goose",
|
|
252
253
|
aider: "Aider",
|
|
253
254
|
codex: "OpenAI Codex",
|
|
254
|
-
kilo: "Kilo Code"
|
|
255
|
+
kilo: "Kilo Code",
|
|
256
|
+
mimo: "MiMo Code"
|
|
255
257
|
};
|
|
256
258
|
const providerModels = {
|
|
257
259
|
claude: ["claude-opus-4-6", "claude-sonnet-4-6", "claude-haiku-4-5", "claude-sonnet-4-5"],
|
|
@@ -292,7 +294,8 @@ async function runConfigWizard(existing) {
|
|
|
292
294
|
${pc.bold("OpenAI Codex")} ${pc.dim("npm i -g @openai/codex")}
|
|
293
295
|
${pc.bold("Goose")} ${pc.dim("https://block.github.io/goose")}
|
|
294
296
|
${pc.bold("Aider")} ${pc.dim("pip install aider-chat")}
|
|
295
|
-
${pc.bold("Kilo Code")} ${pc.dim("npm i -g @kilocode/cli")}
|
|
297
|
+
${pc.bold("Kilo Code")} ${pc.dim("npm i -g @kilocode/cli")}
|
|
298
|
+
${pc.bold("MiMo Code")} ${pc.dim("npm i -g @mimo-ai/cli")}`
|
|
296
299
|
);
|
|
297
300
|
return process.exit(1);
|
|
298
301
|
}
|
|
@@ -426,6 +429,9 @@ remove them or set the file to ${pc.cyan("{}")} \u2014 MCP tools can cause OpenC
|
|
|
426
429
|
"google/gemini-2.5-pro",
|
|
427
430
|
"google/gemini-2.5-flash"
|
|
428
431
|
];
|
|
432
|
+
} else if (providerName === "mimo") {
|
|
433
|
+
const dynamic = fetchMimoModels();
|
|
434
|
+
availableModels = dynamic.length > 0 ? dynamic : ["mimo/mimo-auto", "xiaomi/mimo-v2.5-pro", "xiaomi/mimo-v2.5", "xiaomi/mimo-v2-flash"];
|
|
429
435
|
}
|
|
430
436
|
if (availableModels && availableModels.length > 0) {
|
|
431
437
|
const modelSelection = await clack.multiselect({
|
|
@@ -1861,7 +1867,7 @@ async function reviewAndCreate(plan2, planPath, opts) {
|
|
|
1861
1867
|
log("Run `lisa run` when ready.");
|
|
1862
1868
|
return;
|
|
1863
1869
|
}
|
|
1864
|
-
const { runLoop: runLoop2 } = await import("./loop-
|
|
1870
|
+
const { runLoop: runLoop2 } = await import("./loop-3OBNPSYF.js");
|
|
1865
1871
|
const waves = buildExecutionWaves(plan2.issues);
|
|
1866
1872
|
const maxWaveSize = Math.max(...waves.map((w) => w.length));
|
|
1867
1873
|
await runLoop2(config2, {
|
|
@@ -1957,6 +1963,7 @@ function resolveCard(card) {
|
|
|
1957
1963
|
prUrls: card.prUrls,
|
|
1958
1964
|
merged: card.merged,
|
|
1959
1965
|
ciStatus: card.ciStatus,
|
|
1966
|
+
autoMergeStatus: card.autoMergeStatus,
|
|
1960
1967
|
logFile: card.logFile,
|
|
1961
1968
|
outputLog: card.outputLogTail.join("\n")
|
|
1962
1969
|
};
|
|
@@ -1984,6 +1991,7 @@ function resolveCard(card) {
|
|
|
1984
1991
|
killed: card.killed,
|
|
1985
1992
|
merged: card.merged,
|
|
1986
1993
|
ciStatus: card.ciStatus,
|
|
1994
|
+
autoMergeStatus: card.autoMergeStatus,
|
|
1987
1995
|
logFile: card.logFile,
|
|
1988
1996
|
outputLog: card.outputLogTail.join("\n")
|
|
1989
1997
|
};
|
|
@@ -2072,6 +2080,12 @@ var KanbanPersistence = class {
|
|
|
2072
2080
|
this.updateCard(issueId, { ciStatus });
|
|
2073
2081
|
this.scheduleFlush();
|
|
2074
2082
|
});
|
|
2083
|
+
on("issue:auto-merge-status", (issueId, autoMergeStatus) => {
|
|
2084
|
+
this.updateCard(issueId, {
|
|
2085
|
+
autoMergeStatus
|
|
2086
|
+
});
|
|
2087
|
+
this.scheduleFlush();
|
|
2088
|
+
});
|
|
2075
2089
|
on("issue:reconcile-remove", (issueId) => {
|
|
2076
2090
|
this.removeCard(issueId);
|
|
2077
2091
|
this.scheduleFlush();
|
|
@@ -2237,7 +2251,7 @@ async function executeRun(args) {
|
|
|
2237
2251
|
if (isTTY) {
|
|
2238
2252
|
const { render } = await import("ink");
|
|
2239
2253
|
const { createElement } = await import("react");
|
|
2240
|
-
const { KanbanApp } = await import("./kanban-
|
|
2254
|
+
const { KanbanApp } = await import("./kanban-QQ47VJUY.js");
|
|
2241
2255
|
const demoConfig = {
|
|
2242
2256
|
provider: "claude",
|
|
2243
2257
|
source: "linear",
|
|
@@ -2337,7 +2351,7 @@ Add them to your ${shell} and run: source ${shell}`));
|
|
|
2337
2351
|
const initialCards = persistence.load();
|
|
2338
2352
|
persistedCards = initialCards;
|
|
2339
2353
|
persistence.start();
|
|
2340
|
-
const { registerPlanBridge } = await import("./tui-bridge-
|
|
2354
|
+
const { registerPlanBridge } = await import("./tui-bridge-HVSZNVDO.js");
|
|
2341
2355
|
const cleanupPlan = registerPlanBridge(merged);
|
|
2342
2356
|
onBeforeExit = () => {
|
|
2343
2357
|
persistence.stop();
|
|
@@ -2345,7 +2359,7 @@ Add them to your ${shell} and run: source ${shell}`));
|
|
|
2345
2359
|
};
|
|
2346
2360
|
const { render } = await import("ink");
|
|
2347
2361
|
const { createElement } = await import("react");
|
|
2348
|
-
const { KanbanApp } = await import("./kanban-
|
|
2362
|
+
const { KanbanApp } = await import("./kanban-QQ47VJUY.js");
|
|
2349
2363
|
render(createElement(KanbanApp, { config: merged, initialCards }), { exitOnCtrlC: false });
|
|
2350
2364
|
}
|
|
2351
2365
|
await runLoop(merged, {
|
|
@@ -2501,7 +2515,7 @@ process.on("unhandledRejection", (err) => {
|
|
|
2501
2515
|
}
|
|
2502
2516
|
process.exit(1);
|
|
2503
2517
|
});
|
|
2504
|
-
import("./detection-
|
|
2518
|
+
import("./detection-TGAZED6Q.js").then(
|
|
2505
2519
|
({ getVersion: getVersion2 }) => import("./version-D2YFKS7Q.js").then(({ checkForUpdate }) => checkForUpdate(getVersion2()))
|
|
2506
2520
|
);
|
|
2507
2521
|
runCli();
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import {
|
|
3
3
|
kanbanEmitter,
|
|
4
4
|
useKanbanState
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-ZHB4S7SP.js";
|
|
6
6
|
import {
|
|
7
7
|
resetTitle,
|
|
8
8
|
startSpinner,
|
|
@@ -141,10 +141,14 @@ function Card({
|
|
|
141
141
|
"\u2714 ",
|
|
142
142
|
formatElapsed(card.finishedAt - card.startedAt)
|
|
143
143
|
] }),
|
|
144
|
-
card.prUrls.length > 0 && /* @__PURE__ */
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
144
|
+
card.prUrls.length > 0 && /* @__PURE__ */ jsx(
|
|
145
|
+
Text,
|
|
146
|
+
{
|
|
147
|
+
color: card.autoMergeStatus === "failed" ? "red" : card.merged || card.autoMergeStatus === "merged" ? "magenta" : "yellow",
|
|
148
|
+
dimColor: true,
|
|
149
|
+
children: card.merged || card.autoMergeStatus === "merged" ? "PR\u2714" : card.autoMergeStatus === "waiting" || card.autoMergeStatus === "merging" ? "PR\u23F3" : card.autoMergeStatus === "failed" ? "PR\u2716" : "PR"
|
|
150
|
+
}
|
|
151
|
+
)
|
|
148
152
|
] }) : 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" }) : (
|
|
149
153
|
// Empty row for backlog and done-without-timing — maintains CARD_HEIGHT
|
|
150
154
|
/* @__PURE__ */ jsx(Text, { children: " ".repeat(cardWidth) })
|
|
@@ -534,7 +538,8 @@ function IssueDetail({
|
|
|
534
538
|
const prMetaRow = hasPrMeta ? 1 : 0;
|
|
535
539
|
const pickerRows = showReviewerPicker ? Math.min((card.availableReviewers ?? []).length + 2, 12) : 0;
|
|
536
540
|
const ciRow = card.ciStatus ? 1 : 0;
|
|
537
|
-
const
|
|
541
|
+
const autoMergeRow = card.autoMergeStatus ? 1 : 0;
|
|
542
|
+
const headerOverhead = 6 + prCount + logFileRow + ciRow + autoMergeRow + prMetaRow + pickerRows;
|
|
538
543
|
const bodyRows = Math.max(1, terminalRows - headerOverhead);
|
|
539
544
|
const lines = useMemo(() => processOutputLines(card.outputLog), [card.outputLog]);
|
|
540
545
|
const startLine = Math.max(0, lines.length - bodyRows - logScrollOffset);
|
|
@@ -609,6 +614,16 @@ function IssueDetail({
|
|
|
609
614
|
}
|
|
610
615
|
)
|
|
611
616
|
] }),
|
|
617
|
+
card.autoMergeStatus && /* @__PURE__ */ jsxs4(Box4, { marginTop: 0, children: [
|
|
618
|
+
/* @__PURE__ */ jsx4(Text4, { color: "gray", dimColor: true, children: "MERGE: " }),
|
|
619
|
+
/* @__PURE__ */ jsx4(
|
|
620
|
+
Text4,
|
|
621
|
+
{
|
|
622
|
+
color: card.autoMergeStatus === "merged" ? "magenta" : card.autoMergeStatus === "failed" ? "red" : "yellow",
|
|
623
|
+
children: card.autoMergeStatus === "merged" ? `\u2714 merged (${card.prUrls.length} PR${card.prUrls.length > 1 ? "s" : ""})` : card.autoMergeStatus === "failed" ? "\u2716 failed" : card.autoMergeStatus === "merging" ? "\u23F3 merging..." : "\u23F3 waiting for CI"
|
|
624
|
+
}
|
|
625
|
+
)
|
|
626
|
+
] }),
|
|
612
627
|
hasPrMeta && /* @__PURE__ */ jsxs4(Box4, { marginTop: 0, flexDirection: "row", children: [
|
|
613
628
|
cardReviewers.length > 0 ? /* @__PURE__ */ jsxs4(Fragment2, { children: [
|
|
614
629
|
/* @__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-VVYGYOPG.js";
|
|
8
8
|
import {
|
|
9
9
|
WATCH_POLL_INTERVAL_MS
|
|
10
|
-
} from "./chunk-
|
|
11
|
-
import "./chunk-
|
|
10
|
+
} from "./chunk-YSFHP3A3.js";
|
|
11
|
+
import "./chunk-ZHB4S7SP.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-6ZWVYPR5.js";
|
|
10
10
|
import {
|
|
11
11
|
createSource,
|
|
12
12
|
resolveModels,
|
|
13
13
|
runWithFallback
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-YSFHP3A3.js";
|
|
15
15
|
import {
|
|
16
16
|
kanbanEmitter
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-ZHB4S7SP.js";
|
|
18
18
|
import "./chunk-ZOVVFU7B.js";
|
|
19
19
|
import "./chunk-3EOEDL3T.js";
|
|
20
20
|
import "./chunk-7OCDGYDM.js";
|