sisyphi 1.0.14 → 1.1.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-Q6VQOUN3.js → chunk-M7LZ2ZHD.js} +3 -27
- package/dist/chunk-M7LZ2ZHD.js.map +1 -0
- package/dist/{chunk-YGBGKMTF.js → chunk-REUQ4B45.js} +7 -11
- package/dist/chunk-REUQ4B45.js.map +1 -0
- package/dist/{chunk-MMA43N67.js → chunk-Z32YVDMY.js} +2 -2
- package/dist/chunk-Z32YVDMY.js.map +1 -0
- package/dist/cli.js +38 -47
- package/dist/cli.js.map +1 -1
- package/dist/daemon.js +795 -796
- package/dist/daemon.js.map +1 -1
- package/dist/{paths-FYYSBD27.js → paths-IJXOAN4E.js} +4 -6
- package/dist/templates/CLAUDE.md +16 -14
- package/dist/templates/agent-plugin/agents/CLAUDE.md +17 -6
- package/dist/templates/agent-plugin/agents/design.md +134 -0
- package/dist/templates/agent-plugin/agents/explore.md +39 -0
- package/dist/templates/agent-plugin/agents/operator.md +24 -0
- package/dist/templates/agent-plugin/agents/plan.md +15 -20
- package/dist/templates/agent-plugin/agents/problem.md +119 -0
- package/dist/templates/agent-plugin/agents/requirements.md +138 -0
- package/dist/templates/agent-plugin/agents/review/CLAUDE.md +29 -0
- package/dist/templates/agent-plugin/agents/review/compliance.md +6 -6
- package/dist/templates/agent-plugin/agents/review-plan/code-smells.md +4 -4
- package/dist/templates/agent-plugin/agents/review-plan/requirements-coverage.md +62 -0
- package/dist/templates/agent-plugin/agents/review-plan/security.md +1 -1
- package/dist/templates/agent-plugin/agents/review-plan.md +9 -8
- package/dist/templates/agent-plugin/agents/review.md +1 -1
- package/dist/templates/agent-plugin/agents/test-spec.md +2 -2
- package/dist/templates/agent-plugin/hooks/CLAUDE.md +2 -2
- package/dist/templates/agent-plugin/hooks/explore-user-prompt.sh +13 -0
- package/dist/templates/agent-plugin/hooks/plan-user-prompt.sh +1 -1
- package/dist/templates/agent-plugin/hooks/require-submit.sh +69 -2
- package/dist/templates/agent-plugin/hooks/review-plan-user-prompt.sh +4 -4
- package/dist/templates/agent-plugin/hooks/review-user-prompt.sh +1 -1
- package/dist/templates/agent-suffix.md +0 -2
- package/dist/templates/orchestrator-base.md +167 -145
- package/dist/templates/orchestrator-impl.md +92 -57
- package/dist/templates/orchestrator-planning.md +46 -56
- package/dist/templates/orchestrator-plugin/commands/sisyphus/design.md +13 -0
- package/dist/templates/orchestrator-plugin/commands/sisyphus/problem.md +13 -0
- package/dist/templates/orchestrator-plugin/commands/sisyphus/requirements.md +13 -0
- package/dist/templates/orchestrator-plugin/commands/sisyphus/strategize.md +19 -0
- package/dist/templates/orchestrator-plugin/hooks/explore-gate.sh +15 -0
- package/dist/templates/orchestrator-plugin/hooks/hooks.json +14 -1
- package/dist/templates/orchestrator-plugin/skills/orchestration/task-patterns.md +34 -27
- package/dist/templates/orchestrator-plugin/skills/orchestration/workflow-examples.md +56 -24
- package/dist/templates/orchestrator-strategy.md +233 -0
- package/dist/templates/orchestrator-validation.md +94 -0
- package/dist/tui.js +134 -91
- package/dist/tui.js.map +1 -1
- package/package.json +1 -1
- package/templates/CLAUDE.md +16 -14
- package/templates/agent-plugin/agents/CLAUDE.md +17 -6
- package/templates/agent-plugin/agents/design.md +134 -0
- package/templates/agent-plugin/agents/explore.md +39 -0
- package/templates/agent-plugin/agents/operator.md +24 -0
- package/templates/agent-plugin/agents/plan.md +15 -20
- package/templates/agent-plugin/agents/problem.md +119 -0
- package/templates/agent-plugin/agents/requirements.md +138 -0
- package/templates/agent-plugin/agents/review/CLAUDE.md +29 -0
- package/templates/agent-plugin/agents/review/compliance.md +6 -6
- package/templates/agent-plugin/agents/review-plan/code-smells.md +4 -4
- package/templates/agent-plugin/agents/review-plan/requirements-coverage.md +62 -0
- package/templates/agent-plugin/agents/review-plan/security.md +1 -1
- package/templates/agent-plugin/agents/review-plan.md +9 -8
- package/templates/agent-plugin/agents/review.md +1 -1
- package/templates/agent-plugin/agents/test-spec.md +2 -2
- package/templates/agent-plugin/hooks/CLAUDE.md +2 -2
- package/templates/agent-plugin/hooks/explore-user-prompt.sh +13 -0
- package/templates/agent-plugin/hooks/plan-user-prompt.sh +1 -1
- package/templates/agent-plugin/hooks/require-submit.sh +69 -2
- package/templates/agent-plugin/hooks/review-plan-user-prompt.sh +4 -4
- package/templates/agent-plugin/hooks/review-user-prompt.sh +1 -1
- package/templates/agent-suffix.md +0 -2
- package/templates/orchestrator-base.md +167 -145
- package/templates/orchestrator-impl.md +92 -57
- package/templates/orchestrator-planning.md +46 -56
- package/templates/orchestrator-plugin/commands/sisyphus/design.md +13 -0
- package/templates/orchestrator-plugin/commands/sisyphus/problem.md +13 -0
- package/templates/orchestrator-plugin/commands/sisyphus/requirements.md +13 -0
- package/templates/orchestrator-plugin/commands/sisyphus/strategize.md +19 -0
- package/templates/orchestrator-plugin/hooks/explore-gate.sh +15 -0
- package/templates/orchestrator-plugin/hooks/hooks.json +14 -1
- package/templates/orchestrator-plugin/skills/orchestration/task-patterns.md +34 -27
- package/templates/orchestrator-plugin/skills/orchestration/workflow-examples.md +56 -24
- package/templates/orchestrator-strategy.md +233 -0
- package/templates/orchestrator-validation.md +94 -0
- package/dist/chunk-MMA43N67.js.map +0 -1
- package/dist/chunk-Q6VQOUN3.js.map +0 -1
- package/dist/chunk-YGBGKMTF.js.map +0 -1
- package/dist/templates/agent-plugin/agents/review-plan/spec-coverage.md +0 -44
- package/dist/templates/agent-plugin/agents/spec-draft.md +0 -78
- package/dist/templates/agent-plugin/hooks/hooks.json +0 -25
- package/dist/templates/agent-plugin/hooks/spec-user-prompt.sh +0 -19
- package/dist/templates/orchestrator-plugin/skills/git-management/SKILL.md +0 -111
- package/templates/agent-plugin/agents/review-plan/spec-coverage.md +0 -44
- package/templates/agent-plugin/agents/spec-draft.md +0 -78
- package/templates/agent-plugin/hooks/hooks.json +0 -25
- package/templates/agent-plugin/hooks/spec-user-prompt.sh +0 -19
- package/templates/orchestrator-plugin/skills/git-management/SKILL.md +0 -111
- /package/dist/{paths-FYYSBD27.js.map → paths-IJXOAN4E.js.map} +0 -0
package/dist/tui.js
CHANGED
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
exec,
|
|
6
6
|
execSafe,
|
|
7
7
|
loadConfig
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-Z32YVDMY.js";
|
|
9
9
|
import {
|
|
10
10
|
buildSessionContext,
|
|
11
11
|
computeActiveTimeMs,
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
rawSend,
|
|
14
14
|
resolveReports,
|
|
15
15
|
statusColor
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-M7LZ2ZHD.js";
|
|
17
17
|
import {
|
|
18
18
|
shellQuote
|
|
19
19
|
} from "./chunk-6G226ZK7.js";
|
|
@@ -23,8 +23,9 @@ import {
|
|
|
23
23
|
goalPath,
|
|
24
24
|
logsDir,
|
|
25
25
|
roadmapPath,
|
|
26
|
-
sessionDir
|
|
27
|
-
|
|
26
|
+
sessionDir,
|
|
27
|
+
strategyPath
|
|
28
|
+
} from "./chunk-REUQ4B45.js";
|
|
28
29
|
|
|
29
30
|
// src/tui/terminal.ts
|
|
30
31
|
function emptyKey() {
|
|
@@ -311,6 +312,7 @@ function createAppState(cwd2) {
|
|
|
311
312
|
notification: null,
|
|
312
313
|
notificationTimer: null,
|
|
313
314
|
showLogs: false,
|
|
315
|
+
showStrategy: false,
|
|
314
316
|
inputText: "",
|
|
315
317
|
inputCursorPos: 0,
|
|
316
318
|
detailScroll,
|
|
@@ -318,6 +320,7 @@ function createAppState(cwd2) {
|
|
|
318
320
|
sessions: [],
|
|
319
321
|
selectedSession: null,
|
|
320
322
|
planContent: "",
|
|
323
|
+
strategyContent: "",
|
|
321
324
|
goalContent: "",
|
|
322
325
|
logsContent: "",
|
|
323
326
|
logsCycles: [],
|
|
@@ -544,6 +547,8 @@ function abbreviateMode(mode) {
|
|
|
544
547
|
if (!mode) return "";
|
|
545
548
|
if (mode === "implementation") return "impl";
|
|
546
549
|
if (mode === "planning") return "plan";
|
|
550
|
+
if (mode === "strategy") return "strat";
|
|
551
|
+
if (mode === "validation") return "valid";
|
|
547
552
|
return mode;
|
|
548
553
|
}
|
|
549
554
|
function ansiBold(text) {
|
|
@@ -564,22 +569,10 @@ function ansiColor(text, color, bold = false) {
|
|
|
564
569
|
function modeColor(mode) {
|
|
565
570
|
if (mode === "planning") return "blue";
|
|
566
571
|
if (mode === "implementation") return "green";
|
|
572
|
+
if (mode === "strategy") return "yellow";
|
|
573
|
+
if (mode === "validation") return "magenta";
|
|
567
574
|
return "cyan";
|
|
568
575
|
}
|
|
569
|
-
function mergeStatusDisplay(status) {
|
|
570
|
-
switch (status) {
|
|
571
|
-
case "merged":
|
|
572
|
-
return { icon: "\u2295", label: "merged", color: "green" };
|
|
573
|
-
case "pending":
|
|
574
|
-
return { icon: "\u25CC", label: "pending", color: "yellow" };
|
|
575
|
-
case "no-changes":
|
|
576
|
-
return { icon: "\u2205", label: "no changes", color: "gray" };
|
|
577
|
-
case "conflict":
|
|
578
|
-
return { icon: "\u26A0", label: "conflict", color: "red" };
|
|
579
|
-
default:
|
|
580
|
-
return null;
|
|
581
|
-
}
|
|
582
|
-
}
|
|
583
576
|
function wrapText(text, width) {
|
|
584
577
|
const cleaned = cleanMarkdown(text);
|
|
585
578
|
if (width <= 0) return cleaned.split("\n");
|
|
@@ -674,6 +667,7 @@ function buildTree(sessions, selectedSession, expanded, cwd2, polledContextFiles
|
|
|
674
667
|
cycleNumber: cycle.cycle,
|
|
675
668
|
timestamp: cycle.timestamp,
|
|
676
669
|
completedAt: cycle.completedAt,
|
|
670
|
+
activeMs: cycle.activeMs,
|
|
677
671
|
agentCount: allCycleAgents.length,
|
|
678
672
|
mode: cycle.mode
|
|
679
673
|
});
|
|
@@ -695,8 +689,8 @@ function buildTree(sessions, selectedSession, expanded, cwd2, polledContextFiles
|
|
|
695
689
|
status: agent.status,
|
|
696
690
|
spawnedAt: agent.spawnedAt,
|
|
697
691
|
completedAt: agent.completedAt,
|
|
698
|
-
|
|
699
|
-
|
|
692
|
+
activeMs: agent.activeMs,
|
|
693
|
+
reportCount: agent.reports.length
|
|
700
694
|
});
|
|
701
695
|
if (!agentExpanded || !hasReports) continue;
|
|
702
696
|
for (let ri = 0; ri < agent.reports.length; ri++) {
|
|
@@ -1410,6 +1404,30 @@ function handleNavigateKey(input, key, state2, actions) {
|
|
|
1410
1404
|
})();
|
|
1411
1405
|
return;
|
|
1412
1406
|
}
|
|
1407
|
+
if (input === "o") {
|
|
1408
|
+
if (!cursorNode) {
|
|
1409
|
+
notify(state2, "No node selected");
|
|
1410
|
+
return;
|
|
1411
|
+
}
|
|
1412
|
+
let claudeSessionId;
|
|
1413
|
+
if (cursorNode.type === "agent" || cursorNode.type === "report") {
|
|
1414
|
+
const agent = actions.getAgentForNode(cursorNode);
|
|
1415
|
+
claudeSessionId = agent?.claudeSessionId ?? void 0;
|
|
1416
|
+
} else if (cursorNode.type === "cycle" && session) {
|
|
1417
|
+
const cycle = session.orchestratorCycles.find((c) => c.cycle === cursorNode.cycleNumber);
|
|
1418
|
+
claudeSessionId = cycle?.claudeSessionId;
|
|
1419
|
+
}
|
|
1420
|
+
if (!claudeSessionId) {
|
|
1421
|
+
notify(state2, "No Claude session ID available");
|
|
1422
|
+
return;
|
|
1423
|
+
}
|
|
1424
|
+
try {
|
|
1425
|
+
actions.openClaudeResumePopup(state2.cwd, claudeSessionId);
|
|
1426
|
+
} catch {
|
|
1427
|
+
notify(state2, "Failed to open Claude session");
|
|
1428
|
+
}
|
|
1429
|
+
return;
|
|
1430
|
+
}
|
|
1413
1431
|
if (input === "g") {
|
|
1414
1432
|
if (!state2.selectedSessionId) {
|
|
1415
1433
|
notify(state2, "No session selected");
|
|
@@ -1551,6 +1569,29 @@ function handleNavigateKey(input, key, state2, actions) {
|
|
|
1551
1569
|
}
|
|
1552
1570
|
return;
|
|
1553
1571
|
}
|
|
1572
|
+
if (input === "s") {
|
|
1573
|
+
if (!state2.strategyContent) {
|
|
1574
|
+
notify(state2, "No strategy for this session");
|
|
1575
|
+
return;
|
|
1576
|
+
}
|
|
1577
|
+
state2.showStrategy = !state2.showStrategy;
|
|
1578
|
+
requestRender();
|
|
1579
|
+
return;
|
|
1580
|
+
}
|
|
1581
|
+
if (input === "S") {
|
|
1582
|
+
if (!state2.selectedSessionId) {
|
|
1583
|
+
notify(state2, "No session selected");
|
|
1584
|
+
return;
|
|
1585
|
+
}
|
|
1586
|
+
const sp = strategyPath(state2.cwd, state2.selectedSessionId);
|
|
1587
|
+
const editor = actions.resolveEditor();
|
|
1588
|
+
try {
|
|
1589
|
+
actions.openEditorPopup(state2.cwd, editor, sp);
|
|
1590
|
+
} catch {
|
|
1591
|
+
notify(state2, `Failed to open strategy in ${editor}`);
|
|
1592
|
+
}
|
|
1593
|
+
return;
|
|
1594
|
+
}
|
|
1554
1595
|
if (input === "t") {
|
|
1555
1596
|
if (state2.showLogs) {
|
|
1556
1597
|
if (state2.focusPane === "logs") state2.focusPane = "detail";
|
|
@@ -1831,6 +1872,14 @@ function openShellPopup(cwd2, command) {
|
|
|
1831
1872
|
function openInFileManager(path) {
|
|
1832
1873
|
execSync(`open ${shellQuote(path)}`, { stdio: "inherit", env: EXEC_ENV });
|
|
1833
1874
|
}
|
|
1875
|
+
function openClaudeResumePopup(cwd2, claudeSessionId) {
|
|
1876
|
+
const pathEnv = augmentedPath();
|
|
1877
|
+
const cmd = `PATH=${shellQuote(pathEnv)} claude --resume ${shellQuote(claudeSessionId)}`;
|
|
1878
|
+
execSync(
|
|
1879
|
+
`tmux display-popup -E -w 90% -h 80% -d ${shellQuote(cwd2)} ${shellQuote(cmd)}`,
|
|
1880
|
+
{ stdio: "inherit", env: EXEC_ENV }
|
|
1881
|
+
);
|
|
1882
|
+
}
|
|
1834
1883
|
function openEditorPopup(cwd2, editor, filePath, size) {
|
|
1835
1884
|
const { w = "90%", h = "90%" } = size ?? {};
|
|
1836
1885
|
const editorBin = editor.split(/\s+/)[0].split("/").pop();
|
|
@@ -1902,7 +1951,7 @@ function renderNodeContent(node, maxWidth) {
|
|
|
1902
1951
|
}
|
|
1903
1952
|
case "cycle": {
|
|
1904
1953
|
const isRunning = !node.completedAt;
|
|
1905
|
-
const dur =
|
|
1954
|
+
const dur = isRunning ? "running" : formatDuration(node.activeMs);
|
|
1906
1955
|
const agents = `${node.agentCount} agent${node.agentCount !== 1 ? "s" : ""}`;
|
|
1907
1956
|
const modeShort = abbreviateMode(node.mode);
|
|
1908
1957
|
const mode = modeShort ? ` \xB7 ${modeShort}` : "";
|
|
@@ -1917,34 +1966,22 @@ function renderNodeContent(node, maxWidth) {
|
|
|
1917
1966
|
case "agent": {
|
|
1918
1967
|
const icon = agentStatusIcon(node.status);
|
|
1919
1968
|
const color = statusColor(node.status);
|
|
1920
|
-
const dur = formatDuration(node.
|
|
1921
|
-
const durClr = durationColor(node.
|
|
1969
|
+
const dur = formatDuration(node.activeMs);
|
|
1970
|
+
const durClr = durationColor(node.activeMs) || void 0;
|
|
1922
1971
|
const dim = node.status === "completed";
|
|
1923
1972
|
const displayName = agentDisplayName({
|
|
1924
1973
|
name: node.name,
|
|
1925
1974
|
id: node.agentId,
|
|
1926
1975
|
agentType: node.agentType
|
|
1927
1976
|
});
|
|
1928
|
-
|
|
1929
|
-
let suffixColor;
|
|
1930
|
-
if (node.mergeStatus) {
|
|
1931
|
-
const ms = node.mergeStatus === "pending" ? { icon: "\u2387", color: "yellow" } : mergeStatusDisplay(node.mergeStatus);
|
|
1932
|
-
if (ms) {
|
|
1933
|
-
suffix = ms.icon;
|
|
1934
|
-
suffixColor = ms.color;
|
|
1935
|
-
}
|
|
1936
|
-
}
|
|
1937
|
-
const suffixLen = suffix ? 2 : 0;
|
|
1938
|
-
const maxLabel = Math.max(8, maxWidth - dur.length - suffixLen - 4);
|
|
1977
|
+
const maxLabel = Math.max(8, maxWidth - dur.length - 4);
|
|
1939
1978
|
return {
|
|
1940
1979
|
icon,
|
|
1941
1980
|
label: truncate(displayName, maxLabel),
|
|
1942
1981
|
meta: dur,
|
|
1943
1982
|
color,
|
|
1944
1983
|
dim,
|
|
1945
|
-
metaColor: durClr
|
|
1946
|
-
suffix,
|
|
1947
|
-
suffixColor
|
|
1984
|
+
metaColor: durClr
|
|
1948
1985
|
};
|
|
1949
1986
|
}
|
|
1950
1987
|
case "report": {
|
|
@@ -2148,14 +2185,13 @@ function buildPlanLines(content, maxLines, width) {
|
|
|
2148
2185
|
}
|
|
2149
2186
|
return lines;
|
|
2150
2187
|
}
|
|
2151
|
-
function buildSessionLines(session, planContent, goalContent, width, paneAlive) {
|
|
2188
|
+
function buildSessionLines(session, planContent, goalContent, width, paneAlive, strategyContent = "", showStrategy = false) {
|
|
2152
2189
|
const lines = [];
|
|
2153
2190
|
const contentWidth = width - 4;
|
|
2154
2191
|
const agents = session.agents;
|
|
2155
2192
|
const cycles = session.orchestratorCycles;
|
|
2156
2193
|
const messages = session.messages;
|
|
2157
2194
|
const isDead = session.status === "active" && !paneAlive;
|
|
2158
|
-
const conflicts = agents.filter((a) => a.mergeStatus === "conflict");
|
|
2159
2195
|
const goalText = goalContent ? cleanMarkdown(stripFrontmatter(goalContent).trim()) : session.task;
|
|
2160
2196
|
goalText.split("\n").flatMap((l) => wrapText(l, contentWidth - 2)).forEach((line, i) => {
|
|
2161
2197
|
lines.push(singleLine(`${i === 0 ? " " : " "}${line}`, { bold: true }));
|
|
@@ -2189,28 +2225,34 @@ function buildSessionLines(session, planContent, goalContent, width, paneAlive)
|
|
|
2189
2225
|
seg(" tmux window closed \u2014 [w] reopen [R] resume", { color: "red" })
|
|
2190
2226
|
]);
|
|
2191
2227
|
}
|
|
2192
|
-
if (conflicts.length > 0) {
|
|
2193
|
-
lines.push(
|
|
2194
|
-
singleLine(
|
|
2195
|
-
` \u26A0 ${conflicts.length} merge conflict${conflicts.length > 1 ? "s" : ""}`,
|
|
2196
|
-
{ color: "red", bold: true }
|
|
2197
|
-
)
|
|
2198
|
-
);
|
|
2199
|
-
lines.push(
|
|
2200
|
-
singleLine(
|
|
2201
|
-
" resolve in worktree, then [x] restart agent",
|
|
2202
|
-
{ color: "red", dim: true }
|
|
2203
|
-
)
|
|
2204
|
-
);
|
|
2205
|
-
}
|
|
2206
2228
|
lines.push(singleLine(" "));
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2229
|
+
if (showStrategy && strategyContent) {
|
|
2230
|
+
const stratHint = strategyContent ? " [s] toggle plan" : "";
|
|
2231
|
+
lines.push([
|
|
2232
|
+
seg(" \u258E \u25C8 STRATEGY", { color: "yellow", bold: true }),
|
|
2233
|
+
seg(stratHint, { dim: true })
|
|
2234
|
+
]);
|
|
2235
|
+
const stratLines = buildPlanLines(strategyContent, 99999, width);
|
|
2236
|
+
if (stratLines.length === 0) {
|
|
2237
|
+
lines.push(singleLine(" (empty)", { dim: true, italic: true }));
|
|
2238
|
+
} else {
|
|
2239
|
+
for (const pl of stratLines) {
|
|
2240
|
+
lines.push(singleLine(pl.text, { bold: pl.bold, dim: pl.dim, color: pl.color }));
|
|
2241
|
+
}
|
|
2242
|
+
}
|
|
2211
2243
|
} else {
|
|
2212
|
-
|
|
2213
|
-
|
|
2244
|
+
const toggleHint = strategyContent ? " [s] toggle strategy" : "";
|
|
2245
|
+
lines.push([
|
|
2246
|
+
seg(" \u258E \u25C8 PLAN", { color: "yellow", bold: true }),
|
|
2247
|
+
seg(toggleHint, { dim: true })
|
|
2248
|
+
]);
|
|
2249
|
+
const planLines = buildPlanLines(planContent, 99999, width);
|
|
2250
|
+
if (planLines.length === 0) {
|
|
2251
|
+
lines.push(singleLine(" orchestrator will create one", { dim: true, italic: true }));
|
|
2252
|
+
} else {
|
|
2253
|
+
for (const pl of planLines) {
|
|
2254
|
+
lines.push(singleLine(pl.text, { bold: pl.bold, dim: pl.dim, color: pl.color }));
|
|
2255
|
+
}
|
|
2214
2256
|
}
|
|
2215
2257
|
}
|
|
2216
2258
|
if (session.status === "completed" && session.completionReport) {
|
|
@@ -2258,7 +2300,7 @@ function buildSessionLines(session, planContent, goalContent, width, paneAlive)
|
|
|
2258
2300
|
const dot = isRunning ? "\u25CF" : "\u25CB";
|
|
2259
2301
|
const dotColor = isRunning ? "green" : isNewest ? "white" : "gray";
|
|
2260
2302
|
const rowDim = !isRunning && !isNewest && !isSecond;
|
|
2261
|
-
const duration = isRunning ? "running" : formatDuration(cycle.
|
|
2303
|
+
const duration = isRunning ? "running" : formatDuration(cycle.activeMs);
|
|
2262
2304
|
const n = cycle.agentsSpawned.length;
|
|
2263
2305
|
const startTime = formatTime(cycle.timestamp);
|
|
2264
2306
|
const modeLabel = abbreviateMode(cycle.mode);
|
|
@@ -2314,7 +2356,7 @@ function buildCycleLines(cycle, agents, width) {
|
|
|
2314
2356
|
const lines = [];
|
|
2315
2357
|
const contentWidth = width - 4;
|
|
2316
2358
|
const isRunning = !cycle.completedAt;
|
|
2317
|
-
const dur =
|
|
2359
|
+
const dur = isRunning ? "running" : formatDuration(cycle.activeMs);
|
|
2318
2360
|
const cycleAgents = agents.filter((a) => cycle.agentsSpawned.includes(a.id));
|
|
2319
2361
|
lines.push(singleLine(` Cycle ${cycle.cycle}`, { bold: true }));
|
|
2320
2362
|
lines.push([
|
|
@@ -2327,6 +2369,9 @@ function buildCycleLines(cycle, agents, width) {
|
|
|
2327
2369
|
` ${formatTime(cycle.timestamp)}${cycle.completedAt ? ` \u2192 ${formatTime(cycle.completedAt)}` : ""}`,
|
|
2328
2370
|
{ dim: true }
|
|
2329
2371
|
));
|
|
2372
|
+
if (cycle.claudeSessionId) {
|
|
2373
|
+
lines.push(singleLine(` Session: ${cycle.claudeSessionId}`, { dim: true }));
|
|
2374
|
+
}
|
|
2330
2375
|
lines.push(singleLine(" "));
|
|
2331
2376
|
lines.push([seg(" \u258E \u229E AGENTS", { color: "green", bold: true })]);
|
|
2332
2377
|
if (cycleAgents.length === 0) {
|
|
@@ -2337,8 +2382,8 @@ function buildCycleLines(cycle, agents, width) {
|
|
|
2337
2382
|
const instrPreview = agent.instruction.split("\n")[0];
|
|
2338
2383
|
const latestReport = agent.reports.length > 0 ? agent.reports[agent.reports.length - 1] : null;
|
|
2339
2384
|
const reportSummary = latestReport !== null && agent.status === "completed" ? extractFirstSentence(latestReport.summary, contentWidth - 14) : null;
|
|
2340
|
-
const agentDur = formatDuration(agent.
|
|
2341
|
-
const durClrRaw = durationColor(agent.
|
|
2385
|
+
const agentDur = formatDuration(agent.activeMs);
|
|
2386
|
+
const durClrRaw = durationColor(agent.activeMs);
|
|
2342
2387
|
const durClr = durClrRaw !== "" ? durClrRaw : void 0;
|
|
2343
2388
|
const typeClrRaw = agentTypeColor(agent.agentType);
|
|
2344
2389
|
const typeClr = typeClrRaw !== void 0 ? typeClrRaw : void 0;
|
|
@@ -2377,34 +2422,23 @@ function buildCycleLines(cycle, agents, width) {
|
|
|
2377
2422
|
function buildAgentLines(agent, reportBlocks, width) {
|
|
2378
2423
|
const lines = [];
|
|
2379
2424
|
const contentWidth = width - 4;
|
|
2380
|
-
const dur = formatDuration(agent.
|
|
2425
|
+
const dur = formatDuration(agent.activeMs);
|
|
2381
2426
|
const icon = agentStatusIcon(agent.status);
|
|
2382
2427
|
const color = statusColor(agent.status);
|
|
2383
2428
|
const nameLabel = agentDisplayName(agent);
|
|
2384
|
-
const maxMergeLines = 3;
|
|
2385
2429
|
lines.push([
|
|
2386
2430
|
seg(" "),
|
|
2387
2431
|
seg(icon, { color }),
|
|
2388
2432
|
seg(` ${agent.id} \xB7 ${nameLabel}`, { bold: true })
|
|
2389
2433
|
]);
|
|
2390
|
-
const merge = agent.mergeStatus ? mergeStatusDisplay(agent.mergeStatus) : null;
|
|
2391
2434
|
lines.push([
|
|
2392
2435
|
seg(" "),
|
|
2393
2436
|
seg(agent.status, { color }),
|
|
2394
|
-
seg(` \xB7 ${dur} \xB7 ${agent.agentType}`, { dim: true })
|
|
2395
|
-
...merge ? [seg(" \xB7 ", { dim: true }), seg(`${merge.icon} ${merge.label}`, { color: merge.color })] : agent.mergeStatus ? [seg(" \xB7 ", { dim: true }), seg(agent.mergeStatus, { dim: true })] : []
|
|
2437
|
+
seg(` \xB7 ${dur} \xB7 ${agent.agentType}`, { dim: true })
|
|
2396
2438
|
]);
|
|
2397
2439
|
if (agent.killedReason) {
|
|
2398
2440
|
lines.push(singleLine(` \u26A0 ${agent.killedReason}`, { color: "red" }));
|
|
2399
2441
|
}
|
|
2400
|
-
if (agent.mergeStatus === "conflict" && agent.mergeDetails) {
|
|
2401
|
-
for (const ml of wrapText(agent.mergeDetails, contentWidth - 6).slice(0, maxMergeLines)) {
|
|
2402
|
-
lines.push(singleLine(` \u26A0 ${ml}`, { color: "red" }));
|
|
2403
|
-
}
|
|
2404
|
-
}
|
|
2405
|
-
if (agent.mergeStatus === "conflict") {
|
|
2406
|
-
lines.push(singleLine(" resolve conflicts in worktree dir, then restart", { color: "red", dim: true }));
|
|
2407
|
-
}
|
|
2408
2442
|
lines.push(singleLine(" "));
|
|
2409
2443
|
lines.push(singleLine(" \u258E \u25B7 INSTRUCTION", { color: "white", bold: true }));
|
|
2410
2444
|
for (const wl of wrapText(agent.instruction, contentWidth - 6)) {
|
|
@@ -2445,21 +2479,18 @@ function buildAgentLines(agent, reportBlocks, width) {
|
|
|
2445
2479
|
if (agent.completedAt) {
|
|
2446
2480
|
lines.push(singleLine(` Completed: ${formatTime(agent.completedAt)}`, { dim: true }));
|
|
2447
2481
|
}
|
|
2482
|
+
if (agent.claudeSessionId) {
|
|
2483
|
+
lines.push(singleLine(` Session: ${agent.claudeSessionId}`, { dim: true }));
|
|
2484
|
+
}
|
|
2448
2485
|
if (agent.paneId) {
|
|
2449
2486
|
lines.push(singleLine(` Pane: ${agent.paneId}`, { dim: true }));
|
|
2450
2487
|
}
|
|
2451
|
-
if (agent.worktreePath) {
|
|
2452
|
-
lines.push(singleLine(` Worktree: ${agent.worktreePath}`, { dim: true }));
|
|
2453
|
-
}
|
|
2454
|
-
if (agent.branchName) {
|
|
2455
|
-
lines.push(singleLine(` Branch: ${agent.branchName}`, { dim: true }));
|
|
2456
|
-
}
|
|
2457
2488
|
return lines;
|
|
2458
2489
|
}
|
|
2459
2490
|
function buildReportViewLines(agent, reportBlocks, width) {
|
|
2460
2491
|
const lines = [];
|
|
2461
2492
|
const contentWidth = width - 6;
|
|
2462
|
-
const dur = formatDuration(agent.
|
|
2493
|
+
const dur = formatDuration(agent.activeMs);
|
|
2463
2494
|
const icon = agentStatusIcon(agent.status);
|
|
2464
2495
|
const color = statusColor(agent.status);
|
|
2465
2496
|
const totalReports = agent.reports.length;
|
|
@@ -2552,14 +2583,14 @@ function renderDetailContent(buf, rect, state2, detailCtx) {
|
|
|
2552
2583
|
let borderColor = "gray";
|
|
2553
2584
|
switch (cursorNode.type) {
|
|
2554
2585
|
case "session": {
|
|
2555
|
-
lines = buildSessionLines(session, state2.planContent, state2.goalContent, rect.w, state2.paneAlive);
|
|
2586
|
+
lines = buildSessionLines(session, state2.planContent, state2.goalContent, rect.w, state2.paneAlive, state2.strategyContent, state2.showStrategy);
|
|
2556
2587
|
break;
|
|
2557
2588
|
}
|
|
2558
2589
|
case "cycle": {
|
|
2559
2590
|
const cycleNode = cursorNode;
|
|
2560
2591
|
const cycle = session.orchestratorCycles.find((c) => c.cycle === cycleNode.cycleNumber);
|
|
2561
2592
|
if (!cycle) {
|
|
2562
|
-
lines = buildSessionLines(session, state2.planContent, state2.goalContent, rect.w, state2.paneAlive);
|
|
2593
|
+
lines = buildSessionLines(session, state2.planContent, state2.goalContent, rect.w, state2.paneAlive, state2.strategyContent, state2.showStrategy);
|
|
2563
2594
|
} else {
|
|
2564
2595
|
lines = buildCycleLines(cycle, session.agents, rect.w);
|
|
2565
2596
|
}
|
|
@@ -2569,7 +2600,7 @@ function renderDetailContent(buf, rect, state2, detailCtx) {
|
|
|
2569
2600
|
const agentNode = cursorNode;
|
|
2570
2601
|
const agent = agents.find((a) => a.id === agentNode.agentId);
|
|
2571
2602
|
if (!agent) {
|
|
2572
|
-
lines = buildSessionLines(session, state2.planContent, state2.goalContent, rect.w, state2.paneAlive);
|
|
2603
|
+
lines = buildSessionLines(session, state2.planContent, state2.goalContent, rect.w, state2.paneAlive, state2.strategyContent, state2.showStrategy);
|
|
2573
2604
|
} else {
|
|
2574
2605
|
lines = buildAgentLines(agent, detailReportBlocks, rect.w);
|
|
2575
2606
|
}
|
|
@@ -2579,7 +2610,7 @@ function renderDetailContent(buf, rect, state2, detailCtx) {
|
|
|
2579
2610
|
const reportNode = cursorNode;
|
|
2580
2611
|
const agent = agents.find((a) => a.id === reportNode.agentId);
|
|
2581
2612
|
if (!agent) {
|
|
2582
|
-
lines = buildSessionLines(session, state2.planContent, state2.goalContent, rect.w, state2.paneAlive);
|
|
2613
|
+
lines = buildSessionLines(session, state2.planContent, state2.goalContent, rect.w, state2.paneAlive, state2.strategyContent, state2.showStrategy);
|
|
2583
2614
|
break;
|
|
2584
2615
|
}
|
|
2585
2616
|
const reportIdx = reportNode.reportIndex;
|
|
@@ -2671,7 +2702,7 @@ function renderDetailContent(buf, rect, state2, detailCtx) {
|
|
|
2671
2702
|
break;
|
|
2672
2703
|
}
|
|
2673
2704
|
default: {
|
|
2674
|
-
lines = buildSessionLines(session, state2.planContent, state2.goalContent, rect.w, state2.paneAlive);
|
|
2705
|
+
lines = buildSessionLines(session, state2.planContent, state2.goalContent, rect.w, state2.paneAlive, state2.strategyContent, state2.showStrategy);
|
|
2675
2706
|
break;
|
|
2676
2707
|
}
|
|
2677
2708
|
}
|
|
@@ -2744,7 +2775,7 @@ function renderStatusLine(buf, y, state2, cursorNodeType) {
|
|
|
2744
2775
|
} else if (mode !== "navigate") {
|
|
2745
2776
|
content = D("[enter] send [esc] cancel");
|
|
2746
2777
|
} else if (focusPane === "logs" || focusPane === "detail") {
|
|
2747
|
-
content = B("[jk/\u2191\u2193]") + D(" scroll ") + B("[h/\u2190/tab]") + D(" back ") + B("[t]") + D("oggle logs ") + SEP + B("[m]") + D("sg ") + B("[g]") + D("oal ") + B("[n]") + D("ew ") + B("[p]") + D("lan ") + B("[w]") + D("indow ") + B("[R]") + D("esume ") + B("[q]") + D("uit");
|
|
2778
|
+
content = B("[jk/\u2191\u2193]") + D(" scroll ") + B("[h/\u2190/tab]") + D(" back ") + B("[t]") + D("oggle logs ") + SEP + B("[m]") + D("sg ") + B("[g]") + D("oal ") + B("[n]") + D("ew ") + B("[p]") + D("lan ") + B("[s]") + D("trat ") + B("[w]") + D("indow ") + B("[R]") + D("esume ") + B("[q]") + D("uit");
|
|
2748
2779
|
} else {
|
|
2749
2780
|
let contextFilePart = "";
|
|
2750
2781
|
if (cursorNodeType === "context-file") {
|
|
@@ -2821,8 +2852,10 @@ function renderHelpOverlay(buf, rows, cols) {
|
|
|
2821
2852
|
helpRow(" R resume session", " C continue session", innerWidth),
|
|
2822
2853
|
helpRow(" b rollback cycle", " x restart agent", innerWidth),
|
|
2823
2854
|
helpRow(" r re-run agent", " g edit goal", innerWidth),
|
|
2824
|
-
helpRow(" p open roadmap", "
|
|
2825
|
-
helpRow("
|
|
2855
|
+
helpRow(" p open roadmap", " s toggle strategy", innerWidth),
|
|
2856
|
+
helpRow(" S edit strategy", " w go to window", innerWidth),
|
|
2857
|
+
helpRow(" o resume claude session", " c claude companion", innerWidth),
|
|
2858
|
+
helpRow(" q quit", "", innerWidth),
|
|
2826
2859
|
" ".padEnd(innerWidth),
|
|
2827
2860
|
helpRow(" space \u2192 y copy submenu", " space \u2192 d delete session", innerWidth),
|
|
2828
2861
|
helpRow(" space \u2192 j jump to pane", " space \u2192 k kill", innerWidth),
|
|
@@ -2868,6 +2901,7 @@ function startApp(state2, cleanup2) {
|
|
|
2868
2901
|
try {
|
|
2869
2902
|
let selectedSession = null;
|
|
2870
2903
|
let planContent = "";
|
|
2904
|
+
let strategyContent = "";
|
|
2871
2905
|
let goalContent = "";
|
|
2872
2906
|
let logsContent = "";
|
|
2873
2907
|
let logsCycles = [];
|
|
@@ -2911,6 +2945,13 @@ function startApp(state2, cleanup2) {
|
|
|
2911
2945
|
}
|
|
2912
2946
|
} catch {
|
|
2913
2947
|
}
|
|
2948
|
+
try {
|
|
2949
|
+
const sp = strategyPath(state2.cwd, state2.selectedSessionId);
|
|
2950
|
+
if (existsSync2(sp)) {
|
|
2951
|
+
strategyContent = readFileSync2(sp, "utf-8");
|
|
2952
|
+
}
|
|
2953
|
+
} catch {
|
|
2954
|
+
}
|
|
2914
2955
|
try {
|
|
2915
2956
|
const ld = logsDir(state2.cwd, state2.selectedSessionId);
|
|
2916
2957
|
if (existsSync2(ld)) {
|
|
@@ -2942,6 +2983,7 @@ function startApp(state2, cleanup2) {
|
|
|
2942
2983
|
state2.sessions = sessions;
|
|
2943
2984
|
state2.selectedSession = selectedSession;
|
|
2944
2985
|
state2.planContent = planContent;
|
|
2986
|
+
state2.strategyContent = strategyContent;
|
|
2945
2987
|
state2.goalContent = goalContent;
|
|
2946
2988
|
state2.logsContent = logsContent;
|
|
2947
2989
|
state2.logsCycles = logsCycles;
|
|
@@ -3088,6 +3130,7 @@ function startApp(state2, cleanup2) {
|
|
|
3088
3130
|
openEditorPopup,
|
|
3089
3131
|
editInPopup,
|
|
3090
3132
|
openCompanionPane,
|
|
3133
|
+
openClaudeResumePopup,
|
|
3091
3134
|
selectWindow,
|
|
3092
3135
|
selectPane,
|
|
3093
3136
|
switchToSession,
|