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.
Files changed (130) hide show
  1. package/README.md +293 -0
  2. package/dist/WEPSCLI-shell/agent-runtime.js +824 -0
  3. package/dist/WEPSCLI-shell/agent-runtime.js.map +1 -0
  4. package/dist/WEPSCLI-shell/approval-overlay.js +275 -0
  5. package/dist/WEPSCLI-shell/approval-overlay.js.map +1 -0
  6. package/dist/WEPSCLI-shell/chat-components.js +760 -0
  7. package/dist/WEPSCLI-shell/chat-components.js.map +1 -0
  8. package/dist/WEPSCLI-shell/components.js +850 -0
  9. package/dist/WEPSCLI-shell/components.js.map +1 -0
  10. package/dist/WEPSCLI-shell/config-overlays.js +205 -0
  11. package/dist/WEPSCLI-shell/config-overlays.js.map +1 -0
  12. package/dist/WEPSCLI-shell/debug-log.js +16 -0
  13. package/dist/WEPSCLI-shell/debug-log.js.map +1 -0
  14. package/dist/WEPSCLI-shell/file-change-preview.js +261 -0
  15. package/dist/WEPSCLI-shell/file-change-preview.js.map +1 -0
  16. package/dist/WEPSCLI-shell/helpers.js +112 -0
  17. package/dist/WEPSCLI-shell/helpers.js.map +1 -0
  18. package/dist/WEPSCLI-shell/index.js +3 -0
  19. package/dist/WEPSCLI-shell/index.js.map +1 -0
  20. package/dist/WEPSCLI-shell/provider-add-flow.js +406 -0
  21. package/dist/WEPSCLI-shell/provider-add-flow.js.map +1 -0
  22. package/dist/WEPSCLI-shell/run-wepscli-shell.js +21 -0
  23. package/dist/WEPSCLI-shell/run-wepscli-shell.js.map +1 -0
  24. package/dist/WEPSCLI-shell/runtime-recovery.js +37 -0
  25. package/dist/WEPSCLI-shell/runtime-recovery.js.map +1 -0
  26. package/dist/WEPSCLI-shell/runtime-status.js +66 -0
  27. package/dist/WEPSCLI-shell/runtime-status.js.map +1 -0
  28. package/dist/WEPSCLI-shell/shell-app.js +1047 -0
  29. package/dist/WEPSCLI-shell/shell-app.js.map +1 -0
  30. package/dist/WEPSCLI-shell/shell-modes.js +77 -0
  31. package/dist/WEPSCLI-shell/shell-modes.js.map +1 -0
  32. package/dist/WEPSCLI-shell/slash-commands.js +135 -0
  33. package/dist/WEPSCLI-shell/slash-commands.js.map +1 -0
  34. package/dist/WEPSCLI-shell/theme.js +19 -0
  35. package/dist/WEPSCLI-shell/theme.js.map +1 -0
  36. package/dist/WEPSCLI-shell/tool-approval.js +85 -0
  37. package/dist/WEPSCLI-shell/tool-approval.js.map +1 -0
  38. package/dist/WEPSCLI-shell/tool-diff.js +76 -0
  39. package/dist/WEPSCLI-shell/tool-diff.js.map +1 -0
  40. package/dist/WEPSCLI-shell/tool-file-changes.js +268 -0
  41. package/dist/WEPSCLI-shell/tool-file-changes.js.map +1 -0
  42. package/dist/WEPSCLI-shell/tool-message-detail.js +138 -0
  43. package/dist/WEPSCLI-shell/tool-message-detail.js.map +1 -0
  44. package/dist/WEPSCLI-shell/tool-messages.js +145 -0
  45. package/dist/WEPSCLI-shell/tool-messages.js.map +1 -0
  46. package/dist/WEPSCLI-shell/transcript-panel.js +372 -0
  47. package/dist/WEPSCLI-shell/transcript-panel.js.map +1 -0
  48. package/dist/WEPSCLI-shell/transcript-state.js +62 -0
  49. package/dist/WEPSCLI-shell/transcript-state.js.map +1 -0
  50. package/dist/WEPSCLI-shell/types.js +1 -0
  51. package/dist/WEPSCLI-shell/types.js.map +1 -0
  52. package/dist/cli.js +11 -0
  53. package/dist/cli.js.map +1 -0
  54. package/dist/config.js +40 -0
  55. package/dist/config.js.map +1 -0
  56. package/dist/index.js +4 -0
  57. package/dist/index.js.map +1 -0
  58. package/dist/main.js +140 -0
  59. package/dist/main.js.map +1 -0
  60. package/dist/onboarding/action-screen.js +90 -0
  61. package/dist/onboarding/action-screen.js.map +1 -0
  62. package/dist/onboarding/framed-screen.js +35 -0
  63. package/dist/onboarding/framed-screen.js.map +1 -0
  64. package/dist/onboarding/onboarding-app.js +312 -0
  65. package/dist/onboarding/onboarding-app.js.map +1 -0
  66. package/dist/onboarding/run-onboarding.js +23 -0
  67. package/dist/onboarding/run-onboarding.js.map +1 -0
  68. package/dist/onboarding/select-screen.js +21 -0
  69. package/dist/onboarding/select-screen.js.map +1 -0
  70. package/dist/onboarding/summary-screen.js +23 -0
  71. package/dist/onboarding/summary-screen.js.map +1 -0
  72. package/dist/onboarding/text-input-screen.js +55 -0
  73. package/dist/onboarding/text-input-screen.js.map +1 -0
  74. package/dist/onboarding/theme.js +26 -0
  75. package/dist/onboarding/theme.js.map +1 -0
  76. package/dist/provider-profiles/api-key-store.js +51 -0
  77. package/dist/provider-profiles/api-key-store.js.map +1 -0
  78. package/dist/provider-profiles/defaults.js +18 -0
  79. package/dist/provider-profiles/defaults.js.map +1 -0
  80. package/dist/provider-profiles/fetch-models.js +53 -0
  81. package/dist/provider-profiles/fetch-models.js.map +1 -0
  82. package/dist/provider-profiles/index.js +6 -0
  83. package/dist/provider-profiles/index.js.map +1 -0
  84. package/dist/provider-profiles/provider-profile-service.js +223 -0
  85. package/dist/provider-profiles/provider-profile-service.js.map +1 -0
  86. package/dist/provider-profiles/providers-config-store.js +17 -0
  87. package/dist/provider-profiles/providers-config-store.js.map +1 -0
  88. package/dist/provider-profiles/types.js +1 -0
  89. package/dist/provider-profiles/types.js.map +1 -0
  90. package/dist/session-history/session-history-service.js +142 -0
  91. package/dist/session-history/session-history-service.js.map +1 -0
  92. package/dist/shell/animator.js +30 -0
  93. package/dist/shell/animator.js.map +1 -0
  94. package/dist/shell/clickables.js +101 -0
  95. package/dist/shell/clickables.js.map +1 -0
  96. package/dist/shell/dashboard-shell.js +292 -0
  97. package/dist/shell/dashboard-shell.js.map +1 -0
  98. package/dist/shell/index.js +5 -0
  99. package/dist/shell/index.js.map +1 -0
  100. package/dist/shell/keymap.js +14 -0
  101. package/dist/shell/keymap.js.map +1 -0
  102. package/dist/shell/mouse.js +39 -0
  103. package/dist/shell/mouse.js.map +1 -0
  104. package/dist/shell/render.js +122 -0
  105. package/dist/shell/render.js.map +1 -0
  106. package/dist/shell/run-shell.js +36 -0
  107. package/dist/shell/run-shell.js.map +1 -0
  108. package/dist/shell/theme.js +56 -0
  109. package/dist/shell/theme.js.map +1 -0
  110. package/dist/storage/locked-json-file.js +88 -0
  111. package/dist/storage/locked-json-file.js.map +1 -0
  112. package/dist/workbench/animator.js +30 -0
  113. package/dist/workbench/animator.js.map +1 -0
  114. package/dist/workbench/index.js +6 -0
  115. package/dist/workbench/index.js.map +1 -0
  116. package/dist/workbench/mouse.js +39 -0
  117. package/dist/workbench/mouse.js.map +1 -0
  118. package/dist/workbench/render.js +82 -0
  119. package/dist/workbench/render.js.map +1 -0
  120. package/dist/workbench/renderer.js +364 -0
  121. package/dist/workbench/renderer.js.map +1 -0
  122. package/dist/workbench/run-workbench.js +36 -0
  123. package/dist/workbench/run-workbench.js.map +1 -0
  124. package/dist/workbench/theme.js +63 -0
  125. package/dist/workbench/theme.js.map +1 -0
  126. package/dist/workbench/types.js +1 -0
  127. package/dist/workbench/types.js.map +1 -0
  128. package/dist/workbench/workbench-shell.js +649 -0
  129. package/dist/workbench/workbench-shell.js.map +1 -0
  130. 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":[]}