@alcyone-labs/arg-parser 2.14.2 → 3.0.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 (75) hide show
  1. package/README.md +20 -127
  2. package/dist/config/plugins/index.d.ts +36 -4
  3. package/dist/config/plugins/index.d.ts.map +1 -1
  4. package/dist/core/ArgParser.d.ts +124 -464
  5. package/dist/core/ArgParser.d.ts.map +1 -1
  6. package/dist/core/FlagManager.d.ts +36 -136
  7. package/dist/core/FlagManager.d.ts.map +1 -1
  8. package/dist/core/PromptManager.d.ts +42 -91
  9. package/dist/core/PromptManager.d.ts.map +1 -1
  10. package/dist/core/log-path-utils.d.ts +28 -36
  11. package/dist/core/log-path-utils.d.ts.map +1 -1
  12. package/dist/core/types.d.ts +83 -592
  13. package/dist/core/types.d.ts.map +1 -1
  14. package/dist/index.cjs +599 -9658
  15. package/dist/index.cjs.map +1 -1
  16. package/dist/index.d.ts +26 -15
  17. package/dist/index.d.ts.map +1 -1
  18. package/dist/index.min.mjs +615 -8224
  19. package/dist/index.min.mjs.map +1 -1
  20. package/dist/index.mjs +581 -8881
  21. package/dist/index.mjs.map +1 -1
  22. package/dist/plugin/types.d.ts +121 -0
  23. package/dist/plugin/types.d.ts.map +1 -0
  24. package/dist/utils/debug-utils.d.ts +4 -26
  25. package/dist/utils/debug-utils.d.ts.map +1 -1
  26. package/package.json +12 -73
  27. package/dist/assets/.dxtignore.template +0 -37
  28. package/dist/assets/logo_1_small.jpg +0 -0
  29. package/dist/config/ConfigurationManager.d.ts +0 -82
  30. package/dist/config/ConfigurationManager.d.ts.map +0 -1
  31. package/dist/config/plugins/ConfigPlugin.d.ts +0 -60
  32. package/dist/config/plugins/ConfigPlugin.d.ts.map +0 -1
  33. package/dist/config/plugins/ConfigPluginRegistry.d.ts +0 -72
  34. package/dist/config/plugins/ConfigPluginRegistry.d.ts.map +0 -1
  35. package/dist/config/plugins/TomlConfigPlugin.d.ts +0 -30
  36. package/dist/config/plugins/TomlConfigPlugin.d.ts.map +0 -1
  37. package/dist/config/plugins/YamlConfigPlugin.d.ts +0 -29
  38. package/dist/config/plugins/YamlConfigPlugin.d.ts.map +0 -1
  39. package/dist/core/ArgParserBase.d.ts +0 -319
  40. package/dist/core/ArgParserBase.d.ts.map +0 -1
  41. package/dist/core/dxt-path-resolver.d.ts +0 -100
  42. package/dist/core/dxt-path-resolver.d.ts.map +0 -1
  43. package/dist/dxt/DxtGenerator-testUtils.d.ts +0 -22
  44. package/dist/dxt/DxtGenerator-testUtils.d.ts.map +0 -1
  45. package/dist/dxt/DxtGenerator.d.ts +0 -120
  46. package/dist/dxt/DxtGenerator.d.ts.map +0 -1
  47. package/dist/mcp/ArgParserMcp.d.ts +0 -21
  48. package/dist/mcp/ArgParserMcp.d.ts.map +0 -1
  49. package/dist/mcp/mcp-integration.d.ts +0 -86
  50. package/dist/mcp/mcp-integration.d.ts.map +0 -1
  51. package/dist/mcp/mcp-lifecycle.d.ts +0 -163
  52. package/dist/mcp/mcp-lifecycle.d.ts.map +0 -1
  53. package/dist/mcp/mcp-notifications.d.ts +0 -132
  54. package/dist/mcp/mcp-notifications.d.ts.map +0 -1
  55. package/dist/mcp/mcp-prompts.d.ts +0 -132
  56. package/dist/mcp/mcp-prompts.d.ts.map +0 -1
  57. package/dist/mcp/mcp-protocol-versions.d.ts +0 -150
  58. package/dist/mcp/mcp-protocol-versions.d.ts.map +0 -1
  59. package/dist/mcp/mcp-resources.d.ts +0 -133
  60. package/dist/mcp/mcp-resources.d.ts.map +0 -1
  61. package/dist/mcp/mcp-utils.d.ts +0 -20
  62. package/dist/mcp/mcp-utils.d.ts.map +0 -1
  63. package/dist/mcp/zod-compatibility.d.ts +0 -74
  64. package/dist/mcp/zod-compatibility.d.ts.map +0 -1
  65. package/dist/testing/fuzzy-test-cli.d.ts +0 -5
  66. package/dist/testing/fuzzy-test-cli.d.ts.map +0 -1
  67. package/dist/testing/fuzzy-tester.d.ts +0 -101
  68. package/dist/testing/fuzzy-tester.d.ts.map +0 -1
  69. package/dist/tui/index.d.ts +0 -281
  70. package/dist/tui/types.d.ts +0 -60
  71. package/dist/tui/types.d.ts.map +0 -1
  72. package/dist/tui.cjs +0 -1060
  73. package/dist/tui.cjs.map +0 -1
  74. package/dist/tui.mjs +0 -967
  75. package/dist/tui.mjs.map +0 -1
package/dist/tui.mjs DELETED
@@ -1,967 +0,0 @@
1
- import { createComponent, createComponent as createComponent$1, effect, insert, memo, mergeProps, render, render as render$1, spread, useKeyboard, useRenderer, useRenderer as useRenderer$1 } from "@opentui/solid";
2
- import { For, Show, createContext, createMemo, createSignal, onCleanup, onMount, useContext } from "solid-js";
3
- import { createComponent as createComponent$2, escape, ssr, ssrAttribute } from "solid-js/web";
4
- var EXIT_GUARD_STATE_KEY = Symbol.for("@alcyone-labs/arg-parser/tui/ExitGuardState");
5
- function getExitGuardState() {
6
- return process[EXIT_GUARD_STATE_KEY];
7
- }
8
- function setExitGuardState(state) {
9
- if (state) process[EXIT_GUARD_STATE_KEY] = state;
10
- else delete process[EXIT_GUARD_STATE_KEY];
11
- }
12
- function ExitGuard(props) {
13
- const renderer = useRenderer$1();
14
- let state = getExitGuardState();
15
- if (!state) {
16
- const originalExit = process.exit.bind(process);
17
- state = {
18
- originalExit,
19
- renderers: /* @__PURE__ */ new Set(),
20
- activeCount: 0,
21
- isExiting: false
22
- };
23
- setExitGuardState(state);
24
- const guardedExit = ((code) => {
25
- const currentState = getExitGuardState();
26
- if (!currentState) return originalExit(code);
27
- if (currentState.isExiting) return currentState.originalExit(code);
28
- currentState.isExiting = true;
29
- try {
30
- if (typeof code === "number") process.exitCode = code;
31
- for (const r of currentState.renderers) try {
32
- r.destroy();
33
- } catch {}
34
- } finally {
35
- return currentState.originalExit(code);
36
- }
37
- });
38
- process.exit = guardedExit;
39
- }
40
- state.activeCount++;
41
- state.renderers.add(renderer);
42
- onCleanup(() => {
43
- const state$1 = getExitGuardState();
44
- if (!state$1) return;
45
- state$1.renderers.delete(renderer);
46
- state$1.activeCount = Math.max(0, state$1.activeCount - 1);
47
- if (state$1.activeCount === 0) {
48
- process.exit = state$1.originalExit;
49
- setExitGuardState(void 0);
50
- }
51
- });
52
- return props.children;
53
- }
54
- var ShortcutContext = createContext();
55
- function ShortcutProvider(props) {
56
- const [registeredBindings, setRegisteredBindings] = createSignal(props.bindings ?? []);
57
- const [pending, setPending] = createSignal(null);
58
- const register = (binding) => {
59
- setRegisteredBindings((prev) => [...prev, binding]);
60
- return () => {
61
- setRegisteredBindings((prev) => prev.filter((b) => b !== binding));
62
- };
63
- };
64
- const value = {
65
- register,
66
- pending,
67
- bindings: registeredBindings
68
- };
69
- return createComponent$1(ShortcutContext.Provider, {
70
- value,
71
- get children() {
72
- return props.children;
73
- }
74
- });
75
- }
76
- function useShortcuts() {
77
- const context = useContext(ShortcutContext);
78
- if (!context) throw new Error("useShortcuts must be used within a ShortcutProvider");
79
- return context;
80
- }
81
- const TuiThemes = {
82
- dark: {
83
- name: "dark",
84
- colors: {
85
- text: "#ffffff",
86
- muted: "#888888",
87
- background: "#1a1a1a",
88
- accent: "#00d4ff",
89
- success: "#00ff88",
90
- warning: "#ffaa00",
91
- error: "#ff4444",
92
- border: "#444444",
93
- selection: "#0066cc"
94
- }
95
- },
96
- light: {
97
- name: "light",
98
- colors: {
99
- text: "#000000",
100
- muted: "#333333",
101
- background: "#e8e8e8",
102
- accent: "#0044aa",
103
- success: "#005500",
104
- warning: "#885500",
105
- error: "#880000",
106
- border: "#888888",
107
- selection: "#0044aa"
108
- }
109
- },
110
- monokai: {
111
- name: "monokai",
112
- colors: {
113
- text: "#f8f8f2",
114
- muted: "#75715e",
115
- background: "#272822",
116
- accent: "#ae81ff",
117
- success: "#a6e22e",
118
- warning: "#e6db74",
119
- error: "#f92672",
120
- border: "#49483e",
121
- selection: "#49483e"
122
- }
123
- },
124
- dracula: {
125
- name: "dracula",
126
- colors: {
127
- text: "#f8f8f2",
128
- muted: "#6272a4",
129
- background: "#282a36",
130
- accent: "#bd93f9",
131
- success: "#50fa7b",
132
- warning: "#f1fa8c",
133
- error: "#ff5555",
134
- border: "#44475a",
135
- selection: "#44475a"
136
- }
137
- },
138
- nord: {
139
- name: "nord",
140
- colors: {
141
- text: "#eceff4",
142
- muted: "#4c566a",
143
- background: "#2e3440",
144
- accent: "#88c0d0",
145
- success: "#a3be8c",
146
- warning: "#ebcb8b",
147
- error: "#bf616a",
148
- border: "#3b4252",
149
- selection: "#4c566a"
150
- }
151
- },
152
- solarized: {
153
- name: "solarized",
154
- colors: {
155
- text: "#839496",
156
- muted: "#586e75",
157
- background: "#002b36",
158
- accent: "#268bd2",
159
- success: "#859900",
160
- warning: "#b58900",
161
- error: "#dc322f",
162
- border: "#073642",
163
- selection: "#073642"
164
- }
165
- }
166
- };
167
- const THEMES = TuiThemes;
168
- const Theme = {
169
- from: (base) => ({ extend: (overrides) => ({
170
- name: overrides.name ?? `${base.name}-extended`,
171
- colors: {
172
- ...base.colors,
173
- ...overrides.colors
174
- }
175
- }) }),
176
- create: (theme) => theme,
177
- names: () => Object.keys(TuiThemes),
178
- get: (name) => TuiThemes[name] ?? TuiThemes["dark"]
179
- };
180
- var ThemeContext = createContext();
181
- function ThemeProvider(props) {
182
- const themes = { ...TuiThemes };
183
- const [current, setCurrent] = createSignal(themes[props.initial ?? "dark"] ?? themes["dark"]);
184
- const setTheme = (name) => {
185
- if (themes[name]) setCurrent(themes[name]);
186
- };
187
- const cycle = () => {
188
- const currentName = current().name;
189
- const names$1 = Object.keys(themes);
190
- setCurrent(themes[names$1[(names$1.indexOf(currentName) + 1) % names$1.length]]);
191
- };
192
- const register = (theme) => {
193
- themes[theme.name] = theme;
194
- };
195
- const names = () => Object.keys(themes);
196
- const value = {
197
- current,
198
- setTheme,
199
- cycle,
200
- register,
201
- names
202
- };
203
- return createComponent$1(ThemeContext.Provider, {
204
- value,
205
- get children() {
206
- return props.children;
207
- }
208
- });
209
- }
210
- function useTheme() {
211
- const context = useContext(ThemeContext);
212
- if (!context) throw new Error("useTheme must be used within a ThemeProvider");
213
- return context;
214
- }
215
- var ToastContext = createContext();
216
- var DEFAULT_DURATION = 3e3;
217
- function ToastProvider(props) {
218
- const [state, setState] = createSignal({
219
- message: "",
220
- type: "info",
221
- visible: false
222
- });
223
- let hideTimeout = null;
224
- const show = (message, type, duration) => {
225
- if (hideTimeout) clearTimeout(hideTimeout);
226
- setState({
227
- message,
228
- type,
229
- visible: true
230
- });
231
- hideTimeout = setTimeout(() => {
232
- setState((prev) => ({
233
- ...prev,
234
- visible: false
235
- }));
236
- }, duration);
237
- };
238
- const hide = () => {
239
- if (hideTimeout) {
240
- clearTimeout(hideTimeout);
241
- hideTimeout = null;
242
- }
243
- setState((prev) => ({
244
- ...prev,
245
- visible: false
246
- }));
247
- };
248
- const value = {
249
- info: (message, duration = DEFAULT_DURATION) => show(message, "info", duration),
250
- success: (message, duration = DEFAULT_DURATION) => show(message, "success", duration),
251
- error: (message, duration = DEFAULT_DURATION) => show(message, "error", duration),
252
- warning: (message, duration = DEFAULT_DURATION) => show(message, "warning", duration),
253
- state,
254
- hide
255
- };
256
- return createComponent$1(ToastContext.Provider, {
257
- value,
258
- get children() {
259
- return props.children;
260
- }
261
- });
262
- }
263
- function useToast() {
264
- const context = useContext(ToastContext);
265
- if (!context) throw new Error("useToast must be used within a ToastProvider");
266
- return context;
267
- }
268
- function enableMouseReporting() {
269
- process.stdout.write("\x1B[?1000h");
270
- process.stdout.write("\x1B[?1006h");
271
- }
272
- function disableMouseReporting() {
273
- process.stdout.write("\x1B[?1000l");
274
- process.stdout.write("\x1B[?1002l");
275
- process.stdout.write("\x1B[?1003l");
276
- process.stdout.write("\x1B[?1006l");
277
- process.stdout.write("\x1B[?1015l");
278
- }
279
- function clearScreen() {
280
- process.stdout.write("\x1B[2J\x1B[3J\x1B[H");
281
- }
282
- function resetAttributes() {
283
- process.stdout.write("\x1B[0m");
284
- }
285
- function restoreStdin() {
286
- if (process.stdin.isTTY && process.stdin.setRawMode) try {
287
- process.stdin.setRawMode(false);
288
- } catch {}
289
- }
290
- function switchToAlternateScreen() {
291
- process.stdout.write("\x1B[?1049h");
292
- }
293
- function switchToMainScreen() {
294
- process.stdout.write("\x1B[?1049l");
295
- }
296
- function cleanupTerminal() {
297
- switchToMainScreen();
298
- disableMouseReporting();
299
- clearScreen();
300
- resetAttributes();
301
- restoreStdin();
302
- }
303
- function parseMouseScroll(data) {
304
- const sgrMatch = data.toString().match(/\x1b\[<(\d+);(\d+);(\d+)([Mm])/);
305
- if (sgrMatch) {
306
- const button = parseInt(sgrMatch[1], 10);
307
- if (button === 64) return -1;
308
- if (button === 65) return 1;
309
- }
310
- return 0;
311
- }
312
- function createTuiApp(App, config = {}) {
313
- const { theme = "dark", shortcuts = [], onDestroy } = config;
314
- switchToAlternateScreen();
315
- enableMouseReporting();
316
- return render$1(() => createComponent$1(ExitGuard, { get children() {
317
- return createComponent$1(ThemeProvider, {
318
- get initial() {
319
- return theme;
320
- },
321
- get children() {
322
- return createComponent$1(ShortcutProvider, {
323
- get bindings() {
324
- return shortcuts;
325
- },
326
- get children() {
327
- return createComponent$1(ToastProvider, { get children() {
328
- return createComponent$1(App, {});
329
- } });
330
- }
331
- });
332
- }
333
- });
334
- } }), { onDestroy: () => {
335
- cleanupTerminal();
336
- onDestroy?.();
337
- } });
338
- }
339
- var _tmpl$$4 = ["<box width=\"100%\" height=\"100%\">", "</box>"];
340
- var TuiContext = createContext();
341
- function useTui() {
342
- const context = useContext(TuiContext);
343
- if (!context) throw new Error("useTui must be used within a TuiProvider");
344
- return context;
345
- }
346
- function TuiProvider(props) {
347
- const renderer = useRenderer$1();
348
- const reservedRows = props.reservedRows ?? 8;
349
- props.scrollSpeed;
350
- const [viewportHeight, setViewportHeight] = createSignal(Math.max(10, renderer.height - reservedRows));
351
- const [viewportWidth, setViewportWidth] = createSignal(renderer.width);
352
- const exit = (code = 0) => {
353
- process.exitCode = code;
354
- renderer.destroy();
355
- };
356
- const handleResize = (width, height) => {
357
- setViewportHeight(Math.max(10, height - reservedRows));
358
- setViewportWidth(width);
359
- };
360
- onMount(() => {
361
- switchToAlternateScreen();
362
- enableMouseReporting();
363
- renderer.on("resize", handleResize);
364
- });
365
- onCleanup(() => {
366
- renderer.off("resize", handleResize);
367
- cleanupTerminal();
368
- });
369
- const contextValue = {
370
- viewportHeight,
371
- viewportWidth,
372
- exit
373
- };
374
- const themeName = typeof props.theme === "string" ? props.theme : props.theme?.name ?? "dark";
375
- return createComponent$1(ExitGuard, { get children() {
376
- return createComponent$1(TuiContext.Provider, {
377
- value: contextValue,
378
- get children() {
379
- return createComponent$1(ThemeProvider, {
380
- initial: themeName,
381
- get children() {
382
- return createComponent$1(ShortcutProvider, {
383
- get bindings() {
384
- return props.shortcuts ?? [];
385
- },
386
- get children() {
387
- return createComponent$1(ToastProvider, { get children() {
388
- return ssr(_tmpl$$4, escape(props.children));
389
- } });
390
- }
391
- });
392
- }
393
- });
394
- }
395
- });
396
- } });
397
- }
398
- var _tmpl$$3 = ["<box height=\"1\" paddingleft=\"2\">", "</box>"], _tmpl$2$3 = [
399
- "<text",
400
- " bold>",
401
- "</text>"
402
- ], _tmpl$3$2 = [
403
- "<text",
404
- "> ",
405
- " </text>"
406
- ];
407
- function Breadcrumb(props) {
408
- const { current: theme } = useTheme();
409
- const separator = props.separator ?? "›";
410
- const accentColor = () => props.accentColor ?? theme().colors.accent;
411
- const mutedColor = () => props.mutedColor ?? theme().colors.muted;
412
- return ssr(_tmpl$$3, escape(createComponent$2(For, {
413
- get each() {
414
- return props.segments;
415
- },
416
- children: (segment, idx) => [idx() > 0 && ssr(_tmpl$3$2, ssrAttribute("color", escape(mutedColor(), true), false), escape(separator)), ssr(_tmpl$2$3, ssrAttribute("color", escape(accentColor(), true), false), escape(segment))]
417
- })));
418
- }
419
- var _tmpl$$2 = [
420
- "<box height=\"1\"",
421
- "><text",
422
- ">",
423
- "",
424
- "</text></box>"
425
- ], _tmpl$2$2 = [
426
- "<text bold",
427
- " marginBottom=\"1\">",
428
- " (",
429
- "/",
430
- ")</text>"
431
- ], _tmpl$3$1 = [
432
- "<box flexdirection=\"column\" flexgrow=\"1\">",
433
- "",
434
- "</box>"
435
- ];
436
- function unwrap(value) {
437
- return typeof value === "function" ? value() : value;
438
- }
439
- function VirtualList(props) {
440
- const { current: theme } = useTheme();
441
- const [scrollOffset, setScrollOffset] = createSignal(0);
442
- const items = () => unwrap(props.items);
443
- const selectedIndex = () => unwrap(props.selectedIndex);
444
- const viewportHeight = () => unwrap(props.viewportHeight ?? 20);
445
- const showIndicator = props.showIndicator ?? true;
446
- const visibleItems = createMemo(() => {
447
- const allItems = items();
448
- const vh = viewportHeight();
449
- const start = scrollOffset();
450
- const end = Math.min(start + vh, allItems.length);
451
- return allItems.slice(start, end).map((item, localIdx) => ({
452
- item,
453
- globalIndex: start + localIdx
454
- }));
455
- });
456
- const defaultRenderItem = (item, index, selected) => {
457
- const label = props.getLabel ? props.getLabel(item) : String(item);
458
- const t = theme();
459
- return ssr(_tmpl$$2, ssrAttribute("backgroundcolor", selected ? escape(t.colors.selection, true) : escape(void 0, true), false), ssrAttribute("color", selected ? escape(t.colors.background, true) : escape(t.colors.text, true), false), showIndicator ? selected ? "› " : " " : "", escape(label));
460
- };
461
- const renderItem = props.renderItem ?? defaultRenderItem;
462
- return ssr(_tmpl$3$1, escape(createComponent$2(Show, {
463
- get when() {
464
- return props.title;
465
- },
466
- get children() {
467
- return ssr(_tmpl$2$2, ssrAttribute("color", escape(theme().colors.text, true), false), escape(props.title), escape(selectedIndex()) + 1, escape(items().length));
468
- }
469
- })), escape(createComponent$2(For, {
470
- get each() {
471
- return visibleItems();
472
- },
473
- children: ({ item, globalIndex }) => renderItem(item, globalIndex, globalIndex === selectedIndex())
474
- })));
475
- }
476
- function createVirtualListController(items, selectedIndex, setSelectedIndex, viewportHeight) {
477
- const [scrollOffset, setScrollOffset] = createSignal(0);
478
- const adjustScroll = (newIdx) => {
479
- const vh = viewportHeight();
480
- const currentOffset = scrollOffset();
481
- if (newIdx < currentOffset) setScrollOffset(newIdx);
482
- else if (newIdx >= currentOffset + vh) setScrollOffset(newIdx - vh + 1);
483
- };
484
- const scrollBy = (delta) => {
485
- const maxOffset = Math.max(0, items().length - viewportHeight());
486
- setScrollOffset((o) => Math.max(0, Math.min(maxOffset, o + delta)));
487
- };
488
- const selectPrevious = () => {
489
- const newIdx = Math.max(0, selectedIndex() - 1);
490
- setSelectedIndex(newIdx);
491
- adjustScroll(newIdx);
492
- };
493
- const selectNext = () => {
494
- const newIdx = Math.min(items().length - 1, selectedIndex() + 1);
495
- setSelectedIndex(newIdx);
496
- adjustScroll(newIdx);
497
- };
498
- return {
499
- scrollOffset,
500
- adjustScroll,
501
- scrollBy,
502
- selectPrevious,
503
- selectNext
504
- };
505
- }
506
- var _tmpl$$1 = [
507
- "<box height=\"1\"",
508
- "><text",
509
- "> ",
510
- "</text></box>"
511
- ], _tmpl$2$1 = [
512
- "<box width=\"100%\" height=\"100%\" flexdirection=\"column\"",
513
- "><box height=\"3\" borderstyle=\"single\"",
514
- " justifycontent=\"center\" alignitems=\"center\"><text bold",
515
- ">",
516
- "",
517
- " </text></box>",
518
- "<box flexgrow=\"1\" flexdirection=\"row\"><box",
519
- " borderstyle=\"single\"",
520
- " flexdirection=\"column\" padding=\"1\">",
521
- "</box><box flexgrow=\"1\" borderstyle=\"single\"",
522
- " flexdirection=\"column\" padding=\"2\">",
523
- "</box></box>",
524
- "</box>"
525
- ];
526
- function MasterDetail(props) {
527
- const { current: theme } = useTheme();
528
- const masterWidth = props.masterWidth ?? "35%";
529
- return ssr(_tmpl$2$1, ssrAttribute("backgroundcolor", escape(theme().colors.background, true), false), ssrAttribute("bordercolor", escape(theme().colors.accent, true), false), ssrAttribute("color", escape(theme().colors.accent, true), false), props.headerIcon ? ` ${escape(props.headerIcon)} ` : " ", escape(props.header), escape(createComponent$2(Show, {
530
- get when() {
531
- return props.breadcrumb && props.breadcrumb.length > 0;
532
- },
533
- get children() {
534
- return createComponent$2(Breadcrumb, { get segments() {
535
- return props.breadcrumb;
536
- } });
537
- }
538
- })), ssrAttribute("width", escape(masterWidth, true), false), ssrAttribute("bordercolor", escape(theme().colors.border, true), false), escape(props.master), ssrAttribute("bordercolor", escape(theme().colors.border, true), false), escape(props.detail), escape(createComponent$2(Show, {
539
- get when() {
540
- return props.footer;
541
- },
542
- get children() {
543
- return ssr(_tmpl$$1, ssrAttribute("backgroundcolor", escape(theme().colors.background, true), false), ssrAttribute("color", escape(theme().colors.muted, true), false), escape(props.footer));
544
- }
545
- })));
546
- }
547
- function parseWidth(width) {
548
- if (width === void 0) return "30%";
549
- if (typeof width === "number") return width;
550
- if (width.endsWith("%")) return `${parseInt(width.replace("%", ""), 10)}%`;
551
- return width;
552
- }
553
- function MasterDetailLayout(props) {
554
- const masterWidth = parseWidth(props.masterWidth);
555
- const gap = props.gap ?? 1;
556
- const showDivider = props.showDivider ?? true;
557
- return {
558
- type: "box",
559
- props: {
560
- flexDirection: "row",
561
- width: "100%",
562
- height: "100%"
563
- },
564
- children: [
565
- {
566
- type: "box",
567
- props: {
568
- flexBasis: masterWidth,
569
- flexShrink: 0,
570
- overflow: "scroll"
571
- },
572
- children: props.master
573
- },
574
- ...showDivider ? [{
575
- type: "box",
576
- props: {
577
- width: 1,
578
- marginLeft: Math.floor(gap / 2),
579
- marginRight: Math.ceil(gap / 2)
580
- },
581
- children: {
582
- type: "text",
583
- props: { style: { fg: "#444444" } },
584
- children: "│".repeat(100)
585
- }
586
- }] : [],
587
- {
588
- type: "box",
589
- props: {
590
- flexGrow: 1,
591
- overflow: "scroll"
592
- },
593
- children: props.detail
594
- }
595
- ]
596
- };
597
- }
598
- function DrillDownNavigator(props) {
599
- const [stack, setStack] = createSignal([]);
600
- const push = (view) => {
601
- setStack((prev) => [...prev, view]);
602
- props.onNavigate?.(stack().length + 1);
603
- };
604
- const pop = () => {
605
- if (stack().length > 0) {
606
- setStack((prev) => prev.slice(0, -1));
607
- props.onNavigate?.(stack().length - 1);
608
- }
609
- };
610
- const replace = (view) => {
611
- if (stack().length > 0) setStack((prev) => [...prev.slice(0, -1), view]);
612
- else push(view);
613
- };
614
- const reset = () => {
615
- setStack([]);
616
- props.onNavigate?.(0);
617
- };
618
- const depth = () => stack().length;
619
- const canGoBack = () => stack().length > 0;
620
- const api = {
621
- push,
622
- pop,
623
- replace,
624
- reset,
625
- depth,
626
- canGoBack
627
- };
628
- const currentView = () => {
629
- const currentStack = stack();
630
- if (currentStack.length > 0) return currentStack[currentStack.length - 1]();
631
- return props.children(api);
632
- };
633
- return {
634
- type: "box",
635
- props: {
636
- width: "100%",
637
- height: "100%",
638
- onKeyDown: (event) => {
639
- if (event.defaultPrevented) return;
640
- if ((event.key === "Escape" || event.key === "ArrowLeft") && canGoBack()) pop();
641
- }
642
- },
643
- children: currentView()
644
- };
645
- }
646
- function Card(props) {
647
- const borderStyle = props.borderStyle ?? "single";
648
- const padding = props.padding ?? 1;
649
- let borderColor = props.borderColor;
650
- if (!borderColor) try {
651
- const { current } = useTheme();
652
- borderColor = current().colors.border;
653
- } catch {
654
- borderColor = "#444444";
655
- }
656
- return {
657
- type: "box",
658
- props: {
659
- flexDirection: "column",
660
- width: props.width,
661
- height: props.height,
662
- ...props.onClick && { onMouseDown: props.onClick },
663
- style: {
664
- border: borderStyle !== "none" ? borderStyle : void 0,
665
- borderColor,
666
- padding
667
- }
668
- },
669
- children: [...props.title ? [{
670
- type: "text",
671
- props: { style: { bold: true } },
672
- children: ` ${props.title} `
673
- }] : [], props.children]
674
- };
675
- }
676
- function formatValue(value, format, currency) {
677
- if (typeof value === "string") return value;
678
- switch (format) {
679
- case "compact":
680
- if (value >= 1e9) return `${(value / 1e9).toFixed(1)}B`;
681
- if (value >= 1e6) return `${(value / 1e6).toFixed(1)}M`;
682
- if (value >= 1e3) return `${(value / 1e3).toFixed(1)}K`;
683
- return value.toString();
684
- case "percent": return `${(value * 100).toFixed(1)}%`;
685
- case "currency": return new Intl.NumberFormat("en-US", {
686
- style: "currency",
687
- currency: currency ?? "USD",
688
- minimumFractionDigits: 0,
689
- maximumFractionDigits: 2
690
- }).format(value);
691
- case "number":
692
- default: return new Intl.NumberFormat("en-US").format(value);
693
- }
694
- }
695
- function getTrendIndicator(trend) {
696
- switch (trend) {
697
- case "up": return {
698
- symbol: "▲",
699
- color: "#00ff88"
700
- };
701
- case "down": return {
702
- symbol: "▼",
703
- color: "#ff4444"
704
- };
705
- case "neutral":
706
- default: return {
707
- symbol: "─",
708
- color: "#888888"
709
- };
710
- }
711
- }
712
- function StatCard(props) {
713
- const formattedValue = formatValue(props.value, props.format ?? "number", props.currency);
714
- const trendIndicator = props.trend ? getTrendIndicator(props.trend) : null;
715
- return {
716
- type: "box",
717
- props: {
718
- flexDirection: "column",
719
- width: props.width,
720
- padding: 1,
721
- style: { border: "single" },
722
- ...props.onClick && { onMouseDown: props.onClick }
723
- },
724
- children: [{
725
- type: "text",
726
- props: { style: { fg: "#888888" } },
727
- children: props.label
728
- }, {
729
- type: "box",
730
- props: {
731
- flexDirection: "row",
732
- gap: 1
733
- },
734
- children: [{
735
- type: "text",
736
- props: { style: {
737
- bold: true,
738
- fg: "#ffffff"
739
- } },
740
- children: formattedValue
741
- }, ...trendIndicator ? [{
742
- type: "text",
743
- props: { style: { fg: trendIndicator.color } },
744
- children: trendIndicator.symbol
745
- }] : []]
746
- }]
747
- };
748
- }
749
- function MarkdownBlock(props) {
750
- const { current } = useTheme();
751
- return {
752
- type: "box",
753
- props: {
754
- flexDirection: "column",
755
- width: props.width ?? "100%",
756
- height: props.height,
757
- padding: props.padding ?? 0,
758
- overflow: "scroll"
759
- },
760
- children: [{
761
- type: "text",
762
- props: {
763
- style: { fg: current().colors.text },
764
- text: props.content
765
- }
766
- }]
767
- };
768
- }
769
- function Button(props) {
770
- const { current } = useTheme();
771
- const [isHovered, setIsHovered] = createSignal(false);
772
- const [isPressed, setIsPressed] = createSignal(false);
773
- const getBackgroundColor = () => {
774
- if (props.disabled) return current().colors.muted;
775
- switch (props.variant) {
776
- case "danger": return isPressed() ? "#bd2c00" : isHovered() ? "#c82829" : current().colors.error;
777
- case "primary":
778
- default: return isPressed() ? current().colors.selection : isHovered() ? current().colors.accent : current().colors.accent;
779
- }
780
- };
781
- const getTextColor = () => {
782
- if (props.disabled) return current().colors.background;
783
- return props.variant === "primary" || props.variant === "danger" ? "#ffffff" : current().colors.text;
784
- };
785
- return {
786
- type: "box",
787
- props: {
788
- width: props.width,
789
- height: 3,
790
- flexDirection: "row",
791
- alignItems: "center",
792
- justifyContent: "center",
793
- style: {
794
- border: "single",
795
- borderColor: isHovered() && !props.disabled ? current().colors.text : current().colors.border,
796
- bg: getBackgroundColor()
797
- },
798
- onMouseOver: () => !props.disabled && setIsHovered(true),
799
- onMouseOut: () => {
800
- setIsHovered(false);
801
- setIsPressed(false);
802
- },
803
- onMouseDown: () => !props.disabled && setIsPressed(true),
804
- onMouseUp: () => {
805
- if (!props.disabled && isPressed()) {
806
- setIsPressed(false);
807
- props.onClick?.();
808
- }
809
- }
810
- },
811
- children: [{
812
- type: "text",
813
- props: {
814
- style: {
815
- fg: getTextColor(),
816
- bold: true
817
- },
818
- text: ` ${props.label} `
819
- }
820
- }]
821
- };
822
- }
823
- var _tmpl$ = [
824
- "<box width=\"100%\" height=\"100%\" flexdirection=\"column\"",
825
- "><box height=\"3\" borderstyle=\"single\"",
826
- " justifycontent=\"center\" alignitems=\"center\"><text bold",
827
- "> ",
828
- " </text></box>",
829
- "<box flexgrow=\"1\" flexdirection=\"row\">",
830
- "</box>",
831
- "</box>"
832
- ], _tmpl$2 = [
833
- "<box height=\"1\" paddingleft=\"2\"",
834
- ">",
835
- "</box>"
836
- ], _tmpl$3 = [
837
- "<text",
838
- " bold>",
839
- "</text>"
840
- ], _tmpl$4 = ["<text", "> › </text>"], _tmpl$5 = [
841
- "<box height=\"1\"",
842
- "><text",
843
- "> ",
844
- "</text></box>"
845
- ], _tmpl$6 = [
846
- "<box",
847
- " borderstyle=\"single\"",
848
- " flexdirection=\"column\" padding=\"1\">",
849
- "</box>"
850
- ], _tmpl$7 = [
851
- "<box flexgrow=\"1\" borderstyle=\"single\"",
852
- " flexdirection=\"column\" padding=\"2\">",
853
- "</box>"
854
- ], _tmpl$8 = [
855
- "<box height=\"1\"",
856
- "><text",
857
- ">",
858
- "",
859
- "</text></box>"
860
- ];
861
- const LAYOUT_THEMES = {
862
- dark: {
863
- bg: "#0d0d0d",
864
- fg: "#f5f5f5",
865
- accent: "#00d4ff",
866
- muted: "#999999",
867
- error: "#ff4444",
868
- success: "#44ff44",
869
- border: "#444444",
870
- selection: "#00d4ff",
871
- selectionFg: "#000000"
872
- },
873
- light: {
874
- bg: "#e8e8e8",
875
- fg: "#000000",
876
- accent: "#0044aa",
877
- muted: "#333333",
878
- error: "#880000",
879
- success: "#005500",
880
- border: "#888888",
881
- selection: "#0044aa",
882
- selectionFg: "#ffffff"
883
- },
884
- monokai: {
885
- bg: "#272822",
886
- fg: "#f8f8f2",
887
- accent: "#a6e22e",
888
- muted: "#75715e",
889
- error: "#f92672",
890
- success: "#a6e22e",
891
- border: "#49483e",
892
- selection: "#a6e22e",
893
- selectionFg: "#272822"
894
- }
895
- };
896
- function resolveTheme(theme) {
897
- if (!theme) return LAYOUT_THEMES.dark;
898
- if (typeof theme === "string") return LAYOUT_THEMES[theme] ?? LAYOUT_THEMES.dark;
899
- return theme;
900
- }
901
- function MasterDetailLayout$1(props) {
902
- const t = resolveTheme(props.theme);
903
- props.masterWidth;
904
- return ssr(_tmpl$, ssrAttribute("backgroundcolor", escape(t.bg, true), false), ssrAttribute("bordercolor", escape(t.accent, true), false), ssrAttribute("color", escape(t.accent, true), false), escape(props.header), props.breadcrumb && props.breadcrumb.length > 0 && ssr(_tmpl$2, ssrAttribute("backgroundcolor", escape(t.bg, true), false), escape(props.breadcrumb.map((segment, idx) => [idx > 0 && ssr(_tmpl$4, ssrAttribute("color", escape(t.muted, true), false)), ssr(_tmpl$3, ssrAttribute("color", escape(t.accent, true), false), escape(segment))]))), escape(props.children), props.footer && ssr(_tmpl$5, ssrAttribute("backgroundcolor", escape(t.bg, true), false), ssrAttribute("color", escape(t.muted, true), false), escape(props.footer)));
905
- }
906
- function MasterPanel(props) {
907
- const t = resolveTheme(props.theme);
908
- return ssr(_tmpl$6, ssrAttribute("width", escape(props.width, true) ?? "35%", false), ssrAttribute("bordercolor", escape(t.border, true), false), escape(props.children));
909
- }
910
- function DetailPanel(props) {
911
- return ssr(_tmpl$7, ssrAttribute("bordercolor", escape(resolveTheme(props.theme).border, true), false), escape(props.children));
912
- }
913
- function ListItem(props) {
914
- const t = resolveTheme(props.theme);
915
- return ssr(_tmpl$8, ssrAttribute("backgroundcolor", props.selected ? escape(t.selection, true) : escape(void 0, true), false), ssrAttribute("color", props.selected ? escape(t.selectionFg, true) : escape(t.fg, true), false), props.selected ? "› " : " ", escape(props.label));
916
- }
917
- function useVirtualScroll(items, _selectedIdx, viewportHeight) {
918
- const [scrollOffset, setScrollOffset] = createSignal(0);
919
- const adjustScroll = (newIdx) => {
920
- const vh = viewportHeight();
921
- const currentOffset = scrollOffset();
922
- if (newIdx < currentOffset) setScrollOffset(newIdx);
923
- else if (newIdx >= currentOffset + vh) setScrollOffset(newIdx - vh + 1);
924
- };
925
- const visibleItems = createMemo(() => {
926
- const allItems = items();
927
- const vh = viewportHeight();
928
- const start = scrollOffset();
929
- const end = Math.min(start + vh, allItems.length);
930
- return allItems.slice(start, end).map((item, localIdx) => ({
931
- item,
932
- globalIndex: start + localIdx
933
- }));
934
- });
935
- const scrollBy = (delta) => {
936
- const maxOffset = Math.max(0, items().length - viewportHeight());
937
- setScrollOffset((o) => Math.max(0, Math.min(maxOffset, o + delta)));
938
- };
939
- return {
940
- visibleItems,
941
- adjustScroll,
942
- scrollOffset,
943
- scrollBy
944
- };
945
- }
946
- function getViewportHeight(reservedRows = 8, minHeight = 10) {
947
- return Math.max(minHeight, (process.stdout.rows || 24) - reservedRows);
948
- }
949
- function useMouse(options = {}) {
950
- const { onScroll, scrollSpeed = 3 } = options;
951
- const handleInput = (data) => {
952
- const scrollDir = parseMouseScroll(data);
953
- if (scrollDir !== 0 && onScroll) onScroll(scrollDir * scrollSpeed);
954
- };
955
- onMount(() => {
956
- enableMouseReporting();
957
- if (process.stdin.isTTY) process.stdin.setRawMode(true);
958
- process.stdin.on("data", handleInput);
959
- });
960
- onCleanup(() => {
961
- disableMouseReporting();
962
- process.stdin.off("data", handleInput);
963
- });
964
- }
965
- export { Breadcrumb, Button, Card, DetailPanel, DrillDownNavigator, LAYOUT_THEMES, ListItem, MarkdownBlock, MasterDetail, MasterDetailLayout, MasterDetailLayout$1 as MasterDetailTemplate, MasterPanel, ShortcutProvider, StatCard, THEMES, Theme, ThemeProvider, ToastProvider, TuiProvider, TuiThemes, VirtualList, cleanupTerminal, clearScreen, createComponent, createTuiApp, createVirtualListController, disableMouseReporting, effect, enableMouseReporting, getViewportHeight, insert, memo, mergeProps, parseMouseScroll, render, resetAttributes, restoreStdin, spread, switchToAlternateScreen, switchToMainScreen, useKeyboard, useMouse, useRenderer, useShortcuts, useTheme, useToast, useTui, useVirtualScroll };
966
-
967
- //# sourceMappingURL=tui.mjs.map