@tarcisiopgs/lisa 1.32.0 → 1.33.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.
- package/dist/{chunk-AAWXKEV7.js → chunk-G76CXPYT.js} +4 -2
- package/dist/{chunk-K2ILRYXS.js → chunk-MAT63YLV.js} +43 -27
- package/dist/{chunk-66TB6NMR.js → chunk-PPRXJHPW.js} +16 -3
- package/dist/{chunk-NHC3JG2C.js → chunk-TFSN45HD.js} +1 -1
- package/dist/index.js +8 -8
- package/dist/{kanban-F27DQLKJ.js → kanban-MKRXRMTL.js} +35 -12
- package/dist/{loop-PXUNTCQS.js → loop-XJOZ4H54.js} +3 -3
- package/dist/{merge-LRFZXFV2.js → merge-CFQO7VU4.js} +3 -1
- package/dist/{tui-bridge-WKKIHWJT.js → tui-bridge-XTNCKLXF.js} +6 -3
- package/package.json +1 -1
|
@@ -30,7 +30,7 @@ import {
|
|
|
30
30
|
resolveModels,
|
|
31
31
|
runValidationCommands,
|
|
32
32
|
runWithFallback
|
|
33
|
-
} from "./chunk-
|
|
33
|
+
} from "./chunk-TFSN45HD.js";
|
|
34
34
|
import {
|
|
35
35
|
divider,
|
|
36
36
|
error,
|
|
@@ -39,7 +39,7 @@ import {
|
|
|
39
39
|
log,
|
|
40
40
|
ok,
|
|
41
41
|
warn
|
|
42
|
-
} from "./chunk-
|
|
42
|
+
} from "./chunk-PPRXJHPW.js";
|
|
43
43
|
import {
|
|
44
44
|
appendRawEntry,
|
|
45
45
|
migrateGuardrails
|
|
@@ -1109,6 +1109,8 @@ async function refreshKanban(source, config) {
|
|
|
1109
1109
|
for (const issue of allIssues) {
|
|
1110
1110
|
kanbanEmitter.emit("issue:queued", issue);
|
|
1111
1111
|
}
|
|
1112
|
+
const sourceIds = new Set(allIssues.map((i) => i.id));
|
|
1113
|
+
kanbanEmitter.emit("kanban:reconcile-backlog", sourceIds);
|
|
1112
1114
|
} catch {
|
|
1113
1115
|
}
|
|
1114
1116
|
}
|
|
@@ -4,14 +4,14 @@ import {
|
|
|
4
4
|
readContext,
|
|
5
5
|
resolveModels,
|
|
6
6
|
runWithFallback
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-TFSN45HD.js";
|
|
8
8
|
import {
|
|
9
9
|
error,
|
|
10
10
|
log,
|
|
11
11
|
normalizeLabels,
|
|
12
12
|
ok,
|
|
13
13
|
warn
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-PPRXJHPW.js";
|
|
15
15
|
|
|
16
16
|
// src/cli/error.ts
|
|
17
17
|
var CliError = class extends Error {
|
|
@@ -153,6 +153,16 @@ function extractCleanText(text2) {
|
|
|
153
153
|
}
|
|
154
154
|
|
|
155
155
|
// src/plan/create.ts
|
|
156
|
+
function ensureAcceptanceCriteria(description, criteria) {
|
|
157
|
+
if (!criteria.length) return description;
|
|
158
|
+
if (/- \[ \]/.test(description)) return description;
|
|
159
|
+
const checklist = criteria.map((c) => `- [ ] ${c}`).join("\n");
|
|
160
|
+
return `${description}
|
|
161
|
+
|
|
162
|
+
## Acceptance Criteria
|
|
163
|
+
|
|
164
|
+
${checklist}`;
|
|
165
|
+
}
|
|
156
166
|
async function createPlanIssues(source, config, plan) {
|
|
157
167
|
if (!source.createIssue) {
|
|
158
168
|
throw new Error(`Source "${source.name}" does not support createIssue`);
|
|
@@ -163,7 +173,7 @@ async function createPlanIssues(source, config, plan) {
|
|
|
163
173
|
const createdIds = [];
|
|
164
174
|
const orderToId = /* @__PURE__ */ new Map();
|
|
165
175
|
for (const issue of sorted) {
|
|
166
|
-
let description = issue.description;
|
|
176
|
+
let description = ensureAcceptanceCriteria(issue.description, issue.acceptanceCriteria);
|
|
167
177
|
if (issue.dependsOn.length > 0 && !source.linkDependency) {
|
|
168
178
|
const depRefs = issue.dependsOn.map((depOrder) => {
|
|
169
179
|
const depId = orderToId.get(depOrder);
|
|
@@ -174,33 +184,39 @@ async function createPlanIssues(source, config, plan) {
|
|
|
174
184
|
---
|
|
175
185
|
_Depends on: ${depRefs}_`;
|
|
176
186
|
}
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
const
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
187
|
+
try {
|
|
188
|
+
const id = await source.createIssue(
|
|
189
|
+
{
|
|
190
|
+
title: issue.title,
|
|
191
|
+
description,
|
|
192
|
+
status: config.pick_from,
|
|
193
|
+
label: primaryLabel,
|
|
194
|
+
order: issue.order,
|
|
195
|
+
parentId: plan.sourceIssueId
|
|
196
|
+
},
|
|
197
|
+
config
|
|
198
|
+
);
|
|
199
|
+
createdIds.push(id);
|
|
200
|
+
orderToId.set(issue.order, id);
|
|
201
|
+
ok(`${id}: ${issue.title}`);
|
|
202
|
+
if (source.linkDependency && issue.dependsOn.length > 0) {
|
|
203
|
+
for (const depOrder of issue.dependsOn) {
|
|
204
|
+
const depId = orderToId.get(depOrder);
|
|
205
|
+
if (depId) {
|
|
206
|
+
try {
|
|
207
|
+
await source.linkDependency(id, depId);
|
|
208
|
+
} catch (err) {
|
|
209
|
+
warn(
|
|
210
|
+
`Could not link dependency ${id} \u2192 ${depId}: ${err instanceof Error ? err.message : String(err)}`
|
|
211
|
+
);
|
|
212
|
+
}
|
|
201
213
|
}
|
|
202
214
|
}
|
|
203
215
|
}
|
|
216
|
+
} catch (err) {
|
|
217
|
+
warn(
|
|
218
|
+
`Failed to create issue "${issue.title}": ${err instanceof Error ? err.message : String(err)}`
|
|
219
|
+
);
|
|
204
220
|
}
|
|
205
221
|
}
|
|
206
222
|
return createdIds;
|
|
@@ -772,6 +772,7 @@ function registerBellListeners(bellEnabled) {
|
|
|
772
772
|
function useKanbanState(bellEnabled, initialCards = []) {
|
|
773
773
|
const [cards, setCards] = useState(initialCards);
|
|
774
774
|
const [isEmpty, setIsEmpty] = useState(false);
|
|
775
|
+
const [isFetching, setIsFetching] = useState(initialCards.length === 0);
|
|
775
776
|
const [isWatching, setIsWatching] = useState(false);
|
|
776
777
|
const [isWatchPrompt, setIsWatchPrompt] = useState(false);
|
|
777
778
|
const [workComplete, setWorkComplete] = useState(
|
|
@@ -780,6 +781,7 @@ function useKanbanState(bellEnabled, initialCards = []) {
|
|
|
780
781
|
const [modelInUse, setModelInUse] = useState(null);
|
|
781
782
|
useEffect(() => {
|
|
782
783
|
const onQueued = (issue) => {
|
|
784
|
+
setIsFetching(false);
|
|
783
785
|
setCards((prev) => {
|
|
784
786
|
if (prev.some((c) => c.id === issue.id)) return prev;
|
|
785
787
|
const maxOrder = prev.reduce((max, c) => Math.max(max, c.queueOrder ?? 0), 0);
|
|
@@ -919,6 +921,9 @@ function useKanbanState(bellEnabled, initialCards = []) {
|
|
|
919
921
|
outputBuffer.delete(issueId);
|
|
920
922
|
setCards((prev) => prev.filter((c) => c.id !== issueId));
|
|
921
923
|
};
|
|
924
|
+
const onReconcileBacklog = (sourceIds) => {
|
|
925
|
+
setCards((prev) => prev.filter((c) => c.column !== "backlog" || sourceIds.has(c.id)));
|
|
926
|
+
};
|
|
922
927
|
kanbanEmitter.on("issue:queued", onQueued);
|
|
923
928
|
kanbanEmitter.on("issue:started", onStarted);
|
|
924
929
|
kanbanEmitter.on("issue:done", onDone);
|
|
@@ -927,16 +932,23 @@ function useKanbanState(bellEnabled, initialCards = []) {
|
|
|
927
932
|
kanbanEmitter.on("issue:skipped", onSkipped);
|
|
928
933
|
kanbanEmitter.on("issue:killed", onKilled);
|
|
929
934
|
kanbanEmitter.on("issue:reconcile-remove", onReconcileRemove);
|
|
935
|
+
kanbanEmitter.on("kanban:reconcile-backlog", onReconcileBacklog);
|
|
930
936
|
kanbanEmitter.on("provider:paused", onProviderPaused);
|
|
931
937
|
kanbanEmitter.on("provider:resumed", onProviderResumed);
|
|
932
938
|
kanbanEmitter.on("issue:log-file", onLogFile);
|
|
933
939
|
kanbanEmitter.on("issue:output", onOutput);
|
|
934
940
|
const onModelChanged = (model) => setModelInUse(model);
|
|
935
941
|
kanbanEmitter.on("provider:model-changed", onModelChanged);
|
|
936
|
-
const onEmpty = () =>
|
|
942
|
+
const onEmpty = () => {
|
|
943
|
+
setIsEmpty(true);
|
|
944
|
+
setIsFetching(false);
|
|
945
|
+
};
|
|
937
946
|
const onResumed = () => setIsEmpty(false);
|
|
938
947
|
const onComplete = (data) => setWorkComplete(data);
|
|
939
|
-
const onWatching = () =>
|
|
948
|
+
const onWatching = () => {
|
|
949
|
+
setIsWatching(true);
|
|
950
|
+
setIsFetching(false);
|
|
951
|
+
};
|
|
940
952
|
const onWatchResume = () => setIsWatching(false);
|
|
941
953
|
const onWatchPrompt = () => {
|
|
942
954
|
setIsWatchPrompt(true);
|
|
@@ -965,6 +977,7 @@ function useKanbanState(bellEnabled, initialCards = []) {
|
|
|
965
977
|
kanbanEmitter.off("issue:skipped", onSkipped);
|
|
966
978
|
kanbanEmitter.off("issue:killed", onKilled);
|
|
967
979
|
kanbanEmitter.off("issue:reconcile-remove", onReconcileRemove);
|
|
980
|
+
kanbanEmitter.off("kanban:reconcile-backlog", onReconcileBacklog);
|
|
968
981
|
kanbanEmitter.off("provider:paused", onProviderPaused);
|
|
969
982
|
kanbanEmitter.off("provider:resumed", onProviderResumed);
|
|
970
983
|
kanbanEmitter.off("issue:log-file", onLogFile);
|
|
@@ -992,7 +1005,7 @@ function useKanbanState(bellEnabled, initialCards = []) {
|
|
|
992
1005
|
}
|
|
993
1006
|
}
|
|
994
1007
|
}, []);
|
|
995
|
-
return { cards, isEmpty, isWatching, isWatchPrompt, workComplete, modelInUse };
|
|
1008
|
+
return { cards, isEmpty, isFetching, isWatching, isWatchPrompt, workComplete, modelInUse };
|
|
996
1009
|
}
|
|
997
1010
|
|
|
998
1011
|
export {
|
package/dist/index.js
CHANGED
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
parseStructuredOutput,
|
|
8
8
|
runPlanWizard,
|
|
9
9
|
savePlan
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-MAT63YLV.js";
|
|
11
11
|
import {
|
|
12
12
|
detectDefaultBranch,
|
|
13
13
|
detectGitRepos,
|
|
@@ -36,7 +36,7 @@ import {
|
|
|
36
36
|
runLoop,
|
|
37
37
|
saveConfig,
|
|
38
38
|
validateConfig
|
|
39
|
-
} from "./chunk-
|
|
39
|
+
} from "./chunk-G76CXPYT.js";
|
|
40
40
|
import {
|
|
41
41
|
buildContextMdBlock,
|
|
42
42
|
createProvider,
|
|
@@ -48,7 +48,7 @@ import {
|
|
|
48
48
|
readContext,
|
|
49
49
|
resolveModels,
|
|
50
50
|
runWithFallback
|
|
51
|
-
} from "./chunk-
|
|
51
|
+
} from "./chunk-TFSN45HD.js";
|
|
52
52
|
import {
|
|
53
53
|
banner,
|
|
54
54
|
error,
|
|
@@ -58,7 +58,7 @@ import {
|
|
|
58
58
|
setLogLevel,
|
|
59
59
|
setOutputMode,
|
|
60
60
|
updateNotice
|
|
61
|
-
} from "./chunk-
|
|
61
|
+
} from "./chunk-PPRXJHPW.js";
|
|
62
62
|
import "./chunk-3EOEDL3T.js";
|
|
63
63
|
import {
|
|
64
64
|
getKanbanStatePath,
|
|
@@ -1544,7 +1544,7 @@ async function reviewAndCreate(plan2, planPath, opts) {
|
|
|
1544
1544
|
log("Run `lisa run` when ready.");
|
|
1545
1545
|
return;
|
|
1546
1546
|
}
|
|
1547
|
-
const { runLoop: runLoop2 } = await import("./loop-
|
|
1547
|
+
const { runLoop: runLoop2 } = await import("./loop-XJOZ4H54.js");
|
|
1548
1548
|
await runLoop2(config2, {
|
|
1549
1549
|
once: false,
|
|
1550
1550
|
watch: false,
|
|
@@ -1908,7 +1908,7 @@ async function executeRun(args) {
|
|
|
1908
1908
|
if (isTTY) {
|
|
1909
1909
|
const { render } = await import("ink");
|
|
1910
1910
|
const { createElement } = await import("react");
|
|
1911
|
-
const { KanbanApp } = await import("./kanban-
|
|
1911
|
+
const { KanbanApp } = await import("./kanban-MKRXRMTL.js");
|
|
1912
1912
|
const demoConfig = {
|
|
1913
1913
|
provider: "claude",
|
|
1914
1914
|
source: "linear",
|
|
@@ -2008,7 +2008,7 @@ Add them to your ${shell} and run: source ${shell}`));
|
|
|
2008
2008
|
const initialCards = persistence.load();
|
|
2009
2009
|
persistedCards = initialCards;
|
|
2010
2010
|
persistence.start();
|
|
2011
|
-
const { registerPlanBridge } = await import("./tui-bridge-
|
|
2011
|
+
const { registerPlanBridge } = await import("./tui-bridge-XTNCKLXF.js");
|
|
2012
2012
|
const cleanupPlan = registerPlanBridge(merged);
|
|
2013
2013
|
onBeforeExit = () => {
|
|
2014
2014
|
persistence.stop();
|
|
@@ -2016,7 +2016,7 @@ Add them to your ${shell} and run: source ${shell}`));
|
|
|
2016
2016
|
};
|
|
2017
2017
|
const { render } = await import("ink");
|
|
2018
2018
|
const { createElement } = await import("react");
|
|
2019
|
-
const { KanbanApp } = await import("./kanban-
|
|
2019
|
+
const { KanbanApp } = await import("./kanban-MKRXRMTL.js");
|
|
2020
2020
|
render(createElement(KanbanApp, { config: merged, initialCards }), { exitOnCtrlC: false });
|
|
2021
2021
|
}
|
|
2022
2022
|
await runLoop(merged, {
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
import {
|
|
6
6
|
kanbanEmitter,
|
|
7
7
|
useKanbanState
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-PPRXJHPW.js";
|
|
9
9
|
import {
|
|
10
10
|
resetTitle,
|
|
11
11
|
startSpinner,
|
|
@@ -18,6 +18,7 @@ import { useEffect as useEffect5, useState as useState6 } from "react";
|
|
|
18
18
|
|
|
19
19
|
// src/ui/board.tsx
|
|
20
20
|
import { Box as Box3, Text as Text3 } from "ink";
|
|
21
|
+
import Spinner2 from "ink-spinner";
|
|
21
22
|
|
|
22
23
|
// src/ui/column.tsx
|
|
23
24
|
import { Box as Box2, Text as Text2 } from "ink";
|
|
@@ -257,6 +258,7 @@ function Board({
|
|
|
257
258
|
columns,
|
|
258
259
|
labels,
|
|
259
260
|
isEmpty,
|
|
261
|
+
isFetching = false,
|
|
260
262
|
isWatching = false,
|
|
261
263
|
isWatchPrompt = false,
|
|
262
264
|
workComplete,
|
|
@@ -265,6 +267,28 @@ function Board({
|
|
|
265
267
|
paused = false
|
|
266
268
|
}) {
|
|
267
269
|
const { backlog, inProgress, done } = columns;
|
|
270
|
+
if (isFetching) {
|
|
271
|
+
return /* @__PURE__ */ jsx3(Box3, { flexGrow: 1, alignItems: "center", justifyContent: "center", children: /* @__PURE__ */ jsxs3(
|
|
272
|
+
Box3,
|
|
273
|
+
{
|
|
274
|
+
flexDirection: "column",
|
|
275
|
+
borderStyle: "single",
|
|
276
|
+
borderColor: "yellow",
|
|
277
|
+
paddingX: 3,
|
|
278
|
+
paddingY: 1,
|
|
279
|
+
children: [
|
|
280
|
+
/* @__PURE__ */ jsxs3(Box3, { flexDirection: "row", children: [
|
|
281
|
+
/* @__PURE__ */ jsx3(Text3, { color: "yellow", children: /* @__PURE__ */ jsx3(Spinner2, { type: "dots" }) }),
|
|
282
|
+
/* @__PURE__ */ jsx3(Text3, { color: "yellow", bold: true, children: " FETCHING ISSUES..." })
|
|
283
|
+
] }),
|
|
284
|
+
/* @__PURE__ */ jsx3(Box3, { height: 1 }),
|
|
285
|
+
/* @__PURE__ */ jsx3(Text3, { color: "white", dimColor: true, children: "Querying the issue tracker for matching items." }),
|
|
286
|
+
/* @__PURE__ */ jsx3(Box3, { height: 1 }),
|
|
287
|
+
/* @__PURE__ */ jsx3(Text3, { color: "gray", dimColor: true, children: "Press [q] to quit" })
|
|
288
|
+
]
|
|
289
|
+
}
|
|
290
|
+
) });
|
|
291
|
+
}
|
|
268
292
|
if (isWatching) {
|
|
269
293
|
return /* @__PURE__ */ jsx3(Box3, { flexGrow: 1, alignItems: "center", justifyContent: "center", children: /* @__PURE__ */ jsxs3(
|
|
270
294
|
Box3,
|
|
@@ -378,7 +402,7 @@ function Board({
|
|
|
378
402
|
// src/ui/detail.tsx
|
|
379
403
|
import { exec } from "child_process";
|
|
380
404
|
import { Box as Box4, Text as Text4, useInput } from "ink";
|
|
381
|
-
import
|
|
405
|
+
import Spinner3 from "ink-spinner";
|
|
382
406
|
import { useEffect as useEffect3, useMemo, useRef, useState as useState3 } from "react";
|
|
383
407
|
|
|
384
408
|
// src/output/line-color.ts
|
|
@@ -535,7 +559,7 @@ function IssueDetail({ card, onBack, reviewers, assignees }) {
|
|
|
535
559
|
] }),
|
|
536
560
|
/* @__PURE__ */ jsxs4(Box4, { flexDirection: "row", children: [
|
|
537
561
|
isRunning && elapsedDisplay && /* @__PURE__ */ jsxs4(Box4, { flexDirection: "row", marginRight: 2, children: [
|
|
538
|
-
/* @__PURE__ */ jsx4(Text4, { color: "yellow", children: /* @__PURE__ */ jsx4(
|
|
562
|
+
/* @__PURE__ */ jsx4(Text4, { color: "yellow", children: /* @__PURE__ */ jsx4(Spinner3, { type: "dots" }) }),
|
|
539
563
|
/* @__PURE__ */ jsx4(Text4, { color: "yellow", bold: true, children: ` ${elapsedDisplay}` })
|
|
540
564
|
] }),
|
|
541
565
|
isPausedInProgress && elapsedDisplay && /* @__PURE__ */ jsxs4(Box4, { flexDirection: "row", marginRight: 2, children: [
|
|
@@ -575,7 +599,7 @@ function IssueDetail({ card, onBack, reviewers, assignees }) {
|
|
|
575
599
|
!userScrolled && totalLines > bodyRows && /* @__PURE__ */ jsx4(Text4, { color: "gray", dimColor: true, children: "live" })
|
|
576
600
|
] }),
|
|
577
601
|
/* @__PURE__ */ jsx4(Box4, { height: bodyRows, flexDirection: "column", overflow: "hidden", children: card.outputLog.length === 0 ? /* @__PURE__ */ jsxs4(Box4, { flexDirection: "row", marginTop: 1, children: [
|
|
578
|
-
/* @__PURE__ */ jsx4(Text4, { color: "yellow", children: /* @__PURE__ */ jsx4(
|
|
602
|
+
/* @__PURE__ */ jsx4(Text4, { color: "yellow", children: /* @__PURE__ */ jsx4(Spinner3, { type: "dots" }) }),
|
|
579
603
|
/* @__PURE__ */ jsx4(Text4, { color: "gray", dimColor: true, children: " Waiting for provider output..." })
|
|
580
604
|
] }) : visibleLines.map((line, i) => {
|
|
581
605
|
const color = logLineColor(line);
|
|
@@ -591,7 +615,7 @@ function IssueDetail({ card, onBack, reviewers, assignees }) {
|
|
|
591
615
|
|
|
592
616
|
// src/ui/plan-chat.tsx
|
|
593
617
|
import { Box as Box5, Text as Text5, useInput as useInput2 } from "ink";
|
|
594
|
-
import
|
|
618
|
+
import Spinner4 from "ink-spinner";
|
|
595
619
|
import { useEffect as useEffect4, useState as useState4 } from "react";
|
|
596
620
|
import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
597
621
|
var SIDEBAR_TOTAL_WIDTH = 30;
|
|
@@ -718,7 +742,7 @@ function PlanChat({ messages, isThinking, onSend, onCancel }) {
|
|
|
718
742
|
);
|
|
719
743
|
}),
|
|
720
744
|
isThinking && /* @__PURE__ */ jsxs5(Box5, { flexDirection: "row", marginTop: 0, children: [
|
|
721
|
-
/* @__PURE__ */ jsx5(Text5, { color: "yellow", children: /* @__PURE__ */ jsx5(
|
|
745
|
+
/* @__PURE__ */ jsx5(Text5, { color: "yellow", children: /* @__PURE__ */ jsx5(Spinner4, { type: "dots" }) }),
|
|
722
746
|
/* @__PURE__ */ jsx5(Text5, { color: "gray", dimColor: true, children: " Analyzing..." })
|
|
723
747
|
] })
|
|
724
748
|
] }),
|
|
@@ -1062,10 +1086,7 @@ function Sidebar({
|
|
|
1062
1086
|
import { jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
1063
1087
|
function KanbanApp({ config, initialCards = [] }) {
|
|
1064
1088
|
const { exit } = useApp();
|
|
1065
|
-
const { cards, isEmpty, isWatching, isWatchPrompt, workComplete, modelInUse } = useKanbanState(
|
|
1066
|
-
config.bell ?? true,
|
|
1067
|
-
initialCards
|
|
1068
|
-
);
|
|
1089
|
+
const { cards, isEmpty, isFetching, isWatching, isWatchPrompt, workComplete, modelInUse } = useKanbanState(config.bell ?? true, initialCards);
|
|
1069
1090
|
const { rows } = useTerminalSize();
|
|
1070
1091
|
const [activeView, setActiveView] = useState6("board");
|
|
1071
1092
|
const [activeColIndex, setActiveColIndex] = useState6(0);
|
|
@@ -1185,7 +1206,7 @@ function KanbanApp({ config, initialCards = [] }) {
|
|
|
1185
1206
|
}, [cards, selectedCardId, activeView]);
|
|
1186
1207
|
const selectedCard = activeView === "detail" && selectedCardId ? cards.find((c) => c.id === selectedCardId) ?? null : null;
|
|
1187
1208
|
async function handleMergeRequest(card) {
|
|
1188
|
-
const { checkPrCiStatus } = await import("./merge-
|
|
1209
|
+
const { checkPrCiStatus } = await import("./merge-CFQO7VU4.js");
|
|
1189
1210
|
const prUrl = card.prUrls[0];
|
|
1190
1211
|
const ciStatus = await checkPrCiStatus(prUrl);
|
|
1191
1212
|
if (ciStatus === "passing" || ciStatus === "unknown") {
|
|
@@ -1198,7 +1219,7 @@ function KanbanApp({ config, initialCards = [] }) {
|
|
|
1198
1219
|
const card = cards.find((c) => c.id === issueId);
|
|
1199
1220
|
if (!card || card.prUrls.length === 0) return;
|
|
1200
1221
|
setMerging(issueId);
|
|
1201
|
-
const { mergePr } = await import("./merge-
|
|
1222
|
+
const { mergePr } = await import("./merge-CFQO7VU4.js");
|
|
1202
1223
|
let allSuccess = true;
|
|
1203
1224
|
for (const prUrl of card.prUrls) {
|
|
1204
1225
|
const result = await mergePr(prUrl);
|
|
@@ -1413,6 +1434,7 @@ Merge failed: ${result.error}
|
|
|
1413
1434
|
let sidebarMode = "board";
|
|
1414
1435
|
if (isWatchPrompt) sidebarMode = "watch-prompt";
|
|
1415
1436
|
else if (isWatching) sidebarMode = "watching";
|
|
1437
|
+
else if (isFetching && activeView === "board") sidebarMode = "empty";
|
|
1416
1438
|
else if (isEmpty && activeView === "board" && cards.length === 0) sidebarMode = "empty";
|
|
1417
1439
|
else if (isEmpty && activeView === "board" && cards.length > 0) sidebarMode = "idle";
|
|
1418
1440
|
else if (activeView === "plan-chat") sidebarMode = "plan-chat";
|
|
@@ -1496,6 +1518,7 @@ Merge failed: ${result.error}
|
|
|
1496
1518
|
columns: { backlog, inProgress, done },
|
|
1497
1519
|
labels,
|
|
1498
1520
|
isEmpty,
|
|
1521
|
+
isFetching,
|
|
1499
1522
|
isWatching,
|
|
1500
1523
|
isWatchPrompt,
|
|
1501
1524
|
workComplete,
|
|
@@ -3,11 +3,11 @@ import {
|
|
|
3
3
|
checkoutBaseBranches,
|
|
4
4
|
runDemoLoop,
|
|
5
5
|
runLoop
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-G76CXPYT.js";
|
|
7
7
|
import {
|
|
8
8
|
WATCH_POLL_INTERVAL_MS
|
|
9
|
-
} from "./chunk-
|
|
10
|
-
import "./chunk-
|
|
9
|
+
} from "./chunk-TFSN45HD.js";
|
|
10
|
+
import "./chunk-PPRXJHPW.js";
|
|
11
11
|
import "./chunk-3EOEDL3T.js";
|
|
12
12
|
import "./chunk-7OCDGYDM.js";
|
|
13
13
|
import "./chunk-72CYGBT4.js";
|
|
@@ -71,7 +71,9 @@ async function mergePr(prUrl) {
|
|
|
71
71
|
}
|
|
72
72
|
async function mergeGitHubPr(prUrl) {
|
|
73
73
|
try {
|
|
74
|
-
await execa("gh", ["pr", "merge", prUrl, "--delete-branch"], {
|
|
74
|
+
await execa("gh", ["pr", "merge", prUrl, "--squash", "--delete-branch"], {
|
|
75
|
+
timeout: 3e4
|
|
76
|
+
});
|
|
75
77
|
return { success: true };
|
|
76
78
|
} catch (err) {
|
|
77
79
|
return { success: false, error: formatError(err) };
|
|
@@ -6,19 +6,19 @@ import {
|
|
|
6
6
|
markdownToIssue,
|
|
7
7
|
parseStructuredOutput,
|
|
8
8
|
savePlan
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-MAT63YLV.js";
|
|
10
10
|
import {
|
|
11
11
|
createSource,
|
|
12
12
|
resolveModels,
|
|
13
13
|
runWithFallback
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-TFSN45HD.js";
|
|
15
15
|
import {
|
|
16
16
|
error,
|
|
17
17
|
kanbanEmitter,
|
|
18
18
|
log,
|
|
19
19
|
ok,
|
|
20
20
|
warn
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-PPRXJHPW.js";
|
|
22
22
|
import "./chunk-3EOEDL3T.js";
|
|
23
23
|
import "./chunk-7OCDGYDM.js";
|
|
24
24
|
import "./chunk-72CYGBT4.js";
|
|
@@ -133,6 +133,9 @@ async function handleApproval(config, issues, goal) {
|
|
|
133
133
|
} catch (err) {
|
|
134
134
|
warn(`Could not refresh kanban: ${err instanceof Error ? err.message : String(err)}`);
|
|
135
135
|
}
|
|
136
|
+
if (createdIds.length > 0) {
|
|
137
|
+
kanbanEmitter.emit("loop:run");
|
|
138
|
+
}
|
|
136
139
|
}
|
|
137
140
|
function buildChatPrompt(goal, config, chatHistory) {
|
|
138
141
|
const basePrompt = buildPlanningPrompt(goal, config);
|