claudeup 1.7.0 → 3.3.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 (302) hide show
  1. package/bin/claudeup.js +20 -2
  2. package/package.json +10 -19
  3. package/src/data/cli-tools.js +123 -0
  4. package/src/data/cli-tools.ts +140 -0
  5. package/{dist → src}/data/marketplaces.js +23 -24
  6. package/src/data/marketplaces.ts +95 -0
  7. package/src/data/mcp-servers.js +509 -0
  8. package/src/data/mcp-servers.ts +526 -0
  9. package/src/data/statuslines.js +159 -0
  10. package/src/data/statuslines.ts +188 -0
  11. package/src/index.js +4 -0
  12. package/src/index.ts +5 -0
  13. package/{dist → src}/main.js +46 -47
  14. package/src/main.tsx +145 -0
  15. package/src/opentui.d.ts +191 -0
  16. package/src/prerunner/index.js +87 -0
  17. package/src/prerunner/index.ts +124 -0
  18. package/{dist → src}/services/claude-runner.js +9 -10
  19. package/src/services/claude-runner.ts +31 -0
  20. package/{dist → src}/services/claude-settings.js +72 -33
  21. package/src/services/claude-settings.ts +934 -0
  22. package/src/services/local-marketplace.js +339 -0
  23. package/src/services/local-marketplace.ts +489 -0
  24. package/{dist → src}/services/mcp-registry.js +13 -14
  25. package/src/services/mcp-registry.ts +105 -0
  26. package/{dist → src}/services/plugin-manager.js +61 -13
  27. package/src/services/plugin-manager.ts +693 -0
  28. package/{dist → src}/services/plugin-mcp-config.js +19 -18
  29. package/src/services/plugin-mcp-config.ts +242 -0
  30. package/{dist → src}/services/update-cache.js +7 -8
  31. package/src/services/update-cache.ts +78 -0
  32. package/{dist → src}/services/version-check.js +15 -14
  33. package/src/services/version-check.ts +122 -0
  34. package/src/types/index.js +1 -0
  35. package/src/types/index.ts +141 -0
  36. package/src/ui/App.js +213 -0
  37. package/src/ui/App.tsx +359 -0
  38. package/src/ui/components/CategoryHeader.js +9 -0
  39. package/src/ui/components/CategoryHeader.tsx +41 -0
  40. package/{dist → src}/ui/components/ScrollableList.js +19 -6
  41. package/src/ui/components/ScrollableList.tsx +98 -0
  42. package/src/ui/components/SearchInput.js +19 -0
  43. package/src/ui/components/SearchInput.tsx +56 -0
  44. package/src/ui/components/StyledText.js +39 -0
  45. package/src/ui/components/StyledText.tsx +70 -0
  46. package/src/ui/components/TabBar.js +38 -0
  47. package/src/ui/components/TabBar.tsx +88 -0
  48. package/src/ui/components/layout/Panel.js +6 -0
  49. package/src/ui/components/layout/Panel.tsx +62 -0
  50. package/src/ui/components/layout/ProgressBar.js +14 -0
  51. package/src/ui/components/layout/ProgressBar.tsx +47 -0
  52. package/src/ui/components/layout/ScopeTabs.js +6 -0
  53. package/src/ui/components/layout/ScopeTabs.tsx +53 -0
  54. package/src/ui/components/layout/ScreenLayout.js +21 -0
  55. package/src/ui/components/layout/ScreenLayout.tsx +147 -0
  56. package/src/ui/components/layout/index.js +4 -0
  57. package/src/ui/components/layout/index.ts +4 -0
  58. package/src/ui/components/modals/ConfirmModal.js +14 -0
  59. package/src/ui/components/modals/ConfirmModal.tsx +59 -0
  60. package/src/ui/components/modals/InputModal.js +16 -0
  61. package/src/ui/components/modals/InputModal.tsx +68 -0
  62. package/src/ui/components/modals/LoadingModal.js +14 -0
  63. package/src/ui/components/modals/LoadingModal.tsx +40 -0
  64. package/src/ui/components/modals/MessageModal.js +16 -0
  65. package/src/ui/components/modals/MessageModal.tsx +64 -0
  66. package/src/ui/components/modals/ModalContainer.js +56 -0
  67. package/src/ui/components/modals/ModalContainer.tsx +104 -0
  68. package/src/ui/components/modals/SelectModal.js +26 -0
  69. package/src/ui/components/modals/SelectModal.tsx +82 -0
  70. package/src/ui/components/modals/index.js +6 -0
  71. package/src/ui/components/modals/index.ts +6 -0
  72. package/src/ui/hooks/index.js +3 -0
  73. package/src/ui/hooks/index.ts +3 -0
  74. package/{dist → src}/ui/hooks/useAsyncData.js +21 -22
  75. package/src/ui/hooks/useAsyncData.ts +127 -0
  76. package/src/ui/hooks/useKeyboard.js +13 -0
  77. package/src/ui/hooks/useKeyboard.ts +26 -0
  78. package/src/ui/hooks/useKeyboardHandler.js +39 -0
  79. package/src/ui/hooks/useKeyboardHandler.ts +63 -0
  80. package/{dist → src}/ui/screens/CliToolsScreen.js +60 -54
  81. package/src/ui/screens/CliToolsScreen.tsx +468 -0
  82. package/src/ui/screens/EnvVarsScreen.js +154 -0
  83. package/src/ui/screens/EnvVarsScreen.tsx +269 -0
  84. package/{dist → src}/ui/screens/McpRegistryScreen.js +56 -55
  85. package/src/ui/screens/McpRegistryScreen.tsx +331 -0
  86. package/{dist → src}/ui/screens/McpScreen.js +46 -47
  87. package/src/ui/screens/McpScreen.tsx +392 -0
  88. package/src/ui/screens/ModelSelectorScreen.js +292 -0
  89. package/src/ui/screens/ModelSelectorScreen.tsx +441 -0
  90. package/{dist → src}/ui/screens/PluginsScreen.js +305 -293
  91. package/src/ui/screens/PluginsScreen.tsx +1231 -0
  92. package/src/ui/screens/StatusLineScreen.js +200 -0
  93. package/src/ui/screens/StatusLineScreen.tsx +411 -0
  94. package/src/ui/screens/index.js +7 -0
  95. package/src/ui/screens/index.ts +7 -0
  96. package/src/ui/state/AnimationContext.js +34 -0
  97. package/src/ui/state/AnimationContext.tsx +76 -0
  98. package/{dist → src}/ui/state/AppContext.js +31 -32
  99. package/src/ui/state/AppContext.tsx +235 -0
  100. package/{dist → src}/ui/state/DimensionsContext.js +16 -17
  101. package/src/ui/state/DimensionsContext.tsx +144 -0
  102. package/{dist → src}/ui/state/reducer.js +89 -90
  103. package/src/ui/state/reducer.ts +467 -0
  104. package/src/ui/state/types.js +1 -0
  105. package/src/ui/state/types.ts +273 -0
  106. package/{dist → src}/utils/command-utils.js +3 -4
  107. package/src/utils/command-utils.ts +20 -0
  108. package/{dist → src}/utils/fuzzy-search.js +2 -3
  109. package/src/utils/fuzzy-search.ts +138 -0
  110. package/{dist → src}/utils/string-utils.js +6 -6
  111. package/src/utils/string-utils.ts +88 -0
  112. package/dist/data/cli-tools.d.ts +0 -13
  113. package/dist/data/cli-tools.d.ts.map +0 -1
  114. package/dist/data/cli-tools.js +0 -124
  115. package/dist/data/cli-tools.js.map +0 -1
  116. package/dist/data/marketplaces.d.ts +0 -6
  117. package/dist/data/marketplaces.d.ts.map +0 -1
  118. package/dist/data/marketplaces.js.map +0 -1
  119. package/dist/data/mcp-servers.d.ts +0 -8
  120. package/dist/data/mcp-servers.d.ts.map +0 -1
  121. package/dist/data/mcp-servers.js +0 -503
  122. package/dist/data/mcp-servers.js.map +0 -1
  123. package/dist/data/statuslines.d.ts +0 -10
  124. package/dist/data/statuslines.d.ts.map +0 -1
  125. package/dist/data/statuslines.js +0 -160
  126. package/dist/data/statuslines.js.map +0 -1
  127. package/dist/index.d.ts +0 -3
  128. package/dist/index.d.ts.map +0 -1
  129. package/dist/index.js +0 -90
  130. package/dist/index.js.map +0 -1
  131. package/dist/main.d.ts +0 -3
  132. package/dist/main.d.ts.map +0 -1
  133. package/dist/main.js.map +0 -1
  134. package/dist/prerunner/index.d.ts +0 -7
  135. package/dist/prerunner/index.d.ts.map +0 -1
  136. package/dist/prerunner/index.js +0 -64
  137. package/dist/prerunner/index.js.map +0 -1
  138. package/dist/services/claude-runner.d.ts +0 -7
  139. package/dist/services/claude-runner.d.ts.map +0 -1
  140. package/dist/services/claude-runner.js.map +0 -1
  141. package/dist/services/claude-settings.d.ts +0 -73
  142. package/dist/services/claude-settings.d.ts.map +0 -1
  143. package/dist/services/claude-settings.js.map +0 -1
  144. package/dist/services/local-marketplace.d.ts +0 -111
  145. package/dist/services/local-marketplace.d.ts.map +0 -1
  146. package/dist/services/local-marketplace.js +0 -599
  147. package/dist/services/local-marketplace.js.map +0 -1
  148. package/dist/services/mcp-registry.d.ts +0 -10
  149. package/dist/services/mcp-registry.d.ts.map +0 -1
  150. package/dist/services/mcp-registry.js.map +0 -1
  151. package/dist/services/plugin-manager.d.ts +0 -65
  152. package/dist/services/plugin-manager.d.ts.map +0 -1
  153. package/dist/services/plugin-manager.js.map +0 -1
  154. package/dist/services/plugin-mcp-config.d.ts +0 -52
  155. package/dist/services/plugin-mcp-config.d.ts.map +0 -1
  156. package/dist/services/plugin-mcp-config.js.map +0 -1
  157. package/dist/services/update-cache.d.ts +0 -16
  158. package/dist/services/update-cache.d.ts.map +0 -1
  159. package/dist/services/update-cache.js.map +0 -1
  160. package/dist/services/version-check.d.ts +0 -20
  161. package/dist/services/version-check.d.ts.map +0 -1
  162. package/dist/services/version-check.js.map +0 -1
  163. package/dist/types/index.d.ts +0 -105
  164. package/dist/types/index.d.ts.map +0 -1
  165. package/dist/types/index.js +0 -2
  166. package/dist/types/index.js.map +0 -1
  167. package/dist/ui/InkApp.d.ts +0 -5
  168. package/dist/ui/InkApp.d.ts.map +0 -1
  169. package/dist/ui/InkApp.js +0 -188
  170. package/dist/ui/InkApp.js.map +0 -1
  171. package/dist/ui/components/CategoryHeader.d.ts +0 -16
  172. package/dist/ui/components/CategoryHeader.d.ts.map +0 -1
  173. package/dist/ui/components/CategoryHeader.js +0 -11
  174. package/dist/ui/components/CategoryHeader.js.map +0 -1
  175. package/dist/ui/components/ScrollableList.d.ts +0 -16
  176. package/dist/ui/components/ScrollableList.d.ts.map +0 -1
  177. package/dist/ui/components/ScrollableList.js.map +0 -1
  178. package/dist/ui/components/SearchInput.d.ts +0 -18
  179. package/dist/ui/components/SearchInput.d.ts.map +0 -1
  180. package/dist/ui/components/SearchInput.js +0 -30
  181. package/dist/ui/components/SearchInput.js.map +0 -1
  182. package/dist/ui/components/TabBar.d.ts +0 -8
  183. package/dist/ui/components/TabBar.d.ts.map +0 -1
  184. package/dist/ui/components/TabBar.js +0 -18
  185. package/dist/ui/components/TabBar.js.map +0 -1
  186. package/dist/ui/components/layout/Footer.d.ts +0 -14
  187. package/dist/ui/components/layout/Footer.d.ts.map +0 -1
  188. package/dist/ui/components/layout/Footer.js +0 -23
  189. package/dist/ui/components/layout/Footer.js.map +0 -1
  190. package/dist/ui/components/layout/Header.d.ts +0 -4
  191. package/dist/ui/components/layout/Header.d.ts.map +0 -1
  192. package/dist/ui/components/layout/Header.js +0 -25
  193. package/dist/ui/components/layout/Header.js.map +0 -1
  194. package/dist/ui/components/layout/Panel.d.ts +0 -22
  195. package/dist/ui/components/layout/Panel.d.ts.map +0 -1
  196. package/dist/ui/components/layout/Panel.js +0 -8
  197. package/dist/ui/components/layout/Panel.js.map +0 -1
  198. package/dist/ui/components/layout/ProgressBar.d.ts +0 -12
  199. package/dist/ui/components/layout/ProgressBar.d.ts.map +0 -1
  200. package/dist/ui/components/layout/ProgressBar.js +0 -16
  201. package/dist/ui/components/layout/ProgressBar.js.map +0 -1
  202. package/dist/ui/components/layout/ScopeTabs.d.ts +0 -12
  203. package/dist/ui/components/layout/ScopeTabs.d.ts.map +0 -1
  204. package/dist/ui/components/layout/ScopeTabs.js +0 -8
  205. package/dist/ui/components/layout/ScopeTabs.js.map +0 -1
  206. package/dist/ui/components/layout/ScreenLayout.d.ts +0 -30
  207. package/dist/ui/components/layout/ScreenLayout.d.ts.map +0 -1
  208. package/dist/ui/components/layout/ScreenLayout.js +0 -23
  209. package/dist/ui/components/layout/ScreenLayout.js.map +0 -1
  210. package/dist/ui/components/layout/index.d.ts +0 -7
  211. package/dist/ui/components/layout/index.d.ts.map +0 -1
  212. package/dist/ui/components/layout/index.js +0 -7
  213. package/dist/ui/components/layout/index.js.map +0 -1
  214. package/dist/ui/components/modals/ConfirmModal.d.ts +0 -14
  215. package/dist/ui/components/modals/ConfirmModal.d.ts.map +0 -1
  216. package/dist/ui/components/modals/ConfirmModal.js +0 -15
  217. package/dist/ui/components/modals/ConfirmModal.js.map +0 -1
  218. package/dist/ui/components/modals/InputModal.d.ts +0 -16
  219. package/dist/ui/components/modals/InputModal.d.ts.map +0 -1
  220. package/dist/ui/components/modals/InputModal.js +0 -23
  221. package/dist/ui/components/modals/InputModal.js.map +0 -1
  222. package/dist/ui/components/modals/LoadingModal.d.ts +0 -8
  223. package/dist/ui/components/modals/LoadingModal.d.ts.map +0 -1
  224. package/dist/ui/components/modals/LoadingModal.js +0 -8
  225. package/dist/ui/components/modals/LoadingModal.js.map +0 -1
  226. package/dist/ui/components/modals/MessageModal.d.ts +0 -14
  227. package/dist/ui/components/modals/MessageModal.d.ts.map +0 -1
  228. package/dist/ui/components/modals/MessageModal.js +0 -17
  229. package/dist/ui/components/modals/MessageModal.js.map +0 -1
  230. package/dist/ui/components/modals/ModalContainer.d.ts +0 -7
  231. package/dist/ui/components/modals/ModalContainer.d.ts.map +0 -1
  232. package/dist/ui/components/modals/ModalContainer.js +0 -38
  233. package/dist/ui/components/modals/ModalContainer.js.map +0 -1
  234. package/dist/ui/components/modals/SelectModal.d.ts +0 -17
  235. package/dist/ui/components/modals/SelectModal.d.ts.map +0 -1
  236. package/dist/ui/components/modals/SelectModal.js +0 -33
  237. package/dist/ui/components/modals/SelectModal.js.map +0 -1
  238. package/dist/ui/components/modals/index.d.ts +0 -7
  239. package/dist/ui/components/modals/index.d.ts.map +0 -1
  240. package/dist/ui/components/modals/index.js +0 -7
  241. package/dist/ui/components/modals/index.js.map +0 -1
  242. package/dist/ui/hooks/index.d.ts +0 -3
  243. package/dist/ui/hooks/index.d.ts.map +0 -1
  244. package/dist/ui/hooks/index.js +0 -3
  245. package/dist/ui/hooks/index.js.map +0 -1
  246. package/dist/ui/hooks/useAsyncData.d.ts +0 -40
  247. package/dist/ui/hooks/useAsyncData.d.ts.map +0 -1
  248. package/dist/ui/hooks/useAsyncData.js.map +0 -1
  249. package/dist/ui/hooks/useKeyboardNavigation.d.ts +0 -27
  250. package/dist/ui/hooks/useKeyboardNavigation.d.ts.map +0 -1
  251. package/dist/ui/hooks/useKeyboardNavigation.js +0 -82
  252. package/dist/ui/hooks/useKeyboardNavigation.js.map +0 -1
  253. package/dist/ui/screens/CliToolsScreen.d.ts +0 -4
  254. package/dist/ui/screens/CliToolsScreen.d.ts.map +0 -1
  255. package/dist/ui/screens/CliToolsScreen.js.map +0 -1
  256. package/dist/ui/screens/EnvVarsScreen.d.ts +0 -4
  257. package/dist/ui/screens/EnvVarsScreen.d.ts.map +0 -1
  258. package/dist/ui/screens/EnvVarsScreen.js +0 -145
  259. package/dist/ui/screens/EnvVarsScreen.js.map +0 -1
  260. package/dist/ui/screens/McpRegistryScreen.d.ts +0 -4
  261. package/dist/ui/screens/McpRegistryScreen.d.ts.map +0 -1
  262. package/dist/ui/screens/McpRegistryScreen.js.map +0 -1
  263. package/dist/ui/screens/McpScreen.d.ts +0 -4
  264. package/dist/ui/screens/McpScreen.d.ts.map +0 -1
  265. package/dist/ui/screens/McpScreen.js.map +0 -1
  266. package/dist/ui/screens/ModelSelectorScreen.d.ts +0 -4
  267. package/dist/ui/screens/ModelSelectorScreen.d.ts.map +0 -1
  268. package/dist/ui/screens/ModelSelectorScreen.js +0 -143
  269. package/dist/ui/screens/ModelSelectorScreen.js.map +0 -1
  270. package/dist/ui/screens/PluginsScreen.d.ts +0 -4
  271. package/dist/ui/screens/PluginsScreen.d.ts.map +0 -1
  272. package/dist/ui/screens/PluginsScreen.js.map +0 -1
  273. package/dist/ui/screens/StatusLineScreen.d.ts +0 -4
  274. package/dist/ui/screens/StatusLineScreen.d.ts.map +0 -1
  275. package/dist/ui/screens/StatusLineScreen.js +0 -197
  276. package/dist/ui/screens/StatusLineScreen.js.map +0 -1
  277. package/dist/ui/screens/index.d.ts +0 -8
  278. package/dist/ui/screens/index.d.ts.map +0 -1
  279. package/dist/ui/screens/index.js +0 -8
  280. package/dist/ui/screens/index.js.map +0 -1
  281. package/dist/ui/state/AppContext.d.ts +0 -40
  282. package/dist/ui/state/AppContext.d.ts.map +0 -1
  283. package/dist/ui/state/AppContext.js.map +0 -1
  284. package/dist/ui/state/DimensionsContext.d.ts +0 -27
  285. package/dist/ui/state/DimensionsContext.d.ts.map +0 -1
  286. package/dist/ui/state/DimensionsContext.js.map +0 -1
  287. package/dist/ui/state/reducer.d.ts +0 -4
  288. package/dist/ui/state/reducer.d.ts.map +0 -1
  289. package/dist/ui/state/reducer.js.map +0 -1
  290. package/dist/ui/state/types.d.ts +0 -266
  291. package/dist/ui/state/types.d.ts.map +0 -1
  292. package/dist/ui/state/types.js +0 -2
  293. package/dist/ui/state/types.js.map +0 -1
  294. package/dist/utils/command-utils.d.ts +0 -8
  295. package/dist/utils/command-utils.d.ts.map +0 -1
  296. package/dist/utils/command-utils.js.map +0 -1
  297. package/dist/utils/fuzzy-search.d.ts +0 -33
  298. package/dist/utils/fuzzy-search.d.ts.map +0 -1
  299. package/dist/utils/fuzzy-search.js.map +0 -1
  300. package/dist/utils/string-utils.d.ts +0 -24
  301. package/dist/utils/string-utils.d.ts.map +0 -1
  302. package/dist/utils/string-utils.js.map +0 -1
@@ -0,0 +1,76 @@
1
+ import React, {
2
+ createContext,
3
+ useContext,
4
+ useState,
5
+ type ReactNode,
6
+ } from "react";
7
+
8
+ // ============================================================================
9
+ // Context Type
10
+ // ============================================================================
11
+
12
+ interface Timeline {
13
+ id: string;
14
+ // Timeline instance from useTimeline hook
15
+ instance: any;
16
+ }
17
+
18
+ interface AnimationContextValue {
19
+ timelines: Map<string, any>;
20
+ registerTimeline: (id: string, timeline: any) => void;
21
+ unregisterTimeline: (id: string) => void;
22
+ }
23
+
24
+ // ============================================================================
25
+ // Context
26
+ // ============================================================================
27
+
28
+ const AnimationContext = createContext<AnimationContextValue | null>(null);
29
+
30
+ // ============================================================================
31
+ // Provider
32
+ // ============================================================================
33
+
34
+ interface AnimationProviderProps {
35
+ children: ReactNode;
36
+ }
37
+
38
+ export function AnimationProvider({ children }: AnimationProviderProps) {
39
+ const [timelines, setTimelines] = useState<Map<string, any>>(new Map());
40
+
41
+ const registerTimeline = (id: string, timeline: any) => {
42
+ setTimelines((prev) => {
43
+ const next = new Map(prev);
44
+ next.set(id, timeline);
45
+ return next;
46
+ });
47
+ };
48
+
49
+ const unregisterTimeline = (id: string) => {
50
+ setTimelines((prev) => {
51
+ const next = new Map(prev);
52
+ next.delete(id);
53
+ return next;
54
+ });
55
+ };
56
+
57
+ return (
58
+ <AnimationContext.Provider
59
+ value={{ timelines, registerTimeline, unregisterTimeline }}
60
+ >
61
+ {children}
62
+ </AnimationContext.Provider>
63
+ );
64
+ }
65
+
66
+ // ============================================================================
67
+ // Hook: useAnimation
68
+ // ============================================================================
69
+
70
+ export function useAnimation(): AnimationContextValue {
71
+ const context = useContext(AnimationContext);
72
+ if (!context) {
73
+ throw new Error("useAnimation must be used within an AnimationProvider");
74
+ }
75
+ return context;
76
+ }
@@ -1,16 +1,16 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import { createContext, useContext, useReducer } from 'react';
3
- import { appReducer, initialState } from './reducer.js';
1
+ import { jsx as _jsx } from "@opentui/react/jsx-runtime";
2
+ import { createContext, useContext, useReducer, } from "react";
3
+ import { appReducer, initialState } from "./reducer.js";
4
4
  // ============================================================================
5
5
  // Context
6
6
  // ============================================================================
7
7
  const AppContext = createContext(null);
8
- export function AppProvider({ children, initialProjectPath }) {
8
+ export function AppProvider({ children, initialProjectPath, }) {
9
9
  const [state, dispatch] = useReducer(appReducer, {
10
10
  ...initialState,
11
11
  projectPath: initialProjectPath || process.cwd(),
12
12
  });
13
- return _jsx(AppContext.Provider, { value: { state, dispatch }, children: children });
13
+ return (_jsx(AppContext.Provider, { value: { state, dispatch }, children: children }));
14
14
  }
15
15
  // ============================================================================
16
16
  // Hook: useApp
@@ -18,7 +18,7 @@ export function AppProvider({ children, initialProjectPath }) {
18
18
  export function useApp() {
19
19
  const context = useContext(AppContext);
20
20
  if (!context) {
21
- throw new Error('useApp must be used within an AppProvider');
21
+ throw new Error("useApp must be used within an AppProvider");
22
22
  }
23
23
  return context;
24
24
  }
@@ -31,10 +31,10 @@ export function useNavigation() {
31
31
  currentRoute: state.currentRoute,
32
32
  currentScreen: state.currentRoute.screen,
33
33
  navigateTo: (route) => {
34
- dispatch({ type: 'NAVIGATE', route });
34
+ dispatch({ type: "NAVIGATE", route });
35
35
  },
36
36
  navigateToScreen: (screen) => {
37
- dispatch({ type: 'NAVIGATE', route: { screen } });
37
+ dispatch({ type: "NAVIGATE", route: { screen } });
38
38
  },
39
39
  };
40
40
  }
@@ -45,25 +45,25 @@ export function useModal() {
45
45
  const { dispatch } = useApp();
46
46
  return {
47
47
  showModal: (modal) => {
48
- dispatch({ type: 'SHOW_MODAL', modal });
48
+ dispatch({ type: "SHOW_MODAL", modal });
49
49
  },
50
50
  hideModal: () => {
51
- dispatch({ type: 'HIDE_MODAL' });
51
+ dispatch({ type: "HIDE_MODAL" });
52
52
  },
53
53
  confirm: (title, message) => {
54
54
  return new Promise((resolve) => {
55
55
  dispatch({
56
- type: 'SHOW_MODAL',
56
+ type: "SHOW_MODAL",
57
57
  modal: {
58
- type: 'confirm',
58
+ type: "confirm",
59
59
  title,
60
60
  message,
61
61
  onConfirm: () => {
62
- dispatch({ type: 'HIDE_MODAL' });
62
+ dispatch({ type: "HIDE_MODAL" });
63
63
  resolve(true);
64
64
  },
65
65
  onCancel: () => {
66
- dispatch({ type: 'HIDE_MODAL' });
66
+ dispatch({ type: "HIDE_MODAL" });
67
67
  resolve(false);
68
68
  },
69
69
  },
@@ -73,18 +73,18 @@ export function useModal() {
73
73
  input: (title, label, defaultValue) => {
74
74
  return new Promise((resolve) => {
75
75
  dispatch({
76
- type: 'SHOW_MODAL',
76
+ type: "SHOW_MODAL",
77
77
  modal: {
78
- type: 'input',
78
+ type: "input",
79
79
  title,
80
80
  label,
81
81
  defaultValue,
82
82
  onSubmit: (value) => {
83
- dispatch({ type: 'HIDE_MODAL' });
83
+ dispatch({ type: "HIDE_MODAL" });
84
84
  resolve(value);
85
85
  },
86
86
  onCancel: () => {
87
- dispatch({ type: 'HIDE_MODAL' });
87
+ dispatch({ type: "HIDE_MODAL" });
88
88
  resolve(null);
89
89
  },
90
90
  },
@@ -94,35 +94,35 @@ export function useModal() {
94
94
  select: (title, message, options) => {
95
95
  return new Promise((resolve) => {
96
96
  dispatch({
97
- type: 'SHOW_MODAL',
97
+ type: "SHOW_MODAL",
98
98
  modal: {
99
- type: 'select',
99
+ type: "select",
100
100
  title,
101
101
  message,
102
102
  options,
103
103
  onSelect: (value) => {
104
- dispatch({ type: 'HIDE_MODAL' });
104
+ dispatch({ type: "HIDE_MODAL" });
105
105
  resolve(value);
106
106
  },
107
107
  onCancel: () => {
108
- dispatch({ type: 'HIDE_MODAL' });
108
+ dispatch({ type: "HIDE_MODAL" });
109
109
  resolve(null);
110
110
  },
111
111
  },
112
112
  });
113
113
  });
114
114
  },
115
- message: (title, message, variant = 'info') => {
115
+ message: (title, message, variant = "info") => {
116
116
  return new Promise((resolve) => {
117
117
  dispatch({
118
- type: 'SHOW_MODAL',
118
+ type: "SHOW_MODAL",
119
119
  modal: {
120
- type: 'message',
120
+ type: "message",
121
121
  title,
122
122
  message,
123
123
  variant,
124
124
  onDismiss: () => {
125
- dispatch({ type: 'HIDE_MODAL' });
125
+ dispatch({ type: "HIDE_MODAL" });
126
126
  resolve();
127
127
  },
128
128
  },
@@ -131,9 +131,9 @@ export function useModal() {
131
131
  },
132
132
  loading: (message) => {
133
133
  dispatch({
134
- type: 'SHOW_MODAL',
134
+ type: "SHOW_MODAL",
135
135
  modal: {
136
- type: 'loading',
136
+ type: "loading",
137
137
  message,
138
138
  },
139
139
  });
@@ -149,14 +149,13 @@ export function useProgress() {
149
149
  progress: state.progress,
150
150
  isVisible: state.progress !== null,
151
151
  show: (message, current, total) => {
152
- dispatch({ type: 'SHOW_PROGRESS', state: { message, current, total } });
152
+ dispatch({ type: "SHOW_PROGRESS", state: { message, current, total } });
153
153
  },
154
154
  update: (state) => {
155
- dispatch({ type: 'UPDATE_PROGRESS', state });
155
+ dispatch({ type: "UPDATE_PROGRESS", state });
156
156
  },
157
157
  hide: () => {
158
- dispatch({ type: 'HIDE_PROGRESS' });
158
+ dispatch({ type: "HIDE_PROGRESS" });
159
159
  },
160
160
  };
161
161
  }
162
- //# sourceMappingURL=AppContext.js.map
@@ -0,0 +1,235 @@
1
+ import React, {
2
+ createContext,
3
+ useContext,
4
+ useReducer,
5
+ type ReactNode,
6
+ } from "react";
7
+ import { appReducer, initialState } from "./reducer.js";
8
+ import type {
9
+ AppState,
10
+ AppAction,
11
+ Route,
12
+ ModalState,
13
+ ProgressState,
14
+ } from "./types.js";
15
+
16
+ // ============================================================================
17
+ // Context Type
18
+ // ============================================================================
19
+
20
+ interface AppContextValue {
21
+ state: AppState;
22
+ dispatch: React.Dispatch<AppAction>;
23
+ }
24
+
25
+ // ============================================================================
26
+ // Context
27
+ // ============================================================================
28
+
29
+ const AppContext = createContext<AppContextValue | null>(null);
30
+
31
+ // ============================================================================
32
+ // Provider
33
+ // ============================================================================
34
+
35
+ interface AppProviderProps {
36
+ children: ReactNode;
37
+ initialProjectPath?: string;
38
+ }
39
+
40
+ export function AppProvider({
41
+ children,
42
+ initialProjectPath,
43
+ }: AppProviderProps) {
44
+ const [state, dispatch] = useReducer(appReducer, {
45
+ ...initialState,
46
+ projectPath: initialProjectPath || process.cwd(),
47
+ });
48
+
49
+ return (
50
+ <AppContext.Provider value={{ state, dispatch }}>
51
+ {children}
52
+ </AppContext.Provider>
53
+ );
54
+ }
55
+
56
+ // ============================================================================
57
+ // Hook: useApp
58
+ // ============================================================================
59
+
60
+ export function useApp(): AppContextValue {
61
+ const context = useContext(AppContext);
62
+ if (!context) {
63
+ throw new Error("useApp must be used within an AppProvider");
64
+ }
65
+ return context;
66
+ }
67
+
68
+ // ============================================================================
69
+ // Hook: useNavigation
70
+ // ============================================================================
71
+
72
+ export function useNavigation() {
73
+ const { state, dispatch } = useApp();
74
+
75
+ return {
76
+ currentRoute: state.currentRoute,
77
+ currentScreen: state.currentRoute.screen,
78
+
79
+ navigateTo: (route: Route) => {
80
+ dispatch({ type: "NAVIGATE", route });
81
+ },
82
+
83
+ navigateToScreen: (screen: Route["screen"]) => {
84
+ dispatch({ type: "NAVIGATE", route: { screen } as Route });
85
+ },
86
+ };
87
+ }
88
+
89
+ // ============================================================================
90
+ // Hook: useModal
91
+ // ============================================================================
92
+
93
+ export function useModal() {
94
+ const { dispatch } = useApp();
95
+
96
+ return {
97
+ showModal: (modal: ModalState) => {
98
+ dispatch({ type: "SHOW_MODAL", modal });
99
+ },
100
+
101
+ hideModal: () => {
102
+ dispatch({ type: "HIDE_MODAL" });
103
+ },
104
+
105
+ confirm: (title: string, message: string): Promise<boolean> => {
106
+ return new Promise((resolve) => {
107
+ dispatch({
108
+ type: "SHOW_MODAL",
109
+ modal: {
110
+ type: "confirm",
111
+ title,
112
+ message,
113
+ onConfirm: () => {
114
+ dispatch({ type: "HIDE_MODAL" });
115
+ resolve(true);
116
+ },
117
+ onCancel: () => {
118
+ dispatch({ type: "HIDE_MODAL" });
119
+ resolve(false);
120
+ },
121
+ },
122
+ });
123
+ });
124
+ },
125
+
126
+ input: (
127
+ title: string,
128
+ label: string,
129
+ defaultValue?: string,
130
+ ): Promise<string | null> => {
131
+ return new Promise((resolve) => {
132
+ dispatch({
133
+ type: "SHOW_MODAL",
134
+ modal: {
135
+ type: "input",
136
+ title,
137
+ label,
138
+ defaultValue,
139
+ onSubmit: (value: string) => {
140
+ dispatch({ type: "HIDE_MODAL" });
141
+ resolve(value);
142
+ },
143
+ onCancel: () => {
144
+ dispatch({ type: "HIDE_MODAL" });
145
+ resolve(null);
146
+ },
147
+ },
148
+ });
149
+ });
150
+ },
151
+
152
+ select: (
153
+ title: string,
154
+ message: string,
155
+ options: { label: string; value: string; description?: string }[],
156
+ ): Promise<string | null> => {
157
+ return new Promise((resolve) => {
158
+ dispatch({
159
+ type: "SHOW_MODAL",
160
+ modal: {
161
+ type: "select",
162
+ title,
163
+ message,
164
+ options,
165
+ onSelect: (value: string) => {
166
+ dispatch({ type: "HIDE_MODAL" });
167
+ resolve(value);
168
+ },
169
+ onCancel: () => {
170
+ dispatch({ type: "HIDE_MODAL" });
171
+ resolve(null);
172
+ },
173
+ },
174
+ });
175
+ });
176
+ },
177
+
178
+ message: (
179
+ title: string,
180
+ message: string,
181
+ variant: "info" | "success" | "error" = "info",
182
+ ): Promise<void> => {
183
+ return new Promise((resolve) => {
184
+ dispatch({
185
+ type: "SHOW_MODAL",
186
+ modal: {
187
+ type: "message",
188
+ title,
189
+ message,
190
+ variant,
191
+ onDismiss: () => {
192
+ dispatch({ type: "HIDE_MODAL" });
193
+ resolve();
194
+ },
195
+ },
196
+ });
197
+ });
198
+ },
199
+
200
+ loading: (message: string) => {
201
+ dispatch({
202
+ type: "SHOW_MODAL",
203
+ modal: {
204
+ type: "loading",
205
+ message,
206
+ },
207
+ });
208
+ },
209
+ };
210
+ }
211
+
212
+ // ============================================================================
213
+ // Hook: useProgress
214
+ // ============================================================================
215
+
216
+ export function useProgress() {
217
+ const { state, dispatch } = useApp();
218
+
219
+ return {
220
+ progress: state.progress,
221
+ isVisible: state.progress !== null,
222
+
223
+ show: (message: string, current?: number, total?: number) => {
224
+ dispatch({ type: "SHOW_PROGRESS", state: { message, current, total } });
225
+ },
226
+
227
+ update: (state: ProgressState) => {
228
+ dispatch({ type: "UPDATE_PROGRESS", state });
229
+ },
230
+
231
+ hide: () => {
232
+ dispatch({ type: "HIDE_PROGRESS" });
233
+ },
234
+ };
235
+ }
@@ -1,6 +1,6 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import { createContext, useContext, useState, useEffect } from 'react';
3
- import { useStdout } from 'ink';
1
+ import { jsx as _jsx } from "@opentui/react/jsx-runtime";
2
+ import { createContext, useContext, useState, useEffect } from "react";
3
+ import { useRenderer, useOnResize } from "@opentui/react";
4
4
  const DimensionsContext = createContext(null);
5
5
  // Fixed heights for layout elements
6
6
  const SCREEN_HEADER_HEIGHT = 4; // ScreenLayout: border + title row + status/search row + border
@@ -34,22 +34,22 @@ function calculateDimensions(columns, rows, showProgress, showDebug, showUpdateB
34
34
  };
35
35
  }
36
36
  export function DimensionsProvider({ children, showProgress = false, showDebug = false, showUpdateBanner = false, }) {
37
- const { stdout } = useStdout();
38
- const [dimensions, setDimensions] = useState(() => calculateDimensions(stdout?.columns ?? 80, stdout?.rows ?? 24, showProgress, showDebug, showUpdateBanner));
37
+ const renderer = useRenderer();
38
+ const [dimensions, setDimensions] = useState(() => calculateDimensions(renderer.width, renderer.height, showProgress, showDebug, showUpdateBanner));
39
39
  // Handle terminal resize
40
- useEffect(() => {
41
- const handleResize = () => {
42
- setDimensions(calculateDimensions(stdout?.columns ?? 80, stdout?.rows ?? 24, showProgress, showDebug, showUpdateBanner));
43
- };
44
- stdout?.on('resize', handleResize);
45
- return () => {
46
- stdout?.off('resize', handleResize);
47
- };
48
- }, [stdout, showProgress, showDebug, showUpdateBanner]);
40
+ useOnResize((width, height) => {
41
+ setDimensions(calculateDimensions(width, height, showProgress, showDebug, showUpdateBanner));
42
+ });
49
43
  // Update when showProgress/showDebug/showUpdateBanner changes
50
44
  useEffect(() => {
51
- setDimensions(calculateDimensions(stdout?.columns ?? 80, stdout?.rows ?? 24, showProgress, showDebug, showUpdateBanner));
52
- }, [stdout?.columns, stdout?.rows, showProgress, showDebug, showUpdateBanner]);
45
+ setDimensions(calculateDimensions(renderer.width, renderer.height, showProgress, showDebug, showUpdateBanner));
46
+ }, [
47
+ renderer.width,
48
+ renderer.height,
49
+ showProgress,
50
+ showDebug,
51
+ showUpdateBanner,
52
+ ]);
53
53
  return (_jsx(DimensionsContext.Provider, { value: dimensions, children: children }));
54
54
  }
55
55
  export function useDimensions() {
@@ -67,4 +67,3 @@ export function useDimensions() {
67
67
  return context;
68
68
  }
69
69
  export default DimensionsContext;
70
- //# sourceMappingURL=DimensionsContext.js.map
@@ -0,0 +1,144 @@
1
+ import React, { createContext, useContext, useState, useEffect } from "react";
2
+ import { useRenderer, useOnResize } from "@opentui/react";
3
+
4
+ interface Dimensions {
5
+ /** Terminal width */
6
+ terminalWidth: number;
7
+ /** Terminal height */
8
+ terminalHeight: number;
9
+ /** Available height for main content (excluding header, footer, margins) */
10
+ contentHeight: number;
11
+ /** Available width for content (excluding borders, padding) */
12
+ contentWidth: number;
13
+ /** Available lines for ScrollableList in list panels */
14
+ listPanelHeight: number;
15
+ }
16
+
17
+ const DimensionsContext = createContext<Dimensions | null>(null);
18
+
19
+ // Fixed heights for layout elements
20
+ const SCREEN_HEADER_HEIGHT = 4; // ScreenLayout: border + title row + status/search row + border
21
+ const SCREEN_FOOTER_HEIGHT = 2; // ScreenLayout: border-top + footer content
22
+ const APP_MARGINS = 1; // buffer for margins/padding
23
+ const PROGRESS_HEIGHT = 1; // when visible
24
+
25
+ interface DimensionsProviderProps {
26
+ children: React.ReactNode;
27
+ /** Whether progress bar is visible */
28
+ showProgress?: boolean;
29
+ /** Whether debug bar is visible */
30
+ showDebug?: boolean;
31
+ /** Whether update banner is visible */
32
+ showUpdateBanner?: boolean;
33
+ }
34
+
35
+ function calculateDimensions(
36
+ columns: number,
37
+ rows: number,
38
+ showProgress: boolean,
39
+ showDebug: boolean,
40
+ showUpdateBanner: boolean,
41
+ ): Dimensions {
42
+ const terminalWidth = columns;
43
+ const terminalHeight = rows;
44
+
45
+ // Calculate total available height for ScreenLayout (includes its header, panels, footer)
46
+ let contentHeight = terminalHeight - APP_MARGINS;
47
+ if (showProgress) contentHeight -= PROGRESS_HEIGHT;
48
+ if (showDebug) contentHeight -= 1;
49
+ if (showUpdateBanner) contentHeight -= 1;
50
+ contentHeight = Math.max(10, contentHeight); // Minimum 10 lines for full layout
51
+
52
+ // Calculate available content width (accounting for padding)
53
+ const contentWidth = Math.max(40, terminalWidth - 4);
54
+
55
+ // Calculate list panel height for ScrollableList
56
+ // ScreenLayout uses: panelHeight = contentHeight - 4 (header) - 1 (footer)
57
+ // The ScrollableList sits inside the panel
58
+ const listPanelHeight = Math.max(
59
+ 3,
60
+ contentHeight - SCREEN_HEADER_HEIGHT - SCREEN_FOOTER_HEIGHT,
61
+ );
62
+
63
+ return {
64
+ terminalWidth,
65
+ terminalHeight,
66
+ contentHeight,
67
+ contentWidth,
68
+ listPanelHeight,
69
+ };
70
+ }
71
+
72
+ export function DimensionsProvider({
73
+ children,
74
+ showProgress = false,
75
+ showDebug = false,
76
+ showUpdateBanner = false,
77
+ }: DimensionsProviderProps) {
78
+ const renderer = useRenderer();
79
+
80
+ const [dimensions, setDimensions] = useState<Dimensions>(() =>
81
+ calculateDimensions(
82
+ renderer.width,
83
+ renderer.height,
84
+ showProgress,
85
+ showDebug,
86
+ showUpdateBanner,
87
+ ),
88
+ );
89
+
90
+ // Handle terminal resize
91
+ useOnResize((width, height) => {
92
+ setDimensions(
93
+ calculateDimensions(
94
+ width,
95
+ height,
96
+ showProgress,
97
+ showDebug,
98
+ showUpdateBanner,
99
+ ),
100
+ );
101
+ });
102
+
103
+ // Update when showProgress/showDebug/showUpdateBanner changes
104
+ useEffect(() => {
105
+ setDimensions(
106
+ calculateDimensions(
107
+ renderer.width,
108
+ renderer.height,
109
+ showProgress,
110
+ showDebug,
111
+ showUpdateBanner,
112
+ ),
113
+ );
114
+ }, [
115
+ renderer.width,
116
+ renderer.height,
117
+ showProgress,
118
+ showDebug,
119
+ showUpdateBanner,
120
+ ]);
121
+
122
+ return (
123
+ <DimensionsContext.Provider value={dimensions}>
124
+ {children}
125
+ </DimensionsContext.Provider>
126
+ );
127
+ }
128
+
129
+ export function useDimensions(): Dimensions {
130
+ const context = useContext(DimensionsContext);
131
+ if (!context) {
132
+ // Return sensible defaults if used outside provider
133
+ return {
134
+ terminalWidth: 80,
135
+ terminalHeight: 24,
136
+ contentHeight: 23, // 24 - 1 margin
137
+ contentWidth: 76,
138
+ listPanelHeight: 17, // 23 - 4 header - 2 footer
139
+ };
140
+ }
141
+ return context;
142
+ }
143
+
144
+ export default DimensionsContext;