@polterware/polter 0.4.2 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/README.md +70 -184
  2. package/dist/api.js +62 -30
  3. package/dist/app-HGIGWI7F.js +393 -0
  4. package/dist/appPanel-EZOHLTBX.js +1365 -0
  5. package/dist/applier-OEXIUYYO.js +10 -0
  6. package/dist/chunk-3RG5ZIWI.js +10 -0
  7. package/dist/chunk-45CQFZU7.js +262 -0
  8. package/dist/chunk-57CZSEY5.js +5398 -0
  9. package/dist/chunk-6IBRTRLX.js +257 -0
  10. package/dist/chunk-AK3NTS3Y.js +220 -0
  11. package/dist/chunk-BGT5TT2A.js +32 -0
  12. package/dist/chunk-BIN7BDA2.js +77 -0
  13. package/dist/chunk-E2B5FFBU.js +81 -0
  14. package/dist/chunk-EAMHFQKU.js +222 -0
  15. package/dist/chunk-ELSIHPJL.js +455 -0
  16. package/dist/{chunk-XCCKD3RZ.js → chunk-GCS7JEYU.js} +7 -3
  17. package/dist/chunk-GKROVUDG.js +15 -0
  18. package/dist/chunk-GVIKF6UI.js +738 -0
  19. package/dist/chunk-JQB2A3CA.js +72 -0
  20. package/dist/chunk-KEGROLGX.js +50 -0
  21. package/dist/chunk-OKHPN6X7.js +49 -0
  22. package/dist/chunk-RVMOIUSL.js +22 -0
  23. package/dist/chunk-TD6YNU6L.js +22 -0
  24. package/dist/chunk-U64WZOJ3.js +101 -0
  25. package/dist/chunk-U6725U7K.js +138 -0
  26. package/dist/chunk-XNRIN3VM.js +125 -0
  27. package/dist/chunk-ZU5VZHYD.js +28 -0
  28. package/dist/commands-BIIWGCVS.js +15 -0
  29. package/dist/editor-AUFJZ4PE.js +11 -0
  30. package/dist/engine-EZQ26HDJ.js +11 -0
  31. package/dist/globalConf-AGMMIKSL.js +7 -0
  32. package/dist/index.js +49 -7601
  33. package/dist/ipcServer-HXOPKNBP.js +10 -0
  34. package/dist/mcp.js +182 -13892
  35. package/dist/mcpInstaller-J2AGFNWR.js +19 -0
  36. package/dist/parser-4ZBGSI2U.js +10 -0
  37. package/dist/planner-ZVBA66V6.js +9 -0
  38. package/dist/processManager-6T5DBURV.js +37 -0
  39. package/dist/projectConfig-TRCJS3VI.js +21 -0
  40. package/dist/skillSetup-ZQEHJ5ZG.js +14 -0
  41. package/dist/status-QMRCV4XJ.js +8 -0
  42. package/dist/storage-C3D7TLJW.js +17 -0
  43. package/dist/toolResolver-A2BUT3NK.js +17 -0
  44. package/package.json +28 -3
  45. package/dist/chunk-CWBIXRZP.js +0 -2607
@@ -0,0 +1,1365 @@
1
+ import {
2
+ CommandArgs,
3
+ CommandExecution,
4
+ CustomCommand,
5
+ DeclarativePlan,
6
+ DeclarativeStatus,
7
+ FlagSelection,
8
+ GhostBanner,
9
+ InitScaffold,
10
+ McpManage,
11
+ PipelineBuilder,
12
+ PipelineExecution,
13
+ PipelineList,
14
+ ProcessList,
15
+ ProcessLogs,
16
+ ProjectConfig,
17
+ ScriptPicker,
18
+ SelectList,
19
+ SelfUpdate,
20
+ SkillSetup,
21
+ ToolStatus,
22
+ buildHomeItems,
23
+ buildPinnedOnlyItems,
24
+ colors,
25
+ getPinnedCommands,
26
+ getPinnedRuns,
27
+ inkColors,
28
+ panel,
29
+ symbols,
30
+ togglePinnedCommand,
31
+ togglePinnedRun,
32
+ useFullscreen,
33
+ useTerminalDimensions
34
+ } from "./chunk-57CZSEY5.js";
35
+ import "./chunk-KEGROLGX.js";
36
+ import {
37
+ features,
38
+ getFeatureById
39
+ } from "./chunk-AK3NTS3Y.js";
40
+ import "./chunk-XNRIN3VM.js";
41
+ import "./chunk-U64WZOJ3.js";
42
+ import "./chunk-BIN7BDA2.js";
43
+ import "./chunk-GKROVUDG.js";
44
+ import "./chunk-U6725U7K.js";
45
+ import "./chunk-E2B5FFBU.js";
46
+ import "./chunk-OKHPN6X7.js";
47
+ import "./chunk-BGT5TT2A.js";
48
+ import "./chunk-45CQFZU7.js";
49
+ import "./chunk-6IBRTRLX.js";
50
+ import "./chunk-ZU5VZHYD.js";
51
+ import "./chunk-JQB2A3CA.js";
52
+ import {
53
+ findCommandByValue
54
+ } from "./chunk-GVIKF6UI.js";
55
+ import "./chunk-ELSIHPJL.js";
56
+ import "./chunk-RVMOIUSL.js";
57
+ import "./chunk-TD6YNU6L.js";
58
+ import "./chunk-3RG5ZIWI.js";
59
+
60
+ // src/appPanel.tsx
61
+ import { Box as Box9, Text as Text7, useApp, useInput as useInput2 } from "ink";
62
+
63
+ // src/stores/navigationStore.ts
64
+ import { create } from "zustand";
65
+ var FEATURE_IDS = [
66
+ "database",
67
+ "functions",
68
+ "deploy",
69
+ "repo",
70
+ "cicd",
71
+ "auth-storage",
72
+ "networking",
73
+ "packages",
74
+ "infrastructure",
75
+ "setup"
76
+ ];
77
+ var VIEW_MAP = {
78
+ pinned: "pinned",
79
+ "custom-command": "custom-command",
80
+ pipelines: "pipelines",
81
+ "tool-status": "tool-status",
82
+ config: "config",
83
+ "self-update": "self-update",
84
+ processes: "processes",
85
+ scripts: "scripts",
86
+ declarative: "declarative",
87
+ "skill-setup": "skill-setup"
88
+ };
89
+ var useNavigationStore = create((set) => ({
90
+ view: "pipelines",
91
+ featureId: "database",
92
+ innerScreen: "home",
93
+ innerParams: {},
94
+ innerStack: [],
95
+ selectSidebarItem: (itemId) => {
96
+ if (FEATURE_IDS.includes(itemId)) {
97
+ set({
98
+ view: "feature",
99
+ featureId: itemId,
100
+ innerScreen: "home",
101
+ innerParams: {},
102
+ innerStack: []
103
+ });
104
+ return;
105
+ }
106
+ const view = VIEW_MAP[itemId];
107
+ if (view) {
108
+ set((state) => ({
109
+ view,
110
+ featureId: state.featureId,
111
+ innerScreen: "home",
112
+ innerParams: {},
113
+ innerStack: []
114
+ }));
115
+ }
116
+ },
117
+ navigateInner: (screen, params) => {
118
+ set((state) => ({
119
+ innerStack: [...state.innerStack, { screen: state.innerScreen, params: state.innerParams }],
120
+ innerScreen: screen,
121
+ innerParams: params ?? {}
122
+ }));
123
+ },
124
+ goBackInner: () => {
125
+ set((state) => {
126
+ if (state.innerStack.length === 0) {
127
+ return { innerScreen: "home", innerParams: {} };
128
+ }
129
+ const newStack = [...state.innerStack];
130
+ const last = newStack.pop();
131
+ return {
132
+ innerStack: newStack,
133
+ innerScreen: last.screen,
134
+ innerParams: last.params
135
+ };
136
+ });
137
+ },
138
+ goHomeInner: () => {
139
+ set({ innerScreen: "home", innerParams: {}, innerStack: [] });
140
+ },
141
+ switchViewAndNavigate: (view, screen, params) => {
142
+ set({
143
+ view,
144
+ innerScreen: screen,
145
+ innerParams: params ?? {},
146
+ innerStack: [{ screen: "home", params: {} }]
147
+ });
148
+ }
149
+ }));
150
+
151
+ // src/hooks/usePanelNavigation.ts
152
+ function usePanelNavigation() {
153
+ return useNavigationStore();
154
+ }
155
+
156
+ // src/stores/focusStore.ts
157
+ import { create as create2 } from "zustand";
158
+ var useFocusStore = create2((set) => ({
159
+ focused: "sidebar",
160
+ isSidebarFocused: true,
161
+ isMainFocused: false,
162
+ toggleFocus: () => {
163
+ set((state) => {
164
+ const next = state.focused === "sidebar" ? "main" : "sidebar";
165
+ return {
166
+ focused: next,
167
+ isSidebarFocused: next === "sidebar",
168
+ isMainFocused: next === "main"
169
+ };
170
+ });
171
+ },
172
+ focusSidebar: () => {
173
+ set({ focused: "sidebar", isSidebarFocused: true, isMainFocused: false });
174
+ },
175
+ focusMain: () => {
176
+ set({ focused: "main", isSidebarFocused: false, isMainFocused: true });
177
+ }
178
+ }));
179
+
180
+ // src/hooks/usePanelFocus.ts
181
+ function usePanelFocus() {
182
+ return useFocusStore();
183
+ }
184
+
185
+ // src/hooks/useSidebarItems.ts
186
+ import { useMemo } from "react";
187
+ function useSidebarItems() {
188
+ return useMemo(() => {
189
+ const items = [];
190
+ items.push({ id: "__sep_workflows__", label: "---", icon: "", type: "separator", sectionTitle: "Workflows" });
191
+ items.push({ id: "pipelines", label: "Pipelines", icon: "\u{1F517}", type: "action", section: "workflows" });
192
+ items.push({ id: "pinned", label: "Pinned", icon: "\u{1F4CC}", type: "action", section: "workflows" });
193
+ items.push({ id: "custom-command", label: "Custom Cmd", icon: "\u270F\uFE0F", type: "action", section: "workflows" });
194
+ items.push({ id: "processes", label: "Processes", icon: "\u{1F4BB}", type: "action", section: "workflows" });
195
+ items.push({ id: "scripts", label: "Scripts", icon: "\u{1F4DC}", type: "action", section: "workflows" });
196
+ items.push({ id: "__sep_features__", label: "---", icon: "", type: "separator", sectionTitle: "Features" });
197
+ for (const feature of features) {
198
+ items.push({
199
+ id: feature.id,
200
+ label: feature.label,
201
+ icon: feature.icon,
202
+ type: "feature",
203
+ section: "features"
204
+ });
205
+ }
206
+ items.push({ id: "__sep_system__", label: "---", icon: "", type: "separator", sectionTitle: "System" });
207
+ items.push({ id: "declarative", label: "Infrastructure", icon: "\u{1F3D7}\uFE0F", type: "action", section: "system" });
208
+ items.push({ id: "tool-status", label: "Tool Status", icon: "\u{1F527}", type: "action", section: "system" });
209
+ items.push({ id: "config", label: "Config", icon: "\u2699\uFE0F", type: "action", section: "system" });
210
+ items.push({ id: "skill-setup", label: "Skill Setup", icon: "\u{1F9E0}", type: "action", section: "system" });
211
+ items.push({ id: "self-update", label: "Update", icon: "\u2B06\uFE0F", type: "action", section: "system" });
212
+ return items;
213
+ }, []);
214
+ }
215
+
216
+ // src/stores/modalStore.ts
217
+ import { create as create3 } from "zustand";
218
+ var useModalStore = create3((set) => ({
219
+ isOpen: false,
220
+ modalContent: null,
221
+ modalTitle: "",
222
+ openModal: (content, title) => {
223
+ set({ isOpen: true, modalContent: content, modalTitle: title });
224
+ },
225
+ closeModal: () => {
226
+ set({ isOpen: false, modalContent: null, modalTitle: "" });
227
+ }
228
+ }));
229
+
230
+ // src/hooks/useModal.ts
231
+ function useModal() {
232
+ return useModalStore();
233
+ }
234
+
235
+ // src/components/PanelLayout.tsx
236
+ import { Box } from "ink";
237
+ import { jsx, jsxs } from "react/jsx-runtime";
238
+ function PanelLayout({
239
+ header,
240
+ footer,
241
+ sidebar,
242
+ main,
243
+ width,
244
+ height,
245
+ bannerHeight,
246
+ singlePanel = false
247
+ }) {
248
+ const footerHeight = 1;
249
+ const contentHeight = Math.max(5, height - bannerHeight - footerHeight);
250
+ const sidebarWidth = singlePanel ? 0 : panel.sidebarWidth(width);
251
+ const mainWidth = singlePanel ? width : width - sidebarWidth;
252
+ return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", width, height, children: [
253
+ header,
254
+ /* @__PURE__ */ jsxs(Box, { flexDirection: "row", height: contentHeight, children: [
255
+ !singlePanel && /* @__PURE__ */ jsx(Box, { width: sidebarWidth, height: contentHeight, children: sidebar }),
256
+ /* @__PURE__ */ jsx(Box, { width: mainWidth, height: contentHeight, children: main })
257
+ ] }),
258
+ /* @__PURE__ */ jsx(Box, { height: footerHeight, children: footer })
259
+ ] });
260
+ }
261
+
262
+ // src/components/Panel.tsx
263
+ import { Box as Box2, Text } from "ink";
264
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
265
+ function Panel({
266
+ id,
267
+ title,
268
+ width,
269
+ height,
270
+ focused = false,
271
+ children
272
+ }) {
273
+ const borderColor = focused ? panel.borderFocused : panel.borderDim;
274
+ return /* @__PURE__ */ jsxs2(
275
+ Box2,
276
+ {
277
+ flexDirection: "column",
278
+ width,
279
+ height,
280
+ borderStyle: "round",
281
+ borderColor,
282
+ overflow: "hidden",
283
+ children: [
284
+ title && /* @__PURE__ */ jsx2(Box2, { marginBottom: 0, children: /* @__PURE__ */ jsxs2(Text, { color: focused ? inkColors.accent : void 0, bold: focused, dimColor: !focused, children: [
285
+ " ",
286
+ title,
287
+ " "
288
+ ] }) }),
289
+ /* @__PURE__ */ jsx2(Box2, { flexDirection: "column", flexGrow: 1, overflow: "hidden", children })
290
+ ]
291
+ }
292
+ );
293
+ }
294
+
295
+ // src/components/Sidebar.tsx
296
+ import { useEffect, useMemo as useMemo2, useState } from "react";
297
+ import { Box as Box3, Text as Text2, useInput } from "ink";
298
+ import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
299
+ function groupSections(items) {
300
+ const groups = [];
301
+ let current = null;
302
+ for (const item of items) {
303
+ if (item.type === "separator" && item.sectionTitle) {
304
+ current = { title: item.sectionTitle, items: [] };
305
+ groups.push(current);
306
+ } else if (current) {
307
+ current.items.push(item);
308
+ }
309
+ }
310
+ return groups;
311
+ }
312
+ function Sidebar({
313
+ items,
314
+ selectedId,
315
+ isFocused,
316
+ height,
317
+ onSelect,
318
+ onHighlight
319
+ }) {
320
+ const selectableItems = useMemo2(
321
+ () => items.filter((item) => item.type !== "separator"),
322
+ [items]
323
+ );
324
+ const selectedIdx = selectableItems.findIndex((item) => item.id === selectedId);
325
+ const [cursorIdx, setCursorIdx] = useState(Math.max(0, selectedIdx));
326
+ const sections = useMemo2(() => groupSections(items), [items]);
327
+ const [inputReady, setInputReady] = useState(false);
328
+ useEffect(() => {
329
+ const t = setTimeout(() => setInputReady(true), 0);
330
+ return () => clearTimeout(t);
331
+ }, []);
332
+ useEffect(() => {
333
+ const idx = selectableItems.findIndex((item) => item.id === selectedId);
334
+ if (idx >= 0) setCursorIdx(idx);
335
+ }, [selectedId, selectableItems]);
336
+ useInput(
337
+ (input, key) => {
338
+ if (key.upArrow || input === "k") {
339
+ setCursorIdx((prev) => {
340
+ const next = prev > 0 ? prev - 1 : selectableItems.length - 1;
341
+ const item = selectableItems[next];
342
+ if (item && onHighlight) onHighlight(item.id);
343
+ return next;
344
+ });
345
+ }
346
+ if (key.downArrow || input === "j") {
347
+ setCursorIdx((prev) => {
348
+ const next = prev < selectableItems.length - 1 ? prev + 1 : 0;
349
+ const item = selectableItems[next];
350
+ if (item && onHighlight) onHighlight(item.id);
351
+ return next;
352
+ });
353
+ }
354
+ if (key.return || key.rightArrow) {
355
+ const item = selectableItems[cursorIdx];
356
+ if (item) {
357
+ onSelect(item.id);
358
+ }
359
+ }
360
+ },
361
+ { isActive: isFocused && inputReady }
362
+ );
363
+ const sectionIndices = useMemo2(() => {
364
+ let idx = 0;
365
+ return sections.map((section) => {
366
+ const start = idx;
367
+ idx += section.items.length;
368
+ return { start, end: idx - 1 };
369
+ });
370
+ }, [sections]);
371
+ return /* @__PURE__ */ jsx3(Box3, { flexDirection: "column", gap: 0, children: sections.map((section, sectionIdx) => {
372
+ const { start: sectionStartIdx, end: sectionEndIdx } = sectionIndices[sectionIdx];
373
+ const hasCursorInSection = isFocused && cursorIdx >= sectionStartIdx && cursorIdx <= sectionEndIdx;
374
+ const hasActiveInSection = section.items.some((item) => item.id === selectedId);
375
+ const borderColor = hasCursorInSection || hasActiveInSection ? inkColors.accent : "#555555";
376
+ return /* @__PURE__ */ jsxs3(
377
+ Box3,
378
+ {
379
+ flexDirection: "column",
380
+ borderStyle: "round",
381
+ borderColor,
382
+ paddingX: 1,
383
+ children: [
384
+ /* @__PURE__ */ jsx3(Text2, { dimColor: true, bold: true, children: section.title }),
385
+ section.items.map((item, itemIdx) => {
386
+ const thisIdx = sectionStartIdx + itemIdx;
387
+ const isCursor = isFocused && thisIdx === cursorIdx;
388
+ const isActive = item.id === selectedId;
389
+ return /* @__PURE__ */ jsx3(Box3, { gap: 0, children: /* @__PURE__ */ jsxs3(
390
+ Text2,
391
+ {
392
+ color: isCursor ? inkColors.accent : isActive ? inkColors.accent : void 0,
393
+ bold: isCursor || isActive,
394
+ dimColor: !isCursor && !isActive,
395
+ children: [
396
+ isCursor ? `${symbols.pointerActive} ` : " ",
397
+ item.icon,
398
+ " ",
399
+ item.label
400
+ ]
401
+ }
402
+ ) }, item.id);
403
+ })
404
+ ]
405
+ },
406
+ section.title
407
+ );
408
+ }) });
409
+ }
410
+
411
+ // src/components/PanelFooter.tsx
412
+ import { Box as Box4, Text as Text3 } from "ink";
413
+ import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
414
+ function PanelFooter({ hints, width }) {
415
+ return /* @__PURE__ */ jsx4(Box4, { width, children: /* @__PURE__ */ jsx4(Box4, { gap: 1, children: hints.map((hint) => /* @__PURE__ */ jsxs4(Box4, { gap: 0, children: [
416
+ /* @__PURE__ */ jsx4(Text3, { color: inkColors.accent, bold: true, children: hint.key }),
417
+ /* @__PURE__ */ jsxs4(Text3, { dimColor: true, children: [
418
+ ":",
419
+ hint.action
420
+ ] })
421
+ ] }, hint.key)) }) });
422
+ }
423
+
424
+ // src/components/Modal.tsx
425
+ import { Box as Box5, Text as Text4 } from "ink";
426
+ import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
427
+ function Modal({
428
+ title,
429
+ width,
430
+ height,
431
+ children
432
+ }) {
433
+ const modalWidth = Math.min(width - 4, 60);
434
+ const modalHeight = Math.min(height - 4, 20);
435
+ const padX = Math.max(0, Math.floor((width - modalWidth) / 2));
436
+ const padY = Math.max(0, Math.floor((height - modalHeight) / 2));
437
+ return /* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", width, height, children: [
438
+ padY > 0 && /* @__PURE__ */ jsx5(Box5, { height: padY }),
439
+ /* @__PURE__ */ jsx5(Box5, { marginLeft: padX, children: /* @__PURE__ */ jsxs5(
440
+ Box5,
441
+ {
442
+ flexDirection: "column",
443
+ width: modalWidth,
444
+ height: modalHeight,
445
+ borderStyle: "double",
446
+ borderColor: inkColors.accent,
447
+ paddingX: 1,
448
+ children: [
449
+ /* @__PURE__ */ jsx5(Box5, { marginBottom: 1, children: /* @__PURE__ */ jsx5(Text4, { color: inkColors.accent, bold: true, children: title }) }),
450
+ /* @__PURE__ */ jsx5(Box5, { flexDirection: "column", flexGrow: 1, overflow: "hidden", children })
451
+ ]
452
+ }
453
+ ) })
454
+ ] });
455
+ }
456
+
457
+ // src/components/FeatureCommands.tsx
458
+ import { useMemo as useMemo3 } from "react";
459
+ import { Box as Box6, Text as Text5 } from "ink";
460
+
461
+ // src/hooks/usePinAction.ts
462
+ import { useEffect as useEffect2 } from "react";
463
+ import ms from "ms";
464
+
465
+ // src/stores/pinStore.ts
466
+ import { create as create4 } from "zustand";
467
+ function loadPins() {
468
+ const pinnedCommands = getPinnedCommands();
469
+ const pinnedRuns = getPinnedRuns();
470
+ return {
471
+ pinnedCommands,
472
+ pinnedRuns,
473
+ pinnedCommandSet: new Set(pinnedCommands),
474
+ pinnedRunSet: new Set(pinnedRuns)
475
+ };
476
+ }
477
+ var usePinStore = create4((set, get) => ({
478
+ ...loadPins(),
479
+ pinFeedback: void 0,
480
+ togglePinCommand: (commandId) => {
481
+ const wasPinned = get().pinnedCommandSet.has(commandId);
482
+ togglePinnedCommand(commandId);
483
+ set({
484
+ ...loadPins(),
485
+ pinFeedback: wasPinned ? `Unpinned "${commandId}"` : `Pinned "${commandId}"`
486
+ });
487
+ },
488
+ togglePinRun: (runId) => {
489
+ const wasPinned = get().pinnedRunSet.has(runId);
490
+ togglePinnedRun(runId);
491
+ set({
492
+ ...loadPins(),
493
+ pinFeedback: wasPinned ? `Unpinned run "${runId}"` : `Pinned run "${runId}"`
494
+ });
495
+ },
496
+ refreshPins: () => {
497
+ set(loadPins());
498
+ },
499
+ clearFeedback: () => {
500
+ set({ pinFeedback: void 0 });
501
+ }
502
+ }));
503
+
504
+ // src/hooks/usePinAction.ts
505
+ function usePinAction(onPinsChanged) {
506
+ const store = usePinStore();
507
+ useEffect2(() => {
508
+ store.refreshPins();
509
+ }, []);
510
+ useEffect2(() => {
511
+ if (!store.pinFeedback) return;
512
+ const timeout = setTimeout(() => store.clearFeedback(), ms("1.4s"));
513
+ return () => clearTimeout(timeout);
514
+ }, [store.pinFeedback]);
515
+ const handleRightAction = (item) => {
516
+ if (item.kind === "command") {
517
+ store.togglePinCommand(item.value);
518
+ onPinsChanged?.();
519
+ return;
520
+ }
521
+ if (item.kind === "run") {
522
+ store.togglePinRun(item.value);
523
+ onPinsChanged?.();
524
+ }
525
+ };
526
+ return {
527
+ pinnedCommands: store.pinnedCommands,
528
+ pinnedRuns: store.pinnedRuns,
529
+ pinnedCommandSet: store.pinnedCommandSet,
530
+ pinnedRunSet: store.pinnedRunSet,
531
+ pinFeedback: store.pinFeedback,
532
+ handleRightAction,
533
+ refreshPins: store.refreshPins
534
+ };
535
+ }
536
+
537
+ // src/components/FeatureCommands.tsx
538
+ import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
539
+ function FeatureCommands({
540
+ feature,
541
+ onNavigate,
542
+ onExit,
543
+ onBack,
544
+ onPinsChanged,
545
+ width = 80,
546
+ height = 24,
547
+ isInputActive = true
548
+ }) {
549
+ const {
550
+ pinnedCommands,
551
+ pinnedRuns,
552
+ pinFeedback,
553
+ handleRightAction
554
+ } = usePinAction(onPinsChanged);
555
+ const items = useMemo3(
556
+ () => buildHomeItems({
557
+ activeFeature: feature,
558
+ pinnedCommands,
559
+ pinnedRuns,
560
+ showPinnedSection: false,
561
+ showFeatureHeader: false
562
+ }),
563
+ [feature, pinnedCommands, pinnedRuns]
564
+ );
565
+ const handleSelect = (value, item) => {
566
+ if (!item) return;
567
+ if (item.kind === "command") {
568
+ const cmdDef = findCommandByValue(value);
569
+ if (cmdDef) {
570
+ onNavigate("command-args", {
571
+ command: value,
572
+ commandId: cmdDef.id,
573
+ tool: cmdDef.tool
574
+ });
575
+ } else {
576
+ onNavigate("command-args", { command: value, tool: "supabase" });
577
+ }
578
+ return;
579
+ }
580
+ if (item.kind === "run") {
581
+ const args = value.split(" ").filter(Boolean);
582
+ if (args.length > 0) {
583
+ const basePart = args[0] ?? "";
584
+ const cmdDef = findCommandByValue(basePart);
585
+ const tool = cmdDef?.tool ?? "supabase";
586
+ onNavigate("confirm-execute", { args, tool, interactive: cmdDef?.interactive });
587
+ }
588
+ return;
589
+ }
590
+ };
591
+ return /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", paddingX: 1, children: [
592
+ pinFeedback && /* @__PURE__ */ jsx6(Box6, { marginBottom: 1, children: /* @__PURE__ */ jsxs6(Text5, { color: inkColors.accent, children: [
593
+ "\u2713 ",
594
+ pinFeedback
595
+ ] }) }),
596
+ /* @__PURE__ */ jsx6(
597
+ SelectList,
598
+ {
599
+ items,
600
+ onSelect: handleSelect,
601
+ onRightAction: handleRightAction,
602
+ boxedSections: true,
603
+ width: Math.max(20, width - 4),
604
+ maxVisible: Math.max(6, height - 6),
605
+ onCancel: onBack,
606
+ isInputActive,
607
+ arrowNavigation: true,
608
+ panelFocused: isInputActive
609
+ }
610
+ )
611
+ ] });
612
+ }
613
+
614
+ // src/components/PinnedCommands.tsx
615
+ import { useMemo as useMemo4 } from "react";
616
+ import { Box as Box7, Text as Text6 } from "ink";
617
+ import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
618
+ function PinnedCommands({
619
+ onNavigate,
620
+ onBack,
621
+ onPinsChanged,
622
+ width = 80,
623
+ height = 24,
624
+ isInputActive = true
625
+ }) {
626
+ const {
627
+ pinnedCommands,
628
+ pinnedRuns,
629
+ pinFeedback,
630
+ handleRightAction
631
+ } = usePinAction(onPinsChanged);
632
+ const items = useMemo4(
633
+ () => buildPinnedOnlyItems(pinnedCommands, pinnedRuns),
634
+ [pinnedCommands, pinnedRuns]
635
+ );
636
+ const handleSelect = (value, item) => {
637
+ if (!item) return;
638
+ if (item.kind === "command") {
639
+ const cmdDef = findCommandByValue(value);
640
+ if (cmdDef) {
641
+ onNavigate("command-args", {
642
+ command: value,
643
+ commandId: cmdDef.id,
644
+ tool: cmdDef.tool
645
+ });
646
+ } else {
647
+ onNavigate("command-args", { command: value, tool: "supabase" });
648
+ }
649
+ return;
650
+ }
651
+ if (item.kind === "run") {
652
+ const args = value.split(" ").filter(Boolean);
653
+ if (args.length > 0) {
654
+ const basePart = args[0] ?? "";
655
+ const cmdDef = findCommandByValue(basePart);
656
+ const tool = cmdDef?.tool ?? "supabase";
657
+ onNavigate("confirm-execute", { args, tool, interactive: cmdDef?.interactive });
658
+ }
659
+ }
660
+ };
661
+ if (items.length === 0) {
662
+ return /* @__PURE__ */ jsx7(Box7, { flexDirection: "column", paddingX: 1, children: /* @__PURE__ */ jsx7(Text6, { color: "gray", children: "No pinned items. Press p on any command to pin it." }) });
663
+ }
664
+ return /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", paddingX: 1, children: [
665
+ pinFeedback && /* @__PURE__ */ jsx7(Box7, { marginBottom: 1, children: /* @__PURE__ */ jsxs7(Text6, { color: inkColors.accent, children: [
666
+ "\u2713 ",
667
+ pinFeedback
668
+ ] }) }),
669
+ /* @__PURE__ */ jsx7(
670
+ SelectList,
671
+ {
672
+ items,
673
+ onSelect: handleSelect,
674
+ onRightAction: handleRightAction,
675
+ boxedSections: true,
676
+ width: Math.max(20, width - 4),
677
+ maxVisible: Math.max(6, height - 6),
678
+ onCancel: onBack,
679
+ isInputActive,
680
+ arrowNavigation: true,
681
+ panelFocused: isInputActive
682
+ }
683
+ )
684
+ ] });
685
+ }
686
+
687
+ // src/screens/DeclarativeHome.tsx
688
+ import { useMemo as useMemo5 } from "react";
689
+ import { Box as Box8 } from "ink";
690
+ import { jsx as jsx8 } from "react/jsx-runtime";
691
+ var ITEMS = [
692
+ { value: "declarative-plan", label: "Plan / Apply", hint: "Diff and apply polter.yaml", kind: "action" },
693
+ { value: "declarative-status", label: "Infrastructure Status", hint: "Live state from CLI tools", kind: "action" },
694
+ { value: "init-scaffold", label: "Init polter.yaml", hint: "Generate from detected state", kind: "action" }
695
+ ];
696
+ function DeclarativeHome({
697
+ onNavigate,
698
+ onBack,
699
+ width = 80,
700
+ height = 24,
701
+ isInputActive = true
702
+ }) {
703
+ const handleSelect = useMemo5(
704
+ () => (value) => onNavigate(value),
705
+ [onNavigate]
706
+ );
707
+ return /* @__PURE__ */ jsx8(Box8, { flexDirection: "column", paddingX: 1, children: /* @__PURE__ */ jsx8(
708
+ SelectList,
709
+ {
710
+ items: ITEMS,
711
+ onSelect: handleSelect,
712
+ onCancel: onBack,
713
+ width: Math.max(20, width - 4),
714
+ maxVisible: Math.max(6, height - 4),
715
+ isInputActive,
716
+ arrowNavigation: true,
717
+ panelFocused: isInputActive
718
+ }
719
+ ) });
720
+ }
721
+
722
+ // src/appPanel.tsx
723
+ import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
724
+ var screenLabels = {
725
+ "command-args": "Args",
726
+ "flag-selection": "Flags",
727
+ "confirm-execute": "Execute",
728
+ "command-execution": "Execute",
729
+ "custom-command": "Custom Cmd",
730
+ "pipeline-list": "Pipelines",
731
+ "pipeline-builder": "Builder",
732
+ "pipeline-execution": "Run",
733
+ "self-update": "Update",
734
+ "tool-status": "Status",
735
+ "project-config": "Config",
736
+ "mcp-manage": "MCP",
737
+ "process-list": "Processes",
738
+ "process-logs": "Logs",
739
+ "declarative-plan": "Plan/Apply",
740
+ "declarative-status": "Status",
741
+ "init-scaffold": "Init",
742
+ "script-picker": "Scripts",
743
+ "skill-setup": "Skill Setup"
744
+ };
745
+ function buildBreadcrumb(nav) {
746
+ let base;
747
+ switch (nav.view) {
748
+ case "feature": {
749
+ const feat = getFeatureById(nav.featureId);
750
+ base = feat ? `${feat.icon} ${feat.label}` : nav.featureId;
751
+ break;
752
+ }
753
+ case "pinned":
754
+ base = "\u{1F4CC} Pinned";
755
+ break;
756
+ case "custom-command":
757
+ base = "\u270F\uFE0F Custom Cmd";
758
+ break;
759
+ case "pipelines":
760
+ base = "\u{1F517} Pipelines";
761
+ break;
762
+ case "tool-status":
763
+ base = "\u{1F527} Status";
764
+ break;
765
+ case "config":
766
+ base = "\u2699\uFE0F Config";
767
+ break;
768
+ case "self-update":
769
+ base = "\u2B06\uFE0F Update";
770
+ break;
771
+ case "processes":
772
+ base = "\u{1F4BB} Processes";
773
+ break;
774
+ case "scripts":
775
+ base = "\u{1F4DC} Scripts";
776
+ break;
777
+ case "declarative":
778
+ base = "\u{1F3D7}\uFE0F Infrastructure";
779
+ break;
780
+ case "skill-setup":
781
+ base = "\u{1F9E0} Skill Setup";
782
+ break;
783
+ default:
784
+ base = nav.view;
785
+ }
786
+ if (nav.innerScreen === "home") {
787
+ return base;
788
+ }
789
+ const parts = [base];
790
+ for (const entry of nav.innerStack) {
791
+ if (entry.screen !== "home") {
792
+ parts.push(screenLabels[entry.screen] ?? entry.screen);
793
+ }
794
+ }
795
+ parts.push(screenLabels[nav.innerScreen] ?? nav.innerScreen);
796
+ return parts.join(" \u203A ");
797
+ }
798
+ var FOOTER_HINTS = [
799
+ { key: "Tab", action: "focus" },
800
+ { key: "\u2190/Esc", action: "back" },
801
+ { key: "\u2192/Enter", action: "select" },
802
+ { key: "j/k", action: "nav" },
803
+ { key: "p", action: "pin" },
804
+ { key: "q", action: "quit" },
805
+ { key: "?", action: "help" }
806
+ ];
807
+ function AppPanel() {
808
+ useFullscreen();
809
+ const { width, height } = useTerminalDimensions();
810
+ const { exit } = useApp();
811
+ const nav = usePanelNavigation();
812
+ const focus = usePanelFocus();
813
+ const sidebarItems = useSidebarItems();
814
+ const modal = useModal();
815
+ const singlePanel = width < 60 || height < 15;
816
+ const handleExit = () => {
817
+ process.stdout.write(
818
+ "\n" + colors.dim("Thank you for using ") + colors.primaryBold("Polter") + colors.dim("!") + "\n\n"
819
+ );
820
+ exit();
821
+ };
822
+ useInput2((input, key) => {
823
+ if (modal.isOpen) {
824
+ if (key.escape || input === "q") {
825
+ modal.closeModal();
826
+ }
827
+ return;
828
+ }
829
+ if (input === "q") {
830
+ handleExit();
831
+ return;
832
+ }
833
+ if (key.tab) {
834
+ focus.toggleFocus();
835
+ return;
836
+ }
837
+ if (key.leftArrow && focus.isMainFocused && nav.innerScreen === "home") {
838
+ focus.focusSidebar();
839
+ return;
840
+ }
841
+ if (key.escape && focus.isMainFocused && nav.innerScreen === "home") {
842
+ focus.focusSidebar();
843
+ return;
844
+ }
845
+ if (input === "?") {
846
+ modal.openModal(
847
+ /* @__PURE__ */ jsxs8(Box9, { flexDirection: "column", children: [
848
+ /* @__PURE__ */ jsxs8(Text7, { children: [
849
+ /* @__PURE__ */ jsx9(Text7, { bold: true, children: "\u2190/\u2192" }),
850
+ " Move between sidebar and main panel"
851
+ ] }),
852
+ /* @__PURE__ */ jsxs8(Text7, { children: [
853
+ /* @__PURE__ */ jsx9(Text7, { bold: true, children: "Tab" }),
854
+ " Toggle sidebar / main panel"
855
+ ] }),
856
+ /* @__PURE__ */ jsxs8(Text7, { children: [
857
+ /* @__PURE__ */ jsx9(Text7, { bold: true, children: "j/k" }),
858
+ " Navigate up/down"
859
+ ] }),
860
+ /* @__PURE__ */ jsxs8(Text7, { children: [
861
+ /* @__PURE__ */ jsx9(Text7, { bold: true, children: "Enter" }),
862
+ " Select item"
863
+ ] }),
864
+ /* @__PURE__ */ jsxs8(Text7, { children: [
865
+ /* @__PURE__ */ jsx9(Text7, { bold: true, children: "Esc" }),
866
+ " Go back (or return to sidebar)"
867
+ ] }),
868
+ /* @__PURE__ */ jsxs8(Text7, { children: [
869
+ /* @__PURE__ */ jsx9(Text7, { bold: true, children: "q" }),
870
+ " Quit Polter"
871
+ ] }),
872
+ /* @__PURE__ */ jsxs8(Text7, { children: [
873
+ /* @__PURE__ */ jsx9(Text7, { bold: true, children: "?" }),
874
+ " Show this help"
875
+ ] }),
876
+ /* @__PURE__ */ jsxs8(Text7, { children: [
877
+ /* @__PURE__ */ jsx9(Text7, { bold: true, children: "p" }),
878
+ " Pin/unpin command"
879
+ ] })
880
+ ] }),
881
+ "Keyboard Shortcuts"
882
+ );
883
+ }
884
+ });
885
+ const activeSidebarId = (() => {
886
+ switch (nav.view) {
887
+ case "feature":
888
+ return nav.featureId;
889
+ case "pinned":
890
+ return "pinned";
891
+ case "custom-command":
892
+ return "custom-command";
893
+ case "pipelines":
894
+ return "pipelines";
895
+ case "tool-status":
896
+ return "tool-status";
897
+ case "config":
898
+ return "config";
899
+ case "self-update":
900
+ return "self-update";
901
+ case "processes":
902
+ return "processes";
903
+ case "scripts":
904
+ return "scripts";
905
+ case "declarative":
906
+ return "declarative";
907
+ case "skill-setup":
908
+ return "skill-setup";
909
+ default:
910
+ return nav.featureId;
911
+ }
912
+ })();
913
+ const handleSidebarHighlight = (itemId) => {
914
+ if (itemId === "exit") return;
915
+ nav.selectSidebarItem(itemId);
916
+ };
917
+ const handleSidebarSelect = (itemId) => {
918
+ if (itemId === "exit") {
919
+ handleExit();
920
+ return;
921
+ }
922
+ nav.selectSidebarItem(itemId);
923
+ focus.focusMain();
924
+ };
925
+ const bannerHeight = width < 60 ? 6 : 10;
926
+ const footerHints = FOOTER_HINTS;
927
+ const mainContentHeight = Math.max(5, height - bannerHeight - 1 - 2);
928
+ const mainContentWidth = singlePanel ? width : width - Math.max(20, Math.min(35, Math.floor(width * 0.3)));
929
+ const renderMainContent = () => {
930
+ if (nav.innerScreen !== "home") {
931
+ return renderInnerScreen();
932
+ }
933
+ switch (nav.view) {
934
+ case "pinned":
935
+ return /* @__PURE__ */ jsx9(
936
+ PinnedCommands,
937
+ {
938
+ onNavigate: nav.navigateInner,
939
+ onBack: focus.focusSidebar,
940
+ width: mainContentWidth - 2,
941
+ height: mainContentHeight,
942
+ isInputActive: focus.isMainFocused
943
+ }
944
+ );
945
+ case "feature": {
946
+ const feature = getFeatureById(nav.featureId);
947
+ if (!feature) {
948
+ return /* @__PURE__ */ jsxs8(Text7, { color: "red", children: [
949
+ "Feature not found: ",
950
+ nav.featureId
951
+ ] });
952
+ }
953
+ return /* @__PURE__ */ jsx9(
954
+ FeatureCommands,
955
+ {
956
+ feature,
957
+ onNavigate: nav.navigateInner,
958
+ onExit: handleExit,
959
+ onBack: focus.focusSidebar,
960
+ width: mainContentWidth - 2,
961
+ height: mainContentHeight,
962
+ isInputActive: focus.isMainFocused
963
+ }
964
+ );
965
+ }
966
+ case "custom-command":
967
+ return /* @__PURE__ */ jsx9(
968
+ CustomCommand,
969
+ {
970
+ onNavigate: nav.navigateInner,
971
+ onBack: focus.focusSidebar,
972
+ width: mainContentWidth - 2,
973
+ height: mainContentHeight,
974
+ panelMode: true,
975
+ isInputActive: focus.isMainFocused
976
+ }
977
+ );
978
+ case "pipelines":
979
+ return /* @__PURE__ */ jsx9(
980
+ PipelineList,
981
+ {
982
+ onNavigate: nav.navigateInner,
983
+ onBack: focus.focusSidebar,
984
+ width: mainContentWidth - 2,
985
+ height: mainContentHeight,
986
+ panelMode: true,
987
+ isInputActive: focus.isMainFocused
988
+ }
989
+ );
990
+ case "tool-status":
991
+ return /* @__PURE__ */ jsx9(
992
+ ToolStatus,
993
+ {
994
+ onBack: focus.focusSidebar,
995
+ onNavigate: nav.navigateInner,
996
+ width: mainContentWidth - 2,
997
+ height: mainContentHeight,
998
+ panelMode: true,
999
+ isInputActive: focus.isMainFocused
1000
+ }
1001
+ );
1002
+ case "processes":
1003
+ return /* @__PURE__ */ jsx9(
1004
+ ProcessList,
1005
+ {
1006
+ onNavigate: nav.navigateInner,
1007
+ onBack: focus.focusSidebar,
1008
+ width: mainContentWidth - 2,
1009
+ height: mainContentHeight,
1010
+ panelMode: true,
1011
+ isInputActive: focus.isMainFocused
1012
+ }
1013
+ );
1014
+ case "scripts":
1015
+ return /* @__PURE__ */ jsx9(
1016
+ ScriptPicker,
1017
+ {
1018
+ onNavigate: nav.navigateInner,
1019
+ onBack: focus.focusSidebar,
1020
+ width: mainContentWidth - 2,
1021
+ height: mainContentHeight,
1022
+ panelMode: true,
1023
+ isInputActive: focus.isMainFocused
1024
+ }
1025
+ );
1026
+ case "declarative":
1027
+ return /* @__PURE__ */ jsx9(
1028
+ DeclarativeHome,
1029
+ {
1030
+ onNavigate: nav.navigateInner,
1031
+ onBack: focus.focusSidebar,
1032
+ width: mainContentWidth - 2,
1033
+ height: mainContentHeight,
1034
+ isInputActive: focus.isMainFocused
1035
+ }
1036
+ );
1037
+ case "skill-setup":
1038
+ return /* @__PURE__ */ jsx9(
1039
+ SkillSetup,
1040
+ {
1041
+ onBack: focus.focusSidebar,
1042
+ width: mainContentWidth - 2,
1043
+ height: mainContentHeight,
1044
+ panelMode: true,
1045
+ isInputActive: focus.isMainFocused
1046
+ }
1047
+ );
1048
+ case "config":
1049
+ return /* @__PURE__ */ jsx9(
1050
+ ProjectConfig,
1051
+ {
1052
+ onBack: focus.focusSidebar,
1053
+ width: mainContentWidth - 2,
1054
+ height: mainContentHeight,
1055
+ panelMode: true,
1056
+ isInputActive: focus.isMainFocused
1057
+ }
1058
+ );
1059
+ case "self-update":
1060
+ return /* @__PURE__ */ jsx9(
1061
+ SelfUpdate,
1062
+ {
1063
+ onBack: focus.focusSidebar,
1064
+ onExit: handleExit,
1065
+ width: mainContentWidth - 2,
1066
+ height: mainContentHeight,
1067
+ panelMode: true,
1068
+ isInputActive: focus.isMainFocused
1069
+ }
1070
+ );
1071
+ default:
1072
+ return /* @__PURE__ */ jsx9(Text7, { children: "Select an item from the sidebar" });
1073
+ }
1074
+ };
1075
+ const renderInnerScreen = () => {
1076
+ const isActive = focus.isMainFocused;
1077
+ const w = mainContentWidth - 2;
1078
+ switch (nav.innerScreen) {
1079
+ case "command-args":
1080
+ return /* @__PURE__ */ jsx9(
1081
+ CommandArgs,
1082
+ {
1083
+ command: nav.innerParams.command ?? "",
1084
+ tool: nav.innerParams.tool,
1085
+ onNavigate: nav.navigateInner,
1086
+ onBack: nav.goBackInner,
1087
+ width: w,
1088
+ panelMode: true,
1089
+ isInputActive: isActive
1090
+ }
1091
+ );
1092
+ case "custom-command":
1093
+ return /* @__PURE__ */ jsx9(
1094
+ CustomCommand,
1095
+ {
1096
+ onNavigate: nav.navigateInner,
1097
+ onBack: nav.goBackInner,
1098
+ width: w,
1099
+ height: mainContentHeight,
1100
+ panelMode: true,
1101
+ isInputActive: isActive
1102
+ }
1103
+ );
1104
+ case "flag-selection":
1105
+ return /* @__PURE__ */ jsx9(
1106
+ FlagSelection,
1107
+ {
1108
+ args: nav.innerParams.args ?? [],
1109
+ tool: nav.innerParams.tool,
1110
+ interactive: nav.innerParams.interactive,
1111
+ onNavigate: nav.navigateInner,
1112
+ onBack: nav.goBackInner,
1113
+ width: w,
1114
+ height: mainContentHeight,
1115
+ panelMode: true,
1116
+ isInputActive: isActive
1117
+ }
1118
+ );
1119
+ case "confirm-execute":
1120
+ case "command-execution":
1121
+ return /* @__PURE__ */ jsx9(
1122
+ CommandExecution,
1123
+ {
1124
+ args: nav.innerParams.args ?? [],
1125
+ tool: nav.innerParams.tool,
1126
+ rawCommand: nav.innerParams.rawCommand,
1127
+ interactive: nav.innerParams.interactive,
1128
+ cwd: nav.innerParams.cwd,
1129
+ onBack: nav.goBackInner,
1130
+ onHome: nav.goHomeInner,
1131
+ onExit: handleExit,
1132
+ onRunSuggestion: (sugTool, sugArgs) => {
1133
+ nav.switchViewAndNavigate("custom-command", "confirm-execute", { tool: sugTool, args: sugArgs, interactive: true });
1134
+ },
1135
+ width: w,
1136
+ height: mainContentHeight,
1137
+ panelMode: true,
1138
+ isInputActive: isActive
1139
+ },
1140
+ `${nav.view}-${nav.innerParams.tool}-${(nav.innerParams.args ?? []).join("-")}`
1141
+ );
1142
+ case "pipeline-list":
1143
+ return /* @__PURE__ */ jsx9(
1144
+ PipelineList,
1145
+ {
1146
+ onNavigate: nav.navigateInner,
1147
+ onBack: nav.goBackInner,
1148
+ width: w,
1149
+ height: mainContentHeight,
1150
+ panelMode: true,
1151
+ isInputActive: isActive
1152
+ }
1153
+ );
1154
+ case "pipeline-builder":
1155
+ return /* @__PURE__ */ jsx9(
1156
+ PipelineBuilder,
1157
+ {
1158
+ onBack: nav.goBackInner,
1159
+ width: w,
1160
+ height: mainContentHeight,
1161
+ panelMode: true,
1162
+ isInputActive: isActive
1163
+ }
1164
+ );
1165
+ case "pipeline-execution":
1166
+ return /* @__PURE__ */ jsx9(
1167
+ PipelineExecution,
1168
+ {
1169
+ pipelineId: nav.innerParams.pipelineId ?? "",
1170
+ onBack: nav.goBackInner,
1171
+ onExit: handleExit,
1172
+ width: w,
1173
+ panelMode: true,
1174
+ isInputActive: isActive
1175
+ }
1176
+ );
1177
+ case "self-update":
1178
+ return /* @__PURE__ */ jsx9(
1179
+ SelfUpdate,
1180
+ {
1181
+ onBack: nav.goBackInner,
1182
+ onExit: handleExit,
1183
+ width: w,
1184
+ height: mainContentHeight,
1185
+ panelMode: true,
1186
+ isInputActive: isActive
1187
+ }
1188
+ );
1189
+ case "tool-status":
1190
+ return /* @__PURE__ */ jsx9(
1191
+ ToolStatus,
1192
+ {
1193
+ onBack: nav.goBackInner,
1194
+ onNavigate: nav.navigateInner,
1195
+ width: w,
1196
+ height: mainContentHeight,
1197
+ panelMode: true,
1198
+ isInputActive: isActive
1199
+ }
1200
+ );
1201
+ case "mcp-manage":
1202
+ return /* @__PURE__ */ jsx9(
1203
+ McpManage,
1204
+ {
1205
+ onBack: nav.goBackInner,
1206
+ width: w,
1207
+ height: mainContentHeight,
1208
+ panelMode: true,
1209
+ isInputActive: isActive
1210
+ }
1211
+ );
1212
+ case "process-list":
1213
+ return /* @__PURE__ */ jsx9(
1214
+ ProcessList,
1215
+ {
1216
+ onNavigate: nav.navigateInner,
1217
+ onBack: nav.goBackInner,
1218
+ width: w,
1219
+ height: mainContentHeight,
1220
+ panelMode: true,
1221
+ isInputActive: isActive
1222
+ }
1223
+ );
1224
+ case "process-logs":
1225
+ return /* @__PURE__ */ jsx9(
1226
+ ProcessLogs,
1227
+ {
1228
+ processId: nav.innerParams.processId ?? "",
1229
+ onBack: nav.goBackInner,
1230
+ width: w,
1231
+ height: mainContentHeight,
1232
+ panelMode: true,
1233
+ isInputActive: isActive
1234
+ }
1235
+ );
1236
+ case "project-config":
1237
+ return /* @__PURE__ */ jsx9(
1238
+ ProjectConfig,
1239
+ {
1240
+ onBack: nav.goBackInner,
1241
+ width: w,
1242
+ height: mainContentHeight,
1243
+ panelMode: true,
1244
+ isInputActive: isActive
1245
+ }
1246
+ );
1247
+ case "declarative-plan":
1248
+ return /* @__PURE__ */ jsx9(
1249
+ DeclarativePlan,
1250
+ {
1251
+ onBack: nav.goBackInner,
1252
+ onNavigate: nav.navigateInner,
1253
+ width: w,
1254
+ height: mainContentHeight,
1255
+ panelMode: true,
1256
+ isInputActive: isActive
1257
+ }
1258
+ );
1259
+ case "declarative-status":
1260
+ return /* @__PURE__ */ jsx9(
1261
+ DeclarativeStatus,
1262
+ {
1263
+ onBack: nav.goBackInner,
1264
+ width: w,
1265
+ height: mainContentHeight,
1266
+ panelMode: true,
1267
+ isInputActive: isActive
1268
+ }
1269
+ );
1270
+ case "init-scaffold":
1271
+ return /* @__PURE__ */ jsx9(
1272
+ InitScaffold,
1273
+ {
1274
+ onBack: nav.goBackInner,
1275
+ onNavigate: nav.navigateInner,
1276
+ width: w,
1277
+ height: mainContentHeight,
1278
+ panelMode: true,
1279
+ isInputActive: isActive
1280
+ }
1281
+ );
1282
+ case "script-picker":
1283
+ return /* @__PURE__ */ jsx9(
1284
+ ScriptPicker,
1285
+ {
1286
+ onNavigate: nav.navigateInner,
1287
+ onBack: nav.goBackInner,
1288
+ width: w,
1289
+ height: mainContentHeight,
1290
+ panelMode: true,
1291
+ isInputActive: isActive
1292
+ }
1293
+ );
1294
+ case "skill-setup":
1295
+ return /* @__PURE__ */ jsx9(
1296
+ SkillSetup,
1297
+ {
1298
+ onBack: nav.goBackInner,
1299
+ width: w,
1300
+ height: mainContentHeight,
1301
+ panelMode: true,
1302
+ isInputActive: isActive
1303
+ }
1304
+ );
1305
+ default:
1306
+ return /* @__PURE__ */ jsxs8(Text7, { color: "red", children: [
1307
+ "Unknown screen: ",
1308
+ nav.innerScreen
1309
+ ] });
1310
+ }
1311
+ };
1312
+ if (modal.isOpen) {
1313
+ return /* @__PURE__ */ jsx9(Box9, { flexDirection: "column", width, height, children: /* @__PURE__ */ jsx9(Modal, { title: modal.modalTitle, width, height, children: modal.modalContent }) });
1314
+ }
1315
+ const header = /* @__PURE__ */ jsx9(GhostBanner, { width, compact: true });
1316
+ const sidebar = /* @__PURE__ */ jsx9(
1317
+ Panel,
1318
+ {
1319
+ id: "sidebar",
1320
+ title: "Menu",
1321
+ width: Math.max(20, Math.min(35, Math.floor(width * 0.3))),
1322
+ height: Math.max(5, height - bannerHeight - 1),
1323
+ focused: focus.isSidebarFocused,
1324
+ children: /* @__PURE__ */ jsx9(
1325
+ Sidebar,
1326
+ {
1327
+ items: sidebarItems,
1328
+ selectedId: activeSidebarId,
1329
+ isFocused: focus.isSidebarFocused,
1330
+ height: Math.max(5, height - bannerHeight - 4),
1331
+ onSelect: handleSidebarSelect,
1332
+ onHighlight: handleSidebarHighlight
1333
+ }
1334
+ )
1335
+ }
1336
+ );
1337
+ const main = /* @__PURE__ */ jsx9(
1338
+ Panel,
1339
+ {
1340
+ id: "main",
1341
+ title: buildBreadcrumb(nav),
1342
+ width: mainContentWidth,
1343
+ height: Math.max(5, height - bannerHeight - 1),
1344
+ focused: focus.isMainFocused,
1345
+ children: renderMainContent()
1346
+ }
1347
+ );
1348
+ const footer = /* @__PURE__ */ jsx9(PanelFooter, { hints: footerHints, width });
1349
+ return /* @__PURE__ */ jsx9(
1350
+ PanelLayout,
1351
+ {
1352
+ header,
1353
+ footer,
1354
+ sidebar,
1355
+ main,
1356
+ width,
1357
+ height,
1358
+ bannerHeight,
1359
+ singlePanel
1360
+ }
1361
+ );
1362
+ }
1363
+ export {
1364
+ AppPanel
1365
+ };