@navios/commander-tui 1.3.0 → 1.4.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 (240) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/{src/__tests__/mocks/scm-mock.ts → dist/base/src/__tests__/mocks/scm-mock.d.ts} +3 -1
  3. package/dist/base/src/__tests__/mocks/scm-mock.d.ts.map +1 -0
  4. package/dist/base/src/__tests__/setup.d.ts +2 -0
  5. package/dist/base/src/__tests__/setup.d.ts.map +1 -0
  6. package/dist/base/src/__tests__/utils/factories.d.ts +67 -0
  7. package/dist/base/src/__tests__/utils/factories.d.ts.map +1 -0
  8. package/dist/base/src/__tests__/utils/render-utils.d.ts +21 -0
  9. package/dist/base/src/__tests__/utils/render-utils.d.ts.map +1 -0
  10. package/dist/base/src/__tests__/utils/test-container.d.ts +20 -0
  11. package/dist/base/src/__tests__/utils/test-container.d.ts.map +1 -0
  12. package/dist/base/src/adapters/interface.d.ts +9 -2
  13. package/dist/base/src/adapters/interface.d.ts.map +1 -1
  14. package/dist/base/src/overrides/missing-adapter.override.d.ts +10 -0
  15. package/dist/base/src/overrides/missing-adapter.override.d.ts.map +1 -1
  16. package/dist/base/src/schemas/logger-options.d.ts +1 -1
  17. package/dist/base/src/services/index.d.ts +1 -0
  18. package/dist/base/src/services/index.d.ts.map +1 -1
  19. package/dist/base/src/services/logger.d.ts.map +1 -1
  20. package/dist/base/src/services/readline_prompt.d.ts +27 -0
  21. package/dist/base/src/services/readline_prompt.d.ts.map +1 -0
  22. package/dist/base/src/services/screen.d.ts +14 -8
  23. package/dist/base/src/services/screen.d.ts.map +1 -1
  24. package/dist/base/src/services/screen_manager.d.ts +62 -12
  25. package/dist/base/src/services/screen_manager.d.ts.map +1 -1
  26. package/dist/base/src/types/events.types.d.ts +40 -0
  27. package/dist/base/src/types/events.types.d.ts.map +1 -0
  28. package/dist/base/src/types/index.d.ts +1 -0
  29. package/dist/base/src/types/index.d.ts.map +1 -1
  30. package/dist/base/src/types/screen.types.d.ts +28 -0
  31. package/dist/base/src/types/screen.types.d.ts.map +1 -1
  32. package/dist/base/src/utils/colors/helpers.d.ts +0 -16
  33. package/dist/base/src/utils/colors/helpers.d.ts.map +1 -1
  34. package/dist/base/src/utils/index.d.ts +2 -0
  35. package/dist/base/src/utils/index.d.ts.map +1 -1
  36. package/dist/base/src/utils/prompt.d.ts +7 -0
  37. package/dist/base/src/utils/prompt.d.ts.map +1 -0
  38. package/dist/base/src/utils/runtime.d.ts +10 -0
  39. package/dist/base/src/utils/runtime.d.ts.map +1 -0
  40. package/dist/base/src/utils/stdout-printer.d.ts +5 -0
  41. package/dist/base/src/utils/stdout-printer.d.ts.map +1 -1
  42. package/dist/base/tsconfig.base.tsbuildinfo +1 -1
  43. package/dist/base/tsconfig.tsbuildinfo +1 -0
  44. package/dist/ink/src/adapters/ink/components/file/file_log.d.ts +28 -0
  45. package/dist/ink/src/adapters/ink/components/file/file_log.d.ts.map +1 -0
  46. package/dist/ink/src/adapters/ink/components/file/index.d.ts +2 -0
  47. package/dist/ink/src/adapters/ink/components/file/index.d.ts.map +1 -0
  48. package/dist/ink/src/adapters/ink/components/filter/filter_bar.d.ts +7 -0
  49. package/dist/ink/src/adapters/ink/components/filter/filter_bar.d.ts.map +1 -0
  50. package/dist/ink/src/adapters/ink/components/filter/index.d.ts +2 -0
  51. package/dist/ink/src/adapters/ink/components/filter/index.d.ts.map +1 -0
  52. package/dist/ink/src/adapters/ink/components/help/help_overlay.d.ts +6 -0
  53. package/dist/ink/src/adapters/ink/components/help/help_overlay.d.ts.map +1 -0
  54. package/dist/ink/src/adapters/ink/components/help/index.d.ts +2 -0
  55. package/dist/ink/src/adapters/ink/components/help/index.d.ts.map +1 -0
  56. package/dist/ink/src/adapters/ink/components/index.d.ts +9 -0
  57. package/dist/ink/src/adapters/ink/components/index.d.ts.map +1 -0
  58. package/dist/ink/src/adapters/ink/components/log/index.d.ts +2 -0
  59. package/dist/ink/src/adapters/ink/components/log/index.d.ts.map +1 -0
  60. package/dist/ink/src/adapters/ink/components/log/log_message.d.ts +15 -0
  61. package/dist/ink/src/adapters/ink/components/log/log_message.d.ts.map +1 -0
  62. package/dist/ink/src/adapters/ink/components/prompt/index.d.ts +2 -0
  63. package/dist/ink/src/adapters/ink/components/prompt/index.d.ts.map +1 -0
  64. package/dist/ink/src/adapters/ink/components/prompt/prompt_renderer.d.ts +6 -0
  65. package/dist/ink/src/adapters/ink/components/prompt/prompt_renderer.d.ts.map +1 -0
  66. package/dist/ink/src/adapters/ink/components/screen/group_renderer.d.ts +14 -0
  67. package/dist/ink/src/adapters/ink/components/screen/group_renderer.d.ts.map +1 -0
  68. package/dist/ink/src/adapters/ink/components/screen/index.d.ts +7 -0
  69. package/dist/ink/src/adapters/ink/components/screen/index.d.ts.map +1 -0
  70. package/dist/ink/src/adapters/ink/components/screen/loading_message.d.ts +6 -0
  71. package/dist/ink/src/adapters/ink/components/screen/loading_message.d.ts.map +1 -0
  72. package/dist/ink/src/adapters/ink/components/screen/message_renderer.d.ts +6 -0
  73. package/dist/ink/src/adapters/ink/components/screen/message_renderer.d.ts.map +1 -0
  74. package/dist/ink/src/adapters/ink/components/screen/progress_message.d.ts +6 -0
  75. package/dist/ink/src/adapters/ink/components/screen/progress_message.d.ts.map +1 -0
  76. package/dist/ink/src/adapters/ink/components/screen/screen_bridge.d.ts +14 -0
  77. package/dist/ink/src/adapters/ink/components/screen/screen_bridge.d.ts.map +1 -0
  78. package/dist/ink/src/adapters/ink/components/screen/table_message.d.ts +6 -0
  79. package/dist/ink/src/adapters/ink/components/screen/table_message.d.ts.map +1 -0
  80. package/dist/ink/src/adapters/ink/components/screen_manager_bridge.d.ts +8 -0
  81. package/dist/ink/src/adapters/ink/components/screen_manager_bridge.d.ts.map +1 -0
  82. package/dist/ink/src/adapters/ink/components/sidebar/index.d.ts +4 -0
  83. package/dist/ink/src/adapters/ink/components/sidebar/index.d.ts.map +1 -0
  84. package/dist/ink/src/adapters/ink/components/sidebar/sidebar.d.ts +11 -0
  85. package/dist/ink/src/adapters/ink/components/sidebar/sidebar.d.ts.map +1 -0
  86. package/dist/ink/src/adapters/ink/components/sidebar/sidebar_item.d.ts +9 -0
  87. package/dist/ink/src/adapters/ink/components/sidebar/sidebar_item.d.ts.map +1 -0
  88. package/dist/ink/src/adapters/ink/components/sidebar/sidebar_separator.d.ts +2 -0
  89. package/dist/ink/src/adapters/ink/components/sidebar/sidebar_separator.d.ts.map +1 -0
  90. package/dist/ink/src/adapters/ink/context/index.d.ts +2 -0
  91. package/dist/ink/src/adapters/ink/context/index.d.ts.map +1 -0
  92. package/dist/ink/src/adapters/ink/context/logger_context.d.ts +33 -0
  93. package/dist/ink/src/adapters/ink/context/logger_context.d.ts.map +1 -0
  94. package/dist/ink/src/adapters/ink/hooks/index.d.ts +2 -0
  95. package/dist/ink/src/adapters/ink/hooks/index.d.ts.map +1 -0
  96. package/dist/ink/src/adapters/ink/hooks/use_theme.d.ts +7 -0
  97. package/dist/ink/src/adapters/ink/hooks/use_theme.d.ts.map +1 -0
  98. package/dist/ink/src/adapters/ink/index.d.ts +18 -0
  99. package/dist/ink/src/adapters/ink/index.d.ts.map +1 -0
  100. package/dist/ink/src/adapters/react-shared/hooks/index.d.ts +4 -0
  101. package/dist/ink/src/adapters/react-shared/hooks/index.d.ts.map +1 -0
  102. package/dist/ink/src/adapters/react-shared/hooks/use_filter_state.d.ts +18 -0
  103. package/dist/ink/src/adapters/react-shared/hooks/use_filter_state.d.ts.map +1 -0
  104. package/dist/ink/src/adapters/react-shared/hooks/use_keyboard_manager.d.ts +26 -0
  105. package/dist/ink/src/adapters/react-shared/hooks/use_keyboard_manager.d.ts.map +1 -0
  106. package/dist/ink/src/adapters/react-shared/hooks/use_manager_subscription.d.ts +7 -0
  107. package/dist/ink/src/adapters/react-shared/hooks/use_manager_subscription.d.ts.map +1 -0
  108. package/dist/ink/src/adapters/react-shared/index.d.ts +2 -0
  109. package/dist/ink/src/adapters/react-shared/index.d.ts.map +1 -0
  110. package/dist/ink/tsconfig.ink.tsbuildinfo +1 -0
  111. package/dist/react/src/adapters/react-shared/hooks/index.d.ts +4 -0
  112. package/dist/react/src/adapters/react-shared/hooks/index.d.ts.map +1 -0
  113. package/dist/react/src/adapters/react-shared/hooks/use_filter_state.d.ts +18 -0
  114. package/dist/react/src/adapters/react-shared/hooks/use_filter_state.d.ts.map +1 -0
  115. package/dist/react/src/adapters/react-shared/hooks/use_keyboard_manager.d.ts +26 -0
  116. package/dist/react/src/adapters/react-shared/hooks/use_keyboard_manager.d.ts.map +1 -0
  117. package/dist/react/src/adapters/react-shared/hooks/use_manager_subscription.d.ts +7 -0
  118. package/dist/react/src/adapters/react-shared/hooks/use_manager_subscription.d.ts.map +1 -0
  119. package/dist/react/src/adapters/react-shared/index.d.ts +2 -0
  120. package/dist/react/src/adapters/react-shared/index.d.ts.map +1 -0
  121. package/dist/react/tsconfig.react.tsbuildinfo +1 -1
  122. package/dist/solid/tsconfig.solid.tsbuildinfo +1 -1
  123. package/lib/index.cjs +2177 -178
  124. package/lib/index.cjs.map +1 -1
  125. package/lib/index.d.cts +942 -78
  126. package/lib/index.d.cts.map +1 -0
  127. package/lib/index.d.mts +902 -38
  128. package/lib/index.d.mts.map +1 -0
  129. package/lib/index.mjs +2098 -135
  130. package/lib/index.mjs.map +1 -1
  131. package/package.json +1 -31
  132. package/src/__tests__/services/logger.spec.ts +32 -0
  133. package/src/__tests__/services/screen.spec.ts +106 -95
  134. package/src/__tests__/utils/factories.ts +2 -0
  135. package/src/adapters/interface.ts +10 -2
  136. package/src/overrides/missing-adapter.override.ts +16 -6
  137. package/src/services/index.ts +1 -0
  138. package/src/services/logger.ts +7 -1
  139. package/src/services/readline_prompt.ts +194 -0
  140. package/src/services/screen.ts +106 -54
  141. package/src/services/screen_manager.ts +282 -74
  142. package/src/types/events.types.ts +84 -0
  143. package/src/types/index.ts +3 -0
  144. package/src/types/screen.types.ts +34 -0
  145. package/src/utils/colors/helpers.ts +0 -25
  146. package/src/utils/index.ts +6 -0
  147. package/src/utils/prompt.ts +18 -0
  148. package/src/utils/runtime.ts +14 -0
  149. package/src/utils/stdout-printer.ts +16 -5
  150. package/tsconfig.base.json +1 -17
  151. package/tsconfig.json +1 -6
  152. package/tsdown.config.mts +13 -70
  153. package/lib/adapters/react/index.cjs +0 -1768
  154. package/lib/adapters/react/index.cjs.map +0 -1
  155. package/lib/adapters/react/index.d.cts +0 -80
  156. package/lib/adapters/react/index.d.mts +0 -80
  157. package/lib/adapters/react/index.mjs +0 -1760
  158. package/lib/adapters/react/index.mjs.map +0 -1
  159. package/lib/adapters/solid/index.cjs +0 -3855
  160. package/lib/adapters/solid/index.cjs.map +0 -1
  161. package/lib/adapters/solid/index.d.cts +0 -74
  162. package/lib/adapters/solid/index.d.mts +0 -74
  163. package/lib/adapters/solid/index.mjs +0 -3847
  164. package/lib/adapters/solid/index.mjs.map +0 -1
  165. package/lib/filter_engine-DXqu9Vaq.cjs +0 -1836
  166. package/lib/filter_engine-DXqu9Vaq.cjs.map +0 -1
  167. package/lib/filter_engine-DmqhEhpA.mjs +0 -1609
  168. package/lib/filter_engine-DmqhEhpA.mjs.map +0 -1
  169. package/lib/interface-CTHQ08aY.d.mts +0 -699
  170. package/lib/interface-DQEIz9Mb.d.cts +0 -699
  171. package/src/__tests__/components/__snapshots__/filter_bar.spec.tsx.snap +0 -2293
  172. package/src/__tests__/components/__snapshots__/loading_message.spec.tsx.snap +0 -1414
  173. package/src/__tests__/components/__snapshots__/log_message.spec.tsx.snap +0 -3245
  174. package/src/__tests__/components/__snapshots__/progress_message.spec.tsx.snap +0 -1783
  175. package/src/__tests__/components/__snapshots__/prompt_renderer.spec.tsx.snap +0 -3203
  176. package/src/__tests__/components/__snapshots__/sidebar.spec.tsx.snap +0 -2857
  177. package/src/__tests__/components/filter_bar.spec.tsx +0 -190
  178. package/src/__tests__/components/loading_message.spec.tsx +0 -110
  179. package/src/__tests__/components/log_message.spec.tsx +0 -166
  180. package/src/__tests__/components/progress_message.spec.tsx +0 -147
  181. package/src/__tests__/components/prompt_renderer.spec.tsx +0 -274
  182. package/src/__tests__/components/sidebar.spec.tsx +0 -322
  183. package/src/__tests__/utils/render-utils.tsx +0 -39
  184. package/src/adapters/react/components/file/file_log.tsx +0 -241
  185. package/src/adapters/react/components/file/index.ts +0 -1
  186. package/src/adapters/react/components/filter/filter_bar.tsx +0 -79
  187. package/src/adapters/react/components/filter/index.ts +0 -1
  188. package/src/adapters/react/components/help/help_overlay.tsx +0 -100
  189. package/src/adapters/react/components/help/index.ts +0 -1
  190. package/src/adapters/react/components/log/index.ts +0 -1
  191. package/src/adapters/react/components/log/log_message.tsx +0 -102
  192. package/src/adapters/react/components/prompt/index.ts +0 -2
  193. package/src/adapters/react/components/prompt/prompt_renderer.tsx +0 -346
  194. package/src/adapters/react/components/screen/group_renderer.tsx +0 -64
  195. package/src/adapters/react/components/screen/index.ts +0 -6
  196. package/src/adapters/react/components/screen/loading_message.tsx +0 -43
  197. package/src/adapters/react/components/screen/message_renderer.tsx +0 -108
  198. package/src/adapters/react/components/screen/progress_message.tsx +0 -60
  199. package/src/adapters/react/components/screen/screen_bridge.tsx +0 -149
  200. package/src/adapters/react/components/screen/table_message.tsx +0 -57
  201. package/src/adapters/react/components/screen_manager_bridge.tsx +0 -245
  202. package/src/adapters/react/components/sidebar/index.ts +0 -3
  203. package/src/adapters/react/components/sidebar/sidebar.tsx +0 -102
  204. package/src/adapters/react/components/sidebar/sidebar_item.tsx +0 -50
  205. package/src/adapters/react/components/sidebar/sidebar_separator.tsx +0 -13
  206. package/src/adapters/react/context/index.ts +0 -1
  207. package/src/adapters/react/context/logger_context.tsx +0 -109
  208. package/src/adapters/react/hooks/index.ts +0 -1
  209. package/src/adapters/react/hooks/use_theme.ts +0 -12
  210. package/src/adapters/react/index.ts +0 -39
  211. package/src/adapters/solid/components/file/file_log.tsx +0 -221
  212. package/src/adapters/solid/components/file/index.ts +0 -1
  213. package/src/adapters/solid/components/filter/filter_bar.tsx +0 -84
  214. package/src/adapters/solid/components/filter/index.ts +0 -1
  215. package/src/adapters/solid/components/help/help_overlay.tsx +0 -106
  216. package/src/adapters/solid/components/help/index.ts +0 -1
  217. package/src/adapters/solid/components/log/index.ts +0 -1
  218. package/src/adapters/solid/components/log/log_message.tsx +0 -92
  219. package/src/adapters/solid/components/prompt/index.ts +0 -2
  220. package/src/adapters/solid/components/prompt/prompt_renderer.tsx +0 -350
  221. package/src/adapters/solid/components/screen/group_renderer.tsx +0 -61
  222. package/src/adapters/solid/components/screen/index.ts +0 -6
  223. package/src/adapters/solid/components/screen/loading_message.tsx +0 -39
  224. package/src/adapters/solid/components/screen/message_renderer.tsx +0 -122
  225. package/src/adapters/solid/components/screen/progress_message.tsx +0 -61
  226. package/src/adapters/solid/components/screen/screen_bridge.tsx +0 -155
  227. package/src/adapters/solid/components/screen/table_message.tsx +0 -58
  228. package/src/adapters/solid/components/screen_manager_bridge.tsx +0 -243
  229. package/src/adapters/solid/components/sidebar/index.ts +0 -3
  230. package/src/adapters/solid/components/sidebar/sidebar.tsx +0 -108
  231. package/src/adapters/solid/components/sidebar/sidebar_item.tsx +0 -55
  232. package/src/adapters/solid/components/sidebar/sidebar_separator.tsx +0 -13
  233. package/src/adapters/solid/context/index.ts +0 -2
  234. package/src/adapters/solid/context/logger_context.tsx +0 -95
  235. package/src/adapters/solid/hooks/index.ts +0 -1
  236. package/src/adapters/solid/hooks/use_theme.ts +0 -12
  237. package/src/adapters/solid/index.tsx +0 -43
  238. package/src/adapters/solid/jsx.d.ts +0 -98
  239. package/tsconfig.react.json +0 -16
  240. package/tsconfig.solid.json +0 -16
package/lib/index.cjs CHANGED
@@ -1,7 +1,589 @@
1
- const require_filter_engine = require('./filter_engine-DXqu9Vaq.cjs');
2
- let _opentui_core = require("@opentui/core");
1
+ //#region rolldown:runtime
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __copyProps = (to, from, except, desc) => {
9
+ if (from && typeof from === "object" || typeof from === "function") {
10
+ for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
11
+ key = keys[i];
12
+ if (!__hasOwnProp.call(to, key) && key !== except) {
13
+ __defProp(to, key, {
14
+ get: ((k) => from[k]).bind(null, key),
15
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
16
+ });
17
+ }
18
+ }
19
+ }
20
+ return to;
21
+ };
22
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
23
+ value: mod,
24
+ enumerable: true
25
+ }) : target, mod));
26
+
27
+ //#endregion
3
28
  let _navios_core = require("@navios/core");
29
+ let node_events = require("node:events");
30
+ let node_readline = require("node:readline");
31
+ node_readline = __toESM(node_readline);
32
+
33
+ //#region src/types/screen.types.ts
34
+ /**
35
+ * Render mode determines how the TUI operates.
36
+ * This is set during bind() and affects prompts, screen printing, and exit behavior.
37
+ */ var RenderMode = /* @__PURE__ */ function(RenderMode$1) {
38
+ /** bind() never called - screens print on completion, prompts return defaults */ RenderMode$1["UNBOUND"] = "unbound";
39
+ /** bind() called with useOpenTUI: false - stdout mode with readline prompts */ RenderMode$1["STDOUT_INTERACTIVE"] = "stdout";
40
+ /** bind() called with useOpenTUI: true but adapter unavailable - fallback to stdout with warning */ RenderMode$1["STDOUT_FALLBACK"] = "fallback";
41
+ /** Full TUI rendering active with adapter */ RenderMode$1["TUI_ACTIVE"] = "tui";
42
+ return RenderMode$1;
43
+ }({});
44
+
45
+ //#endregion
46
+ //#region src/types/filter.types.ts
47
+ /**
48
+ * All log levels in order.
49
+ */ const ALL_LOG_LEVELS = [
50
+ "verbose",
51
+ "debug",
52
+ "log",
53
+ "warn",
54
+ "error",
55
+ "fatal"
56
+ ];
57
+ /**
58
+ * Create a default filter state.
59
+ */ function createDefaultFilterState() {
60
+ return {
61
+ enabledLevels: new Set(ALL_LOG_LEVELS),
62
+ searchQuery: "",
63
+ isVisible: false,
64
+ focusedField: "search"
65
+ };
66
+ }
67
+ /**
68
+ * Check if any filtering is active.
69
+ */ function hasActiveFilter(filter) {
70
+ return filter.searchQuery !== "" || filter.enabledLevels.size < ALL_LOG_LEVELS.length;
71
+ }
72
+
73
+ //#endregion
74
+ //#region src/types/events.types.ts
75
+ /**
76
+ * All manager events that adapters typically subscribe to for re-renders.
77
+ */ const MANAGER_EVENTS = [
78
+ "screen:added",
79
+ "screen:removed",
80
+ "screen:reordered",
81
+ "activeScreen:changed",
82
+ "focus:changed",
83
+ "sidebar:indexChanged",
84
+ "mode:changed"
85
+ ];
86
+ /**
87
+ * All screen events that adapters typically subscribe to for re-renders.
88
+ */ const SCREEN_EVENTS = [
89
+ "message:added",
90
+ "message:updated",
91
+ "messages:cleared",
92
+ "status:changed",
93
+ "visibility:changed",
94
+ "badge:changed",
95
+ "prompt:activated",
96
+ "prompt:updated",
97
+ "prompt:resolved"
98
+ ];
99
+ /**
100
+ * Sidebar-specific events that require re-render.
101
+ */ const SIDEBAR_EVENTS = [
102
+ "screen:added",
103
+ "screen:removed",
104
+ "screen:reordered",
105
+ "sidebar:indexChanged",
106
+ "focus:changed",
107
+ "activeScreen:changed"
108
+ ];
109
+ /**
110
+ * Content area events that affect active screen changes.
111
+ */ const CONTENT_MANAGER_EVENTS = ["activeScreen:changed", "focus:changed"];
112
+
113
+ //#endregion
114
+ //#region src/utils/colors/log-colors.ts
115
+ /**
116
+ * Default color scheme for all log levels.
117
+ * Each level has a prominent border color and a subtle background tint.
118
+ */ const DEFAULT_LOG_LEVEL_COLORS = {
119
+ verbose: {
120
+ border: "#6B7280",
121
+ background: "#6B728015"
122
+ },
123
+ debug: {
124
+ border: "#8B5CF6",
125
+ background: "#8B5CF615"
126
+ },
127
+ log: {
128
+ border: "#3B82F6",
129
+ background: "#3B82F615"
130
+ },
131
+ warn: {
132
+ border: "#F59E0B",
133
+ background: "#F59E0B15"
134
+ },
135
+ error: {
136
+ border: "#EF4444",
137
+ background: "#EF444415"
138
+ },
139
+ fatal: {
140
+ border: "#DC2626",
141
+ background: "#DC262625",
142
+ text: "#FCA5A5"
143
+ }
144
+ };
145
+ /**
146
+ * Colors for semantic variants (override level colors when variant is set).
147
+ */ const VARIANT_COLORS = {
148
+ success: {
149
+ border: "#22C55E",
150
+ background: "#22C55E15"
151
+ },
152
+ trace: {
153
+ border: "#6B7280",
154
+ background: "#6B728015"
155
+ }
156
+ };
157
+ /**
158
+ * Error highlighting colors.
159
+ */ const ERROR_HIGHLIGHT_COLORS = {
160
+ background: "#EF444425",
161
+ border: "#EF4444",
162
+ gutterBackground: "#EF444440"
163
+ };
164
+
165
+ //#endregion
166
+ //#region src/utils/colors/sidebar-colors.ts
167
+ /**
168
+ * Sidebar colors.
169
+ */ const SIDEBAR_COLORS = {
170
+ background: void 0,
171
+ selectedBackground: "#1F293780",
172
+ hoverBackground: "#374151",
173
+ text: "#E5E7EB",
174
+ textDim: "#6B7280",
175
+ border: "#374151",
176
+ badge: "#3B82F6",
177
+ focusBorder: "#3B82F6"
178
+ };
179
+ /**
180
+ * Screen header colors.
181
+ */ const HEADER_COLORS = {
182
+ background: void 0,
183
+ text: "#F9FAFB",
184
+ border: "#374151"
185
+ };
186
+ /**
187
+ * Screen status indicator colors and icons.
188
+ */ const STATUS_INDICATORS = {
189
+ waiting: {
190
+ icon: "○",
191
+ color: "#6B7280"
192
+ },
193
+ pending: {
194
+ icon: "◐",
195
+ color: "#F59E0B"
196
+ },
197
+ success: {
198
+ icon: "✓",
199
+ color: "#22C55E"
200
+ },
201
+ fail: {
202
+ icon: "✗",
203
+ color: "#EF4444"
204
+ }
205
+ };
206
+ /**
207
+ * Separator colors for sidebar sections.
208
+ */ const SEPARATOR_COLORS = {
209
+ line: "#374151",
210
+ text: "#6B7280"
211
+ };
212
+
213
+ //#endregion
214
+ //#region src/utils/colors/progress-colors.ts
215
+ /**
216
+ * Progress bar colors.
217
+ */ const PROGRESS_COLORS = {
218
+ border: "#3B82F6",
219
+ background: "#3B82F615",
220
+ barFilled: "#3B82F6",
221
+ barEmpty: "#374151",
222
+ text: "#E5E7EB",
223
+ textDim: "#9CA3AF",
224
+ complete: "#22C55E",
225
+ completeBackground: "#22C55E15",
226
+ failed: "#EF4444",
227
+ failedBackground: "#EF444415"
228
+ };
229
+ /**
230
+ * Group colors for collapsible log groups.
231
+ */ const GROUP_COLORS = {
232
+ border: "#6B7280",
233
+ background: "#6B728010",
234
+ headerText: "#E5E7EB",
235
+ icon: "#9CA3AF"
236
+ };
237
+
238
+ //#endregion
239
+ //#region src/utils/colors/table-colors.ts
240
+ /**
241
+ * Table colors (uses info/blue scheme).
242
+ */ const TABLE_COLORS = {
243
+ border: "#3B82F6",
244
+ background: "#3B82F615",
245
+ headerText: "#F9FAFB",
246
+ cellText: "#E5E7EB",
247
+ title: "#F9FAFB",
248
+ separator: "#3B82F650"
249
+ };
250
+
251
+ //#endregion
252
+ //#region src/utils/colors/file-colors.ts
253
+ /**
254
+ * File display colors (uses info/blue scheme).
255
+ */ const FILE_COLORS = {
256
+ border: "#3B82F6",
257
+ background: "#3B82F615",
258
+ headerText: "#F9FAFB",
259
+ headerBackground: "#3B82F625"
260
+ };
261
+
262
+ //#endregion
263
+ //#region src/utils/colors/prompt-colors.ts
264
+ /**
265
+ * Prompt colors for interactive prompts.
266
+ */ const PROMPT_COLORS = {
267
+ question: "#F9FAFB",
268
+ optionText: "#E5E7EB",
269
+ optionTextDim: "#9CA3AF",
270
+ optionSelected: "#3B82F6",
271
+ optionSelectedBackground: "#1E3A5F",
272
+ confirmButton: "#22C55E",
273
+ cancelButton: "#EF4444",
274
+ buttonBackground: "#374151",
275
+ buttonSelectedBackground: "#1F2937",
276
+ inputBorder: "#3B82F6",
277
+ inputBackground: "#1F2937",
278
+ inputText: "#F9FAFB",
279
+ inputPlaceholder: "#6B7280",
280
+ inputCursor: "#3B82F6",
281
+ border: "#374151",
282
+ focusBorder: "#3B82F6"
283
+ };
4
284
 
285
+ //#endregion
286
+ //#region src/utils/colors/helpers.ts
287
+ /**
288
+ * Gets colors for a specific log level.
289
+ *
290
+ * @param level - The log level
291
+ * @param customColors - Optional custom color map
292
+ */ function getLogLevelColors(level, customColors) {
293
+ const defaultColors = DEFAULT_LOG_LEVEL_COLORS[level];
294
+ const custom = customColors?.[level];
295
+ return {
296
+ border: custom?.border ?? defaultColors.border,
297
+ background: custom?.background ?? defaultColors.background,
298
+ text: custom?.text ?? defaultColors.text
299
+ };
300
+ }
301
+
302
+ //#endregion
303
+ //#region src/utils/filetype.ts
304
+ /**
305
+ * Common file extension to filetype mapping for syntax highlighting.
306
+ */ const COMMON_FILETYPES = {
307
+ ts: "typescript",
308
+ tsx: "tsx",
309
+ js: "javascript",
310
+ jsx: "javascript",
311
+ json: "json",
312
+ md: "markdown",
313
+ py: "python",
314
+ rs: "rust",
315
+ go: "go",
316
+ java: "java",
317
+ c: "c",
318
+ cpp: "cpp",
319
+ h: "c",
320
+ hpp: "cpp",
321
+ css: "css",
322
+ html: "html",
323
+ yaml: "yaml",
324
+ yml: "yaml",
325
+ sh: "bash",
326
+ bash: "bash",
327
+ zsh: "bash",
328
+ toml: "toml",
329
+ xml: "xml",
330
+ sql: "sql",
331
+ rb: "ruby",
332
+ php: "php",
333
+ swift: "swift",
334
+ kt: "kotlin",
335
+ scala: "scala",
336
+ hs: "haskell",
337
+ elm: "elm",
338
+ vue: "vue",
339
+ svelte: "svelte"
340
+ };
341
+ /**
342
+ * Resolves filetype from file path for syntax highlighting.
343
+ *
344
+ * @param filePath - Full file path or just filename
345
+ * @returns Filetype string for tree-sitter, or undefined
346
+ */ function resolveFiletype(filePath) {
347
+ const lastDot = filePath.lastIndexOf(".");
348
+ if (lastDot === -1) return void 0;
349
+ return COMMON_FILETYPES[filePath.slice(lastDot + 1).toLowerCase()];
350
+ }
351
+ /**
352
+ * Gets the filename from a full path.
353
+ *
354
+ * @param filePath - Full file path
355
+ * @returns Just the filename
356
+ */ function getFileName(filePath) {
357
+ const lastSlash = Math.max(filePath.lastIndexOf("/"), filePath.lastIndexOf("\\"));
358
+ return lastSlash === -1 ? filePath : filePath.slice(lastSlash + 1);
359
+ }
360
+
361
+ //#endregion
362
+ //#region src/utils/stdout-printer.ts
363
+ const RESET = "\x1B[0m";
364
+ const BOLD = "\x1B[1m";
365
+ const DIM = "\x1B[2m";
366
+ function hexToAnsi(hex, isForeground = true) {
367
+ const cleanHex = hex.replace("#", "").slice(0, 6);
368
+ if (!/^[0-9A-Fa-f]{6}$/.test(cleanHex)) return "";
369
+ const r = parseInt(cleanHex.slice(0, 2), 16);
370
+ const g = parseInt(cleanHex.slice(2, 4), 16);
371
+ const b = parseInt(cleanHex.slice(4, 6), 16);
372
+ return `\x1b[${isForeground ? 38 : 48};2;${r};${g};${b}m`;
373
+ }
374
+ function getLogLevelAnsiColor(level, variant) {
375
+ return hexToAnsi((variant ? VARIANT_COLORS[variant] : DEFAULT_LOG_LEVEL_COLORS[level]).border, true);
376
+ }
377
+ function formatLevel(level, variant) {
378
+ return `${getLogLevelAnsiColor(level, variant)}${BOLD}[${(variant ?? level).toUpperCase().padEnd(7)}]${RESET}`;
379
+ }
380
+ function formatTimestamp(date$2) {
381
+ return `${DIM}${date$2.toLocaleTimeString()}${RESET}`;
382
+ }
383
+ function printMessage(message, stream) {
384
+ switch (message.type) {
385
+ case "log": {
386
+ const logMessage = message;
387
+ const timestamp = formatTimestamp(message.timestamp);
388
+ const level = formatLevel(logMessage.level, logMessage.variant);
389
+ const label = logMessage.label ? ` ${DIM}[${logMessage.label}]${RESET}` : "";
390
+ stream.write(`${timestamp} ${level}${label} ${logMessage.content}\n`);
391
+ break;
392
+ }
393
+ case "file": {
394
+ const header = `${DIM}─── ${message.filePath} ───${RESET}`;
395
+ stream.write(`${header}\n${message.content}\n`);
396
+ break;
397
+ }
398
+ case "diff": {
399
+ const header = `${DIM}─── ${message.filePath} (diff) ───${RESET}`;
400
+ const coloredDiff = message.diff.split("\n").map((line) => {
401
+ if (line.startsWith("+") && !line.startsWith("+++")) return `\x1b[32m${line}${RESET}`;
402
+ else if (line.startsWith("-") && !line.startsWith("---")) return `\x1b[31m${line}${RESET}`;
403
+ else if (line.startsWith("@@")) return `\x1b[36m${line}${RESET}`;
404
+ return line;
405
+ }).join("\n");
406
+ stream.write(`${header}\n${coloredDiff}\n`);
407
+ break;
408
+ }
409
+ case "fileError": {
410
+ const header = `${DIM}─── ${message.filePath} ───${RESET}`;
411
+ const errorLineSet = new Set(message.errorLines);
412
+ const startLine = message.startLine ?? 1;
413
+ const numberedLines = message.content.split("\n").map((line, index) => {
414
+ const lineNum = startLine + index;
415
+ const numStr = String(lineNum).padStart(4);
416
+ if (errorLineSet.has(lineNum)) return `\x1b[31m${numStr} │ ${line}${RESET}`;
417
+ return `${DIM}${numStr}${RESET} │ ${line}`;
418
+ });
419
+ stream.write(`${header}\n${numberedLines.join("\n")}\n`);
420
+ break;
421
+ }
422
+ case "loading": {
423
+ const loadingMessage = message;
424
+ const status = loadingMessage.status;
425
+ const content = loadingMessage.resolvedContent ?? loadingMessage.content;
426
+ let level = "log";
427
+ let variant;
428
+ if (status === "success") {
429
+ level = "log";
430
+ variant = "success";
431
+ } else if (status === "fail") level = "error";
432
+ const timestamp = formatTimestamp(message.timestamp);
433
+ const levelStr = formatLevel(level, variant);
434
+ const prefix = status === "loading" ? "... " : "";
435
+ stream.write(`${timestamp} ${levelStr} ${prefix}${content}\n`);
436
+ break;
437
+ }
438
+ case "progress": {
439
+ const { label, current, total, status, resolvedContent } = message;
440
+ const percentage = total > 0 ? Math.round(current / total * 100) : 0;
441
+ const barWidth = 20;
442
+ const filledWidth = Math.round(percentage / 100 * barWidth);
443
+ const emptyWidth = barWidth - filledWidth;
444
+ const progressColor = hexToAnsi(PROGRESS_COLORS.barFilled);
445
+ const emptyColor = hexToAnsi(PROGRESS_COLORS.barEmpty);
446
+ const filledBar = "█".repeat(filledWidth);
447
+ const emptyBar = "░".repeat(emptyWidth);
448
+ let statusIcon = "";
449
+ let statusColor = "";
450
+ if (status === "complete") {
451
+ statusIcon = "✓";
452
+ statusColor = hexToAnsi(PROGRESS_COLORS.complete);
453
+ } else if (status === "failed") {
454
+ statusIcon = "✗";
455
+ statusColor = hexToAnsi(PROGRESS_COLORS.failed);
456
+ }
457
+ const displayLabel = resolvedContent ?? label;
458
+ const progressBar = `${progressColor}${filledBar}${RESET}${emptyColor}${emptyBar}${RESET}`;
459
+ const percentStr = `${String(percentage).padStart(3)}%`;
460
+ if (statusIcon) stream.write(`${statusColor}${statusIcon}${RESET} ${displayLabel} [${progressBar}] ${percentStr}\n`);
461
+ else stream.write(` ${displayLabel} [${progressBar}] ${percentStr} (${current}/${total})\n`);
462
+ break;
463
+ }
464
+ case "group": {
465
+ const { label, collapsed, isEnd } = message;
466
+ const groupColor = hexToAnsi(GROUP_COLORS.border);
467
+ const iconColor = hexToAnsi(GROUP_COLORS.icon);
468
+ if (isEnd) stream.write(`${groupColor}└─${RESET} ${DIM}end ${label}${RESET}\n`);
469
+ else {
470
+ const icon = collapsed ? "▶" : "▼";
471
+ stream.write(`${groupColor}┌─${RESET} ${iconColor}${icon}${RESET} ${BOLD}${label}${RESET}\n`);
472
+ }
473
+ break;
474
+ }
475
+ case "table": {
476
+ const { headers, rows, title } = message;
477
+ const tableColor = hexToAnsi(TABLE_COLORS.border);
478
+ const headerColor = hexToAnsi(TABLE_COLORS.headerText);
479
+ const cellColor = hexToAnsi(TABLE_COLORS.cellText);
480
+ const colWidths = headers.map((h, i) => {
481
+ const maxRowWidth = rows.reduce((max, row) => Math.max(max, (row[i] ?? "").length), 0);
482
+ return Math.max(h.length, maxRowWidth);
483
+ });
484
+ const separator = `${tableColor}├${colWidths.map((w) => "─".repeat(w + 2)).join("┼")}┤${RESET}`;
485
+ const topBorder = `${tableColor}┌${colWidths.map((w) => "─".repeat(w + 2)).join("┬")}┐${RESET}`;
486
+ const bottomBorder = `${tableColor}└${colWidths.map((w) => "─".repeat(w + 2)).join("┴")}┘${RESET}`;
487
+ if (title) stream.write(`${BOLD}${title}${RESET}\n`);
488
+ stream.write(`${topBorder}\n`);
489
+ const headerRow = headers.map((h, i) => ` ${h.padEnd(colWidths[i])} `).join(`${tableColor}│${RESET}`);
490
+ stream.write(`${tableColor}│${RESET}${headerColor}${headerRow}${RESET}${tableColor}│${RESET}\n`);
491
+ stream.write(`${separator}\n`);
492
+ for (const row of rows) {
493
+ const rowStr = headers.map((_, i) => ` ${(row[i] ?? "").padEnd(colWidths[i])} `).join(`${tableColor}│${RESET}`);
494
+ stream.write(`${tableColor}│${RESET}${cellColor}${rowStr}${RESET}${tableColor}│${RESET}\n`);
495
+ }
496
+ stream.write(`${bottomBorder}\n`);
497
+ break;
498
+ }
499
+ }
500
+ }
501
+ /**
502
+ * Print a single message to stdout with optional screen name prefix.
503
+ * Used for immediate output in stdout mode (when OpenTUI is not active).
504
+ */ function printSingleMessage(message, screenName, isError = false) {
505
+ const stream = isError ? process.stderr : process.stdout;
506
+ if (screenName) stream.write(`${DIM}[${screenName}]${RESET} `);
507
+ printMessage(message, stream);
508
+ }
509
+ /**
510
+ * Print all messages to stdout (or stderr if isError)
511
+ */ function printMessagesToStdout(messages, screenName, isError = false) {
512
+ const stream = isError ? process.stderr : process.stdout;
513
+ const headerColor = isError ? "\x1B[31m" : "\x1B[32m";
514
+ const status = isError ? "FAILED" : "COMPLETED";
515
+ stream.write(`\n${headerColor}${BOLD}═══ ${screenName} [${status}] ═══${RESET}\n\n`);
516
+ for (const message of messages) printMessage(message, stream);
517
+ stream.write("\n");
518
+ }
519
+
520
+ //#endregion
521
+ //#region src/utils/format.ts
522
+ /**
523
+ * Format an object for display with configurable depth
524
+ */ function formatObject(obj, depth = 2, currentDepth = 0) {
525
+ if (currentDepth >= depth) {
526
+ if (Array.isArray(obj)) return "[Array]";
527
+ if (typeof obj === "object" && obj !== null) return `[${obj.constructor?.name ?? "Object"}]`;
528
+ return String(obj);
529
+ }
530
+ if (obj === null) return "null";
531
+ if (obj === void 0) return "undefined";
532
+ if (typeof obj === "string") return `"${obj}"`;
533
+ if (typeof obj === "number" || typeof obj === "boolean") return String(obj);
534
+ if (typeof obj === "function") return "[Function]";
535
+ if (obj instanceof Date) return obj.toISOString();
536
+ if (obj instanceof Error) return `${obj.name}: ${obj.message}`;
537
+ const indent = " ".repeat(currentDepth);
538
+ const childIndent = " ".repeat(currentDepth + 1);
539
+ if (Array.isArray(obj)) {
540
+ if (obj.length === 0) return "[]";
541
+ return `[\n${childIndent}${obj.map((item) => formatObject(item, depth, currentDepth + 1)).join(`,\n${childIndent}`)}\n${indent}]`;
542
+ }
543
+ if (typeof obj === "object") {
544
+ const entries = Object.entries(obj);
545
+ if (entries.length === 0) return "{}";
546
+ return `{\n${childIndent}${entries.map(([key, value]) => `${key}: ${formatObject(value, depth, currentDepth + 1)}`).join(`,\n${childIndent}`)}\n${indent}}`;
547
+ }
548
+ return String(obj);
549
+ }
550
+ /**
551
+ * Capture a stack trace, filtering out internal frames
552
+ */ function captureTrace(offset = 0) {
553
+ const lines = ((/* @__PURE__ */ new Error()).stack ?? "").split("\n");
554
+ const begin = lines.findIndex((line) => line.includes("captureTrace"));
555
+ return lines.slice(begin !== -1 ? begin + 1 + offset : 4).join("\n");
556
+ }
557
+
558
+ //#endregion
559
+ //#region src/utils/runtime.ts
560
+ /**
561
+ * Detect if running in Bun environment (OpenTUI is not supported in Bun)
562
+ */ function isBunRuntime() {
563
+ return typeof globalThis.Bun !== "undefined";
564
+ }
565
+ /**
566
+ * Dynamic import that bypasses bundler static analysis.
567
+ * Uses Function constructor to prevent bundlers from resolving the import at build time.
568
+ */ function dynamicImport(modulePath) {
569
+ return new Function("modulePath", "return import(modulePath)")(modulePath);
570
+ }
571
+
572
+ //#endregion
573
+ //#region src/utils/prompt.ts
574
+ /**
575
+ * Get the default value for a prompt based on its type.
576
+ * Used for resolving prompts when no interaction is possible.
577
+ */ function getPromptDefaultValue(prompt) {
578
+ switch (prompt.type) {
579
+ case "choice": return prompt.defaultChoice;
580
+ case "confirm": return prompt.defaultValue;
581
+ case "input": return prompt.defaultValue;
582
+ case "multiChoice": return prompt.choices.filter((_, i) => prompt.selectedIndices.has(i)).map((c) => c.value);
583
+ }
584
+ }
585
+
586
+ //#endregion
5
587
  //#region ../../node_modules/zod/v4/core/core.js
6
588
  /** A special constant with type `never` */
7
589
  const NEVER = Object.freeze({ status: "aborted" });
@@ -2628,7 +3210,7 @@ function initializeContext(params) {
2628
3210
  external: params?.external ?? void 0
2629
3211
  };
2630
3212
  }
2631
- function process(schema, ctx, _params = {
3213
+ function process$1(schema, ctx, _params = {
2632
3214
  path: [],
2633
3215
  schemaPath: []
2634
3216
  }) {
@@ -2665,7 +3247,7 @@ function process(schema, ctx, _params = {
2665
3247
  const parent = schema._zod.parent;
2666
3248
  if (parent) {
2667
3249
  if (!result.ref) result.ref = parent;
2668
- process(parent, ctx, params);
3250
+ process$1(parent, ctx, params);
2669
3251
  ctx.seen.get(parent).isParent = true;
2670
3252
  }
2671
3253
  }
@@ -2877,7 +3459,7 @@ const createToJSONSchemaMethod = (schema, processors = {}) => (params) => {
2877
3459
  ...params,
2878
3460
  processors
2879
3461
  });
2880
- process(schema, ctx);
3462
+ process$1(schema, ctx);
2881
3463
  extractDefs(ctx, schema);
2882
3464
  return finalize(ctx, schema);
2883
3465
  };
@@ -2889,7 +3471,7 @@ const createStandardJSONSchemaMethod = (schema, io, processors = {}) => (params)
2889
3471
  io,
2890
3472
  processors
2891
3473
  });
2892
- process(schema, ctx);
3474
+ process$1(schema, ctx);
2893
3475
  extractDefs(ctx, schema);
2894
3476
  return finalize(ctx, schema);
2895
3477
  };
@@ -2976,7 +3558,7 @@ const arrayProcessor = (schema, ctx, _json, params) => {
2976
3558
  if (typeof minimum === "number") json.minItems = minimum;
2977
3559
  if (typeof maximum === "number") json.maxItems = maximum;
2978
3560
  json.type = "array";
2979
- json.items = process(def.element, ctx, {
3561
+ json.items = process$1(def.element, ctx, {
2980
3562
  ...params,
2981
3563
  path: [...params.path, "items"]
2982
3564
  });
@@ -2987,7 +3569,7 @@ const objectProcessor = (schema, ctx, _json, params) => {
2987
3569
  json.type = "object";
2988
3570
  json.properties = {};
2989
3571
  const shape = def.shape;
2990
- for (const key in shape) json.properties[key] = process(shape[key], ctx, {
3572
+ for (const key in shape) json.properties[key] = process$1(shape[key], ctx, {
2991
3573
  ...params,
2992
3574
  path: [
2993
3575
  ...params.path,
@@ -3005,7 +3587,7 @@ const objectProcessor = (schema, ctx, _json, params) => {
3005
3587
  if (def.catchall?._zod.def.type === "never") json.additionalProperties = false;
3006
3588
  else if (!def.catchall) {
3007
3589
  if (ctx.io === "output") json.additionalProperties = false;
3008
- } else if (def.catchall) json.additionalProperties = process(def.catchall, ctx, {
3590
+ } else if (def.catchall) json.additionalProperties = process$1(def.catchall, ctx, {
3009
3591
  ...params,
3010
3592
  path: [...params.path, "additionalProperties"]
3011
3593
  });
@@ -3013,7 +3595,7 @@ const objectProcessor = (schema, ctx, _json, params) => {
3013
3595
  const unionProcessor = (schema, ctx, json, params) => {
3014
3596
  const def = schema._zod.def;
3015
3597
  const isExclusive = def.inclusive === false;
3016
- const options = def.options.map((x, i) => process(x, ctx, {
3598
+ const options = def.options.map((x, i) => process$1(x, ctx, {
3017
3599
  ...params,
3018
3600
  path: [
3019
3601
  ...params.path,
@@ -3026,7 +3608,7 @@ const unionProcessor = (schema, ctx, json, params) => {
3026
3608
  };
3027
3609
  const intersectionProcessor = (schema, ctx, json, params) => {
3028
3610
  const def = schema._zod.def;
3029
- const a = process(def.left, ctx, {
3611
+ const a = process$1(def.left, ctx, {
3030
3612
  ...params,
3031
3613
  path: [
3032
3614
  ...params.path,
@@ -3034,7 +3616,7 @@ const intersectionProcessor = (schema, ctx, json, params) => {
3034
3616
  0
3035
3617
  ]
3036
3618
  });
3037
- const b = process(def.right, ctx, {
3619
+ const b = process$1(def.right, ctx, {
3038
3620
  ...params,
3039
3621
  path: [
3040
3622
  ...params.path,
@@ -3047,7 +3629,7 @@ const intersectionProcessor = (schema, ctx, json, params) => {
3047
3629
  };
3048
3630
  const nullableProcessor = (schema, ctx, json, params) => {
3049
3631
  const def = schema._zod.def;
3050
- const inner = process(def.innerType, ctx, params);
3632
+ const inner = process$1(def.innerType, ctx, params);
3051
3633
  const seen = ctx.seen.get(schema);
3052
3634
  if (ctx.target === "openapi-3.0") {
3053
3635
  seen.ref = def.innerType;
@@ -3056,27 +3638,27 @@ const nullableProcessor = (schema, ctx, json, params) => {
3056
3638
  };
3057
3639
  const nonoptionalProcessor = (schema, ctx, _json, params) => {
3058
3640
  const def = schema._zod.def;
3059
- process(def.innerType, ctx, params);
3641
+ process$1(def.innerType, ctx, params);
3060
3642
  const seen = ctx.seen.get(schema);
3061
3643
  seen.ref = def.innerType;
3062
3644
  };
3063
3645
  const defaultProcessor = (schema, ctx, json, params) => {
3064
3646
  const def = schema._zod.def;
3065
- process(def.innerType, ctx, params);
3647
+ process$1(def.innerType, ctx, params);
3066
3648
  const seen = ctx.seen.get(schema);
3067
3649
  seen.ref = def.innerType;
3068
3650
  json.default = JSON.parse(JSON.stringify(def.defaultValue));
3069
3651
  };
3070
3652
  const prefaultProcessor = (schema, ctx, json, params) => {
3071
3653
  const def = schema._zod.def;
3072
- process(def.innerType, ctx, params);
3654
+ process$1(def.innerType, ctx, params);
3073
3655
  const seen = ctx.seen.get(schema);
3074
3656
  seen.ref = def.innerType;
3075
3657
  if (ctx.io === "input") json._prefault = JSON.parse(JSON.stringify(def.defaultValue));
3076
3658
  };
3077
3659
  const catchProcessor = (schema, ctx, json, params) => {
3078
3660
  const def = schema._zod.def;
3079
- process(def.innerType, ctx, params);
3661
+ process$1(def.innerType, ctx, params);
3080
3662
  const seen = ctx.seen.get(schema);
3081
3663
  seen.ref = def.innerType;
3082
3664
  let catchValue;
@@ -3090,20 +3672,20 @@ const catchProcessor = (schema, ctx, json, params) => {
3090
3672
  const pipeProcessor = (schema, ctx, _json, params) => {
3091
3673
  const def = schema._zod.def;
3092
3674
  const innerType = ctx.io === "input" ? def.in._zod.def.type === "transform" ? def.out : def.in : def.out;
3093
- process(innerType, ctx, params);
3675
+ process$1(innerType, ctx, params);
3094
3676
  const seen = ctx.seen.get(schema);
3095
3677
  seen.ref = innerType;
3096
3678
  };
3097
3679
  const readonlyProcessor = (schema, ctx, json, params) => {
3098
3680
  const def = schema._zod.def;
3099
- process(def.innerType, ctx, params);
3681
+ process$1(def.innerType, ctx, params);
3100
3682
  const seen = ctx.seen.get(schema);
3101
3683
  seen.ref = def.innerType;
3102
3684
  json.readOnly = true;
3103
3685
  };
3104
3686
  const optionalProcessor = (schema, ctx, _json, params) => {
3105
3687
  const def = schema._zod.def;
3106
- process(def.innerType, ctx, params);
3688
+ process$1(def.innerType, ctx, params);
3107
3689
  const seen = ctx.seen.get(schema);
3108
3690
  seen.ref = def.innerType;
3109
3691
  };
@@ -3759,7 +4341,7 @@ const ScreenOptionsSchema = object({
3759
4341
  const LoggerOptionsSchema = object({
3760
4342
  screen: ScreenOptionsSchema.or(string()).optional().default("default"),
3761
4343
  context: string().optional(),
3762
- enabledLevels: array(_enum(require_filter_engine.ALL_LOG_LEVELS)).default(require_filter_engine.ALL_LOG_LEVELS)
4344
+ enabledLevels: array(_enum(ALL_LOG_LEVELS)).default(ALL_LOG_LEVELS)
3763
4345
  });
3764
4346
 
3765
4347
  //#endregion
@@ -3782,6 +4364,14 @@ const ScreenLogger = _navios_core.InjectionToken.create("ScreenLoggerInstance",
3782
4364
  //#region src/tokens/prompt.ts
3783
4365
  const Prompt = _navios_core.InjectionToken.create("Prompt", PromptOptionsSchema);
3784
4366
 
4367
+ //#endregion
4368
+ //#region src/tokens/adapter.ts
4369
+ /**
4370
+ * Injection token for the TUI rendering adapter.
4371
+ * Import the specific adapter (e.g., '@navios/commander-tui/adapters/react')
4372
+ * to register an implementation.
4373
+ */ const Adapter = _navios_core.InjectionToken.create("Adapter");
4374
+
3785
4375
  //#endregion
3786
4376
  //#region src/tokens/screen-manager.ts
3787
4377
  /**
@@ -4681,7 +5271,7 @@ function overrideConsoleLogger(hidden = false) {
4681
5271
  static: true
4682
5272
  } });
4683
5273
  setup(options) {
4684
- this.logger.setLogLevels(options.logLevels ?? require_filter_engine.ALL_LOG_LEVELS);
5274
+ this.logger.setLogLevels(options.logLevels ?? ALL_LOG_LEVELS);
4685
5275
  }
4686
5276
  log(message) {
4687
5277
  this.logger.log(message);
@@ -4991,29 +5581,708 @@ function _apply_decs_2203_r$3(targetClass, memberDecs, classDecs, parentClass) {
4991
5581
  return (_apply_decs_2203_r$3 = applyDecs2203RFactory$3())(targetClass, memberDecs, classDecs, parentClass);
4992
5582
  }
4993
5583
  var _dec$3, _initClass$3;
5584
+ const MISSING_ADAPTER_ERROR = "Adapter not registered, add import statement for @navios/tui-adapter-react, @navios/tui-adapter-ink or @navios/tui-adapter-solid to your module";
4994
5585
  let _MissingAdapterOverride;
4995
5586
  _dec$3 = (0, _navios_core.Injectable)({
4996
- token: require_filter_engine.Adapter,
5587
+ token: Adapter,
4997
5588
  priority: -100
4998
5589
  });
4999
5590
  var MissingAdapterOverride = class {
5000
5591
  static {
5001
5592
  ({c: [_MissingAdapterOverride, _initClass$3]} = _apply_decs_2203_r$3(this, [], [_dec$3]));
5002
5593
  }
5594
+ /**
5595
+ * Marker property to identify this as the missing adapter fallback.
5596
+ * Used by ScreenManager.bind() to detect and handle graceful fallback.
5597
+ */ isMissingAdapter = true;
5003
5598
  createRoot() {
5004
- throw new Error("Adapter not registered, add import statement for @navios/commander-tui/adapters/react or @navios/commander-tui/adapters/solid to your module");
5599
+ throw new Error(MISSING_ADAPTER_ERROR);
5005
5600
  }
5006
5601
  renderToRoot() {
5007
- throw new Error("Adapter not registered, add import statement for @navios/commander-tui/adapters/react or @navios/commander-tui/adapters/solid to your module");
5602
+ throw new Error(MISSING_ADAPTER_ERROR);
5008
5603
  }
5009
5604
  static {
5010
5605
  _initClass$3();
5011
5606
  }
5012
5607
  };
5013
5608
 
5609
+ //#endregion
5610
+ //#region src/themes/dark.ts
5611
+ /**
5612
+ * Default dark theme.
5613
+ * Migrated from the scattered color files in utils/colors/.
5614
+ */ const darkTheme = {
5615
+ name: "dark",
5616
+ logLevels: {
5617
+ verbose: {
5618
+ border: "#6B7280",
5619
+ background: "#6B728015"
5620
+ },
5621
+ debug: {
5622
+ border: "#8B5CF6",
5623
+ background: "#8B5CF615"
5624
+ },
5625
+ log: {
5626
+ border: "#3B82F6",
5627
+ background: "#3B82F615"
5628
+ },
5629
+ warn: {
5630
+ border: "#F59E0B",
5631
+ background: "#F59E0B15"
5632
+ },
5633
+ error: {
5634
+ border: "#EF4444",
5635
+ background: "#EF444415"
5636
+ },
5637
+ fatal: {
5638
+ border: "#DC2626",
5639
+ background: "#DC262625",
5640
+ text: "#FCA5A5"
5641
+ }
5642
+ },
5643
+ sidebar: {
5644
+ background: void 0,
5645
+ selectedBackground: "#1F293780",
5646
+ hoverBackground: "#374151",
5647
+ text: "#E5E7EB",
5648
+ textDim: "#6B7280",
5649
+ border: "#374151",
5650
+ badge: "#3B82F6",
5651
+ focusBorder: "#3B82F6"
5652
+ },
5653
+ header: {
5654
+ background: void 0,
5655
+ text: "#F9FAFB",
5656
+ border: "#374151"
5657
+ },
5658
+ statusIndicators: {
5659
+ waiting: {
5660
+ icon: "○",
5661
+ color: "#6B7280"
5662
+ },
5663
+ pending: {
5664
+ icon: "◐",
5665
+ color: "#F59E0B"
5666
+ },
5667
+ success: {
5668
+ icon: "✓",
5669
+ color: "#22C55E"
5670
+ },
5671
+ fail: {
5672
+ icon: "✗",
5673
+ color: "#EF4444"
5674
+ },
5675
+ static: {
5676
+ icon: "●",
5677
+ color: "#3B82F6"
5678
+ }
5679
+ },
5680
+ separator: {
5681
+ line: "#374151",
5682
+ text: "#6B7280"
5683
+ },
5684
+ progress: {
5685
+ border: "#3B82F6",
5686
+ background: "#3B82F615",
5687
+ barFilled: "#3B82F6",
5688
+ barEmpty: "#374151",
5689
+ text: "#E5E7EB",
5690
+ textDim: "#9CA3AF",
5691
+ complete: "#22C55E",
5692
+ completeBackground: "#22C55E15",
5693
+ failed: "#EF4444",
5694
+ failedBackground: "#EF444415"
5695
+ },
5696
+ group: {
5697
+ border: "#6B7280",
5698
+ background: "#6B728010",
5699
+ headerText: "#E5E7EB",
5700
+ icon: "#9CA3AF"
5701
+ },
5702
+ table: {
5703
+ border: "#3B82F6",
5704
+ background: "#3B82F615",
5705
+ headerText: "#F9FAFB",
5706
+ cellText: "#E5E7EB",
5707
+ title: "#F9FAFB",
5708
+ separator: "#3B82F650"
5709
+ },
5710
+ file: {
5711
+ border: "#3B82F6",
5712
+ background: "#3B82F615",
5713
+ headerText: "#F9FAFB",
5714
+ headerBackground: "#3B82F625"
5715
+ },
5716
+ prompt: {
5717
+ question: "#F9FAFB",
5718
+ optionText: "#E5E7EB",
5719
+ optionTextDim: "#9CA3AF",
5720
+ optionSelected: "#3B82F6",
5721
+ optionSelectedBackground: "#1E3A5F",
5722
+ confirmButton: "#22C55E",
5723
+ cancelButton: "#EF4444",
5724
+ buttonBackground: "#374151",
5725
+ buttonSelectedBackground: "#1F2937",
5726
+ inputBorder: "#3B82F6",
5727
+ inputBackground: "#1F2937",
5728
+ inputText: "#F9FAFB",
5729
+ inputPlaceholder: "#6B7280",
5730
+ inputCursor: "#3B82F6",
5731
+ border: "#374151",
5732
+ focusBorder: "#3B82F6"
5733
+ },
5734
+ errorHighlight: {
5735
+ background: "#EF444425",
5736
+ border: "#EF4444",
5737
+ gutterBackground: "#EF444440"
5738
+ },
5739
+ filter: {
5740
+ background: "#1F293780",
5741
+ border: "#3B82F6",
5742
+ text: "#E5E7EB",
5743
+ textDim: "#6B7280",
5744
+ inputBackground: "#1F2937",
5745
+ inputText: "#F9FAFB",
5746
+ inputPlaceholder: "#6B7280",
5747
+ cursor: "#3B82F6",
5748
+ activeLevel: "#3B82F6",
5749
+ inactiveLevel: "#4B5563"
5750
+ },
5751
+ help: {
5752
+ background: "#1F2937",
5753
+ border: "#3B82F6",
5754
+ title: "#F9FAFB",
5755
+ category: "#3B82F6",
5756
+ key: "#F59E0B",
5757
+ description: "#E5E7EB",
5758
+ hint: "#6B7280"
5759
+ },
5760
+ colors: {
5761
+ primary: "#3B82F6",
5762
+ secondary: "#8B5CF6",
5763
+ success: "#22C55E",
5764
+ warning: "#F59E0B",
5765
+ error: "#EF4444",
5766
+ muted: "#6B7280",
5767
+ background: "#111827",
5768
+ foreground: "#F9FAFB"
5769
+ }
5770
+ };
5771
+
5772
+ //#endregion
5773
+ //#region src/themes/light.ts
5774
+ /**
5775
+ * Light theme for terminals with light backgrounds.
5776
+ */ const lightTheme = {
5777
+ name: "light",
5778
+ logLevels: {
5779
+ verbose: {
5780
+ border: "#9CA3AF",
5781
+ background: "#F3F4F6"
5782
+ },
5783
+ debug: {
5784
+ border: "#7C3AED",
5785
+ background: "#EDE9FE"
5786
+ },
5787
+ log: {
5788
+ border: "#2563EB",
5789
+ background: "#DBEAFE"
5790
+ },
5791
+ warn: {
5792
+ border: "#D97706",
5793
+ background: "#FEF3C7"
5794
+ },
5795
+ error: {
5796
+ border: "#DC2626",
5797
+ background: "#FEE2E2"
5798
+ },
5799
+ fatal: {
5800
+ border: "#991B1B",
5801
+ background: "#FECACA",
5802
+ text: "#7F1D1D"
5803
+ }
5804
+ },
5805
+ sidebar: {
5806
+ background: "#F9FAFB",
5807
+ selectedBackground: "#E5E7EB",
5808
+ hoverBackground: "#F3F4F6",
5809
+ text: "#1F2937",
5810
+ textDim: "#6B7280",
5811
+ border: "#D1D5DB",
5812
+ badge: "#2563EB",
5813
+ focusBorder: "#2563EB"
5814
+ },
5815
+ header: {
5816
+ background: "#F9FAFB",
5817
+ text: "#111827",
5818
+ border: "#D1D5DB"
5819
+ },
5820
+ statusIndicators: {
5821
+ waiting: {
5822
+ icon: "○",
5823
+ color: "#9CA3AF"
5824
+ },
5825
+ pending: {
5826
+ icon: "◐",
5827
+ color: "#D97706"
5828
+ },
5829
+ success: {
5830
+ icon: "✓",
5831
+ color: "#16A34A"
5832
+ },
5833
+ fail: {
5834
+ icon: "✗",
5835
+ color: "#DC2626"
5836
+ },
5837
+ static: {
5838
+ icon: "●",
5839
+ color: "#2563EB"
5840
+ }
5841
+ },
5842
+ separator: {
5843
+ line: "#D1D5DB",
5844
+ text: "#6B7280"
5845
+ },
5846
+ progress: {
5847
+ border: "#2563EB",
5848
+ background: "#DBEAFE",
5849
+ barFilled: "#2563EB",
5850
+ barEmpty: "#E5E7EB",
5851
+ text: "#1F2937",
5852
+ textDim: "#6B7280",
5853
+ complete: "#16A34A",
5854
+ completeBackground: "#DCFCE7",
5855
+ failed: "#DC2626",
5856
+ failedBackground: "#FEE2E2"
5857
+ },
5858
+ group: {
5859
+ border: "#9CA3AF",
5860
+ background: "#F3F4F6",
5861
+ headerText: "#1F2937",
5862
+ icon: "#6B7280"
5863
+ },
5864
+ table: {
5865
+ border: "#2563EB",
5866
+ background: "#DBEAFE",
5867
+ headerText: "#111827",
5868
+ cellText: "#1F2937",
5869
+ title: "#111827",
5870
+ separator: "#93C5FD"
5871
+ },
5872
+ file: {
5873
+ border: "#2563EB",
5874
+ background: "#DBEAFE",
5875
+ headerText: "#111827",
5876
+ headerBackground: "#BFDBFE"
5877
+ },
5878
+ prompt: {
5879
+ question: "#111827",
5880
+ optionText: "#1F2937",
5881
+ optionTextDim: "#6B7280",
5882
+ optionSelected: "#2563EB",
5883
+ optionSelectedBackground: "#DBEAFE",
5884
+ confirmButton: "#16A34A",
5885
+ cancelButton: "#DC2626",
5886
+ buttonBackground: "#E5E7EB",
5887
+ buttonSelectedBackground: "#D1D5DB",
5888
+ inputBorder: "#2563EB",
5889
+ inputBackground: "#FFFFFF",
5890
+ inputText: "#111827",
5891
+ inputPlaceholder: "#9CA3AF",
5892
+ inputCursor: "#2563EB",
5893
+ border: "#D1D5DB",
5894
+ focusBorder: "#2563EB"
5895
+ },
5896
+ errorHighlight: {
5897
+ background: "#FEE2E2",
5898
+ border: "#DC2626",
5899
+ gutterBackground: "#FECACA"
5900
+ },
5901
+ filter: {
5902
+ background: "#F3F4F6",
5903
+ border: "#2563EB",
5904
+ text: "#1F2937",
5905
+ textDim: "#6B7280",
5906
+ inputBackground: "#FFFFFF",
5907
+ inputText: "#111827",
5908
+ inputPlaceholder: "#9CA3AF",
5909
+ cursor: "#2563EB",
5910
+ activeLevel: "#2563EB",
5911
+ inactiveLevel: "#D1D5DB"
5912
+ },
5913
+ help: {
5914
+ background: "#FFFFFF",
5915
+ border: "#2563EB",
5916
+ title: "#111827",
5917
+ category: "#2563EB",
5918
+ key: "#D97706",
5919
+ description: "#1F2937",
5920
+ hint: "#6B7280"
5921
+ },
5922
+ colors: {
5923
+ primary: "#2563EB",
5924
+ secondary: "#7C3AED",
5925
+ success: "#16A34A",
5926
+ warning: "#D97706",
5927
+ error: "#DC2626",
5928
+ muted: "#6B7280",
5929
+ background: "#FFFFFF",
5930
+ foreground: "#111827"
5931
+ }
5932
+ };
5933
+
5934
+ //#endregion
5935
+ //#region src/themes/high-contrast.ts
5936
+ /**
5937
+ * High contrast theme for accessibility.
5938
+ * Uses pure black/white with saturated colors for maximum visibility.
5939
+ */ const highContrastTheme = {
5940
+ name: "high-contrast",
5941
+ logLevels: {
5942
+ verbose: {
5943
+ border: "#FFFFFF",
5944
+ background: "#1A1A1A",
5945
+ text: "#FFFFFF"
5946
+ },
5947
+ debug: {
5948
+ border: "#A855F7",
5949
+ background: "#1A1A1A",
5950
+ text: "#E9D5FF"
5951
+ },
5952
+ log: {
5953
+ border: "#3B82F6",
5954
+ background: "#1A1A1A",
5955
+ text: "#BFDBFE"
5956
+ },
5957
+ warn: {
5958
+ border: "#FBBF24",
5959
+ background: "#1A1A1A",
5960
+ text: "#FEF08A"
5961
+ },
5962
+ error: {
5963
+ border: "#EF4444",
5964
+ background: "#1A1A1A",
5965
+ text: "#FECACA"
5966
+ },
5967
+ fatal: {
5968
+ border: "#FF0000",
5969
+ background: "#330000",
5970
+ text: "#FFFFFF"
5971
+ }
5972
+ },
5973
+ sidebar: {
5974
+ background: "#000000",
5975
+ selectedBackground: "#333333",
5976
+ hoverBackground: "#1A1A1A",
5977
+ text: "#FFFFFF",
5978
+ textDim: "#AAAAAA",
5979
+ border: "#FFFFFF",
5980
+ badge: "#FFFF00",
5981
+ focusBorder: "#FFFF00"
5982
+ },
5983
+ header: {
5984
+ background: "#000000",
5985
+ text: "#FFFFFF",
5986
+ border: "#FFFFFF"
5987
+ },
5988
+ statusIndicators: {
5989
+ waiting: {
5990
+ icon: "○",
5991
+ color: "#AAAAAA"
5992
+ },
5993
+ pending: {
5994
+ icon: "◐",
5995
+ color: "#FBBF24"
5996
+ },
5997
+ success: {
5998
+ icon: "✓",
5999
+ color: "#22C55E"
6000
+ },
6001
+ fail: {
6002
+ icon: "✗",
6003
+ color: "#EF4444"
6004
+ },
6005
+ static: {
6006
+ icon: "●",
6007
+ color: "#00FFFF"
6008
+ }
6009
+ },
6010
+ separator: {
6011
+ line: "#FFFFFF",
6012
+ text: "#AAAAAA"
6013
+ },
6014
+ progress: {
6015
+ border: "#3B82F6",
6016
+ background: "#1A1A1A",
6017
+ barFilled: "#3B82F6",
6018
+ barEmpty: "#333333",
6019
+ text: "#FFFFFF",
6020
+ textDim: "#AAAAAA",
6021
+ complete: "#22C55E",
6022
+ completeBackground: "#1A1A1A",
6023
+ failed: "#EF4444",
6024
+ failedBackground: "#1A1A1A"
6025
+ },
6026
+ group: {
6027
+ border: "#FFFFFF",
6028
+ background: "#1A1A1A",
6029
+ headerText: "#FFFFFF",
6030
+ icon: "#AAAAAA"
6031
+ },
6032
+ table: {
6033
+ border: "#FFFFFF",
6034
+ background: "#1A1A1A",
6035
+ headerText: "#FFFFFF",
6036
+ cellText: "#FFFFFF",
6037
+ title: "#FFFFFF",
6038
+ separator: "#666666"
6039
+ },
6040
+ file: {
6041
+ border: "#FFFFFF",
6042
+ background: "#1A1A1A",
6043
+ headerText: "#FFFFFF",
6044
+ headerBackground: "#333333"
6045
+ },
6046
+ prompt: {
6047
+ question: "#FFFFFF",
6048
+ optionText: "#FFFFFF",
6049
+ optionTextDim: "#AAAAAA",
6050
+ optionSelected: "#FFFF00",
6051
+ optionSelectedBackground: "#333333",
6052
+ confirmButton: "#22C55E",
6053
+ cancelButton: "#EF4444",
6054
+ buttonBackground: "#333333",
6055
+ buttonSelectedBackground: "#1A1A1A",
6056
+ inputBorder: "#FFFF00",
6057
+ inputBackground: "#1A1A1A",
6058
+ inputText: "#FFFFFF",
6059
+ inputPlaceholder: "#666666",
6060
+ inputCursor: "#FFFF00",
6061
+ border: "#FFFFFF",
6062
+ focusBorder: "#FFFF00"
6063
+ },
6064
+ errorHighlight: {
6065
+ background: "#330000",
6066
+ border: "#FF0000",
6067
+ gutterBackground: "#660000"
6068
+ },
6069
+ filter: {
6070
+ background: "#1A1A1A",
6071
+ border: "#FFFF00",
6072
+ text: "#FFFFFF",
6073
+ textDim: "#AAAAAA",
6074
+ inputBackground: "#000000",
6075
+ inputText: "#FFFFFF",
6076
+ inputPlaceholder: "#666666",
6077
+ cursor: "#FFFF00",
6078
+ activeLevel: "#FFFF00",
6079
+ inactiveLevel: "#666666"
6080
+ },
6081
+ help: {
6082
+ background: "#000000",
6083
+ border: "#FFFFFF",
6084
+ title: "#FFFFFF",
6085
+ category: "#FFFF00",
6086
+ key: "#00FFFF",
6087
+ description: "#FFFFFF",
6088
+ hint: "#AAAAAA"
6089
+ },
6090
+ colors: {
6091
+ primary: "#3B82F6",
6092
+ secondary: "#A855F7",
6093
+ success: "#22C55E",
6094
+ warning: "#FBBF24",
6095
+ error: "#EF4444",
6096
+ muted: "#AAAAAA",
6097
+ background: "#000000",
6098
+ foreground: "#FFFFFF"
6099
+ }
6100
+ };
6101
+
6102
+ //#endregion
6103
+ //#region src/themes/utils.ts
6104
+ /**
6105
+ * Deep merge two objects, with source taking precedence.
6106
+ */ function deepMerge(target, source) {
6107
+ const result = { ...target };
6108
+ for (const key in source) if (Object.prototype.hasOwnProperty.call(source, key)) {
6109
+ const sourceValue = source[key];
6110
+ const targetValue = target[key];
6111
+ if (sourceValue !== void 0 && typeof sourceValue === "object" && sourceValue !== null && !Array.isArray(sourceValue) && typeof targetValue === "object" && targetValue !== null && !Array.isArray(targetValue)) result[key] = deepMerge(targetValue, sourceValue);
6112
+ else if (sourceValue !== void 0) result[key] = sourceValue;
6113
+ }
6114
+ return result;
6115
+ }
6116
+ /**
6117
+ * Get a theme by preset name.
6118
+ */ function getThemePreset(preset) {
6119
+ switch (preset) {
6120
+ case "dark": return darkTheme;
6121
+ case "light": return lightTheme;
6122
+ case "high-contrast": return highContrastTheme;
6123
+ default: return darkTheme;
6124
+ }
6125
+ }
6126
+ /**
6127
+ * Merge a base theme with partial overrides.
6128
+ */ function mergeThemes(base, overrides) {
6129
+ return deepMerge(base, overrides);
6130
+ }
6131
+ /**
6132
+ * Create a custom theme by extending the dark theme with overrides.
6133
+ */ function createTheme(overrides) {
6134
+ return mergeThemes(darkTheme, overrides);
6135
+ }
6136
+ /**
6137
+ * Create a custom theme by extending a specific base theme.
6138
+ */ function createThemeFrom(base, overrides) {
6139
+ return mergeThemes(typeof base === "string" ? getThemePreset(base) : base, overrides);
6140
+ }
6141
+ /**
6142
+ * Resolve a theme value which can be a Theme object or a preset name.
6143
+ */ function resolveTheme(theme) {
6144
+ return typeof theme === "string" ? getThemePreset(theme) : theme;
6145
+ }
6146
+
6147
+ //#endregion
6148
+ //#region src/services/readline_prompt.ts
6149
+ /**
6150
+ * Readline-based prompt service for stdout mode.
6151
+ * Provides basic interactive prompts when TUI adapter is not available.
6152
+ */ var ReadlinePromptService = class {
6153
+ rl = null;
6154
+ promptQueue = [];
6155
+ isProcessing = false;
6156
+ ensureInterface() {
6157
+ if (!this.rl) this.rl = node_readline.createInterface({
6158
+ input: process.stdin,
6159
+ output: process.stdout
6160
+ });
6161
+ return this.rl;
6162
+ }
6163
+ /**
6164
+ * Handle a prompt interactively via readline.
6165
+ * Prompts are queued and processed sequentially.
6166
+ */ async handlePrompt(prompt) {
6167
+ return new Promise((resolve) => {
6168
+ this.promptQueue.push({
6169
+ prompt,
6170
+ resolve
6171
+ });
6172
+ this.processQueue();
6173
+ });
6174
+ }
6175
+ async processQueue() {
6176
+ if (this.isProcessing || this.promptQueue.length === 0) return;
6177
+ this.isProcessing = true;
6178
+ while (this.promptQueue.length > 0) {
6179
+ const { prompt, resolve } = this.promptQueue.shift();
6180
+ resolve(await this.processPrompt(prompt));
6181
+ }
6182
+ this.isProcessing = false;
6183
+ }
6184
+ async processPrompt(prompt) {
6185
+ switch (prompt.type) {
6186
+ case "choice": return this.handleChoice(prompt);
6187
+ case "confirm": return this.handleConfirm(prompt);
6188
+ case "input": return this.handleInput(prompt);
6189
+ case "multiChoice": return this.handleMultiChoice(prompt);
6190
+ }
6191
+ }
6192
+ async handleChoice(prompt) {
6193
+ const rl = this.ensureInterface();
6194
+ console.log(`\n${prompt.question}`);
6195
+ prompt.choices.forEach((choice, index) => {
6196
+ const marker = choice.value === prompt.defaultChoice ? "*" : " ";
6197
+ const inputHint = choice.input ? " (allows custom input)" : "";
6198
+ console.log(` ${marker} ${index + 1}. ${choice.label}${inputHint}`);
6199
+ });
6200
+ return new Promise((resolve) => {
6201
+ rl.question("Enter number (or press Enter for default): ", (answer) => {
6202
+ const trimmed = answer.trim();
6203
+ if (!trimmed) {
6204
+ resolve(prompt.defaultChoice);
6205
+ return;
6206
+ }
6207
+ const num = parseInt(trimmed, 10);
6208
+ if (num >= 1 && num <= prompt.choices.length) {
6209
+ const choice = prompt.choices[num - 1];
6210
+ if (choice.input) rl.question(`Enter value for "${choice.label}": `, (inputValue) => {
6211
+ resolve(inputValue.trim() || choice.value);
6212
+ });
6213
+ else resolve(choice.value);
6214
+ } else resolve(prompt.defaultChoice);
6215
+ });
6216
+ });
6217
+ }
6218
+ async handleConfirm(prompt) {
6219
+ const rl = this.ensureInterface();
6220
+ const defaultText = prompt.defaultValue ? "Y/n" : "y/N";
6221
+ return new Promise((resolve) => {
6222
+ rl.question(`${prompt.question} [${defaultText}]: `, (answer) => {
6223
+ const trimmed = answer.trim().toLowerCase();
6224
+ if (!trimmed) {
6225
+ resolve(prompt.defaultValue);
6226
+ return;
6227
+ }
6228
+ resolve(trimmed === "y" || trimmed === "yes");
6229
+ });
6230
+ });
6231
+ }
6232
+ async handleInput(prompt) {
6233
+ const rl = this.ensureInterface();
6234
+ const defaultHint = prompt.defaultValue ? ` (default: ${prompt.defaultValue})` : "";
6235
+ const placeholderHint = prompt.placeholder ? ` [${prompt.placeholder}]` : "";
6236
+ return new Promise((resolve) => {
6237
+ rl.question(`${prompt.question}${placeholderHint}${defaultHint}: `, (answer) => {
6238
+ resolve(answer.trim() || prompt.defaultValue);
6239
+ });
6240
+ });
6241
+ }
6242
+ async handleMultiChoice(prompt) {
6243
+ const rl = this.ensureInterface();
6244
+ console.log(`\n${prompt.question}`);
6245
+ console.log(`(Select ${prompt.minSelect}-${prompt.maxSelect} options, enter comma-separated numbers)`);
6246
+ prompt.choices.forEach((choice, index) => {
6247
+ const selected = prompt.selectedIndices.has(index) ? "[x]" : "[ ]";
6248
+ console.log(` ${selected} ${index + 1}. ${choice.label}`);
6249
+ });
6250
+ return new Promise((resolve) => {
6251
+ rl.question("Enter numbers (e.g., 1,3,5): ", (answer) => {
6252
+ const trimmed = answer.trim();
6253
+ if (!trimmed) {
6254
+ resolve(prompt.choices.filter((_, i) => prompt.selectedIndices.has(i)).map((c) => c.value));
6255
+ return;
6256
+ }
6257
+ const indices = trimmed.split(",").map((s) => parseInt(s.trim(), 10) - 1).filter((n) => n >= 0 && n < prompt.choices.length);
6258
+ if (indices.length < prompt.minSelect) {
6259
+ console.log(`Minimum ${prompt.minSelect} selections required. Using defaults.`);
6260
+ resolve(prompt.choices.filter((_, i) => prompt.selectedIndices.has(i)).map((c) => c.value));
6261
+ return;
6262
+ }
6263
+ if (indices.length > prompt.maxSelect) {
6264
+ console.log(`Maximum ${prompt.maxSelect} selections allowed. Taking first ${prompt.maxSelect}.`);
6265
+ indices.splice(prompt.maxSelect);
6266
+ }
6267
+ resolve(indices.map((i) => prompt.choices[i].value));
6268
+ });
6269
+ });
6270
+ }
6271
+ /**
6272
+ * Cleanup readline interface
6273
+ */ destroy() {
6274
+ if (this.rl) {
6275
+ this.rl.close();
6276
+ this.rl = null;
6277
+ }
6278
+ this.promptQueue = [];
6279
+ this.isProcessing = false;
6280
+ }
6281
+ };
6282
+
5014
6283
  //#endregion
5015
6284
  //#region src/services/screen.ts
5016
- var ScreenInstance = class {
6285
+ var ScreenInstance = class extends node_events.EventEmitter {
5017
6286
  id;
5018
6287
  name;
5019
6288
  icon;
@@ -5022,13 +6291,13 @@ var ScreenInstance = class {
5022
6291
  hidden = false;
5023
6292
  messages = [];
5024
6293
  manager = null;
5025
- changeListeners = /* @__PURE__ */ new Set();
5026
6294
  printFn = null;
5027
6295
  hasPrinted = false;
5028
6296
  version = 0;
5029
6297
  promptQueue = [];
5030
6298
  activePrompt = null;
5031
6299
  constructor(id, options) {
6300
+ super();
5032
6301
  this.id = id;
5033
6302
  this.name = options.name;
5034
6303
  this.icon = options.icon;
@@ -5066,7 +6335,7 @@ var ScreenInstance = class {
5066
6335
  }
5067
6336
  setBadgeCount(count) {
5068
6337
  this.badgeCount = count;
5069
- this.notifyChange();
6338
+ this.emit("badge:changed", count);
5070
6339
  return this;
5071
6340
  }
5072
6341
  isHidden() {
@@ -5075,7 +6344,7 @@ var ScreenInstance = class {
5075
6344
  setHidden(hidden) {
5076
6345
  this.hidden = hidden;
5077
6346
  this.manager?.onScreenVisibilityChanged(this);
5078
- this.notifyChange();
6347
+ this.emit("visibility:changed", hidden);
5079
6348
  return this;
5080
6349
  }
5081
6350
  show() {
@@ -5088,15 +6357,22 @@ var ScreenInstance = class {
5088
6357
  return this.status;
5089
6358
  }
5090
6359
  /**
5091
- * Set screen status. When success/fail and TUI is not bound, prints to stdout/stderr
6360
+ * Check if a log level is enabled globally via the ScreenManager.
6361
+ * Returns true if no manager is set or if the level is allowed.
6362
+ */ isLogLevelEnabled(level) {
6363
+ if (!this.manager) return true;
6364
+ return this.manager.isLogLevelEnabled(level);
6365
+ }
6366
+ /**
6367
+ * Set screen status. When success/fail and not in TUI mode, prints to stdout/stderr
5092
6368
  */ setStatus(status) {
5093
6369
  const wasComplete = this.status === "success" || this.status === "fail";
5094
6370
  this.status = status;
5095
6371
  if (!wasComplete && (status === "success" || status === "fail")) {
5096
- if (!this.manager?.isTuiBound()) this.printToConsole();
6372
+ if (!this.manager?.hasTuiRenderer()) this.printToConsole();
5097
6373
  this.manager?.onScreenCompleted(this);
5098
6374
  }
5099
- this.notifyChange();
6375
+ this.emit("status:changed", status);
5100
6376
  return this;
5101
6377
  }
5102
6378
  /**
@@ -5105,9 +6381,12 @@ var ScreenInstance = class {
5105
6381
  return this.status === "success" || this.status === "fail";
5106
6382
  }
5107
6383
  /**
5108
- * Check if this screen has been printed to console
6384
+ * Check if this screen has been printed to console.
6385
+ * Static screens in non-TUI modes are considered printed as they print incrementally.
5109
6386
  */ hasPrintedToConsole() {
5110
- return this.hasPrinted;
6387
+ if (this.hasPrinted) return true;
6388
+ if (this.status === "static" && !this.manager?.hasTuiRenderer()) return true;
6389
+ return false;
5111
6390
  }
5112
6391
  /**
5113
6392
  * Force print to console (called when TUI unbinds)
@@ -5124,19 +6403,25 @@ var ScreenInstance = class {
5124
6403
  */ addMessage(message) {
5125
6404
  this.messages.push(message);
5126
6405
  this.incrementVersion();
5127
- this.notifyChange();
6406
+ if (this.status === "static" && !this.manager?.hasTuiRenderer()) this.printSingleMessageToConsole(message);
6407
+ this.emit("message:added", message.id);
5128
6408
  }
5129
6409
  /**
5130
6410
  * Update a loading message (internal use by Logger)
5131
6411
  */ updateMessage(id, updates) {
5132
6412
  const index = this.messages.findIndex((m) => m.id === id);
5133
6413
  if (index !== -1) {
6414
+ const oldMessage = this.messages[index];
5134
6415
  this.messages[index] = {
5135
6416
  ...this.messages[index],
5136
6417
  ...updates
5137
6418
  };
5138
6419
  this.incrementVersion();
5139
- this.notifyChange();
6420
+ if (this.status === "static" && !this.manager?.hasTuiRenderer()) {
6421
+ const newMessage = this.messages[index];
6422
+ if (newMessage.status !== "loading" && oldMessage.status === "loading") this.printSingleMessageToConsole(newMessage);
6423
+ }
6424
+ this.emit("message:updated", id);
5140
6425
  }
5141
6426
  }
5142
6427
  /**
@@ -5144,12 +6429,17 @@ var ScreenInstance = class {
5144
6429
  */ updateProgressMessage(id, updates) {
5145
6430
  const index = this.messages.findIndex((m) => m.id === id);
5146
6431
  if (index !== -1) {
6432
+ const oldMessage = this.messages[index];
5147
6433
  this.messages[index] = {
5148
6434
  ...this.messages[index],
5149
6435
  ...updates
5150
6436
  };
5151
6437
  this.incrementVersion();
5152
- this.notifyChange();
6438
+ if (this.status === "static" && !this.manager?.hasTuiRenderer()) {
6439
+ const newMessage = this.messages[index];
6440
+ if ((newMessage.status === "complete" || newMessage.status === "failed") && oldMessage.status !== "complete" && oldMessage.status !== "failed") this.printSingleMessageToConsole(newMessage);
6441
+ }
6442
+ this.emit("message:updated", id);
5153
6443
  }
5154
6444
  }
5155
6445
  /**
@@ -5157,7 +6447,7 @@ var ScreenInstance = class {
5157
6447
  */ clear() {
5158
6448
  this.messages = [];
5159
6449
  this.incrementVersion();
5160
- this.notifyChange();
6450
+ this.emit("messages:cleared");
5161
6451
  return this;
5162
6452
  }
5163
6453
  /**
@@ -5165,21 +6455,26 @@ var ScreenInstance = class {
5165
6455
  * Returns a promise that resolves when the user responds
5166
6456
  */ _addPrompt(prompt) {
5167
6457
  return new Promise((resolve) => {
6458
+ const mode = this.manager?.getRenderMode() ?? RenderMode.UNBOUND;
6459
+ if (mode === RenderMode.UNBOUND) {
6460
+ this.resolvePromptWithDefault(prompt, resolve);
6461
+ return;
6462
+ }
6463
+ if (mode === RenderMode.STDOUT_INTERACTIVE || mode === RenderMode.STDOUT_FALLBACK) {
6464
+ this.manager?.handleReadlinePrompt(prompt).then(resolve);
6465
+ return;
6466
+ }
5168
6467
  const pending = {
5169
6468
  data: prompt,
5170
6469
  resolve
5171
6470
  };
5172
- if (!this.manager?.isTuiBound()) {
5173
- this.resolvePromptWithDefault(prompt, resolve);
5174
- return;
5175
- }
5176
6471
  if (prompt.timeout && prompt.timeoutStarted) pending.timeoutId = setTimeout(() => {
5177
6472
  if (this.activePrompt === pending) {
5178
6473
  this.resolvePromptWithDefault(prompt, resolve);
5179
6474
  this.activePrompt = null;
5180
6475
  this.activateNextPrompt();
5181
6476
  this.incrementVersion();
5182
- this.notifyChange();
6477
+ this.emit("prompt:resolved");
5183
6478
  } else {
5184
6479
  const idx = this.promptQueue.indexOf(pending);
5185
6480
  if (idx !== -1) {
@@ -5196,20 +6491,7 @@ var ScreenInstance = class {
5196
6491
  /**
5197
6492
  * Resolve a prompt with its default value
5198
6493
  */ resolvePromptWithDefault(prompt, resolve) {
5199
- switch (prompt.type) {
5200
- case "choice":
5201
- resolve(prompt.defaultChoice);
5202
- break;
5203
- case "confirm":
5204
- resolve(prompt.defaultValue);
5205
- break;
5206
- case "input":
5207
- resolve(prompt.defaultValue);
5208
- break;
5209
- case "multiChoice":
5210
- resolve(prompt.choices.filter((_, i) => prompt.selectedIndices.has(i)).map((c) => c.value));
5211
- break;
5212
- }
6494
+ resolve(getPromptDefaultValue(prompt));
5213
6495
  }
5214
6496
  /**
5215
6497
  * Get the currently active prompt (for rendering)
@@ -5233,7 +6515,7 @@ var ScreenInstance = class {
5233
6515
  const maxIndex = prompt.choices.length - 1;
5234
6516
  prompt.focusedIndex = Math.max(0, Math.min(index, maxIndex));
5235
6517
  } else if (prompt.type === "confirm") prompt.selectedValue = index === 0;
5236
- this.notifyChange();
6518
+ this.emit("prompt:updated");
5237
6519
  }
5238
6520
  /**
5239
6521
  * Navigate prompt selection up
@@ -5260,7 +6542,7 @@ var ScreenInstance = class {
5260
6542
  const prompt = this.activePrompt.data;
5261
6543
  if (prompt.type === "confirm") {
5262
6544
  prompt.selectedValue = true;
5263
- this.notifyChange();
6545
+ this.emit("prompt:updated");
5264
6546
  }
5265
6547
  }
5266
6548
  promptNavigateRight() {
@@ -5268,7 +6550,7 @@ var ScreenInstance = class {
5268
6550
  const prompt = this.activePrompt.data;
5269
6551
  if (prompt.type === "confirm") {
5270
6552
  prompt.selectedValue = false;
5271
- this.notifyChange();
6553
+ this.emit("prompt:updated");
5272
6554
  }
5273
6555
  }
5274
6556
  /**
@@ -5280,7 +6562,7 @@ var ScreenInstance = class {
5280
6562
  const p = prompt;
5281
6563
  if (p.selectedIndices.has(p.focusedIndex)) p.selectedIndices.delete(p.focusedIndex);
5282
6564
  else if (p.selectedIndices.size < p.maxSelect) p.selectedIndices.add(p.focusedIndex);
5283
- this.notifyChange();
6565
+ this.emit("prompt:updated");
5284
6566
  }
5285
6567
  }
5286
6568
  /**
@@ -5292,7 +6574,7 @@ var ScreenInstance = class {
5292
6574
  if (prompt.type === "choice") {
5293
6575
  if (prompt.choices[prompt.selectedIndex]?.input) {
5294
6576
  prompt.inputMode = true;
5295
- this.notifyChange();
6577
+ this.emit("prompt:updated");
5296
6578
  return true;
5297
6579
  }
5298
6580
  } else if (prompt.type === "input") return true;
@@ -5305,7 +6587,7 @@ var ScreenInstance = class {
5305
6587
  const prompt = this.activePrompt.data;
5306
6588
  if (prompt.type === "choice" && prompt.inputMode) {
5307
6589
  prompt.inputMode = false;
5308
- this.notifyChange();
6590
+ this.emit("prompt:updated");
5309
6591
  }
5310
6592
  }
5311
6593
  /**
@@ -5324,10 +6606,10 @@ var ScreenInstance = class {
5324
6606
  const prompt = this.activePrompt.data;
5325
6607
  if (prompt.type === "choice" && prompt.inputMode) {
5326
6608
  prompt.inputValue = value;
5327
- this.notifyChange();
6609
+ this.emit("prompt:updated");
5328
6610
  } else if (prompt.type === "input") {
5329
6611
  prompt.value = value;
5330
- this.notifyChange();
6612
+ this.emit("prompt:updated");
5331
6613
  }
5332
6614
  }
5333
6615
  /**
@@ -5337,10 +6619,10 @@ var ScreenInstance = class {
5337
6619
  const prompt = this.activePrompt.data;
5338
6620
  if (prompt.type === "choice" && prompt.inputMode) {
5339
6621
  prompt.inputValue += char;
5340
- this.notifyChange();
6622
+ this.emit("prompt:updated");
5341
6623
  } else if (prompt.type === "input") {
5342
6624
  prompt.value += char;
5343
- this.notifyChange();
6625
+ this.emit("prompt:updated");
5344
6626
  }
5345
6627
  }
5346
6628
  /**
@@ -5350,10 +6632,10 @@ var ScreenInstance = class {
5350
6632
  const prompt = this.activePrompt.data;
5351
6633
  if (prompt.type === "choice" && prompt.inputMode) {
5352
6634
  prompt.inputValue = prompt.inputValue.slice(0, -1);
5353
- this.notifyChange();
6635
+ this.emit("prompt:updated");
5354
6636
  } else if (prompt.type === "input") {
5355
6637
  prompt.value = prompt.value.slice(0, -1);
5356
- this.notifyChange();
6638
+ this.emit("prompt:updated");
5357
6639
  }
5358
6640
  }
5359
6641
  /**
@@ -5398,7 +6680,7 @@ var ScreenInstance = class {
5398
6680
  this.activePrompt = null;
5399
6681
  this.activateNextPrompt();
5400
6682
  this.incrementVersion();
5401
- this.notifyChange();
6683
+ this.emit("prompt:resolved");
5402
6684
  }
5403
6685
  /**
5404
6686
  * Activate the next prompt in the queue
@@ -5407,17 +6689,13 @@ var ScreenInstance = class {
5407
6689
  this.activePrompt = this.promptQueue.shift();
5408
6690
  this.manager?.onScreenPromptActivated(this);
5409
6691
  this.incrementVersion();
5410
- this.notifyChange();
6692
+ this.emit("prompt:activated");
5411
6693
  }
5412
6694
  }
5413
6695
  /**
5414
- * Register a change listener for re-renders
5415
- */ onChange(listener) {
5416
- this.changeListeners.add(listener);
5417
- return () => this.changeListeners.delete(listener);
5418
- }
5419
- notifyChange() {
5420
- this.changeListeners.forEach((listener) => listener());
6696
+ * Print a single message immediately to stdout (for static screens in stdout mode)
6697
+ */ printSingleMessageToConsole(message) {
6698
+ printSingleMessage(message, this.name, false);
5421
6699
  }
5422
6700
  /**
5423
6701
  * Print all messages to stdout/stderr with ANSI colors
@@ -5710,24 +6988,29 @@ function applyDecs2203RFactory$2() {
5710
6988
  function _apply_decs_2203_r$2(targetClass, memberDecs, classDecs, parentClass) {
5711
6989
  return (_apply_decs_2203_r$2 = applyDecs2203RFactory$2())(targetClass, memberDecs, classDecs, parentClass);
5712
6990
  }
5713
- var _dec$2, _initClass$2;
6991
+ var _dec$2, _initClass$2, _EventEmitter;
5714
6992
  let _ScreenManagerInstance;
5715
6993
  _dec$2 = (0, _navios_core.Injectable)({ token: ScreenManager });
5716
- var ScreenManagerInstance = class {
6994
+ var ScreenManagerInstance = class extends (_EventEmitter = node_events.EventEmitter) {
5717
6995
  static {
5718
- ({c: [_ScreenManagerInstance, _initClass$2]} = _apply_decs_2203_r$2(this, [], [_dec$2]));
6996
+ ({c: [_ScreenManagerInstance, _initClass$2]} = _apply_decs_2203_r$2(this, [], [_dec$2], _EventEmitter));
6997
+ }
6998
+ constructor() {
6999
+ super();
5719
7000
  }
5720
7001
  screens = /* @__PURE__ */ new Map();
5721
7002
  screenOrder = [];
5722
7003
  activeScreenId = null;
5723
7004
  renderer = null;
5724
7005
  root = null;
5725
- adapter = (0, _navios_core.inject)(require_filter_engine.Adapter);
5726
- isBound = false;
5727
- changeListeners = /* @__PURE__ */ new Set();
7006
+ adapter = null;
7007
+ container = (0, _navios_core.inject)(_navios_core.Container);
7008
+ mode = RenderMode.UNBOUND;
7009
+ readlinePromptService = null;
5728
7010
  bindOptions = {};
5729
7011
  autoCloseTimer = null;
5730
7012
  theme;
7013
+ globalLogLevels = null;
5731
7014
  focusArea = "content";
5732
7015
  selectedIndex = 0;
5733
7016
  /**
@@ -5736,12 +7019,12 @@ var ScreenManagerInstance = class {
5736
7019
  const id = `screen-${Date.now()}-${Math.random().toString(36).slice(2)}`;
5737
7020
  const screen = new ScreenInstance(id, options);
5738
7021
  screen._setManager(this);
5739
- screen._setPrintFn(require_filter_engine.printMessagesToStdout);
5740
- screen.onChange(() => this.notifyChange());
7022
+ screen._setPrintFn(printMessagesToStdout);
5741
7023
  this.screens.set(id, screen);
5742
7024
  this.screenOrder.push(id);
5743
7025
  if (!this.activeScreenId && !screen.isHidden()) this.activeScreenId = id;
5744
- this.notifyChange();
7026
+ this.checkAutoClose();
7027
+ this.emit("screen:added", id);
5745
7028
  return screen;
5746
7029
  }
5747
7030
  getScreenByName(name) {
@@ -5755,71 +7038,190 @@ var ScreenManagerInstance = class {
5755
7038
  if (!this.screens.has(id)) return;
5756
7039
  this.screens.delete(id);
5757
7040
  this.screenOrder = this.screenOrder.filter((sid) => sid !== id);
5758
- if (this.activeScreenId === id) this.activeScreenId = this.getScreens()[0]?.getId() ?? null;
7041
+ if (this.activeScreenId === id) {
7042
+ this.activeScreenId = this.getScreens()[0]?.getId() ?? null;
7043
+ this.emit("activeScreen:changed", this.activeScreenId);
7044
+ }
5759
7045
  const visibleScreens = this.getScreens();
5760
- if (this.selectedIndex >= visibleScreens.length) this.selectedIndex = Math.max(0, visibleScreens.length - 1);
5761
- this.notifyChange();
7046
+ if (this.selectedIndex >= visibleScreens.length) {
7047
+ const newIndex = Math.max(0, visibleScreens.length - 1);
7048
+ if (newIndex !== this.selectedIndex) {
7049
+ this.selectedIndex = newIndex;
7050
+ this.emit("sidebar:indexChanged", this.selectedIndex);
7051
+ }
7052
+ }
7053
+ this.checkAutoClose();
7054
+ this.emit("screen:removed", id);
5762
7055
  }
5763
7056
  /**
5764
7057
  * Non-blocking bind - starts TUI rendering in background
5765
7058
  */ async bind(options) {
5766
- if (this.isBound) return;
7059
+ if (this.mode !== RenderMode.UNBOUND) return;
5767
7060
  this.bindOptions = options ?? {};
5768
- if (options?.theme) this.theme = typeof options.theme === "string" ? require_filter_engine.getThemePreset(options.theme) : options.theme;
5769
- this.renderer = await (0, _opentui_core.createCliRenderer)({
5770
- exitOnCtrlC: options?.exitOnCtrlC ?? true,
5771
- useAlternateScreen: true,
5772
- useMouse: options?.useMouse ?? true
5773
- });
5774
- this.root = await this.adapter.createRoot(this.renderer);
5775
- this.isBound = true;
5776
- this.render();
7061
+ if (options?.theme) this.theme = typeof options.theme === "string" ? getThemePreset(options.theme) : options.theme;
7062
+ if (!(options?.useOpenTUI ?? !isBunRuntime())) {
7063
+ this.mode = RenderMode.STDOUT_INTERACTIVE;
7064
+ this.readlinePromptService = new ReadlinePromptService();
7065
+ this.emit("mode:changed", this.mode);
7066
+ return;
7067
+ }
7068
+ try {
7069
+ this.adapter = await this.container.get(Adapter);
7070
+ if (this.adapter.isMissingAdapter) throw new Error("No adapter registered");
7071
+ if (this.adapter.handlesOwnRenderer) this.root = await this.adapter.createRoot();
7072
+ else {
7073
+ const { createCliRenderer } = await dynamicImport("@opentui/core");
7074
+ this.renderer = await createCliRenderer({
7075
+ exitOnCtrlC: options?.exitOnCtrlC ?? true,
7076
+ useAlternateScreen: true,
7077
+ useMouse: options?.useMouse ?? true
7078
+ });
7079
+ this.root = await this.adapter.createRoot(this.renderer);
7080
+ }
7081
+ this.mode = RenderMode.TUI_ACTIVE;
7082
+ this.emit("mode:changed", this.mode);
7083
+ this.render();
7084
+ } catch {
7085
+ console.warn("[commander-tui] TUI adapter not available, falling back to stdout mode. To enable TUI, import a TUI adapter: @navios/tui-adapter-react, @navios/tui-adapter-ink, or @navios/tui-adapter-solid");
7086
+ this.mode = RenderMode.STDOUT_FALLBACK;
7087
+ this.readlinePromptService = new ReadlinePromptService();
7088
+ this.adapter = null;
7089
+ this.renderer = null;
7090
+ this.root = null;
7091
+ this.emit("mode:changed", this.mode);
7092
+ }
7093
+ }
7094
+ /**
7095
+ * Get the current render mode
7096
+ */ getRenderMode() {
7097
+ return this.mode;
7098
+ }
7099
+ /**
7100
+ * Check if TUI is interactive (any mode except UNBOUND).
7101
+ * In interactive modes, prompts can be handled via readline or TUI.
7102
+ */ isInteractive() {
7103
+ return this.mode !== RenderMode.UNBOUND;
7104
+ }
7105
+ /**
7106
+ * Check if TUI rendering is active (TUI_ACTIVE mode).
7107
+ * When true, screens are rendered in the TUI and not printed to stdout.
7108
+ */ hasTuiRenderer() {
7109
+ return this.mode === RenderMode.TUI_ACTIVE;
7110
+ }
7111
+ /**
7112
+ * Handle a prompt via readline (for stdout modes)
7113
+ */ handleReadlinePrompt(prompt) {
7114
+ if (!this.readlinePromptService) return Promise.resolve(getPromptDefaultValue(prompt));
7115
+ return this.readlinePromptService.handlePrompt(prompt);
5777
7116
  }
5778
7117
  /**
5779
7118
  * Get the configured theme
5780
7119
  */ getTheme() {
5781
7120
  return this.theme;
5782
7121
  }
7122
+ /**
7123
+ * Setup global configuration for the screen manager.
7124
+ * Can be called before or after bind() to configure theme and log levels.
7125
+ */ setup(options) {
7126
+ if (options.theme) this.theme = typeof options.theme === "string" ? getThemePreset(options.theme) : options.theme;
7127
+ if (options.logLevels) this.globalLogLevels = new Set(options.logLevels);
7128
+ }
7129
+ /**
7130
+ * Check if a log level is enabled globally.
7131
+ * Returns true if no global filter is set, or if the level is in the allowed set.
7132
+ */ isLogLevelEnabled(level) {
7133
+ if (this.globalLogLevels === null) return true;
7134
+ return this.globalLogLevels.has(level);
7135
+ }
7136
+ /**
7137
+ * Get the current global log levels filter.
7138
+ * Returns null if no filter is set (all levels allowed).
7139
+ */ getGlobalLogLevels() {
7140
+ return this.globalLogLevels ? Array.from(this.globalLogLevels) : null;
7141
+ }
5783
7142
  onServiceDestroy() {
5784
7143
  this.unbind();
5785
7144
  }
5786
7145
  /**
5787
7146
  * Stop TUI rendering and cleanup
5788
- * Flushes all completed screens to stdout/stderr
7147
+ * Flushes screens to stdout/stderr based on mode
5789
7148
  */ unbind() {
5790
- if (!this.isBound) return;
7149
+ if (this.mode === RenderMode.UNBOUND) {
7150
+ this.flushRemainingScreens();
7151
+ return;
7152
+ }
7153
+ const previousMode = this.mode;
5791
7154
  if (this.autoCloseTimer) {
5792
7155
  clearTimeout(this.autoCloseTimer);
5793
7156
  this.autoCloseTimer = null;
5794
7157
  }
5795
- this.root?.unmount();
5796
- if (this.renderer && "disableMouse" in this.renderer) this.renderer.disableMouse();
5797
- this.renderer?.destroy();
7158
+ if (previousMode === RenderMode.TUI_ACTIVE) {
7159
+ if (this.root) this.root.unmount();
7160
+ if (this.renderer) {
7161
+ if ("disableMouse" in this.renderer) this.renderer.disableMouse();
7162
+ this.renderer.destroy();
7163
+ }
7164
+ }
7165
+ if (this.readlinePromptService) {
7166
+ this.readlinePromptService.destroy();
7167
+ this.readlinePromptService = null;
7168
+ }
7169
+ this.flushScreensOnExit(previousMode);
7170
+ this.mode = RenderMode.UNBOUND;
5798
7171
  this.renderer = null;
5799
7172
  this.root = null;
5800
- this.isBound = false;
5801
- this.flushCompletedScreens();
7173
+ this.adapter = null;
7174
+ this.emit("mode:changed", this.mode);
7175
+ }
7176
+ /**
7177
+ * Flush screens on exit based on the mode we're exiting from
7178
+ */ flushScreensOnExit(previousMode) {
7179
+ for (const id of this.screenOrder) {
7180
+ const screen = this.screens.get(id);
7181
+ if (!screen || screen.isHidden()) continue;
7182
+ if (previousMode === RenderMode.TUI_ACTIVE) screen._flushToConsole(true);
7183
+ else if (!screen.hasPrintedToConsole()) screen._flushToConsole(true);
7184
+ }
5802
7185
  }
5803
7186
  /**
5804
- * Print all completed screens that haven't been printed yet
5805
- */ flushCompletedScreens() {
7187
+ * Flush any remaining non-hidden screens that haven't been printed.
7188
+ * Called on destroy even in UNBOUND mode to handle forgotten completions.
7189
+ */ flushRemainingScreens() {
5806
7190
  for (const id of this.screenOrder) {
5807
7191
  const screen = this.screens.get(id);
5808
- if (screen && !screen.hasPrintedToConsole()) screen._flushToConsole(true);
7192
+ if (!screen || screen.isHidden()) continue;
7193
+ if (!screen.hasPrintedToConsole()) screen._flushToConsole(true);
5809
7194
  }
5810
7195
  }
5811
7196
  /**
5812
7197
  * Check if TUI is currently bound
7198
+ * @deprecated Use isInteractive() instead
5813
7199
  */ isTuiBound() {
5814
- return this.isBound;
7200
+ return this.isInteractive();
7201
+ }
7202
+ /**
7203
+ * Check if TUI rendering is active (has renderer or self-rendering adapter).
7204
+ * @deprecated Use hasTuiRenderer() instead
7205
+ */ isTuiRendererActive() {
7206
+ return this.hasTuiRenderer();
7207
+ }
7208
+ /**
7209
+ * Check if OpenTUI rendering is active (has renderer).
7210
+ * @deprecated Use hasTuiRenderer() instead
7211
+ */ isOpenTUIActive() {
7212
+ return this.hasTuiRenderer();
5815
7213
  }
5816
7214
  /**
5817
7215
  * Called by Screen when a prompt becomes active
5818
7216
  * Focuses the screen and switches to content area
5819
7217
  */ onScreenPromptActivated(screen) {
5820
- this.setActiveScreen(screen);
5821
- this.focusArea = "content";
5822
- this.notifyChange();
7218
+ const prevActiveId = this.activeScreenId;
7219
+ this.activeScreenId = screen.getId();
7220
+ if (prevActiveId !== this.activeScreenId) this.emit("activeScreen:changed", this.activeScreenId);
7221
+ if (this.focusArea !== "content") {
7222
+ this.focusArea = "content";
7223
+ this.emit("focus:changed", this.focusArea);
7224
+ }
5823
7225
  }
5824
7226
  /**
5825
7227
  * Check if any screen has an active prompt
@@ -5840,10 +7242,18 @@ var ScreenManagerInstance = class {
5840
7242
  if (screen.isHidden() && this.activeScreenId === screen.getId()) {
5841
7243
  this.activeScreenId = this.getScreens()[0]?.getId() ?? null;
5842
7244
  this.selectedIndex = 0;
7245
+ this.emit("activeScreen:changed", this.activeScreenId);
7246
+ this.emit("sidebar:indexChanged", this.selectedIndex);
5843
7247
  }
5844
7248
  const visibleScreens = this.getScreens();
5845
- if (this.selectedIndex >= visibleScreens.length) this.selectedIndex = Math.max(0, visibleScreens.length - 1);
5846
- this.notifyChange();
7249
+ if (this.selectedIndex >= visibleScreens.length) {
7250
+ const newIndex = Math.max(0, visibleScreens.length - 1);
7251
+ if (newIndex !== this.selectedIndex) {
7252
+ this.selectedIndex = newIndex;
7253
+ this.emit("sidebar:indexChanged", this.selectedIndex);
7254
+ }
7255
+ }
7256
+ this.checkAutoClose();
5847
7257
  }
5848
7258
  /**
5849
7259
  * Called by Screen when status becomes success/fail
@@ -5855,9 +7265,16 @@ var ScreenManagerInstance = class {
5855
7265
  this.screenOrder.splice(index, 1);
5856
7266
  this.screenOrder.push(id);
5857
7267
  const visibleScreens = this.getScreens();
5858
- if (this.selectedIndex >= visibleScreens.length) this.selectedIndex = Math.max(0, visibleScreens.length - 1);
7268
+ if (this.selectedIndex >= visibleScreens.length) {
7269
+ const newIndex = Math.max(0, visibleScreens.length - 1);
7270
+ if (newIndex !== this.selectedIndex) {
7271
+ this.selectedIndex = newIndex;
7272
+ this.emit("sidebar:indexChanged", this.selectedIndex);
7273
+ }
7274
+ }
7275
+ this.checkAutoClose();
7276
+ this.emit("screen:reordered");
5859
7277
  }
5860
- this.notifyChange();
5861
7278
  }
5862
7279
  /**
5863
7280
  * Check if all screens are successful (or only static) and start auto-close timer if enabled.
@@ -5865,7 +7282,7 @@ var ScreenManagerInstance = class {
5865
7282
  * If there are only static screens, the timer will trigger after the delay with no new activity.
5866
7283
  */ checkAutoClose() {
5867
7284
  const autoClose = this.bindOptions.autoClose;
5868
- if (!autoClose || !this.isBound) return;
7285
+ if (!autoClose || this.mode === RenderMode.UNBOUND) return;
5869
7286
  if (this.autoCloseTimer) {
5870
7287
  clearTimeout(this.autoCloseTimer);
5871
7288
  this.autoCloseTimer = null;
@@ -5897,8 +7314,9 @@ var ScreenManagerInstance = class {
5897
7314
  /**
5898
7315
  * Set the active screen
5899
7316
  */ setActiveScreen(screen) {
7317
+ const prevActiveId = this.activeScreenId;
5900
7318
  this.activeScreenId = screen.getId();
5901
- this.notifyChange();
7319
+ if (prevActiveId !== this.activeScreenId) this.emit("activeScreen:changed", this.activeScreenId);
5902
7320
  }
5903
7321
  /**
5904
7322
  * Get bind options
@@ -5908,15 +7326,20 @@ var ScreenManagerInstance = class {
5908
7326
  /**
5909
7327
  * Set focus area (sidebar or content)
5910
7328
  */ setFocusArea(area) {
5911
- this.focusArea = area;
5912
- this.notifyChange();
7329
+ if (this.focusArea !== area) {
7330
+ this.focusArea = area;
7331
+ this.emit("focus:changed", area);
7332
+ }
5913
7333
  }
5914
7334
  /**
5915
7335
  * Set selected index in sidebar
5916
7336
  */ setSelectedIndex(index) {
5917
7337
  const visibleScreens = this.getScreens();
5918
- this.selectedIndex = Math.max(0, Math.min(index, visibleScreens.length - 1));
5919
- this.notifyChange();
7338
+ const newIndex = Math.max(0, Math.min(index, visibleScreens.length - 1));
7339
+ if (this.selectedIndex !== newIndex) {
7340
+ this.selectedIndex = newIndex;
7341
+ this.emit("sidebar:indexChanged", newIndex);
7342
+ }
5920
7343
  }
5921
7344
  /**
5922
7345
  * Navigate sidebar up
@@ -5938,20 +7361,10 @@ var ScreenManagerInstance = class {
5938
7361
  * Toggle focus between sidebar and content
5939
7362
  */ toggleFocus() {
5940
7363
  this.focusArea = this.focusArea === "sidebar" ? "content" : "sidebar";
5941
- this.notifyChange();
5942
- }
5943
- /**
5944
- * Register a change listener for re-renders
5945
- */ onChange(listener) {
5946
- this.changeListeners.add(listener);
5947
- return () => this.changeListeners.delete(listener);
5948
- }
5949
- notifyChange() {
5950
- this.checkAutoClose();
5951
- this.changeListeners.forEach((listener) => listener());
7364
+ this.emit("focus:changed", this.focusArea);
5952
7365
  }
5953
7366
  render() {
5954
- if (!this.root) return;
7367
+ if (!this.root || !this.adapter) return;
5955
7368
  this.adapter.renderToRoot(this.root, {
5956
7369
  manager: this,
5957
7370
  theme: this.theme
@@ -6253,7 +7666,10 @@ var ScreenLoggerInstance = class {
6253
7666
  ({c: [_ScreenLoggerInstance, _initClass$1]} = _apply_decs_2203_r$1(this, [], [_dec$1]));
6254
7667
  }
6255
7668
  constructor(options) {
6256
- this.screen = (0, _navios_core.inject)(Screen, typeof options.screen === "string" ? { name: options.screen } : options.screen);
7669
+ this.screen = (0, _navios_core.inject)(Screen, typeof options.screen === "string" ? {
7670
+ name: options.screen,
7671
+ static: true
7672
+ } : options.screen);
6257
7673
  this.context = options.context;
6258
7674
  this.enabledLevels = new Set(options.enabledLevels);
6259
7675
  }
@@ -6261,7 +7677,8 @@ var ScreenLoggerInstance = class {
6261
7677
  context;
6262
7678
  enabledLevels;
6263
7679
  isLevelEnabled(level) {
6264
- return this.enabledLevels.has(level);
7680
+ if (!this.enabledLevels.has(level)) return false;
7681
+ return this.screen.isLogLevelEnabled(level);
6265
7682
  }
6266
7683
  verbose(msg, label) {
6267
7684
  return this.write("verbose", msg, label);
@@ -6271,7 +7688,7 @@ var ScreenLoggerInstance = class {
6271
7688
  return this;
6272
7689
  }
6273
7690
  trace(msg, label) {
6274
- const trace = require_filter_engine.captureTrace(1);
7691
+ const trace = captureTrace(1);
6275
7692
  return this.write("verbose", msg, label, trace, "trace");
6276
7693
  }
6277
7694
  debug(msg, label) {
@@ -6294,7 +7711,7 @@ var ScreenLoggerInstance = class {
6294
7711
  }
6295
7712
  write(level, content, label, trace, variant) {
6296
7713
  if (!this.isLevelEnabled(level)) return this;
6297
- const formattedContent = typeof content === "object" ? require_filter_engine.formatObject(content) : content;
7714
+ const formattedContent = typeof content === "object" ? formatObject(content) : content;
6298
7715
  const message = {
6299
7716
  id: generateId(),
6300
7717
  type: "log",
@@ -6877,15 +8294,590 @@ var PromptInstance = class {
6877
8294
  };
6878
8295
 
6879
8296
  //#endregion
6880
- exports.ALL_LOG_LEVELS = require_filter_engine.ALL_LOG_LEVELS;
6881
- exports.Adapter = require_filter_engine.Adapter;
6882
- exports.COMMON_FILETYPES = require_filter_engine.COMMON_FILETYPES;
6883
- exports.DEFAULT_LOG_LEVEL_COLORS = require_filter_engine.DEFAULT_LOG_LEVEL_COLORS;
6884
- exports.ERROR_HIGHLIGHT_COLORS = require_filter_engine.ERROR_HIGHLIGHT_COLORS;
6885
- exports.FILE_COLORS = require_filter_engine.FILE_COLORS;
6886
- exports.FilterEngine = require_filter_engine.FilterEngine;
6887
- exports.GROUP_COLORS = require_filter_engine.GROUP_COLORS;
6888
- exports.HEADER_COLORS = require_filter_engine.HEADER_COLORS;
8297
+ //#region src/keyboard/keyboard_manager.ts
8298
+ /**
8299
+ * Manages keyboard bindings and dispatches key events to handlers.
8300
+ */ var KeyboardManager = class {
8301
+ bindings = [];
8302
+ disabled = /* @__PURE__ */ new Set();
8303
+ constructor(config$1) {
8304
+ if (config$1?.bindings) this.bindings = [...config$1.bindings];
8305
+ if (config$1?.disabled) this.disabled = new Set(config$1.disabled);
8306
+ this.sortBindings();
8307
+ }
8308
+ /**
8309
+ * Add bindings to the manager.
8310
+ */ addBindings(bindings) {
8311
+ this.bindings.push(...bindings);
8312
+ this.sortBindings();
8313
+ }
8314
+ /**
8315
+ * Remove a binding by key name.
8316
+ */ removeBinding(key) {
8317
+ this.bindings = this.bindings.filter((b) => {
8318
+ return !(Array.isArray(b.key) ? b.key : [b.key]).includes(key);
8319
+ });
8320
+ }
8321
+ /**
8322
+ * Disable a key (prevents it from being matched).
8323
+ */ disableKey(key) {
8324
+ this.disabled.add(key);
8325
+ }
8326
+ /**
8327
+ * Enable a previously disabled key.
8328
+ */ enableKey(key) {
8329
+ this.disabled.delete(key);
8330
+ }
8331
+ /**
8332
+ * Handle a key event, dispatching to the appropriate handler.
8333
+ * Returns true if a handler consumed the event.
8334
+ */ handleKey(key, context) {
8335
+ const binding = this.findMatchingBinding(key, context);
8336
+ if (binding) return binding.handler(key, context) !== false;
8337
+ return false;
8338
+ }
8339
+ /**
8340
+ * Get all bindings for display in help overlay.
8341
+ */ getBindingsForHelp() {
8342
+ return this.bindings.filter((b) => b.description);
8343
+ }
8344
+ /**
8345
+ * Get bindings grouped by category.
8346
+ */ getBindingsByCategory() {
8347
+ const grouped = {
8348
+ general: [],
8349
+ navigation: [],
8350
+ screen: [],
8351
+ prompt: [],
8352
+ filter: []
8353
+ };
8354
+ for (const binding of this.bindings) if (binding.description) grouped[binding.category].push(binding);
8355
+ return grouped;
8356
+ }
8357
+ /**
8358
+ * Find a matching binding for the given key and context.
8359
+ */ findMatchingBinding(key, context) {
8360
+ for (const binding of this.bindings) if (this.keyMatches(key, binding) && this.conditionMatches(binding.when, context) && !this.isDisabled(binding)) return binding;
8361
+ return null;
8362
+ }
8363
+ /**
8364
+ * Check if a key event matches a binding's key specification.
8365
+ */ keyMatches(key, binding) {
8366
+ const keys = Array.isArray(binding.key) ? binding.key : [binding.key];
8367
+ if (!(keys.includes(key.name) || key.sequence && keys.includes(key.sequence))) return false;
8368
+ const ctrlMatches = (binding.ctrl ?? false) === (key.ctrl ?? false);
8369
+ const metaMatches = (binding.meta ?? false) === (key.meta ?? false);
8370
+ const shiftMatches = (binding.shift ?? false) === (key.shift ?? false);
8371
+ return ctrlMatches && metaMatches && shiftMatches;
8372
+ }
8373
+ /**
8374
+ * Check if context matches a binding's condition.
8375
+ */ conditionMatches(condition, context) {
8376
+ if (!condition) return true;
8377
+ if (condition.hasPrompt !== void 0 && condition.hasPrompt !== context.hasPrompt) return false;
8378
+ if (condition.inInputMode !== void 0 && condition.inInputMode !== context.inInputMode) return false;
8379
+ if (condition.focusArea !== void 0 && condition.focusArea !== context.focusArea) return false;
8380
+ if (condition.isFilterActive !== void 0 && condition.isFilterActive !== context.isFilterActive) return false;
8381
+ if (condition.isHelpVisible !== void 0 && condition.isHelpVisible !== context.isHelpVisible) return false;
8382
+ if (condition.hasSidebar !== void 0 && condition.hasSidebar !== context.hasSidebar) return false;
8383
+ return true;
8384
+ }
8385
+ /**
8386
+ * Check if a binding is disabled.
8387
+ */ isDisabled(binding) {
8388
+ return (Array.isArray(binding.key) ? binding.key : [binding.key]).some((k) => this.disabled.has(k));
8389
+ }
8390
+ /**
8391
+ * Sort bindings by priority (higher first).
8392
+ */ sortBindings() {
8393
+ this.bindings.sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0));
8394
+ }
8395
+ };
8396
+ /**
8397
+ * Format a key binding for display.
8398
+ */ function formatKeyBinding(binding) {
8399
+ const keys = Array.isArray(binding.key) ? binding.key : [binding.key];
8400
+ const parts = [];
8401
+ if (binding.ctrl) parts.push("Ctrl");
8402
+ if (binding.meta) parts.push("Cmd");
8403
+ if (binding.shift) parts.push("Shift");
8404
+ const keyDisplay = keys.map((k) => {
8405
+ switch (k) {
8406
+ case "up": return "↑";
8407
+ case "down": return "↓";
8408
+ case "left": return "←";
8409
+ case "right": return "→";
8410
+ case "return": return "Enter";
8411
+ case "escape": return "Esc";
8412
+ case "space": return "Space";
8413
+ case "tab": return "Tab";
8414
+ case "\\": return "\\";
8415
+ default: return k;
8416
+ }
8417
+ }).join("/");
8418
+ parts.push(keyDisplay);
8419
+ return parts.join("+");
8420
+ }
8421
+
8422
+ //#endregion
8423
+ //#region src/keyboard/create_bindings.ts
8424
+ /**
8425
+ * Create the default keybindings with access to manager and screens.
8426
+ */ function createDefaultBindings(handlers) {
8427
+ const { manager, getActiveScreen, toggleHelp, toggleFilter, closeFilter } = handlers;
8428
+ const bindings = [];
8429
+ bindings.push({
8430
+ key: "escape",
8431
+ handler: () => {
8432
+ const screen = getActiveScreen();
8433
+ if (screen?.isPromptInInputMode()) {
8434
+ screen.promptExitInputMode();
8435
+ return true;
8436
+ }
8437
+ },
8438
+ description: "Exit input mode",
8439
+ category: "prompt",
8440
+ when: {
8441
+ hasPrompt: true,
8442
+ inInputMode: true
8443
+ },
8444
+ priority: 100
8445
+ });
8446
+ bindings.push({
8447
+ key: "return",
8448
+ handler: () => {
8449
+ const screen = getActiveScreen();
8450
+ if (screen?.isPromptInInputMode()) {
8451
+ screen.promptSubmit();
8452
+ return true;
8453
+ }
8454
+ },
8455
+ description: "Submit input",
8456
+ category: "prompt",
8457
+ when: {
8458
+ hasPrompt: true,
8459
+ inInputMode: true
8460
+ },
8461
+ priority: 100
8462
+ });
8463
+ bindings.push({
8464
+ key: "backspace",
8465
+ handler: () => {
8466
+ const screen = getActiveScreen();
8467
+ if (screen?.isPromptInInputMode()) {
8468
+ screen.promptDeleteLastChar();
8469
+ return true;
8470
+ }
8471
+ },
8472
+ description: "Delete character",
8473
+ category: "prompt",
8474
+ when: {
8475
+ hasPrompt: true,
8476
+ inInputMode: true
8477
+ },
8478
+ priority: 100
8479
+ });
8480
+ bindings.push({
8481
+ key: ["up", "k"],
8482
+ handler: () => {
8483
+ const screen = getActiveScreen();
8484
+ const prompt = screen?.getActivePrompt();
8485
+ if (prompt?.type === "choice" || prompt?.type === "multiChoice") {
8486
+ screen?.promptNavigateUp();
8487
+ return true;
8488
+ }
8489
+ },
8490
+ description: "Navigate up",
8491
+ category: "prompt",
8492
+ when: {
8493
+ hasPrompt: true,
8494
+ inInputMode: false
8495
+ },
8496
+ priority: 90
8497
+ });
8498
+ bindings.push({
8499
+ key: ["down", "j"],
8500
+ handler: () => {
8501
+ const screen = getActiveScreen();
8502
+ const prompt = screen?.getActivePrompt();
8503
+ if (prompt?.type === "choice" || prompt?.type === "multiChoice") {
8504
+ screen?.promptNavigateDown();
8505
+ return true;
8506
+ }
8507
+ },
8508
+ description: "Navigate down",
8509
+ category: "prompt",
8510
+ when: {
8511
+ hasPrompt: true,
8512
+ inInputMode: false
8513
+ },
8514
+ priority: 90
8515
+ });
8516
+ bindings.push({
8517
+ key: ["left", "h"],
8518
+ handler: () => {
8519
+ const screen = getActiveScreen();
8520
+ if ((screen?.getActivePrompt())?.type === "confirm") {
8521
+ screen?.promptNavigateLeft();
8522
+ return true;
8523
+ }
8524
+ },
8525
+ description: "Select confirm",
8526
+ category: "prompt",
8527
+ when: {
8528
+ hasPrompt: true,
8529
+ inInputMode: false
8530
+ },
8531
+ priority: 90
8532
+ });
8533
+ bindings.push({
8534
+ key: ["right", "l"],
8535
+ handler: () => {
8536
+ const screen = getActiveScreen();
8537
+ if ((screen?.getActivePrompt())?.type === "confirm") {
8538
+ screen?.promptNavigateRight();
8539
+ return true;
8540
+ }
8541
+ },
8542
+ description: "Select cancel",
8543
+ category: "prompt",
8544
+ when: {
8545
+ hasPrompt: true,
8546
+ inInputMode: false
8547
+ },
8548
+ priority: 90
8549
+ });
8550
+ bindings.push({
8551
+ key: "space",
8552
+ handler: () => {
8553
+ const screen = getActiveScreen();
8554
+ if ((screen?.getActivePrompt())?.type === "multiChoice") {
8555
+ screen?.promptToggleSelection();
8556
+ return true;
8557
+ }
8558
+ },
8559
+ description: "Toggle selection",
8560
+ category: "prompt",
8561
+ when: {
8562
+ hasPrompt: true,
8563
+ inInputMode: false
8564
+ },
8565
+ priority: 90
8566
+ });
8567
+ bindings.push({
8568
+ key: "return",
8569
+ handler: () => {
8570
+ const screen = getActiveScreen();
8571
+ const prompt = screen?.getActivePrompt();
8572
+ if (!prompt) return false;
8573
+ if (prompt.type === "choice") {
8574
+ if (!screen?.promptEnterInputMode()) screen?.promptSubmit();
8575
+ return true;
8576
+ } else if (prompt.type === "confirm") {
8577
+ screen?.promptSubmit();
8578
+ return true;
8579
+ } else if (prompt.type === "multiChoice") {
8580
+ if (screen?.canSubmitPrompt()) screen.promptSubmit();
8581
+ return true;
8582
+ }
8583
+ },
8584
+ description: "Submit selection",
8585
+ category: "prompt",
8586
+ when: {
8587
+ hasPrompt: true,
8588
+ inInputMode: false
8589
+ },
8590
+ priority: 90
8591
+ });
8592
+ bindings.push({
8593
+ key: "?",
8594
+ handler: () => {
8595
+ toggleHelp();
8596
+ return true;
8597
+ },
8598
+ description: "Toggle help",
8599
+ category: "general",
8600
+ when: {
8601
+ hasPrompt: false,
8602
+ isFilterActive: false
8603
+ },
8604
+ priority: 50
8605
+ });
8606
+ bindings.push({
8607
+ key: "escape",
8608
+ handler: () => {
8609
+ toggleHelp();
8610
+ return true;
8611
+ },
8612
+ description: "Close help",
8613
+ category: "general",
8614
+ when: { isHelpVisible: true },
8615
+ priority: 80
8616
+ });
8617
+ bindings.push({
8618
+ key: "/",
8619
+ handler: () => {
8620
+ toggleFilter();
8621
+ return true;
8622
+ },
8623
+ description: "Toggle filter",
8624
+ category: "filter",
8625
+ when: {
8626
+ hasPrompt: false,
8627
+ isHelpVisible: false
8628
+ },
8629
+ priority: 50
8630
+ });
8631
+ bindings.push({
8632
+ key: "escape",
8633
+ handler: () => {
8634
+ closeFilter();
8635
+ return true;
8636
+ },
8637
+ description: "Close filter",
8638
+ category: "filter",
8639
+ when: { isFilterActive: true },
8640
+ priority: 70
8641
+ });
8642
+ bindings.push({
8643
+ key: "tab",
8644
+ handler: () => {
8645
+ handlers.filterCycleField();
8646
+ return true;
8647
+ },
8648
+ description: "Cycle filter fields",
8649
+ category: "filter",
8650
+ when: { isFilterActive: true },
8651
+ priority: 70
8652
+ });
8653
+ bindings.push({
8654
+ key: "backspace",
8655
+ handler: () => {
8656
+ handlers.filterDeleteChar();
8657
+ return true;
8658
+ },
8659
+ description: "Delete character",
8660
+ category: "filter",
8661
+ when: { isFilterActive: true },
8662
+ priority: 70
8663
+ });
8664
+ for (let i = 1; i <= 7; i++) bindings.push({
8665
+ key: String(i),
8666
+ handler: () => {
8667
+ handlers.filterToggleLevel(i - 1);
8668
+ return true;
8669
+ },
8670
+ description: `Toggle level ${i}`,
8671
+ category: "filter",
8672
+ when: { isFilterActive: true },
8673
+ priority: 70
8674
+ });
8675
+ bindings.push({
8676
+ key: "q",
8677
+ handler: () => {
8678
+ manager.unbind();
8679
+ return true;
8680
+ },
8681
+ description: "Exit",
8682
+ category: "general",
8683
+ when: {
8684
+ hasPrompt: false,
8685
+ isFilterActive: false,
8686
+ isHelpVisible: false
8687
+ },
8688
+ priority: 10
8689
+ });
8690
+ bindings.push({
8691
+ key: "tab",
8692
+ handler: (_, ctx) => {
8693
+ if (ctx.hasSidebar) {
8694
+ manager.toggleFocus();
8695
+ return true;
8696
+ }
8697
+ },
8698
+ description: "Toggle focus",
8699
+ category: "navigation",
8700
+ when: {
8701
+ hasPrompt: false,
8702
+ isFilterActive: false
8703
+ },
8704
+ priority: 20
8705
+ });
8706
+ bindings.push({
8707
+ key: "\\",
8708
+ handler: (_, ctx) => {
8709
+ if (ctx.hasSidebar) {
8710
+ manager.toggleFocus();
8711
+ return true;
8712
+ }
8713
+ },
8714
+ description: "Toggle focus",
8715
+ category: "navigation",
8716
+ when: {
8717
+ hasPrompt: false,
8718
+ isFilterActive: false
8719
+ },
8720
+ priority: 20
8721
+ });
8722
+ bindings.push({
8723
+ key: ["up", "k"],
8724
+ handler: () => {
8725
+ manager.navigateUp();
8726
+ return true;
8727
+ },
8728
+ description: "Navigate up",
8729
+ category: "navigation",
8730
+ when: {
8731
+ focusArea: "sidebar",
8732
+ hasPrompt: false
8733
+ },
8734
+ priority: 30
8735
+ });
8736
+ bindings.push({
8737
+ key: ["down", "j"],
8738
+ handler: () => {
8739
+ manager.navigateDown();
8740
+ return true;
8741
+ },
8742
+ description: "Navigate down",
8743
+ category: "navigation",
8744
+ when: {
8745
+ focusArea: "sidebar",
8746
+ hasPrompt: false
8747
+ },
8748
+ priority: 30
8749
+ });
8750
+ bindings.push({
8751
+ key: "return",
8752
+ handler: () => {
8753
+ manager.selectCurrent();
8754
+ return true;
8755
+ },
8756
+ description: "Select screen",
8757
+ category: "navigation",
8758
+ when: {
8759
+ focusArea: "sidebar",
8760
+ hasPrompt: false
8761
+ },
8762
+ priority: 30
8763
+ });
8764
+ for (let i = 1; i <= 9; i++) bindings.push({
8765
+ key: String(i),
8766
+ handler: () => {
8767
+ const screens = manager.getScreens();
8768
+ if (i <= screens.length) {
8769
+ manager.setActiveScreen(screens[i - 1]);
8770
+ manager.setSelectedIndex(i - 1);
8771
+ return true;
8772
+ }
8773
+ },
8774
+ description: `Jump to screen ${i}`,
8775
+ category: "screen",
8776
+ when: {
8777
+ hasPrompt: false,
8778
+ isFilterActive: false
8779
+ },
8780
+ priority: 15
8781
+ });
8782
+ bindings.push({
8783
+ key: "c",
8784
+ handler: () => {
8785
+ getActiveScreen()?.clear();
8786
+ return true;
8787
+ },
8788
+ description: "Clear screen",
8789
+ category: "screen",
8790
+ when: {
8791
+ focusArea: "content",
8792
+ hasPrompt: false,
8793
+ isFilterActive: false
8794
+ },
8795
+ priority: 15
8796
+ });
8797
+ return bindings;
8798
+ }
8799
+ /**
8800
+ * Handle printable character input for prompts and filter.
8801
+ * This should be called for any key not handled by bindings.
8802
+ */ function handlePrintableInput(key, context, handlers) {
8803
+ if (!key.sequence || key.sequence.length !== 1 || key.ctrl || key.meta) return false;
8804
+ const charCode = key.sequence.charCodeAt(0);
8805
+ if (charCode < 32 || charCode > 126) return false;
8806
+ if (context.isFilterActive) {
8807
+ handlers.filterAppendChar(key.sequence);
8808
+ return true;
8809
+ }
8810
+ if (context.hasPrompt && context.inInputMode) {
8811
+ handlers.getActiveScreen()?.promptAppendInput(key.sequence);
8812
+ return true;
8813
+ }
8814
+ return false;
8815
+ }
8816
+
8817
+ //#endregion
8818
+ //#region src/filter/filter_engine.ts
8819
+ /**
8820
+ * Filter engine for filtering log messages.
8821
+ */ var FilterEngine = class {
8822
+ /**
8823
+ * Apply filter to messages array.
8824
+ */ static filterMessages(messages, filter) {
8825
+ if (filter.searchQuery === "" && filter.enabledLevels.size === ALL_LOG_LEVELS.length) return messages;
8826
+ return messages.filter((msg) => {
8827
+ if (msg.type !== "log") {
8828
+ if (filter.searchQuery) return this.messageMatchesSearch(msg, filter.searchQuery);
8829
+ if (msg.type === "group") return true;
8830
+ return true;
8831
+ }
8832
+ const logMsg = msg;
8833
+ if (!filter.enabledLevels.has(logMsg.level)) return false;
8834
+ if (filter.searchQuery && !this.messageMatchesSearch(logMsg, filter.searchQuery)) return false;
8835
+ return true;
8836
+ });
8837
+ }
8838
+ /**
8839
+ * Check if a message matches the search query.
8840
+ */ static messageMatchesSearch(msg, query) {
8841
+ const lowerQuery = query.toLowerCase();
8842
+ switch (msg.type) {
8843
+ case "log": return msg.content.toLowerCase().includes(lowerQuery) || (msg.label?.toLowerCase().includes(lowerQuery) ?? false);
8844
+ case "file":
8845
+ case "fileError": return msg.filePath.toLowerCase().includes(lowerQuery) || msg.content.toLowerCase().includes(lowerQuery);
8846
+ case "diff": return msg.filePath.toLowerCase().includes(lowerQuery) || msg.diff.toLowerCase().includes(lowerQuery);
8847
+ case "loading": return msg.content.toLowerCase().includes(lowerQuery) || (msg.resolvedContent?.toLowerCase().includes(lowerQuery) ?? false);
8848
+ case "progress": return msg.label.toLowerCase().includes(lowerQuery);
8849
+ case "group": return msg.label.toLowerCase().includes(lowerQuery);
8850
+ case "table": return (msg.title?.toLowerCase().includes(lowerQuery) ?? false) || msg.headers.some((h) => h.toLowerCase().includes(lowerQuery)) || msg.rows.some((row) => row.some((cell) => cell.toLowerCase().includes(lowerQuery)));
8851
+ default: return false;
8852
+ }
8853
+ }
8854
+ /**
8855
+ * Count messages by log level.
8856
+ */ static countByLevel(messages) {
8857
+ const counts = {
8858
+ debug: 0,
8859
+ log: 0,
8860
+ verbose: 0,
8861
+ error: 0,
8862
+ fatal: 0,
8863
+ warn: 0
8864
+ };
8865
+ for (const msg of messages) if (msg.type === "log") counts[msg.level]++;
8866
+ return counts;
8867
+ }
8868
+ };
8869
+
8870
+ //#endregion
8871
+ exports.ALL_LOG_LEVELS = ALL_LOG_LEVELS;
8872
+ exports.Adapter = Adapter;
8873
+ exports.COMMON_FILETYPES = COMMON_FILETYPES;
8874
+ exports.CONTENT_MANAGER_EVENTS = CONTENT_MANAGER_EVENTS;
8875
+ exports.DEFAULT_LOG_LEVEL_COLORS = DEFAULT_LOG_LEVEL_COLORS;
8876
+ exports.ERROR_HIGHLIGHT_COLORS = ERROR_HIGHLIGHT_COLORS;
8877
+ exports.FILE_COLORS = FILE_COLORS;
8878
+ exports.FilterEngine = FilterEngine;
8879
+ exports.GROUP_COLORS = GROUP_COLORS;
8880
+ exports.HEADER_COLORS = HEADER_COLORS;
6889
8881
  exports.IsomorphicLogger = IsomorphicLogger;
6890
8882
  Object.defineProperty(exports, 'IsomorphicLoggerFactory', {
6891
8883
  enumerable: true,
@@ -6893,16 +8885,17 @@ Object.defineProperty(exports, 'IsomorphicLoggerFactory', {
6893
8885
  return _IsomorphicLoggerFactory;
6894
8886
  }
6895
8887
  });
6896
- exports.KeyboardManager = require_filter_engine.KeyboardManager;
8888
+ exports.KeyboardManager = KeyboardManager;
6897
8889
  exports.LoggerOptionsSchema = LoggerOptionsSchema;
8890
+ exports.MANAGER_EVENTS = MANAGER_EVENTS;
6898
8891
  Object.defineProperty(exports, 'MissingAdapterOverride', {
6899
8892
  enumerable: true,
6900
8893
  get: function () {
6901
8894
  return _MissingAdapterOverride;
6902
8895
  }
6903
8896
  });
6904
- exports.PROGRESS_COLORS = require_filter_engine.PROGRESS_COLORS;
6905
- exports.PROMPT_COLORS = require_filter_engine.PROMPT_COLORS;
8897
+ exports.PROGRESS_COLORS = PROGRESS_COLORS;
8898
+ exports.PROMPT_COLORS = PROMPT_COLORS;
6906
8899
  exports.Prompt = Prompt;
6907
8900
  Object.defineProperty(exports, 'PromptInstance', {
6908
8901
  enumerable: true,
@@ -6911,9 +8904,13 @@ Object.defineProperty(exports, 'PromptInstance', {
6911
8904
  }
6912
8905
  });
6913
8906
  exports.PromptOptionsSchema = PromptOptionsSchema;
6914
- exports.SEPARATOR_COLORS = require_filter_engine.SEPARATOR_COLORS;
6915
- exports.SIDEBAR_COLORS = require_filter_engine.SIDEBAR_COLORS;
6916
- exports.STATUS_INDICATORS = require_filter_engine.STATUS_INDICATORS;
8907
+ exports.ReadlinePromptService = ReadlinePromptService;
8908
+ exports.RenderMode = RenderMode;
8909
+ exports.SCREEN_EVENTS = SCREEN_EVENTS;
8910
+ exports.SEPARATOR_COLORS = SEPARATOR_COLORS;
8911
+ exports.SIDEBAR_COLORS = SIDEBAR_COLORS;
8912
+ exports.SIDEBAR_EVENTS = SIDEBAR_EVENTS;
8913
+ exports.STATUS_INDICATORS = STATUS_INDICATORS;
6917
8914
  exports.Screen = Screen;
6918
8915
  Object.defineProperty(exports, 'ScreenFactory', {
6919
8916
  enumerable: true,
@@ -6937,28 +8934,30 @@ Object.defineProperty(exports, 'ScreenManagerInstance', {
6937
8934
  }
6938
8935
  });
6939
8936
  exports.ScreenOptionsSchema = ScreenOptionsSchema;
6940
- exports.TABLE_COLORS = require_filter_engine.TABLE_COLORS;
6941
- exports.VARIANT_COLORS = require_filter_engine.VARIANT_COLORS;
6942
- exports.captureTrace = require_filter_engine.captureTrace;
6943
- exports.createBorderColor = require_filter_engine.createBorderColor;
6944
- exports.createDefaultBindings = require_filter_engine.createDefaultBindings;
6945
- exports.createDefaultFilterState = require_filter_engine.createDefaultFilterState;
6946
- exports.createTheme = require_filter_engine.createTheme;
6947
- exports.createThemeFrom = require_filter_engine.createThemeFrom;
6948
- exports.createTintedColor = require_filter_engine.createTintedColor;
6949
- exports.darkTheme = require_filter_engine.darkTheme;
6950
- exports.formatKeyBinding = require_filter_engine.formatKeyBinding;
6951
- exports.formatObject = require_filter_engine.formatObject;
6952
- exports.getFileName = require_filter_engine.getFileName;
6953
- exports.getLogLevelColors = require_filter_engine.getLogLevelColors;
6954
- exports.getThemePreset = require_filter_engine.getThemePreset;
6955
- exports.handlePrintableInput = require_filter_engine.handlePrintableInput;
6956
- exports.hasActiveFilter = require_filter_engine.hasActiveFilter;
6957
- exports.highContrastTheme = require_filter_engine.highContrastTheme;
6958
- exports.lightTheme = require_filter_engine.lightTheme;
6959
- exports.mergeThemes = require_filter_engine.mergeThemes;
8937
+ exports.TABLE_COLORS = TABLE_COLORS;
8938
+ exports.VARIANT_COLORS = VARIANT_COLORS;
8939
+ exports.captureTrace = captureTrace;
8940
+ exports.createDefaultBindings = createDefaultBindings;
8941
+ exports.createDefaultFilterState = createDefaultFilterState;
8942
+ exports.createTheme = createTheme;
8943
+ exports.createThemeFrom = createThemeFrom;
8944
+ exports.darkTheme = darkTheme;
8945
+ exports.dynamicImport = dynamicImport;
8946
+ exports.formatKeyBinding = formatKeyBinding;
8947
+ exports.formatObject = formatObject;
8948
+ exports.getFileName = getFileName;
8949
+ exports.getLogLevelColors = getLogLevelColors;
8950
+ exports.getPromptDefaultValue = getPromptDefaultValue;
8951
+ exports.getThemePreset = getThemePreset;
8952
+ exports.handlePrintableInput = handlePrintableInput;
8953
+ exports.hasActiveFilter = hasActiveFilter;
8954
+ exports.highContrastTheme = highContrastTheme;
8955
+ exports.isBunRuntime = isBunRuntime;
8956
+ exports.lightTheme = lightTheme;
8957
+ exports.mergeThemes = mergeThemes;
6960
8958
  exports.overrideConsoleLogger = overrideConsoleLogger;
6961
- exports.printMessagesToStdout = require_filter_engine.printMessagesToStdout;
6962
- exports.resolveFiletype = require_filter_engine.resolveFiletype;
6963
- exports.resolveTheme = require_filter_engine.resolveTheme;
8959
+ exports.printMessagesToStdout = printMessagesToStdout;
8960
+ exports.printSingleMessage = printSingleMessage;
8961
+ exports.resolveFiletype = resolveFiletype;
8962
+ exports.resolveTheme = resolveTheme;
6964
8963
  //# sourceMappingURL=index.cjs.map