Skip to content

Commit b8bfe1d

Browse files
Merge pull request #286 from corbitsdev/cl-4365-split-the-event-log-into-assembly-and-component-modules
Split the event log into pure line-assembly and React presentation modules
2 parents c79a3c8 + f38ea5f commit b8bfe1d

20 files changed

Lines changed: 3611 additions & 2698 deletions

src/tui/app.tsx

Lines changed: 278 additions & 1346 deletions
Large diffs are not rendered by default.

src/tui/chrome-geometry.ts

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
import { goalShowsAcceptancePanel, goalShowsWorkPrimary } from "../agent/goal.js";
2+
import { extraPromptChromeRows } from "./prompt-layout.js";
3+
import type { PluginsAdmin } from "./components/plugins-manager.js";
4+
5+
export type GoalChromeArgs = {
6+
goalSnapshot: import("../agent/goal.js").GoalSnapshot | null;
7+
};
8+
9+
export type GoalChromeResult = {
10+
goalActive: boolean;
11+
goalPhase: import("../agent/goal.js").GoalPhase | null;
12+
showAcceptance: boolean;
13+
workPrimary: boolean;
14+
};
15+
16+
/** Goal chrome follows lifecycle phase: planning / reviewing / completed →
17+
* Acceptance panel; implementing → Work primary (Acceptance compact; header
18+
* shows phase). */
19+
export function resolveGoalChrome({ goalSnapshot }: GoalChromeArgs): GoalChromeResult {
20+
const goalActive =
21+
goalSnapshot !== null &&
22+
goalSnapshot.status !== "inactive" &&
23+
goalSnapshot.status !== "cleared";
24+
const goalPhase = goalActive ? goalSnapshot!.phase : null;
25+
return {
26+
goalActive,
27+
goalPhase,
28+
showAcceptance: goalPhase !== null && goalShowsAcceptancePanel(goalPhase),
29+
workPrimary: goalPhase !== null && goalShowsWorkPrimary(goalPhase),
30+
};
31+
}
32+
33+
export function goalChromeRowCount(args: {
34+
goalActive: boolean;
35+
showAcceptance: boolean;
36+
criteriaCount: number;
37+
}): number {
38+
const { goalActive, showAcceptance, criteriaCount } = args;
39+
if (!goalActive) return 0;
40+
// compact phase strip during implementing
41+
if (!showAcceptance) return 3;
42+
return (criteriaCount === 0 ? 2 : criteriaCount + 2) + 2;
43+
}
44+
45+
// The task strip renders above the in-flight indicator: one line when compact,
46+
// the full checklist plus its heading when expanded. +1 is the marginTop wrapper.
47+
export function taskChromeRowCount(args: {
48+
hasActiveTasks: boolean;
49+
taskCount: number;
50+
workExpanded: boolean;
51+
}): number {
52+
const { hasActiveTasks, taskCount, workExpanded } = args;
53+
if (!hasActiveTasks) return 0;
54+
return (workExpanded ? taskCount + 1 : 1) + 1;
55+
}
56+
57+
// The plugins overlay renders outside the modal-stack accounting (like the
58+
// permissions overlay), so reserve rows for its box: chrome + one row per
59+
// plugin + the selected plugin's credential rows.
60+
export function pluginChromeRowCount(args: {
61+
pluginsOpen: boolean;
62+
pluginsAdmin: PluginsAdmin | undefined;
63+
}): number {
64+
const { pluginsOpen, pluginsAdmin } = args;
65+
if (!pluginsOpen || pluginsAdmin === undefined) return 0;
66+
const list = pluginsAdmin.list();
67+
const widestCreds = list.reduce((n, p) => Math.max(n, p.credentials.length), 0);
68+
return 6 + list.length + widestCreds + 2;
69+
}
70+
71+
export function extraChromeRowCount(args: {
72+
mcpNeedsAuthCount: number;
73+
commandMessagePresent: boolean;
74+
goalChromeRows: number;
75+
taskChromeRows: number;
76+
pluginChromeRows: number;
77+
quotaErrorPresent: boolean;
78+
inferenceRetryPresent: boolean;
79+
subAgentChromeRows: number;
80+
inputValue: string;
81+
columns: number | undefined;
82+
rows: number | undefined;
83+
}): number {
84+
return (
85+
(args.mcpNeedsAuthCount > 0 ? 1 : 0) +
86+
(args.commandMessagePresent ? 1 : 0) +
87+
args.goalChromeRows +
88+
args.taskChromeRows +
89+
args.pluginChromeRows +
90+
(args.quotaErrorPresent ? 1 : 0) +
91+
(args.inferenceRetryPresent ? 1 : 0) +
92+
args.subAgentChromeRows +
93+
extraPromptChromeRows(args.inputValue, args.columns ?? 80, args.rows ?? 24)
94+
);
95+
}

0 commit comments

Comments
 (0)