wepscli 0.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/README.md +293 -0
- package/dist/WEPSCLI-shell/agent-runtime.js +824 -0
- package/dist/WEPSCLI-shell/agent-runtime.js.map +1 -0
- package/dist/WEPSCLI-shell/approval-overlay.js +275 -0
- package/dist/WEPSCLI-shell/approval-overlay.js.map +1 -0
- package/dist/WEPSCLI-shell/chat-components.js +760 -0
- package/dist/WEPSCLI-shell/chat-components.js.map +1 -0
- package/dist/WEPSCLI-shell/components.js +850 -0
- package/dist/WEPSCLI-shell/components.js.map +1 -0
- package/dist/WEPSCLI-shell/config-overlays.js +205 -0
- package/dist/WEPSCLI-shell/config-overlays.js.map +1 -0
- package/dist/WEPSCLI-shell/debug-log.js +16 -0
- package/dist/WEPSCLI-shell/debug-log.js.map +1 -0
- package/dist/WEPSCLI-shell/file-change-preview.js +261 -0
- package/dist/WEPSCLI-shell/file-change-preview.js.map +1 -0
- package/dist/WEPSCLI-shell/helpers.js +112 -0
- package/dist/WEPSCLI-shell/helpers.js.map +1 -0
- package/dist/WEPSCLI-shell/index.js +3 -0
- package/dist/WEPSCLI-shell/index.js.map +1 -0
- package/dist/WEPSCLI-shell/provider-add-flow.js +406 -0
- package/dist/WEPSCLI-shell/provider-add-flow.js.map +1 -0
- package/dist/WEPSCLI-shell/run-wepscli-shell.js +21 -0
- package/dist/WEPSCLI-shell/run-wepscli-shell.js.map +1 -0
- package/dist/WEPSCLI-shell/runtime-recovery.js +37 -0
- package/dist/WEPSCLI-shell/runtime-recovery.js.map +1 -0
- package/dist/WEPSCLI-shell/runtime-status.js +66 -0
- package/dist/WEPSCLI-shell/runtime-status.js.map +1 -0
- package/dist/WEPSCLI-shell/shell-app.js +1047 -0
- package/dist/WEPSCLI-shell/shell-app.js.map +1 -0
- package/dist/WEPSCLI-shell/shell-modes.js +77 -0
- package/dist/WEPSCLI-shell/shell-modes.js.map +1 -0
- package/dist/WEPSCLI-shell/slash-commands.js +135 -0
- package/dist/WEPSCLI-shell/slash-commands.js.map +1 -0
- package/dist/WEPSCLI-shell/theme.js +19 -0
- package/dist/WEPSCLI-shell/theme.js.map +1 -0
- package/dist/WEPSCLI-shell/tool-approval.js +85 -0
- package/dist/WEPSCLI-shell/tool-approval.js.map +1 -0
- package/dist/WEPSCLI-shell/tool-diff.js +76 -0
- package/dist/WEPSCLI-shell/tool-diff.js.map +1 -0
- package/dist/WEPSCLI-shell/tool-file-changes.js +268 -0
- package/dist/WEPSCLI-shell/tool-file-changes.js.map +1 -0
- package/dist/WEPSCLI-shell/tool-message-detail.js +138 -0
- package/dist/WEPSCLI-shell/tool-message-detail.js.map +1 -0
- package/dist/WEPSCLI-shell/tool-messages.js +145 -0
- package/dist/WEPSCLI-shell/tool-messages.js.map +1 -0
- package/dist/WEPSCLI-shell/transcript-panel.js +372 -0
- package/dist/WEPSCLI-shell/transcript-panel.js.map +1 -0
- package/dist/WEPSCLI-shell/transcript-state.js +62 -0
- package/dist/WEPSCLI-shell/transcript-state.js.map +1 -0
- package/dist/WEPSCLI-shell/types.js +1 -0
- package/dist/WEPSCLI-shell/types.js.map +1 -0
- package/dist/cli.js +11 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.js +40 -0
- package/dist/config.js.map +1 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/main.js +140 -0
- package/dist/main.js.map +1 -0
- package/dist/onboarding/action-screen.js +90 -0
- package/dist/onboarding/action-screen.js.map +1 -0
- package/dist/onboarding/framed-screen.js +35 -0
- package/dist/onboarding/framed-screen.js.map +1 -0
- package/dist/onboarding/onboarding-app.js +312 -0
- package/dist/onboarding/onboarding-app.js.map +1 -0
- package/dist/onboarding/run-onboarding.js +23 -0
- package/dist/onboarding/run-onboarding.js.map +1 -0
- package/dist/onboarding/select-screen.js +21 -0
- package/dist/onboarding/select-screen.js.map +1 -0
- package/dist/onboarding/summary-screen.js +23 -0
- package/dist/onboarding/summary-screen.js.map +1 -0
- package/dist/onboarding/text-input-screen.js +55 -0
- package/dist/onboarding/text-input-screen.js.map +1 -0
- package/dist/onboarding/theme.js +26 -0
- package/dist/onboarding/theme.js.map +1 -0
- package/dist/provider-profiles/api-key-store.js +51 -0
- package/dist/provider-profiles/api-key-store.js.map +1 -0
- package/dist/provider-profiles/defaults.js +18 -0
- package/dist/provider-profiles/defaults.js.map +1 -0
- package/dist/provider-profiles/fetch-models.js +53 -0
- package/dist/provider-profiles/fetch-models.js.map +1 -0
- package/dist/provider-profiles/index.js +6 -0
- package/dist/provider-profiles/index.js.map +1 -0
- package/dist/provider-profiles/provider-profile-service.js +223 -0
- package/dist/provider-profiles/provider-profile-service.js.map +1 -0
- package/dist/provider-profiles/providers-config-store.js +17 -0
- package/dist/provider-profiles/providers-config-store.js.map +1 -0
- package/dist/provider-profiles/types.js +1 -0
- package/dist/provider-profiles/types.js.map +1 -0
- package/dist/session-history/session-history-service.js +142 -0
- package/dist/session-history/session-history-service.js.map +1 -0
- package/dist/shell/animator.js +30 -0
- package/dist/shell/animator.js.map +1 -0
- package/dist/shell/clickables.js +101 -0
- package/dist/shell/clickables.js.map +1 -0
- package/dist/shell/dashboard-shell.js +292 -0
- package/dist/shell/dashboard-shell.js.map +1 -0
- package/dist/shell/index.js +5 -0
- package/dist/shell/index.js.map +1 -0
- package/dist/shell/keymap.js +14 -0
- package/dist/shell/keymap.js.map +1 -0
- package/dist/shell/mouse.js +39 -0
- package/dist/shell/mouse.js.map +1 -0
- package/dist/shell/render.js +122 -0
- package/dist/shell/render.js.map +1 -0
- package/dist/shell/run-shell.js +36 -0
- package/dist/shell/run-shell.js.map +1 -0
- package/dist/shell/theme.js +56 -0
- package/dist/shell/theme.js.map +1 -0
- package/dist/storage/locked-json-file.js +88 -0
- package/dist/storage/locked-json-file.js.map +1 -0
- package/dist/workbench/animator.js +30 -0
- package/dist/workbench/animator.js.map +1 -0
- package/dist/workbench/index.js +6 -0
- package/dist/workbench/index.js.map +1 -0
- package/dist/workbench/mouse.js +39 -0
- package/dist/workbench/mouse.js.map +1 -0
- package/dist/workbench/render.js +82 -0
- package/dist/workbench/render.js.map +1 -0
- package/dist/workbench/renderer.js +364 -0
- package/dist/workbench/renderer.js.map +1 -0
- package/dist/workbench/run-workbench.js +36 -0
- package/dist/workbench/run-workbench.js.map +1 -0
- package/dist/workbench/theme.js +63 -0
- package/dist/workbench/theme.js.map +1 -0
- package/dist/workbench/types.js +1 -0
- package/dist/workbench/types.js.map +1 -0
- package/dist/workbench/workbench-shell.js +649 -0
- package/dist/workbench/workbench-shell.js.map +1 -0
- package/package.json +65 -0
|
@@ -0,0 +1,364 @@
|
|
|
1
|
+
import { visibleWidth, wrapTextWithAnsi } from "@mariozechner/pi-tui";
|
|
2
|
+
import { computeCenteredRect, computeWorkbenchLayout, fitLines, framePanelFixed, joinColumns, padLine } from "./render.js";
|
|
3
|
+
import { getPanelStyle, pulseDot, sweepText, workbenchTheme } from "./theme.js";
|
|
4
|
+
export function renderWorkbench(state) {
|
|
5
|
+
const layout = computeWorkbenchLayout(state.width, state.height);
|
|
6
|
+
const bodyStartRow = layout.headerHeight + 1;
|
|
7
|
+
const header = renderHeader(state, layout.headerHeight);
|
|
8
|
+
const body = renderBody(state, layout, bodyStartRow);
|
|
9
|
+
const dockStartRow = bodyStartRow + layout.bodyHeight;
|
|
10
|
+
const dock = state.showDock ? renderDock(state, state.width, layout.dockHeight, dockStartRow) : {
|
|
11
|
+
lines: fitLines([padLine(sweepText("Preparing bottom dock...", state.frame + 6), state.width)], state.width, layout.dockHeight),
|
|
12
|
+
dockRegions: [],
|
|
13
|
+
composerRegion: undefined
|
|
14
|
+
};
|
|
15
|
+
const lines = [...header.lines, ...body.lines, ...dock.lines];
|
|
16
|
+
if (!state.overlay) {
|
|
17
|
+
return {
|
|
18
|
+
lines,
|
|
19
|
+
toolbarRegions: header.toolbarRegions,
|
|
20
|
+
railRegions: body.railRegions,
|
|
21
|
+
mainRegions: body.mainRegions,
|
|
22
|
+
dockRegions: dock.dockRegions,
|
|
23
|
+
overlayRegions: [],
|
|
24
|
+
composerRegion: dock.composerRegion
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
const overlay = compositeOverlay(state, lines);
|
|
28
|
+
return {
|
|
29
|
+
lines: overlay.lines,
|
|
30
|
+
toolbarRegions: header.toolbarRegions,
|
|
31
|
+
railRegions: body.railRegions,
|
|
32
|
+
mainRegions: body.mainRegions,
|
|
33
|
+
dockRegions: dock.dockRegions,
|
|
34
|
+
overlayRegions: overlay.overlayRegions,
|
|
35
|
+
composerRegion: dock.composerRegion
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
function renderHeader(state, height) {
|
|
39
|
+
const toolbar = renderButtons(state, [{
|
|
40
|
+
id: "session:new",
|
|
41
|
+
label: state.width < 96 ? "New" : "New Session",
|
|
42
|
+
variant: "primary"
|
|
43
|
+
}, {
|
|
44
|
+
id: "overlay:provider-switch",
|
|
45
|
+
label: state.width < 96 ? "Provider" : "Providers",
|
|
46
|
+
variant: "active"
|
|
47
|
+
}, {
|
|
48
|
+
id: "overlay:model-switch",
|
|
49
|
+
label: state.width < 96 ? "Model" : "Models",
|
|
50
|
+
variant: "secondary"
|
|
51
|
+
}, {
|
|
52
|
+
id: "nav:history",
|
|
53
|
+
label: state.width < 96 ? "Recent" : "History",
|
|
54
|
+
variant: "secondary"
|
|
55
|
+
}], state.width - 2);
|
|
56
|
+
const toolbarRegions = toolbar.regions.map(region => ({
|
|
57
|
+
group: "toolbar",
|
|
58
|
+
id: region.id,
|
|
59
|
+
row: 2 + region.row,
|
|
60
|
+
col: 2 + region.col,
|
|
61
|
+
width: region.width,
|
|
62
|
+
height: region.height
|
|
63
|
+
}));
|
|
64
|
+
const statusLine = [sweepText("WEPSCLI WORKBENCH", state.frame), workbenchTheme.muted(`view ${state.getViewLabel(state.view)}`), workbenchTheme.accent(state.activeProfile?.label ?? "no provider"), workbenchTheme.muted(state.activeSelection.modelId ?? "no model")].join(workbenchTheme.muted(" | "));
|
|
65
|
+
const lines = [workbenchTheme.headerBackground(padLine(` ${statusLine} `, state.width)), workbenchTheme.headerBackground(padLine(` ${toolbar.lines[0] ?? ""} `, state.width))];
|
|
66
|
+
if (height >= 3) {
|
|
67
|
+
const thirdLine = toolbar.lines[1] ?? workbenchTheme.muted(" Tab focus | Enter select | h home p providers m models s sessions ");
|
|
68
|
+
lines.push(workbenchTheme.headerBackground(padLine(` ${thirdLine} `, state.width)));
|
|
69
|
+
}
|
|
70
|
+
return {
|
|
71
|
+
lines: fitLines(lines, state.width, height),
|
|
72
|
+
toolbarRegions
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
function renderBody(state, layout, bodyStartRow) {
|
|
76
|
+
const columns = [];
|
|
77
|
+
const widths = [];
|
|
78
|
+
const railRegions = [];
|
|
79
|
+
let mainRegions = [];
|
|
80
|
+
let currentCol = 1;
|
|
81
|
+
if (layout.showRail) {
|
|
82
|
+
const rail = renderRailPanel(state, layout.railWidth, layout.bodyHeight, bodyStartRow, currentCol);
|
|
83
|
+
columns.push(rail.lines);
|
|
84
|
+
widths.push(layout.railWidth);
|
|
85
|
+
railRegions.push(...rail.railRegions);
|
|
86
|
+
currentCol += layout.railWidth + layout.gap;
|
|
87
|
+
}
|
|
88
|
+
const main = state.showBody ? renderMainPanel(state, layout.mainWidth, layout.bodyHeight, bodyStartRow, currentCol) : {
|
|
89
|
+
lines: fitLines([padLine(sweepText("Booting main workbench surface...", state.frame), layout.mainWidth)], layout.mainWidth, layout.bodyHeight),
|
|
90
|
+
mainRegions: []
|
|
91
|
+
};
|
|
92
|
+
columns.push(main.lines);
|
|
93
|
+
widths.push(layout.mainWidth);
|
|
94
|
+
mainRegions = main.mainRegions;
|
|
95
|
+
currentCol += layout.mainWidth + layout.gap;
|
|
96
|
+
if (layout.showInspector) {
|
|
97
|
+
const inspector = state.showInspector ? renderInspectorPanel(state, layout.inspectorWidth, layout.bodyHeight) : fitLines([padLine(sweepText("Preparing inspector status surfaces...", state.frame + 3), layout.inspectorWidth)], layout.inspectorWidth, layout.bodyHeight);
|
|
98
|
+
columns.push(inspector);
|
|
99
|
+
widths.push(layout.inspectorWidth);
|
|
100
|
+
}
|
|
101
|
+
let joined = columns[0] ?? [];
|
|
102
|
+
for (let i = 1; i < columns.length; i += 1) {
|
|
103
|
+
joined = joinColumns(joined, widths[i - 1], columns[i], widths[i], layout.gap);
|
|
104
|
+
}
|
|
105
|
+
return {
|
|
106
|
+
lines: fitLines(joined, state.width, layout.bodyHeight),
|
|
107
|
+
railRegions,
|
|
108
|
+
mainRegions
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
function renderRailPanel(state, width, height, startRow, startCol) {
|
|
112
|
+
const innerWidth = Math.max(1, width - 2);
|
|
113
|
+
const body = [];
|
|
114
|
+
const railRegions = [];
|
|
115
|
+
body.push(workbenchTheme.accent("Navigation"));
|
|
116
|
+
for (const [index, item] of state.railItems.entries()) {
|
|
117
|
+
const isActive = state.view === item.id;
|
|
118
|
+
const isSelected = state.focusRegion === "rail" && state.railSelectionIndex === index;
|
|
119
|
+
const button = state.styleButton(item.label, isActive ? "active" : isSelected ? "primary" : "secondary");
|
|
120
|
+
const buttonRow = body.length;
|
|
121
|
+
body.push(button);
|
|
122
|
+
body.push(workbenchTheme.muted(item.description));
|
|
123
|
+
body.push("");
|
|
124
|
+
railRegions.push({
|
|
125
|
+
group: "rail",
|
|
126
|
+
id: `nav:${item.id}`,
|
|
127
|
+
row: startRow + 1 + buttonRow,
|
|
128
|
+
col: startCol + 1,
|
|
129
|
+
width: visibleWidth(button),
|
|
130
|
+
height: 1
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
body.push(workbenchTheme.accent(`Quick Launch ${workbenchTheme.accentSoft(`[${pulseDot(state.frame)}]`)}`));
|
|
134
|
+
const quickButtons = renderButtons(state, [{
|
|
135
|
+
id: "overlay:provider-switch",
|
|
136
|
+
label: "Provider Dialog",
|
|
137
|
+
variant: "primary"
|
|
138
|
+
}, {
|
|
139
|
+
id: "overlay:model-switch",
|
|
140
|
+
label: "Model Dialog",
|
|
141
|
+
variant: "secondary"
|
|
142
|
+
}, {
|
|
143
|
+
id: "session:new",
|
|
144
|
+
label: "New Task",
|
|
145
|
+
variant: "success"
|
|
146
|
+
}], innerWidth);
|
|
147
|
+
const quickStartRow = body.length;
|
|
148
|
+
body.push(...quickButtons.lines);
|
|
149
|
+
body.push("");
|
|
150
|
+
body.push(workbenchTheme.muted("Use the rail or the toolbar. No hidden panel-sized hit areas."));
|
|
151
|
+
railRegions.push(...quickButtons.regions.map(region => ({
|
|
152
|
+
group: "rail",
|
|
153
|
+
id: region.id,
|
|
154
|
+
row: startRow + 1 + quickStartRow + region.row,
|
|
155
|
+
col: startCol + 1 + region.col,
|
|
156
|
+
width: region.width,
|
|
157
|
+
height: region.height
|
|
158
|
+
})));
|
|
159
|
+
return {
|
|
160
|
+
lines: framePanelFixed(state.focusRegion === "rail" ? "Left Rail [active]" : "Left Rail", body.map(line => padLine(line, innerWidth)), width, height, getPanelStyle("rail", state.focusRegion === "rail", state.focusRegion === "rail")),
|
|
161
|
+
railRegions
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
function renderMainPanel(state, width, height, startRow, startCol) {
|
|
165
|
+
const innerWidth = Math.max(1, width - 2);
|
|
166
|
+
const body = [workbenchTheme.accent(`Workbench ${workbenchTheme.accentSoft(`[${state.getViewLabel(state.view)}]`)}`), workbenchTheme.text(state.activeProfile ? `Provider ${state.activeProfile.label} | Model ${state.activeSelection.modelId ?? state.activeProfile.models[0]?.id ?? "none"}` : "No active provider selected yet."), workbenchTheme.muted("Primary actions live in the cards below. Click a card or move with Up/Down and press Enter."), ""];
|
|
167
|
+
const mainRegions = [];
|
|
168
|
+
for (const [index, card] of state.mainCards.entries()) {
|
|
169
|
+
const rendered = renderCard(state, card, innerWidth, state.focusRegion === "main" && state.mainSelectionIndex === index);
|
|
170
|
+
const firstRow = body.length;
|
|
171
|
+
body.push(...rendered.lines, "");
|
|
172
|
+
mainRegions.push({
|
|
173
|
+
group: "main",
|
|
174
|
+
id: card.id,
|
|
175
|
+
row: startRow + 1 + firstRow,
|
|
176
|
+
col: startCol + 2,
|
|
177
|
+
width: Math.max(1, innerWidth - 2),
|
|
178
|
+
height: rendered.lines.length
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
const remaining = Math.max(0, height - 2 - body.length);
|
|
182
|
+
if (remaining > 0) {
|
|
183
|
+
body.push(workbenchTheme.accent(`Recent Activity ${workbenchTheme.accentSoft(`[${pulseDot(state.frame)}]`)}`));
|
|
184
|
+
for (const entry of state.timeline.slice(0, Math.max(1, remaining - 1))) {
|
|
185
|
+
body.push(workbenchTheme.text(entry));
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
return {
|
|
189
|
+
lines: framePanelFixed(state.focusRegion === "main" ? "Main Workbench [active]" : "Main Workbench", body.map(line => padLine(line, innerWidth)), width, height, getPanelStyle("main", state.focusRegion === "main", state.focusRegion === "main" && state.focusPulseActive)),
|
|
190
|
+
mainRegions
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
function renderInspectorPanel(state, width, height) {
|
|
194
|
+
const innerWidth = Math.max(1, width - 2);
|
|
195
|
+
const body = [workbenchTheme.accent("Selection"), workbenchTheme.text(`View: ${state.getViewLabel(state.view)}`), workbenchTheme.text(`Provider: ${state.activeProfile?.label ?? "none"}`), workbenchTheme.text(`Model: ${state.activeSelection.modelId ?? "none"}`), "", workbenchTheme.accent("Task State"), workbenchTheme.success(`Workbench rebuild in progress ${pulseDot(state.frame)}`), workbenchTheme.text(`Focus: ${state.getFocusLabel(state.focusRegion)}`), workbenchTheme.text(`Queued sessions: ${state.sessionsCount}`), "", workbenchTheme.accent("Context"), workbenchTheme.text("Agent dir:"), workbenchTheme.muted(state.agentDir), workbenchTheme.text(`Profiles loaded: ${state.profiles.length}`), workbenchTheme.text(`Timeline entries: ${state.timeline.length}`), "", workbenchTheme.accent("Todo"), workbenchTheme.text("1. Replace stub activity with real session timeline"), workbenchTheme.text("2. Add inline tool execution and diff surfaces"), workbenchTheme.text("3. Turn picker overlays into richer dialogs")];
|
|
196
|
+
return framePanelFixed("Inspector", body.map(line => padLine(line, innerWidth)), width, height, getPanelStyle("inspector", false, state.focusPulseActive));
|
|
197
|
+
}
|
|
198
|
+
function renderDock(state, width, height, startRow) {
|
|
199
|
+
const innerWidth = Math.max(1, width - 2);
|
|
200
|
+
const actionButtons = renderButtons(state, [{
|
|
201
|
+
id: "overlay:provider-switch",
|
|
202
|
+
label: `Provider ${state.truncateLabel(state.activeProfile?.label ?? "none", 14)}`,
|
|
203
|
+
variant: "primary"
|
|
204
|
+
}, {
|
|
205
|
+
id: "overlay:model-switch",
|
|
206
|
+
label: `Model ${state.truncateLabel(state.activeSelection.modelId ?? "none", 14)}`,
|
|
207
|
+
variant: "secondary"
|
|
208
|
+
}, {
|
|
209
|
+
id: "overlay:session-list",
|
|
210
|
+
label: "Sessions",
|
|
211
|
+
variant: "secondary"
|
|
212
|
+
}, {
|
|
213
|
+
id: "session:new",
|
|
214
|
+
label: "New Task",
|
|
215
|
+
variant: "success"
|
|
216
|
+
}, {
|
|
217
|
+
id: "focus:composer",
|
|
218
|
+
label: "Focus Composer",
|
|
219
|
+
variant: "active"
|
|
220
|
+
}], innerWidth);
|
|
221
|
+
const composerLines = state.renderComposer(innerWidth);
|
|
222
|
+
const actionStartRow = startRow + 1;
|
|
223
|
+
const dockRegions = actionButtons.regions.map(region => ({
|
|
224
|
+
group: "dock",
|
|
225
|
+
id: region.id,
|
|
226
|
+
row: actionStartRow + region.row,
|
|
227
|
+
col: 2 + region.col,
|
|
228
|
+
width: region.width,
|
|
229
|
+
height: region.height
|
|
230
|
+
}));
|
|
231
|
+
const composerRow = actionStartRow + actionButtons.lines.length + 2;
|
|
232
|
+
const composerRegion = {
|
|
233
|
+
row: composerRow,
|
|
234
|
+
col: 2,
|
|
235
|
+
width: innerWidth,
|
|
236
|
+
height: Math.max(1, composerLines.length)
|
|
237
|
+
};
|
|
238
|
+
const body = [...actionButtons.lines, "", workbenchTheme.accent("Composer"), ...composerLines, workbenchTheme.muted(`Focus ${state.getFocusLabel(state.focusRegion)} | /providers /models /sessions also work`)];
|
|
239
|
+
return {
|
|
240
|
+
lines: framePanelFixed(state.focusRegion === "composer" ? "Bottom Dock [active]" : "Bottom Dock", body.map(line => padLine(line, innerWidth)), width, height, getPanelStyle("dock", state.focusRegion === "composer", state.focusRegion === "composer" && state.focusPulseActive)),
|
|
241
|
+
dockRegions,
|
|
242
|
+
composerRegion
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
function compositeOverlay(state, baseLines) {
|
|
246
|
+
const options = state.overlayOptions;
|
|
247
|
+
const overlayWidth = Math.max(38, Math.min(76, Math.floor(state.width * 0.66)));
|
|
248
|
+
const overlayHeight = Math.max(10, Math.min(state.height - 4, 8 + Math.min(options.length, 5) * 2));
|
|
249
|
+
const rect = computeCenteredRect(state.width, state.height, overlayWidth, overlayHeight);
|
|
250
|
+
const innerWidth = Math.max(1, rect.width - 2);
|
|
251
|
+
const maxVisibleOptions = Math.max(1, Math.floor((rect.height - 6) / 2));
|
|
252
|
+
const selectedIndex = state.overlaySelectionIndex;
|
|
253
|
+
const startIndex = Math.max(0, Math.min(selectedIndex - Math.floor(maxVisibleOptions / 2), Math.max(0, options.length - maxVisibleOptions)));
|
|
254
|
+
const visibleOptions = options.slice(startIndex, startIndex + maxVisibleOptions);
|
|
255
|
+
const body = [workbenchTheme.text(getOverlayDescription(state)), workbenchTheme.muted("Use Up/Down, click a row, or press Enter."), ""];
|
|
256
|
+
const overlayRegions = [];
|
|
257
|
+
for (const [index, option] of visibleOptions.entries()) {
|
|
258
|
+
const absoluteIndex = startIndex + index;
|
|
259
|
+
const isSelected = absoluteIndex === selectedIndex;
|
|
260
|
+
const label = state.styleButton(option.label, option.disabled ? "secondary" : isSelected ? "active" : "primary");
|
|
261
|
+
const firstRow = body.length;
|
|
262
|
+
body.push(`${isSelected ? workbenchTheme.accentStrong(">") : workbenchTheme.muted(" ")} ${label} ${option.badge ? workbenchTheme.success(option.badge) : ""}`.trimEnd());
|
|
263
|
+
body.push(` ${option.disabled ? workbenchTheme.warning(option.description) : workbenchTheme.muted(option.description)}`);
|
|
264
|
+
overlayRegions.push({
|
|
265
|
+
group: "overlay",
|
|
266
|
+
id: option.id,
|
|
267
|
+
row: rect.row + 1 + firstRow,
|
|
268
|
+
col: rect.col + 2,
|
|
269
|
+
width: Math.max(1, innerWidth - 2),
|
|
270
|
+
height: 2
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
body.push("");
|
|
274
|
+
body.push(workbenchTheme.muted(options.length > visibleOptions.length ? `Showing ${startIndex + 1}-${startIndex + visibleOptions.length} of ${options.length} | Esc close` : `Enter select | Esc close | ${pulseDot(state.frame)} active dialog`));
|
|
275
|
+
const overlayLines = framePanelFixed(getOverlayTitle(state), body.map(line => padLine(line, innerWidth)), rect.width, rect.height, getPanelStyle("overlay", true, true));
|
|
276
|
+
const output = [...baseLines];
|
|
277
|
+
for (let i = 0; i < overlayLines.length; i += 1) {
|
|
278
|
+
const targetIndex = rect.row - 1 + i;
|
|
279
|
+
if (targetIndex < 0 || targetIndex >= output.length) {
|
|
280
|
+
continue;
|
|
281
|
+
}
|
|
282
|
+
const base = output[targetIndex] ?? " ".repeat(state.width);
|
|
283
|
+
const before = base.slice(0, Math.max(0, rect.col - 1));
|
|
284
|
+
const afterStart = Math.max(0, rect.col - 1 + rect.width);
|
|
285
|
+
const after = afterStart < base.length ? base.slice(afterStart) : "";
|
|
286
|
+
output[targetIndex] = `${before}${padLine(overlayLines[i], rect.width)}${after}`;
|
|
287
|
+
}
|
|
288
|
+
return {
|
|
289
|
+
lines: output,
|
|
290
|
+
overlayRegions
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
function renderButtons(state, items, width) {
|
|
294
|
+
const lines = [];
|
|
295
|
+
const regions = [];
|
|
296
|
+
let currentLine = "";
|
|
297
|
+
let currentWidth = 0;
|
|
298
|
+
let row = 0;
|
|
299
|
+
for (const item of items) {
|
|
300
|
+
const button = state.styleButton(item.label, item.variant);
|
|
301
|
+
const buttonWidth = visibleWidth(button);
|
|
302
|
+
const gap = currentLine ? 1 : 0;
|
|
303
|
+
if (currentWidth + gap + buttonWidth > width && currentLine) {
|
|
304
|
+
lines.push(currentLine);
|
|
305
|
+
currentLine = "";
|
|
306
|
+
currentWidth = 0;
|
|
307
|
+
row += 1;
|
|
308
|
+
}
|
|
309
|
+
const startCol = currentWidth + (currentLine ? 1 : 0);
|
|
310
|
+
currentLine += `${currentLine ? " " : ""}${button}`;
|
|
311
|
+
currentWidth = visibleWidth(currentLine);
|
|
312
|
+
regions.push({
|
|
313
|
+
id: item.id,
|
|
314
|
+
row,
|
|
315
|
+
col: startCol,
|
|
316
|
+
width: buttonWidth,
|
|
317
|
+
height: 1
|
|
318
|
+
});
|
|
319
|
+
}
|
|
320
|
+
if (currentLine) {
|
|
321
|
+
lines.push(currentLine);
|
|
322
|
+
}
|
|
323
|
+
return {
|
|
324
|
+
lines,
|
|
325
|
+
regions
|
|
326
|
+
};
|
|
327
|
+
}
|
|
328
|
+
function renderCard(state, card, width, selected) {
|
|
329
|
+
const cardWidth = Math.max(18, width - 2);
|
|
330
|
+
const cardInnerWidth = Math.max(10, cardWidth - 2);
|
|
331
|
+
const border = selected ? workbenchTheme.accentStrong : workbenchTheme.accentSoft;
|
|
332
|
+
const title = selected ? workbenchTheme.accentStrong(card.title) : workbenchTheme.text(card.title);
|
|
333
|
+
const descLines = card.description.flatMap(line => wrapTextWithAnsi(line, Math.max(8, cardInnerWidth - 2))).slice(0, 2);
|
|
334
|
+
const actionLine = state.styleButton(card.actionLabel, selected ? "active" : card.variant);
|
|
335
|
+
const frameLine = content => ` ${border("|")}${padLine(content, cardInnerWidth)}${border("|")}`;
|
|
336
|
+
const lines = [` ${border(`+${"-".repeat(cardInnerWidth)}+`)}`, frameLine(title), frameLine(workbenchTheme.muted(descLines[0] ?? "")), frameLine(workbenchTheme.muted(descLines[1] ?? "")), frameLine(actionLine), ` ${border(`+${"-".repeat(cardInnerWidth)}+`)}`];
|
|
337
|
+
return {
|
|
338
|
+
lines: lines.map(line => padLine(line, width))
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
function getOverlayTitle(state) {
|
|
342
|
+
switch (state.overlay) {
|
|
343
|
+
case "provider-switch":
|
|
344
|
+
return "Provider Picker";
|
|
345
|
+
case "model-switch":
|
|
346
|
+
return "Model Picker";
|
|
347
|
+
case "session-list":
|
|
348
|
+
return "Session Picker";
|
|
349
|
+
case undefined:
|
|
350
|
+
return "Dialog";
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
function getOverlayDescription(state) {
|
|
354
|
+
switch (state.overlay) {
|
|
355
|
+
case "provider-switch":
|
|
356
|
+
return "Select the provider card the workbench should use by default.";
|
|
357
|
+
case "model-switch":
|
|
358
|
+
return "Choose the current default model for the active provider.";
|
|
359
|
+
case "session-list":
|
|
360
|
+
return "Pick a staged session surface to continue while history integration is pending.";
|
|
361
|
+
case undefined:
|
|
362
|
+
return "";
|
|
363
|
+
}
|
|
364
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["visibleWidth","wrapTextWithAnsi","computeCenteredRect","computeWorkbenchLayout","fitLines","framePanelFixed","joinColumns","padLine","getPanelStyle","pulseDot","sweepText","workbenchTheme","renderWorkbench","state","layout","width","height","bodyStartRow","headerHeight","header","renderHeader","body","renderBody","dockStartRow","bodyHeight","dock","showDock","renderDock","dockHeight","lines","frame","dockRegions","composerRegion","undefined","overlay","toolbarRegions","railRegions","mainRegions","overlayRegions","compositeOverlay","toolbar","renderButtons","id","label","variant","regions","map","region","group","row","col","statusLine","muted","getViewLabel","view","accent","activeProfile","activeSelection","modelId","join","headerBackground","thirdLine","push","columns","widths","currentCol","showRail","rail","renderRailPanel","railWidth","gap","main","showBody","renderMainPanel","mainWidth","showInspector","inspector","renderInspectorPanel","inspectorWidth","joined","i","length","startRow","startCol","innerWidth","Math","max","index","item","railItems","entries","isActive","isSelected","focusRegion","railSelectionIndex","button","styleButton","buttonRow","description","accentSoft","quickButtons","quickStartRow","line","text","models","card","mainCards","rendered","renderCard","mainSelectionIndex","firstRow","remaining","entry","timeline","slice","focusPulseActive","success","getFocusLabel","sessionsCount","agentDir","profiles","actionButtons","truncateLabel","composerLines","renderComposer","actionStartRow","composerRow","baseLines","options","overlayOptions","overlayWidth","min","floor","overlayHeight","rect","maxVisibleOptions","selectedIndex","overlaySelectionIndex","startIndex","visibleOptions","getOverlayDescription","option","absoluteIndex","disabled","accentStrong","badge","trimEnd","warning","overlayLines","getOverlayTitle","output","targetIndex","base","repeat","before","afterStart","after","items","currentLine","currentWidth","buttonWidth","selected","cardWidth","cardInnerWidth","border","title","descLines","flatMap","actionLine","actionLabel","frameLine","content"],"sources":["renderer.ts"],"sourcesContent":["import { visibleWidth, wrapTextWithAnsi } from \"@mariozechner/pi-tui\";\r\nimport { computeCenteredRect, computeWorkbenchLayout, fitLines, framePanelFixed, joinColumns, padLine, type Rect } from \"./render.js\";\r\nimport { getPanelStyle, pulseDot, sweepText, workbenchTheme } from \"./theme.js\";\r\nimport type {\r\n\tButtonSpec,\r\n\tClickRegion,\r\n\tLocalRegion,\r\n\tRenderedButtons,\r\n\tRenderWorkbenchResult,\r\n\tRenderWorkbenchState,\r\n\tWorkbenchCard,\r\n} from \"./types.js\";\r\n\r\nexport function renderWorkbench(state: RenderWorkbenchState): RenderWorkbenchResult {\r\n\tconst layout = computeWorkbenchLayout(state.width, state.height);\r\n\tconst bodyStartRow = layout.headerHeight + 1;\r\n\r\n\tconst header = renderHeader(state, layout.headerHeight);\r\n\tconst body = renderBody(state, layout, bodyStartRow);\r\n\tconst dockStartRow = bodyStartRow + layout.bodyHeight;\r\n\tconst dock = state.showDock\r\n\t\t? renderDock(state, state.width, layout.dockHeight, dockStartRow)\r\n\t\t: {\r\n\t\t\t\tlines: fitLines([padLine(sweepText(\"Preparing bottom dock...\", state.frame + 6), state.width)], state.width, layout.dockHeight),\r\n\t\t\t\tdockRegions: [],\r\n\t\t\t\tcomposerRegion: undefined,\r\n\t\t\t};\r\n\r\n\tconst lines = [...header.lines, ...body.lines, ...dock.lines];\r\n\tif (!state.overlay) {\r\n\t\treturn {\r\n\t\t\tlines,\r\n\t\t\ttoolbarRegions: header.toolbarRegions,\r\n\t\t\trailRegions: body.railRegions,\r\n\t\t\tmainRegions: body.mainRegions,\r\n\t\t\tdockRegions: dock.dockRegions,\r\n\t\t\toverlayRegions: [],\r\n\t\t\tcomposerRegion: dock.composerRegion,\r\n\t\t};\r\n\t}\r\n\r\n\tconst overlay = compositeOverlay(state, lines);\r\n\treturn {\r\n\t\tlines: overlay.lines,\r\n\t\ttoolbarRegions: header.toolbarRegions,\r\n\t\trailRegions: body.railRegions,\r\n\t\tmainRegions: body.mainRegions,\r\n\t\tdockRegions: dock.dockRegions,\r\n\t\toverlayRegions: overlay.overlayRegions,\r\n\t\tcomposerRegion: dock.composerRegion,\r\n\t};\r\n}\r\n\r\nfunction renderHeader(state: RenderWorkbenchState, height: number): { lines: string[]; toolbarRegions: ClickRegion[] } {\r\n\tconst toolbar = renderButtons(\r\n\t\tstate,\r\n\t\t[\r\n\t\t\t{ id: \"session:new\", label: state.width < 96 ? \"New\" : \"New Session\", variant: \"primary\" },\r\n\t\t\t{ id: \"overlay:provider-switch\", label: state.width < 96 ? \"Provider\" : \"Providers\", variant: \"active\" },\r\n\t\t\t{ id: \"overlay:model-switch\", label: state.width < 96 ? \"Model\" : \"Models\", variant: \"secondary\" },\r\n\t\t\t{ id: \"nav:history\", label: state.width < 96 ? \"Recent\" : \"History\", variant: \"secondary\" },\r\n\t\t],\r\n\t\tstate.width - 2,\r\n\t);\r\n\r\n\tconst toolbarRegions = toolbar.regions.map((region) => ({\r\n\t\tgroup: \"toolbar\" as const,\r\n\t\tid: region.id,\r\n\t\trow: 2 + region.row,\r\n\t\tcol: 2 + region.col,\r\n\t\twidth: region.width,\r\n\t\theight: region.height,\r\n\t}));\r\n\r\n\tconst statusLine = [\r\n\t\tsweepText(\"WEPSCLI WORKBENCH\", state.frame),\r\n\t\tworkbenchTheme.muted(`view ${state.getViewLabel(state.view)}`),\r\n\t\tworkbenchTheme.accent(state.activeProfile?.label ?? \"no provider\"),\r\n\t\tworkbenchTheme.muted(state.activeSelection.modelId ?? \"no model\"),\r\n\t].join(workbenchTheme.muted(\" | \"));\r\n\r\n\tconst lines = [\r\n\t\tworkbenchTheme.headerBackground(padLine(` ${statusLine} `, state.width)),\r\n\t\tworkbenchTheme.headerBackground(padLine(` ${toolbar.lines[0] ?? \"\"} `, state.width)),\r\n\t];\r\n\r\n\tif (height >= 3) {\r\n\t\tconst thirdLine =\r\n\t\t\ttoolbar.lines[1] ??\r\n\t\t\tworkbenchTheme.muted(\" Tab focus | Enter select | h home p providers m models s sessions \");\r\n\t\tlines.push(workbenchTheme.headerBackground(padLine(` ${thirdLine} `, state.width)));\r\n\t}\r\n\r\n\treturn {\r\n\t\tlines: fitLines(lines, state.width, height),\r\n\t\ttoolbarRegions,\r\n\t};\r\n}\r\n\r\nfunction renderBody(\r\n\tstate: RenderWorkbenchState,\r\n\tlayout: ReturnType<typeof computeWorkbenchLayout>,\r\n\tbodyStartRow: number,\r\n): { lines: string[]; railRegions: ClickRegion[]; mainRegions: ClickRegion[] } {\r\n\tconst columns: string[][] = [];\r\n\tconst widths: number[] = [];\r\n\tconst railRegions: ClickRegion[] = [];\r\n\tlet mainRegions: ClickRegion[] = [];\r\n\tlet currentCol = 1;\r\n\r\n\tif (layout.showRail) {\r\n\t\tconst rail = renderRailPanel(state, layout.railWidth, layout.bodyHeight, bodyStartRow, currentCol);\r\n\t\tcolumns.push(rail.lines);\r\n\t\twidths.push(layout.railWidth);\r\n\t\trailRegions.push(...rail.railRegions);\r\n\t\tcurrentCol += layout.railWidth + layout.gap;\r\n\t}\r\n\r\n\tconst main = state.showBody\r\n\t\t? renderMainPanel(state, layout.mainWidth, layout.bodyHeight, bodyStartRow, currentCol)\r\n\t\t: {\r\n\t\t\t\tlines: fitLines([padLine(sweepText(\"Booting main workbench surface...\", state.frame), layout.mainWidth)], layout.mainWidth, layout.bodyHeight),\r\n\t\t\t\tmainRegions: [],\r\n\t\t\t};\r\n\tcolumns.push(main.lines);\r\n\twidths.push(layout.mainWidth);\r\n\tmainRegions = main.mainRegions;\r\n\tcurrentCol += layout.mainWidth + layout.gap;\r\n\r\n\tif (layout.showInspector) {\r\n\t\tconst inspector = state.showInspector\r\n\t\t\t? renderInspectorPanel(state, layout.inspectorWidth, layout.bodyHeight)\r\n\t\t\t: fitLines(\r\n\t\t\t\t\t[padLine(sweepText(\"Preparing inspector status surfaces...\", state.frame + 3), layout.inspectorWidth)],\r\n\t\t\t\t\tlayout.inspectorWidth,\r\n\t\t\t\t\tlayout.bodyHeight,\r\n\t\t\t\t);\r\n\t\tcolumns.push(inspector);\r\n\t\twidths.push(layout.inspectorWidth);\r\n\t}\r\n\r\n\tlet joined = columns[0] ?? [];\r\n\tfor (let i = 1; i < columns.length; i += 1) {\r\n\t\tjoined = joinColumns(joined, widths[i - 1]!, columns[i]!, widths[i]!, layout.gap);\r\n\t}\r\n\r\n\treturn {\r\n\t\tlines: fitLines(joined, state.width, layout.bodyHeight),\r\n\t\trailRegions,\r\n\t\tmainRegions,\r\n\t};\r\n}\r\n\r\nfunction renderRailPanel(\r\n\tstate: RenderWorkbenchState,\r\n\twidth: number,\r\n\theight: number,\r\n\tstartRow: number,\r\n\tstartCol: number,\r\n): { lines: string[]; railRegions: ClickRegion[] } {\r\n\tconst innerWidth = Math.max(1, width - 2);\r\n\tconst body: string[] = [];\r\n\tconst railRegions: ClickRegion[] = [];\r\n\r\n\tbody.push(workbenchTheme.accent(\"Navigation\"));\r\n\tfor (const [index, item] of state.railItems.entries()) {\r\n\t\tconst isActive = state.view === item.id;\r\n\t\tconst isSelected = state.focusRegion === \"rail\" && state.railSelectionIndex === index;\r\n\t\tconst button = state.styleButton(item.label, isActive ? \"active\" : isSelected ? \"primary\" : \"secondary\");\r\n\t\tconst buttonRow = body.length;\r\n\t\tbody.push(button);\r\n\t\tbody.push(workbenchTheme.muted(item.description));\r\n\t\tbody.push(\"\");\r\n\t\trailRegions.push({\r\n\t\t\tgroup: \"rail\",\r\n\t\t\tid: `nav:${item.id}`,\r\n\t\t\trow: startRow + 1 + buttonRow,\r\n\t\t\tcol: startCol + 1,\r\n\t\t\twidth: visibleWidth(button),\r\n\t\t\theight: 1,\r\n\t\t});\r\n\t}\r\n\r\n\tbody.push(workbenchTheme.accent(`Quick Launch ${workbenchTheme.accentSoft(`[${pulseDot(state.frame)}]`)}`));\r\n\tconst quickButtons = renderButtons(\r\n\t\tstate,\r\n\t\t[\r\n\t\t\t{ id: \"overlay:provider-switch\", label: \"Provider Dialog\", variant: \"primary\" },\r\n\t\t\t{ id: \"overlay:model-switch\", label: \"Model Dialog\", variant: \"secondary\" },\r\n\t\t\t{ id: \"session:new\", label: \"New Task\", variant: \"success\" },\r\n\t\t],\r\n\t\tinnerWidth,\r\n\t);\r\n\tconst quickStartRow = body.length;\r\n\tbody.push(...quickButtons.lines);\r\n\tbody.push(\"\");\r\n\tbody.push(workbenchTheme.muted(\"Use the rail or the toolbar. No hidden panel-sized hit areas.\"));\r\n\r\n\trailRegions.push(\r\n\t\t...quickButtons.regions.map((region) => ({\r\n\t\t\tgroup: \"rail\" as const,\r\n\t\t\tid: region.id,\r\n\t\t\trow: startRow + 1 + quickStartRow + region.row,\r\n\t\t\tcol: startCol + 1 + region.col,\r\n\t\t\twidth: region.width,\r\n\t\t\theight: region.height,\r\n\t\t})),\r\n\t);\r\n\r\n\treturn {\r\n\t\tlines: framePanelFixed(\r\n\t\t\tstate.focusRegion === \"rail\" ? \"Left Rail [active]\" : \"Left Rail\",\r\n\t\t\tbody.map((line) => padLine(line, innerWidth)),\r\n\t\t\twidth,\r\n\t\t\theight,\r\n\t\t\tgetPanelStyle(\"rail\", state.focusRegion === \"rail\", state.focusRegion === \"rail\"),\r\n\t\t),\r\n\t\trailRegions,\r\n\t};\r\n}\r\n\r\nfunction renderMainPanel(\r\n\tstate: RenderWorkbenchState,\r\n\twidth: number,\r\n\theight: number,\r\n\tstartRow: number,\r\n\tstartCol: number,\r\n): { lines: string[]; mainRegions: ClickRegion[] } {\r\n\tconst innerWidth = Math.max(1, width - 2);\r\n\tconst body: string[] = [\r\n\t\tworkbenchTheme.accent(`Workbench ${workbenchTheme.accentSoft(`[${state.getViewLabel(state.view)}]`)}`),\r\n\t\tworkbenchTheme.text(\r\n\t\t\tstate.activeProfile\r\n\t\t\t\t? `Provider ${state.activeProfile.label} | Model ${state.activeSelection.modelId ?? state.activeProfile.models[0]?.id ?? \"none\"}`\r\n\t\t\t\t: \"No active provider selected yet.\",\r\n\t\t),\r\n\t\tworkbenchTheme.muted(\"Primary actions live in the cards below. Click a card or move with Up/Down and press Enter.\"),\r\n\t\t\"\",\r\n\t];\r\n\tconst mainRegions: ClickRegion[] = [];\r\n\r\n\tfor (const [index, card] of state.mainCards.entries()) {\r\n\t\tconst rendered = renderCard(state, card, innerWidth, state.focusRegion === \"main\" && state.mainSelectionIndex === index);\r\n\t\tconst firstRow = body.length;\r\n\t\tbody.push(...rendered.lines, \"\");\r\n\t\tmainRegions.push({\r\n\t\t\tgroup: \"main\",\r\n\t\t\tid: card.id,\r\n\t\t\trow: startRow + 1 + firstRow,\r\n\t\t\tcol: startCol + 2,\r\n\t\t\twidth: Math.max(1, innerWidth - 2),\r\n\t\t\theight: rendered.lines.length,\r\n\t\t});\r\n\t}\r\n\r\n\tconst remaining = Math.max(0, height - 2 - body.length);\r\n\tif (remaining > 0) {\r\n\t\tbody.push(workbenchTheme.accent(`Recent Activity ${workbenchTheme.accentSoft(`[${pulseDot(state.frame)}]`)}`));\r\n\t\tfor (const entry of state.timeline.slice(0, Math.max(1, remaining - 1))) {\r\n\t\t\tbody.push(workbenchTheme.text(entry));\r\n\t\t}\r\n\t}\r\n\r\n\treturn {\r\n\t\tlines: framePanelFixed(\r\n\t\t\tstate.focusRegion === \"main\" ? \"Main Workbench [active]\" : \"Main Workbench\",\r\n\t\t\tbody.map((line) => padLine(line, innerWidth)),\r\n\t\t\twidth,\r\n\t\t\theight,\r\n\t\t\tgetPanelStyle(\"main\", state.focusRegion === \"main\", state.focusRegion === \"main\" && state.focusPulseActive),\r\n\t\t),\r\n\t\tmainRegions,\r\n\t};\r\n}\r\n\r\nfunction renderInspectorPanel(state: RenderWorkbenchState, width: number, height: number): string[] {\r\n\tconst innerWidth = Math.max(1, width - 2);\r\n\tconst body = [\r\n\t\tworkbenchTheme.accent(\"Selection\"),\r\n\t\tworkbenchTheme.text(`View: ${state.getViewLabel(state.view)}`),\r\n\t\tworkbenchTheme.text(`Provider: ${state.activeProfile?.label ?? \"none\"}`),\r\n\t\tworkbenchTheme.text(`Model: ${state.activeSelection.modelId ?? \"none\"}`),\r\n\t\t\"\",\r\n\t\tworkbenchTheme.accent(\"Task State\"),\r\n\t\tworkbenchTheme.success(`Workbench rebuild in progress ${pulseDot(state.frame)}`),\r\n\t\tworkbenchTheme.text(`Focus: ${state.getFocusLabel(state.focusRegion)}`),\r\n\t\tworkbenchTheme.text(`Queued sessions: ${state.sessionsCount}`),\r\n\t\t\"\",\r\n\t\tworkbenchTheme.accent(\"Context\"),\r\n\t\tworkbenchTheme.text(\"Agent dir:\"),\r\n\t\tworkbenchTheme.muted(state.agentDir),\r\n\t\tworkbenchTheme.text(`Profiles loaded: ${state.profiles.length}`),\r\n\t\tworkbenchTheme.text(`Timeline entries: ${state.timeline.length}`),\r\n\t\t\"\",\r\n\t\tworkbenchTheme.accent(\"Todo\"),\r\n\t\tworkbenchTheme.text(\"1. Replace stub activity with real session timeline\"),\r\n\t\tworkbenchTheme.text(\"2. Add inline tool execution and diff surfaces\"),\r\n\t\tworkbenchTheme.text(\"3. Turn picker overlays into richer dialogs\"),\r\n\t];\r\n\r\n\treturn framePanelFixed(\r\n\t\t\"Inspector\",\r\n\t\tbody.map((line) => padLine(line, innerWidth)),\r\n\t\twidth,\r\n\t\theight,\r\n\t\tgetPanelStyle(\"inspector\", false, state.focusPulseActive),\r\n\t);\r\n}\r\n\r\nfunction renderDock(\r\n\tstate: RenderWorkbenchState,\r\n\twidth: number,\r\n\theight: number,\r\n\tstartRow: number,\r\n): { lines: string[]; dockRegions: ClickRegion[]; composerRegion?: Rect } {\r\n\tconst innerWidth = Math.max(1, width - 2);\r\n\tconst actionButtons = renderButtons(\r\n\t\tstate,\r\n\t\t[\r\n\t\t\t{\r\n\t\t\t\tid: \"overlay:provider-switch\",\r\n\t\t\t\tlabel: `Provider ${state.truncateLabel(state.activeProfile?.label ?? \"none\", 14)}`,\r\n\t\t\t\tvariant: \"primary\",\r\n\t\t\t},\r\n\t\t\t{\r\n\t\t\t\tid: \"overlay:model-switch\",\r\n\t\t\t\tlabel: `Model ${state.truncateLabel(state.activeSelection.modelId ?? \"none\", 14)}`,\r\n\t\t\t\tvariant: \"secondary\",\r\n\t\t\t},\r\n\t\t\t{ id: \"overlay:session-list\", label: \"Sessions\", variant: \"secondary\" },\r\n\t\t\t{ id: \"session:new\", label: \"New Task\", variant: \"success\" },\r\n\t\t\t{ id: \"focus:composer\", label: \"Focus Composer\", variant: \"active\" },\r\n\t\t],\r\n\t\tinnerWidth,\r\n\t);\r\n\tconst composerLines = state.renderComposer(innerWidth);\r\n\tconst actionStartRow = startRow + 1;\r\n\tconst dockRegions = actionButtons.regions.map((region) => ({\r\n\t\tgroup: \"dock\" as const,\r\n\t\tid: region.id,\r\n\t\trow: actionStartRow + region.row,\r\n\t\tcol: 2 + region.col,\r\n\t\twidth: region.width,\r\n\t\theight: region.height,\r\n\t}));\r\n\r\n\tconst composerRow = actionStartRow + actionButtons.lines.length + 2;\r\n\tconst composerRegion: Rect = {\r\n\t\trow: composerRow,\r\n\t\tcol: 2,\r\n\t\twidth: innerWidth,\r\n\t\theight: Math.max(1, composerLines.length),\r\n\t};\r\n\r\n\tconst body = [\r\n\t\t...actionButtons.lines,\r\n\t\t\"\",\r\n\t\tworkbenchTheme.accent(\"Composer\"),\r\n\t\t...composerLines,\r\n\t\tworkbenchTheme.muted(`Focus ${state.getFocusLabel(state.focusRegion)} | /providers /models /sessions also work`),\r\n\t];\r\n\r\n\treturn {\r\n\t\tlines: framePanelFixed(\r\n\t\t\tstate.focusRegion === \"composer\" ? \"Bottom Dock [active]\" : \"Bottom Dock\",\r\n\t\t\tbody.map((line) => padLine(line, innerWidth)),\r\n\t\t\twidth,\r\n\t\t\theight,\r\n\t\t\tgetPanelStyle(\"dock\", state.focusRegion === \"composer\", state.focusRegion === \"composer\" && state.focusPulseActive),\r\n\t\t),\r\n\t\tdockRegions,\r\n\t\tcomposerRegion,\r\n\t};\r\n}\r\n\r\nfunction compositeOverlay(state: RenderWorkbenchState, baseLines: string[]): { lines: string[]; overlayRegions: ClickRegion[] } {\r\n\tconst options = state.overlayOptions;\r\n\tconst overlayWidth = Math.max(38, Math.min(76, Math.floor(state.width * 0.66)));\r\n\tconst overlayHeight = Math.max(10, Math.min(state.height - 4, 8 + Math.min(options.length, 5) * 2));\r\n\tconst rect = computeCenteredRect(state.width, state.height, overlayWidth, overlayHeight);\r\n\tconst innerWidth = Math.max(1, rect.width - 2);\r\n\tconst maxVisibleOptions = Math.max(1, Math.floor((rect.height - 6) / 2));\r\n\tconst selectedIndex = state.overlaySelectionIndex;\r\n\tconst startIndex = Math.max(0, Math.min(selectedIndex - Math.floor(maxVisibleOptions / 2), Math.max(0, options.length - maxVisibleOptions)));\r\n\tconst visibleOptions = options.slice(startIndex, startIndex + maxVisibleOptions);\r\n\r\n\tconst body: string[] = [\r\n\t\tworkbenchTheme.text(getOverlayDescription(state)),\r\n\t\tworkbenchTheme.muted(\"Use Up/Down, click a row, or press Enter.\"),\r\n\t\t\"\",\r\n\t];\r\n\tconst overlayRegions: ClickRegion[] = [];\r\n\r\n\tfor (const [index, option] of visibleOptions.entries()) {\r\n\t\tconst absoluteIndex = startIndex + index;\r\n\t\tconst isSelected = absoluteIndex === selectedIndex;\r\n\t\tconst label = state.styleButton(option.label, option.disabled ? \"secondary\" : isSelected ? \"active\" : \"primary\");\r\n\t\tconst firstRow = body.length;\r\n\t\tbody.push(`${isSelected ? workbenchTheme.accentStrong(\">\") : workbenchTheme.muted(\" \")} ${label} ${option.badge ? workbenchTheme.success(option.badge) : \"\"}`.trimEnd());\r\n\t\tbody.push(` ${option.disabled ? workbenchTheme.warning(option.description) : workbenchTheme.muted(option.description)}`);\r\n\t\toverlayRegions.push({\r\n\t\t\tgroup: \"overlay\",\r\n\t\t\tid: option.id,\r\n\t\t\trow: rect.row + 1 + firstRow,\r\n\t\t\tcol: rect.col + 2,\r\n\t\t\twidth: Math.max(1, innerWidth - 2),\r\n\t\t\theight: 2,\r\n\t\t});\r\n\t}\r\n\r\n\tbody.push(\"\");\r\n\tbody.push(\r\n\t\tworkbenchTheme.muted(\r\n\t\t\toptions.length > visibleOptions.length\r\n\t\t\t\t? `Showing ${startIndex + 1}-${startIndex + visibleOptions.length} of ${options.length} | Esc close`\r\n\t\t\t\t: `Enter select | Esc close | ${pulseDot(state.frame)} active dialog`,\r\n\t\t),\r\n\t);\r\n\r\n\tconst overlayLines = framePanelFixed(\r\n\t\tgetOverlayTitle(state),\r\n\t\tbody.map((line) => padLine(line, innerWidth)),\r\n\t\trect.width,\r\n\t\trect.height,\r\n\t\tgetPanelStyle(\"overlay\", true, true),\r\n\t);\r\n\tconst output = [...baseLines];\r\n\tfor (let i = 0; i < overlayLines.length; i += 1) {\r\n\t\tconst targetIndex = rect.row - 1 + i;\r\n\t\tif (targetIndex < 0 || targetIndex >= output.length) {\r\n\t\t\tcontinue;\r\n\t\t}\r\n\t\tconst base = output[targetIndex] ?? \" \".repeat(state.width);\r\n\t\tconst before = base.slice(0, Math.max(0, rect.col - 1));\r\n\t\tconst afterStart = Math.max(0, rect.col - 1 + rect.width);\r\n\t\tconst after = afterStart < base.length ? base.slice(afterStart) : \"\";\r\n\t\toutput[targetIndex] = `${before}${padLine(overlayLines[i]!, rect.width)}${after}`;\r\n\t}\r\n\r\n\treturn { lines: output, overlayRegions };\r\n}\r\n\r\nfunction renderButtons(state: RenderWorkbenchState, items: ButtonSpec[], width: number): RenderedButtons {\r\n\tconst lines: string[] = [];\r\n\tconst regions: LocalRegion[] = [];\r\n\tlet currentLine = \"\";\r\n\tlet currentWidth = 0;\r\n\tlet row = 0;\r\n\r\n\tfor (const item of items) {\r\n\t\tconst button = state.styleButton(item.label, item.variant);\r\n\t\tconst buttonWidth = visibleWidth(button);\r\n\t\tconst gap = currentLine ? 1 : 0;\r\n\r\n\t\tif (currentWidth + gap + buttonWidth > width && currentLine) {\r\n\t\t\tlines.push(currentLine);\r\n\t\t\tcurrentLine = \"\";\r\n\t\t\tcurrentWidth = 0;\r\n\t\t\trow += 1;\r\n\t\t}\r\n\r\n\t\tconst startCol = currentWidth + (currentLine ? 1 : 0);\r\n\t\tcurrentLine += `${currentLine ? \" \" : \"\"}${button}`;\r\n\t\tcurrentWidth = visibleWidth(currentLine);\r\n\t\tregions.push({\r\n\t\t\tid: item.id,\r\n\t\t\trow,\r\n\t\t\tcol: startCol,\r\n\t\t\twidth: buttonWidth,\r\n\t\t\theight: 1,\r\n\t\t});\r\n\t}\r\n\r\n\tif (currentLine) {\r\n\t\tlines.push(currentLine);\r\n\t}\r\n\r\n\treturn { lines, regions };\r\n}\r\n\r\nfunction renderCard(state: RenderWorkbenchState, card: WorkbenchCard, width: number, selected: boolean): { lines: string[] } {\r\n\tconst cardWidth = Math.max(18, width - 2);\r\n\tconst cardInnerWidth = Math.max(10, cardWidth - 2);\r\n\tconst border = selected ? workbenchTheme.accentStrong : workbenchTheme.accentSoft;\r\n\tconst title = selected ? workbenchTheme.accentStrong(card.title) : workbenchTheme.text(card.title);\r\n\tconst descLines = card.description.flatMap((line) => wrapTextWithAnsi(line, Math.max(8, cardInnerWidth - 2))).slice(0, 2);\r\n\tconst actionLine = state.styleButton(card.actionLabel, selected ? \"active\" : card.variant);\r\n\tconst frameLine = (content: string): string => ` ${border(\"|\")}${padLine(content, cardInnerWidth)}${border(\"|\")}`;\r\n\tconst lines = [\r\n\t\t` ${border(`+${\"-\".repeat(cardInnerWidth)}+`)}`,\r\n\t\tframeLine(title),\r\n\t\tframeLine(workbenchTheme.muted(descLines[0] ?? \"\")),\r\n\t\tframeLine(workbenchTheme.muted(descLines[1] ?? \"\")),\r\n\t\tframeLine(actionLine),\r\n\t\t` ${border(`+${\"-\".repeat(cardInnerWidth)}+`)}`,\r\n\t];\r\n\r\n\treturn { lines: lines.map((line) => padLine(line, width)) };\r\n}\r\n\r\nfunction getOverlayTitle(state: RenderWorkbenchState): string {\r\n\tswitch (state.overlay) {\r\n\t\tcase \"provider-switch\":\r\n\t\t\treturn \"Provider Picker\";\r\n\t\tcase \"model-switch\":\r\n\t\t\treturn \"Model Picker\";\r\n\t\tcase \"session-list\":\r\n\t\t\treturn \"Session Picker\";\r\n\t\tcase undefined:\r\n\t\t\treturn \"Dialog\";\r\n\t}\r\n}\r\n\r\nfunction getOverlayDescription(state: RenderWorkbenchState): string {\r\n\tswitch (state.overlay) {\r\n\t\tcase \"provider-switch\":\r\n\t\t\treturn \"Select the provider card the workbench should use by default.\";\r\n\t\tcase \"model-switch\":\r\n\t\t\treturn \"Choose the current default model for the active provider.\";\r\n\t\tcase \"session-list\":\r\n\t\t\treturn \"Pick a staged session surface to continue while history integration is pending.\";\r\n\t\tcase undefined:\r\n\t\t\treturn \"\";\r\n\t}\r\n}\r\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { ProcessTerminal, TUI } from "@mariozechner/pi-tui";
|
|
2
|
+
import { WorkbenchShell } from "./workbench-shell.js";
|
|
3
|
+
import { DISABLE_MOUSE_SEQUENCE, ENABLE_MOUSE_SEQUENCE, parseMouseSequence } from "./mouse.js";
|
|
4
|
+
export async function runWorkbench(profileService) {
|
|
5
|
+
if (!process.stdin.isTTY || !process.stdout.isTTY) {
|
|
6
|
+
return;
|
|
7
|
+
}
|
|
8
|
+
return new Promise(resolve => {
|
|
9
|
+
const ui = new TUI(new ProcessTerminal());
|
|
10
|
+
let closed = false;
|
|
11
|
+
let removeMouseListener;
|
|
12
|
+
const workbench = new WorkbenchShell(ui, profileService, () => {
|
|
13
|
+
if (closed) return;
|
|
14
|
+
closed = true;
|
|
15
|
+
removeMouseListener?.();
|
|
16
|
+
workbench.dispose();
|
|
17
|
+
ui.terminal.write(DISABLE_MOUSE_SEQUENCE);
|
|
18
|
+
ui.stop();
|
|
19
|
+
resolve();
|
|
20
|
+
});
|
|
21
|
+
ui.terminal.write(ENABLE_MOUSE_SEQUENCE);
|
|
22
|
+
removeMouseListener = ui.addInputListener(data => {
|
|
23
|
+
const event = parseMouseSequence(data);
|
|
24
|
+
if (!event) {
|
|
25
|
+
return undefined;
|
|
26
|
+
}
|
|
27
|
+
const consumed = workbench.handleMouseEvent(event);
|
|
28
|
+
return {
|
|
29
|
+
consume: consumed || true
|
|
30
|
+
};
|
|
31
|
+
});
|
|
32
|
+
ui.addChild(workbench);
|
|
33
|
+
ui.setFocus(workbench);
|
|
34
|
+
ui.start();
|
|
35
|
+
});
|
|
36
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["ProcessTerminal","TUI","WorkbenchShell","DISABLE_MOUSE_SEQUENCE","ENABLE_MOUSE_SEQUENCE","parseMouseSequence","runWorkbench","profileService","process","stdin","isTTY","stdout","Promise","resolve","ui","closed","removeMouseListener","workbench","dispose","terminal","write","stop","addInputListener","data","event","undefined","consumed","handleMouseEvent","consume","addChild","setFocus","start"],"sources":["run-workbench.ts"],"sourcesContent":["import { ProcessTerminal, TUI } from \"@mariozechner/pi-tui\";\r\nimport { ProviderProfileService } from \"../provider-profiles/index.js\";\r\nimport { WorkbenchShell } from \"./workbench-shell.js\";\r\nimport { DISABLE_MOUSE_SEQUENCE, ENABLE_MOUSE_SEQUENCE, parseMouseSequence } from \"./mouse.js\";\r\n\r\nexport async function runWorkbench(profileService: ProviderProfileService): Promise<void> {\r\n\tif (!process.stdin.isTTY || !process.stdout.isTTY) {\r\n\t\treturn;\r\n\t}\r\n\r\n\treturn new Promise<void>((resolve) => {\r\n\t\tconst ui = new TUI(new ProcessTerminal());\r\n\t\tlet closed = false;\r\n\t\tlet removeMouseListener: (() => void) | undefined;\r\n\r\n\t\tconst workbench = new WorkbenchShell(ui, profileService, () => {\r\n\t\t\tif (closed) return;\r\n\t\t\tclosed = true;\r\n\t\t\tremoveMouseListener?.();\r\n\t\t\tworkbench.dispose();\r\n\t\t\tui.terminal.write(DISABLE_MOUSE_SEQUENCE);\r\n\t\t\tui.stop();\r\n\t\t\tresolve();\r\n\t\t});\r\n\r\n\t\tui.terminal.write(ENABLE_MOUSE_SEQUENCE);\r\n\t\tremoveMouseListener = ui.addInputListener((data) => {\r\n\t\t\tconst event = parseMouseSequence(data);\r\n\t\t\tif (!event) {\r\n\t\t\t\treturn undefined;\r\n\t\t\t}\r\n\r\n\t\t\tconst consumed = workbench.handleMouseEvent(event);\r\n\t\t\treturn { consume: consumed || true };\r\n\t\t});\r\n\r\n\t\tui.addChild(workbench);\r\n\t\tui.setFocus(workbench);\r\n\t\tui.start();\r\n\t});\r\n}\r\n"],"mappings":"AAAA,SAASA,eAAe,EAAEC,GAAG,QAAQ,sBAAsB;AAE3D,SAASC,cAAc,QAAQ,sBAAsB;AACrD,SAASC,sBAAsB,EAAEC,qBAAqB,EAAEC,kBAAkB,QAAQ,YAAY;AAE9F,OAAO,eAAeC,YAAYA,CAACC,cAAsC,EAAiB;EACzF,IAAI,CAACC,OAAO,CAACC,KAAK,CAACC,KAAK,IAAI,CAACF,OAAO,CAACG,MAAM,CAACD,KAAK,EAAE;IAClD;EACD;EAEA,OAAO,IAAIE,OAAO,CAAQC,OAAO,IAAK;IACrC,MAAMC,EAAE,GAAG,IAAIb,GAAG,CAAC,IAAID,eAAe,CAAC,CAAC,CAAC;IACzC,IAAIe,MAAM,GAAG,KAAK;IAClB,IAAIC,mBAA6C;IAEjD,MAAMC,SAAS,GAAG,IAAIf,cAAc,CAACY,EAAE,EAAEP,cAAc,EAAE,MAAM;MAC9D,IAAIQ,MAAM,EAAE;MACZA,MAAM,GAAG,IAAI;MACbC,mBAAmB,GAAG,CAAC;MACvBC,SAAS,CAACC,OAAO,CAAC,CAAC;MACnBJ,EAAE,CAACK,QAAQ,CAACC,KAAK,CAACjB,sBAAsB,CAAC;MACzCW,EAAE,CAACO,IAAI,CAAC,CAAC;MACTR,OAAO,CAAC,CAAC;IACV,CAAC,CAAC;IAEFC,EAAE,CAACK,QAAQ,CAACC,KAAK,CAAChB,qBAAqB,CAAC;IACxCY,mBAAmB,GAAGF,EAAE,CAACQ,gBAAgB,CAAEC,IAAI,IAAK;MACnD,MAAMC,KAAK,GAAGnB,kBAAkB,CAACkB,IAAI,CAAC;MACtC,IAAI,CAACC,KAAK,EAAE;QACX,OAAOC,SAAS;MACjB;MAEA,MAAMC,QAAQ,GAAGT,SAAS,CAACU,gBAAgB,CAACH,KAAK,CAAC;MAClD,OAAO;QAAEI,OAAO,EAAEF,QAAQ,IAAI;MAAK,CAAC;IACrC,CAAC,CAAC;IAEFZ,EAAE,CAACe,QAAQ,CAACZ,SAAS,CAAC;IACtBH,EAAE,CAACgB,QAAQ,CAACb,SAAS,CAAC;IACtBH,EAAE,CAACiB,KAAK,CAAC,CAAC;EACX,CAAC,CAAC;AACH","ignoreList":[]}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
const bgHeader = "#072338";
|
|
3
|
+
const bgRail = "#05131d";
|
|
4
|
+
const bgMain = "#071a28";
|
|
5
|
+
const bgInspector = "#08131e";
|
|
6
|
+
const bgDock = "#0b2638";
|
|
7
|
+
const bgOverlay = "#0a3146";
|
|
8
|
+
const fgText = "#e6f7ff";
|
|
9
|
+
const fgMuted = "#7ea0b5";
|
|
10
|
+
const fgAccent = "#7dd3fc";
|
|
11
|
+
const fgAccentStrong = "#38bdf8";
|
|
12
|
+
const fgAccentSoft = "#67e8f9";
|
|
13
|
+
const fgSuccess = "#5eead4";
|
|
14
|
+
const fgWarning = "#fde68a";
|
|
15
|
+
const fgDanger = "#fca5a5";
|
|
16
|
+
const backgroundByTone = {
|
|
17
|
+
rail: chalk.bgHex(bgRail),
|
|
18
|
+
main: chalk.bgHex(bgMain),
|
|
19
|
+
inspector: chalk.bgHex(bgInspector),
|
|
20
|
+
dock: chalk.bgHex(bgDock),
|
|
21
|
+
overlay: chalk.bgHex(bgOverlay)
|
|
22
|
+
};
|
|
23
|
+
export const workbenchTheme = {
|
|
24
|
+
headerBackground: text => chalk.bgHex(bgHeader)(text),
|
|
25
|
+
text: text => chalk.hex(fgText)(text),
|
|
26
|
+
muted: text => chalk.hex(fgMuted)(text),
|
|
27
|
+
accent: text => chalk.hex(fgAccent)(text),
|
|
28
|
+
accentStrong: text => chalk.bold(chalk.hex(fgAccentStrong)(text)),
|
|
29
|
+
accentSoft: text => chalk.hex(fgAccentSoft)(text),
|
|
30
|
+
success: text => chalk.hex(fgSuccess)(text),
|
|
31
|
+
warning: text => chalk.hex(fgWarning)(text),
|
|
32
|
+
danger: text => chalk.hex(fgDanger)(text)
|
|
33
|
+
};
|
|
34
|
+
export function getPanelStyle(tone, active, pulsing) {
|
|
35
|
+
const background = backgroundByTone[tone];
|
|
36
|
+
const borderTone = pulsing ? text => chalk.bold(chalk.hex("#bae6fd")(text)) : active ? text => chalk.bold(chalk.hex(fgAccentStrong)(text)) : text => chalk.hex(fgAccentSoft)(text);
|
|
37
|
+
return {
|
|
38
|
+
border: text => background(borderTone(text)),
|
|
39
|
+
body: text => background(text)
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
export function pulseDot(frame) {
|
|
43
|
+
const glyphs = ["o", "O", "0", "O"];
|
|
44
|
+
return glyphs[frame % glyphs.length] ?? "o";
|
|
45
|
+
}
|
|
46
|
+
export function sweepText(text, frame) {
|
|
47
|
+
if (!text) return text;
|
|
48
|
+
const hotspot = frame % Math.max(1, text.length);
|
|
49
|
+
let output = "";
|
|
50
|
+
for (let i = 0; i < text.length; i += 1) {
|
|
51
|
+
const char = text[i] ?? "";
|
|
52
|
+
if (i === hotspot) {
|
|
53
|
+
output += workbenchTheme.accentStrong(char);
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
if (Math.abs(i - hotspot) === 1) {
|
|
57
|
+
output += workbenchTheme.accent(char);
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
output += workbenchTheme.text(char);
|
|
61
|
+
}
|
|
62
|
+
return output;
|
|
63
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["chalk","bgHeader","bgRail","bgMain","bgInspector","bgDock","bgOverlay","fgText","fgMuted","fgAccent","fgAccentStrong","fgAccentSoft","fgSuccess","fgWarning","fgDanger","backgroundByTone","rail","bgHex","main","inspector","dock","overlay","workbenchTheme","headerBackground","text","hex","muted","accent","accentStrong","bold","accentSoft","success","warning","danger","getPanelStyle","tone","active","pulsing","background","borderTone","border","body","pulseDot","frame","glyphs","length","sweepText","hotspot","Math","max","output","i","char","abs"],"sources":["theme.ts"],"sourcesContent":["import chalk from \"chalk\";\r\n\r\nexport type PanelTone = \"rail\" | \"main\" | \"inspector\" | \"dock\" | \"overlay\";\r\n\r\nexport interface PanelVisualStyle {\r\n\tborder: (text: string) => string;\r\n\tbody: (text: string) => string;\r\n}\r\n\r\nconst bgHeader = \"#072338\";\r\nconst bgRail = \"#05131d\";\r\nconst bgMain = \"#071a28\";\r\nconst bgInspector = \"#08131e\";\r\nconst bgDock = \"#0b2638\";\r\nconst bgOverlay = \"#0a3146\";\r\n\r\nconst fgText = \"#e6f7ff\";\r\nconst fgMuted = \"#7ea0b5\";\r\nconst fgAccent = \"#7dd3fc\";\r\nconst fgAccentStrong = \"#38bdf8\";\r\nconst fgAccentSoft = \"#67e8f9\";\r\nconst fgSuccess = \"#5eead4\";\r\nconst fgWarning = \"#fde68a\";\r\nconst fgDanger = \"#fca5a5\";\r\n\r\nconst backgroundByTone: Record<PanelTone, (text: string) => string> = {\r\n\trail: chalk.bgHex(bgRail),\r\n\tmain: chalk.bgHex(bgMain),\r\n\tinspector: chalk.bgHex(bgInspector),\r\n\tdock: chalk.bgHex(bgDock),\r\n\toverlay: chalk.bgHex(bgOverlay),\r\n};\r\n\r\nexport const workbenchTheme = {\r\n\theaderBackground: (text: string) => chalk.bgHex(bgHeader)(text),\r\n\ttext: (text: string) => chalk.hex(fgText)(text),\r\n\tmuted: (text: string) => chalk.hex(fgMuted)(text),\r\n\taccent: (text: string) => chalk.hex(fgAccent)(text),\r\n\taccentStrong: (text: string) => chalk.bold(chalk.hex(fgAccentStrong)(text)),\r\n\taccentSoft: (text: string) => chalk.hex(fgAccentSoft)(text),\r\n\tsuccess: (text: string) => chalk.hex(fgSuccess)(text),\r\n\twarning: (text: string) => chalk.hex(fgWarning)(text),\r\n\tdanger: (text: string) => chalk.hex(fgDanger)(text),\r\n};\r\n\r\nexport function getPanelStyle(tone: PanelTone, active: boolean, pulsing: boolean): PanelVisualStyle {\r\n\tconst background = backgroundByTone[tone];\r\n\tconst borderTone: (text: string) => string = pulsing\r\n\t\t? (text: string) => chalk.bold(chalk.hex(\"#bae6fd\")(text))\r\n\t\t: active\r\n\t\t\t? (text: string) => chalk.bold(chalk.hex(fgAccentStrong)(text))\r\n\t\t\t: (text: string) => chalk.hex(fgAccentSoft)(text);\r\n\r\n\treturn {\r\n\t\tborder: (text: string) => background(borderTone(text)),\r\n\t\tbody: (text: string) => background(text),\r\n\t};\r\n}\r\n\r\nexport function pulseDot(frame: number): string {\r\n\tconst glyphs = [\"o\", \"O\", \"0\", \"O\"];\r\n\treturn glyphs[frame % glyphs.length] ?? \"o\";\r\n}\r\n\r\nexport function sweepText(text: string, frame: number): string {\r\n\tif (!text) return text;\r\n\r\n\tconst hotspot = frame % Math.max(1, text.length);\r\n\tlet output = \"\";\r\n\tfor (let i = 0; i < text.length; i += 1) {\r\n\t\tconst char = text[i] ?? \"\";\r\n\t\tif (i === hotspot) {\r\n\t\t\toutput += workbenchTheme.accentStrong(char);\r\n\t\t\tcontinue;\r\n\t\t}\r\n\t\tif (Math.abs(i - hotspot) === 1) {\r\n\t\t\toutput += workbenchTheme.accent(char);\r\n\t\t\tcontinue;\r\n\t\t}\r\n\t\toutput += workbenchTheme.text(char);\r\n\t}\r\n\treturn output;\r\n}\r\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":[],"sources":["types.ts"],"sourcesContent":["import type { ProviderProfile } from \"../provider-profiles/index.js\";\r\nimport type { Rect } from \"./render.js\";\r\n\r\nexport type WorkbenchView = \"home\" | \"providers\" | \"history\";\r\nexport type WorkbenchFocus = \"rail\" | \"main\" | \"composer\" | \"overlay\";\r\nexport type OverlayKind = \"provider-switch\" | \"model-switch\" | \"session-list\";\r\nexport type ClickRegionGroup = \"toolbar\" | \"rail\" | \"main\" | \"dock\" | \"overlay\";\r\nexport type ButtonVariant = \"active\" | \"primary\" | \"secondary\" | \"success\" | \"warning\";\r\n\r\nexport interface ButtonSpec {\r\n\tid: string;\r\n\tlabel: string;\r\n\tvariant: ButtonVariant;\r\n}\r\n\r\nexport interface ClickRegion {\r\n\tgroup: ClickRegionGroup;\r\n\tid: string;\r\n\trow: number;\r\n\tcol: number;\r\n\twidth: number;\r\n\theight: number;\r\n}\r\n\r\nexport interface LocalRegion {\r\n\tid: string;\r\n\trow: number;\r\n\tcol: number;\r\n\twidth: number;\r\n\theight: number;\r\n}\r\n\r\nexport interface RenderedButtons {\r\n\tlines: string[];\r\n\tregions: LocalRegion[];\r\n}\r\n\r\nexport interface RailItem {\r\n\tid: WorkbenchView;\r\n\tlabel: string;\r\n\tdescription: string;\r\n}\r\n\r\nexport interface WorkbenchCard {\r\n\tid: string;\r\n\ttitle: string;\r\n\tdescription: string[];\r\n\tactionLabel: string;\r\n\tvariant: ButtonVariant;\r\n}\r\n\r\nexport interface SessionRecord {\r\n\tid: string;\r\n\ttitle: string;\r\n\tsummary: string;\r\n\tstate: \"active\" | \"ready\" | \"recent\";\r\n\tupdatedLabel: string;\r\n}\r\n\r\nexport interface OverlayOption {\r\n\tid: string;\r\n\tlabel: string;\r\n\tdescription: string;\r\n\tbadge?: string;\r\n\tdisabled?: boolean;\r\n}\r\n\r\nexport interface RenderWorkbenchState {\r\n\twidth: number;\r\n\theight: number;\r\n\tview: WorkbenchView;\r\n\tfocusRegion: WorkbenchFocus;\r\n\toverlay?: OverlayKind;\r\n\trailSelectionIndex: number;\r\n\tmainSelectionIndex: number;\r\n\toverlaySelectionIndex: number;\r\n\tframe: number;\r\n\tfocusPulseActive: boolean;\r\n\tshowBody: boolean;\r\n\tshowInspector: boolean;\r\n\tshowDock: boolean;\r\n\tprofiles: ProviderProfile[];\r\n\tactiveProfile?: ProviderProfile;\r\n\tactiveSelection: { profileId?: string; modelId?: string };\r\n\trailItems: RailItem[];\r\n\tmainCards: WorkbenchCard[];\r\n\toverlayOptions: OverlayOption[];\r\n\ttimeline: string[];\r\n\tsessionsCount: number;\r\n\tagentDir: string;\r\n\trenderComposer: (width: number) => string[];\r\n\tstyleButton: (label: string, variant: ButtonVariant) => string;\r\n\ttruncateLabel: (value: string, maxLength: number) => string;\r\n\tgetViewLabel: (view: WorkbenchView) => string;\r\n\tgetFocusLabel: (focus: WorkbenchFocus) => string;\r\n}\r\n\r\nexport interface RenderWorkbenchResult {\r\n\tlines: string[];\r\n\ttoolbarRegions: ClickRegion[];\r\n\trailRegions: ClickRegion[];\r\n\tmainRegions: ClickRegion[];\r\n\tdockRegions: ClickRegion[];\r\n\toverlayRegions: ClickRegion[];\r\n\tcomposerRegion?: Rect;\r\n}\r\n"],"mappings":"","ignoreList":[]}
|