claudeup 0.6.4 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (209) hide show
  1. package/bin/claudeup.js +1 -1
  2. package/dist/data/marketplaces.d.ts +2 -0
  3. package/dist/data/marketplaces.d.ts.map +1 -1
  4. package/dist/data/marketplaces.js +51 -8
  5. package/dist/data/marketplaces.js.map +1 -1
  6. package/dist/data/mcp-servers.d.ts.map +1 -1
  7. package/dist/data/mcp-servers.js +82 -0
  8. package/dist/data/mcp-servers.js.map +1 -1
  9. package/dist/index.js +8 -5
  10. package/dist/index.js.map +1 -1
  11. package/dist/main.d.ts +3 -0
  12. package/dist/main.d.ts.map +1 -0
  13. package/dist/main.js +79 -0
  14. package/dist/main.js.map +1 -0
  15. package/dist/services/claude-settings.d.ts +8 -1
  16. package/dist/services/claude-settings.d.ts.map +1 -1
  17. package/dist/services/claude-settings.js +79 -0
  18. package/dist/services/claude-settings.js.map +1 -1
  19. package/dist/services/local-marketplace.d.ts +76 -0
  20. package/dist/services/local-marketplace.d.ts.map +1 -0
  21. package/dist/services/local-marketplace.js +340 -0
  22. package/dist/services/local-marketplace.js.map +1 -0
  23. package/dist/services/plugin-manager.d.ts +39 -2
  24. package/dist/services/plugin-manager.d.ts.map +1 -1
  25. package/dist/services/plugin-manager.js +259 -9
  26. package/dist/services/plugin-manager.js.map +1 -1
  27. package/dist/services/plugin-mcp-config.d.ts +52 -0
  28. package/dist/services/plugin-mcp-config.d.ts.map +1 -0
  29. package/dist/services/plugin-mcp-config.js +176 -0
  30. package/dist/services/plugin-mcp-config.js.map +1 -0
  31. package/dist/types/index.d.ts +6 -1
  32. package/dist/types/index.d.ts.map +1 -1
  33. package/dist/ui/InkApp.d.ts +5 -0
  34. package/dist/ui/InkApp.d.ts.map +1 -0
  35. package/dist/ui/InkApp.js +175 -0
  36. package/dist/ui/InkApp.js.map +1 -0
  37. package/dist/ui/components/CategoryHeader.d.ts +16 -0
  38. package/dist/ui/components/CategoryHeader.d.ts.map +1 -0
  39. package/dist/ui/components/CategoryHeader.js +11 -0
  40. package/dist/ui/components/CategoryHeader.js.map +1 -0
  41. package/dist/ui/components/ScrollableList.d.ts +16 -0
  42. package/dist/ui/components/ScrollableList.d.ts.map +1 -0
  43. package/dist/ui/components/ScrollableList.js +35 -0
  44. package/dist/ui/components/ScrollableList.js.map +1 -0
  45. package/dist/ui/components/SearchInput.d.ts +18 -0
  46. package/dist/ui/components/SearchInput.d.ts.map +1 -0
  47. package/dist/ui/components/SearchInput.js +30 -0
  48. package/dist/ui/components/SearchInput.js.map +1 -0
  49. package/dist/ui/components/TabBar.d.ts +8 -0
  50. package/dist/ui/components/TabBar.d.ts.map +1 -0
  51. package/dist/ui/components/TabBar.js +18 -0
  52. package/dist/ui/components/TabBar.js.map +1 -0
  53. package/dist/ui/components/layout/Footer.d.ts +14 -0
  54. package/dist/ui/components/layout/Footer.d.ts.map +1 -0
  55. package/dist/ui/components/layout/Footer.js +23 -0
  56. package/dist/ui/components/layout/Footer.js.map +1 -0
  57. package/dist/ui/components/layout/Header.d.ts +4 -0
  58. package/dist/ui/components/layout/Header.d.ts.map +1 -0
  59. package/dist/ui/components/layout/Header.js +25 -0
  60. package/dist/ui/components/layout/Header.js.map +1 -0
  61. package/dist/ui/components/layout/Panel.d.ts +22 -0
  62. package/dist/ui/components/layout/Panel.d.ts.map +1 -0
  63. package/dist/ui/components/layout/Panel.js +8 -0
  64. package/dist/ui/components/layout/Panel.js.map +1 -0
  65. package/dist/ui/components/layout/ProgressBar.d.ts +12 -0
  66. package/dist/ui/components/layout/ProgressBar.d.ts.map +1 -0
  67. package/dist/ui/components/layout/ProgressBar.js +16 -0
  68. package/dist/ui/components/layout/ProgressBar.js.map +1 -0
  69. package/dist/ui/components/layout/ScopeTabs.d.ts +12 -0
  70. package/dist/ui/components/layout/ScopeTabs.d.ts.map +1 -0
  71. package/dist/ui/components/layout/ScopeTabs.js +8 -0
  72. package/dist/ui/components/layout/ScopeTabs.js.map +1 -0
  73. package/dist/ui/components/layout/ScreenLayout.d.ts +30 -0
  74. package/dist/ui/components/layout/ScreenLayout.d.ts.map +1 -0
  75. package/dist/ui/components/layout/ScreenLayout.js +23 -0
  76. package/dist/ui/components/layout/ScreenLayout.js.map +1 -0
  77. package/dist/ui/components/layout/index.d.ts +7 -0
  78. package/dist/ui/components/layout/index.d.ts.map +1 -0
  79. package/dist/ui/components/layout/index.js +7 -0
  80. package/dist/ui/components/layout/index.js.map +1 -0
  81. package/dist/ui/components/modals/ConfirmModal.d.ts +14 -0
  82. package/dist/ui/components/modals/ConfirmModal.d.ts.map +1 -0
  83. package/dist/ui/components/modals/ConfirmModal.js +15 -0
  84. package/dist/ui/components/modals/ConfirmModal.js.map +1 -0
  85. package/dist/ui/components/modals/InputModal.d.ts +16 -0
  86. package/dist/ui/components/modals/InputModal.d.ts.map +1 -0
  87. package/dist/ui/components/modals/InputModal.js +23 -0
  88. package/dist/ui/components/modals/InputModal.js.map +1 -0
  89. package/dist/ui/components/modals/LoadingModal.d.ts +8 -0
  90. package/dist/ui/components/modals/LoadingModal.d.ts.map +1 -0
  91. package/dist/ui/components/modals/LoadingModal.js +8 -0
  92. package/dist/ui/components/modals/LoadingModal.js.map +1 -0
  93. package/dist/ui/components/modals/MessageModal.d.ts +14 -0
  94. package/dist/ui/components/modals/MessageModal.d.ts.map +1 -0
  95. package/dist/ui/components/modals/MessageModal.js +17 -0
  96. package/dist/ui/components/modals/MessageModal.js.map +1 -0
  97. package/dist/ui/components/modals/ModalContainer.d.ts +7 -0
  98. package/dist/ui/components/modals/ModalContainer.d.ts.map +1 -0
  99. package/dist/ui/components/modals/ModalContainer.js +38 -0
  100. package/dist/ui/components/modals/ModalContainer.js.map +1 -0
  101. package/dist/ui/components/modals/SelectModal.d.ts +17 -0
  102. package/dist/ui/components/modals/SelectModal.d.ts.map +1 -0
  103. package/dist/ui/components/modals/SelectModal.js +33 -0
  104. package/dist/ui/components/modals/SelectModal.js.map +1 -0
  105. package/dist/ui/components/modals/index.d.ts +7 -0
  106. package/dist/ui/components/modals/index.d.ts.map +1 -0
  107. package/dist/ui/components/modals/index.js +7 -0
  108. package/dist/ui/components/modals/index.js.map +1 -0
  109. package/dist/ui/hooks/index.d.ts +3 -0
  110. package/dist/ui/hooks/index.d.ts.map +1 -0
  111. package/dist/ui/hooks/index.js +3 -0
  112. package/dist/ui/hooks/index.js.map +1 -0
  113. package/dist/ui/hooks/useAsyncData.d.ts +40 -0
  114. package/dist/ui/hooks/useAsyncData.d.ts.map +1 -0
  115. package/dist/ui/hooks/useAsyncData.js +78 -0
  116. package/dist/ui/hooks/useAsyncData.js.map +1 -0
  117. package/dist/ui/hooks/useKeyboardNavigation.d.ts +27 -0
  118. package/dist/ui/hooks/useKeyboardNavigation.d.ts.map +1 -0
  119. package/dist/ui/hooks/useKeyboardNavigation.js +82 -0
  120. package/dist/ui/hooks/useKeyboardNavigation.js.map +1 -0
  121. package/dist/ui/screens/CliToolsScreen.d.ts +4 -0
  122. package/dist/ui/screens/CliToolsScreen.d.ts.map +1 -0
  123. package/dist/ui/screens/CliToolsScreen.js +268 -0
  124. package/dist/ui/screens/CliToolsScreen.js.map +1 -0
  125. package/dist/ui/screens/EnvVarsScreen.d.ts +4 -0
  126. package/dist/ui/screens/EnvVarsScreen.d.ts.map +1 -0
  127. package/dist/ui/screens/EnvVarsScreen.js +145 -0
  128. package/dist/ui/screens/EnvVarsScreen.js.map +1 -0
  129. package/dist/ui/screens/McpRegistryScreen.d.ts +4 -0
  130. package/dist/ui/screens/McpRegistryScreen.d.ts.map +1 -0
  131. package/dist/ui/screens/McpRegistryScreen.js +226 -0
  132. package/dist/ui/screens/McpRegistryScreen.js.map +1 -0
  133. package/dist/ui/screens/McpScreen.d.ts +4 -0
  134. package/dist/ui/screens/McpScreen.d.ts.map +1 -0
  135. package/dist/ui/screens/McpScreen.js +222 -0
  136. package/dist/ui/screens/McpScreen.js.map +1 -0
  137. package/dist/ui/screens/ModelSelectorScreen.d.ts +4 -0
  138. package/dist/ui/screens/ModelSelectorScreen.d.ts.map +1 -0
  139. package/dist/ui/screens/ModelSelectorScreen.js +143 -0
  140. package/dist/ui/screens/ModelSelectorScreen.js.map +1 -0
  141. package/dist/ui/screens/PluginsScreen.d.ts +4 -0
  142. package/dist/ui/screens/PluginsScreen.d.ts.map +1 -0
  143. package/dist/ui/screens/PluginsScreen.js +818 -0
  144. package/dist/ui/screens/PluginsScreen.js.map +1 -0
  145. package/dist/ui/screens/StatusLineScreen.d.ts +4 -0
  146. package/dist/ui/screens/StatusLineScreen.d.ts.map +1 -0
  147. package/dist/ui/screens/StatusLineScreen.js +197 -0
  148. package/dist/ui/screens/StatusLineScreen.js.map +1 -0
  149. package/dist/ui/screens/index.d.ts +8 -0
  150. package/dist/ui/screens/index.d.ts.map +1 -0
  151. package/dist/ui/screens/index.js +8 -0
  152. package/dist/ui/screens/index.js.map +1 -0
  153. package/dist/ui/state/AppContext.d.ts +40 -0
  154. package/dist/ui/state/AppContext.d.ts.map +1 -0
  155. package/dist/ui/state/AppContext.js +162 -0
  156. package/dist/ui/state/AppContext.js.map +1 -0
  157. package/dist/ui/state/DimensionsContext.d.ts +25 -0
  158. package/dist/ui/state/DimensionsContext.d.ts.map +1 -0
  159. package/dist/ui/state/DimensionsContext.js +68 -0
  160. package/dist/ui/state/DimensionsContext.js.map +1 -0
  161. package/dist/ui/state/reducer.d.ts +4 -0
  162. package/dist/ui/state/reducer.d.ts.map +1 -0
  163. package/dist/ui/state/reducer.js +412 -0
  164. package/dist/ui/state/reducer.js.map +1 -0
  165. package/dist/ui/state/types.d.ts +266 -0
  166. package/dist/ui/state/types.d.ts.map +1 -0
  167. package/dist/ui/state/types.js +2 -0
  168. package/dist/ui/state/types.js.map +1 -0
  169. package/dist/utils/fuzzy-search.d.ts +33 -0
  170. package/dist/utils/fuzzy-search.d.ts.map +1 -0
  171. package/dist/utils/fuzzy-search.js +102 -0
  172. package/dist/utils/fuzzy-search.js.map +1 -0
  173. package/dist/utils/string-utils.d.ts +24 -0
  174. package/dist/utils/string-utils.d.ts.map +1 -0
  175. package/dist/utils/string-utils.js +62 -0
  176. package/dist/utils/string-utils.js.map +1 -0
  177. package/package.json +19 -7
  178. package/dist/ui/app.d.ts +0 -38
  179. package/dist/ui/app.d.ts.map +0 -1
  180. package/dist/ui/app.js +0 -590
  181. package/dist/ui/app.js.map +0 -1
  182. package/dist/ui/screens/cli-tools.d.ts +0 -4
  183. package/dist/ui/screens/cli-tools.d.ts.map +0 -1
  184. package/dist/ui/screens/cli-tools.js +0 -369
  185. package/dist/ui/screens/cli-tools.js.map +0 -1
  186. package/dist/ui/screens/env-vars.d.ts +0 -3
  187. package/dist/ui/screens/env-vars.d.ts.map +0 -1
  188. package/dist/ui/screens/env-vars.js +0 -119
  189. package/dist/ui/screens/env-vars.js.map +0 -1
  190. package/dist/ui/screens/main-menu.d.ts +0 -3
  191. package/dist/ui/screens/main-menu.d.ts.map +0 -1
  192. package/dist/ui/screens/main-menu.js +0 -110
  193. package/dist/ui/screens/main-menu.js.map +0 -1
  194. package/dist/ui/screens/mcp-registry.d.ts +0 -10
  195. package/dist/ui/screens/mcp-registry.d.ts.map +0 -1
  196. package/dist/ui/screens/mcp-registry.js +0 -310
  197. package/dist/ui/screens/mcp-registry.js.map +0 -1
  198. package/dist/ui/screens/mcp-setup.d.ts +0 -4
  199. package/dist/ui/screens/mcp-setup.d.ts.map +0 -1
  200. package/dist/ui/screens/mcp-setup.js +0 -492
  201. package/dist/ui/screens/mcp-setup.js.map +0 -1
  202. package/dist/ui/screens/plugins.d.ts +0 -3
  203. package/dist/ui/screens/plugins.d.ts.map +0 -1
  204. package/dist/ui/screens/plugins.js +0 -443
  205. package/dist/ui/screens/plugins.js.map +0 -1
  206. package/dist/ui/screens/statusline.d.ts +0 -5
  207. package/dist/ui/screens/statusline.d.ts.map +0 -1
  208. package/dist/ui/screens/statusline.js +0 -235
  209. package/dist/ui/screens/statusline.js.map +0 -1
@@ -0,0 +1,8 @@
1
+ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
+ import { Box, Text } from 'ink';
3
+ export function ScopeTabs({ scope, onToggle: _onToggle, toggleHint, }) {
4
+ const isProject = scope === 'project';
5
+ return (_jsxs(Box, { marginBottom: 1, flexDirection: "row", gap: 1, children: [_jsx(Box, { children: isProject ? (_jsxs(Text, { backgroundColor: "cyan", color: "black", bold: true, children: [' ', "\u25C6 Project", ' '] })) : (_jsxs(Text, { color: "gray", children: [' ', "\u25CB Project", ' '] })) }), _jsx(Box, { children: !isProject ? (_jsxs(Text, { backgroundColor: "magenta", color: "white", bold: true, children: [' ', "\u25C6 Global", ' '] })) : (_jsxs(Text, { color: "gray", children: [' ', "\u25CB Global", ' '] })) }), toggleHint && (_jsx(Box, { marginLeft: 2, children: _jsxs(Text, { color: "gray", dimColor: true, children: ["(", toggleHint, ")"] }) }))] }));
6
+ }
7
+ export default ScopeTabs;
8
+ //# sourceMappingURL=ScopeTabs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ScopeTabs.js","sourceRoot":"","sources":["../../../../src/ui/components/layout/ScopeTabs.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAWhC,MAAM,UAAU,SAAS,CAAC,EACxB,KAAK,EACL,QAAQ,EAAE,SAAS,EACnB,UAAU,GACK;IACf,MAAM,SAAS,GAAG,KAAK,KAAK,SAAS,CAAC;IAEtC,OAAO,CACL,MAAC,GAAG,IAAC,YAAY,EAAE,CAAC,EAAE,aAAa,EAAC,KAAK,EAAC,GAAG,EAAE,CAAC,aAE9C,KAAC,GAAG,cACD,SAAS,CAAC,CAAC,CAAC,CACX,MAAC,IAAI,IAAC,eAAe,EAAC,MAAM,EAAC,KAAK,EAAC,OAAO,EAAC,IAAI,mBAC5C,GAAG,oBAAW,GAAG,IACb,CACR,CAAC,CAAC,CAAC,CACF,MAAC,IAAI,IAAC,KAAK,EAAC,MAAM,aACf,GAAG,oBAAW,GAAG,IACb,CACR,GACG,EAGN,KAAC,GAAG,cACD,CAAC,SAAS,CAAC,CAAC,CAAC,CACZ,MAAC,IAAI,IAAC,eAAe,EAAC,SAAS,EAAC,KAAK,EAAC,OAAO,EAAC,IAAI,mBAC/C,GAAG,mBAAU,GAAG,IACZ,CACR,CAAC,CAAC,CAAC,CACF,MAAC,IAAI,IAAC,KAAK,EAAC,MAAM,aACf,GAAG,mBAAU,GAAG,IACZ,CACR,GACG,EAGL,UAAU,IAAI,CACb,KAAC,GAAG,IAAC,UAAU,EAAE,CAAC,YAChB,MAAC,IAAI,IAAC,KAAK,EAAC,MAAM,EAAC,QAAQ,wBACvB,UAAU,SACP,GACH,CACP,IACG,CACP,CAAC;AACJ,CAAC;AAED,eAAe,SAAS,CAAC"}
@@ -0,0 +1,30 @@
1
+ import React from 'react';
2
+ import type { Screen } from '../../state/types.js';
3
+ interface ScreenLayoutProps {
4
+ /** Screen title (e.g., "claudeup Plugins") */
5
+ title: string;
6
+ /** Optional subtitle shown to the right of title */
7
+ subtitle?: string;
8
+ /** Current screen for tab highlighting */
9
+ currentScreen: Screen;
10
+ /** Search bar configuration (for screens with search) */
11
+ search?: {
12
+ /** Is search currently active */
13
+ isActive: boolean;
14
+ /** Current search query */
15
+ query: string;
16
+ /** Placeholder when not searching (default: "/") */
17
+ placeholder?: string;
18
+ };
19
+ /** Status line content (for screens without search) - shown in second row */
20
+ statusLine?: React.ReactNode;
21
+ /** Footer hints (left side) */
22
+ footerHints: string;
23
+ /** Left panel content */
24
+ listPanel: React.ReactNode;
25
+ /** Right panel content (detail view) */
26
+ detailPanel: React.ReactNode;
27
+ }
28
+ export declare function ScreenLayout({ title, subtitle, currentScreen, search, statusLine, footerHints, listPanel, detailPanel, }: ScreenLayoutProps): React.ReactElement;
29
+ export default ScreenLayout;
30
+ //# sourceMappingURL=ScreenLayout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ScreenLayout.d.ts","sourceRoot":"","sources":["../../../../src/ui/components/layout/ScreenLayout.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAEnD,UAAU,iBAAiB;IACzB,8CAA8C;IAC9C,KAAK,EAAE,MAAM,CAAC;IACd,oDAAoD;IACpD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,0CAA0C;IAC1C,aAAa,EAAE,MAAM,CAAC;IACtB,yDAAyD;IACzD,MAAM,CAAC,EAAE;QACP,iCAAiC;QACjC,QAAQ,EAAE,OAAO,CAAC;QAClB,2BAA2B;QAC3B,KAAK,EAAE,MAAM,CAAC;QACd,oDAAoD;QACpD,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,CAAC;IACF,6EAA6E;IAC7E,UAAU,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC7B,+BAA+B;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,yBAAyB;IACzB,SAAS,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,wCAAwC;IACxC,WAAW,EAAE,KAAK,CAAC,SAAS,CAAC;CAC9B;AAID,wBAAgB,YAAY,CAAC,EAC3B,KAAK,EACL,QAAQ,EACR,aAAa,EACb,MAAM,EACN,UAAU,EACV,WAAW,EACX,SAAS,EACT,WAAW,GACZ,EAAE,iBAAiB,GAAG,KAAK,CAAC,YAAY,CA2FxC;AAED,eAAe,YAAY,CAAC"}
@@ -0,0 +1,23 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { Box, Text } from 'ink';
3
+ import { useDimensions } from '../../state/DimensionsContext.js';
4
+ import { TabBar } from '../TabBar.js';
5
+ const HEADER_COLOR = '#7e57c2';
6
+ export function ScreenLayout({ title, subtitle, currentScreen, search, statusLine, footerHints, listPanel, detailPanel, }) {
7
+ const dimensions = useDimensions();
8
+ // Calculate panel heights
9
+ // Header: 4 lines (border + title + status/search + border)
10
+ // Footer: 2 lines (border-top + content)
11
+ const headerHeight = 4;
12
+ const footerHeight = 2;
13
+ const panelHeight = Math.max(5, dimensions.contentHeight - headerHeight - footerHeight);
14
+ return (_jsxs(Box, { flexDirection: "column", height: dimensions.contentHeight, children: [_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: HEADER_COLOR, paddingX: 1, marginBottom: 0, children: [_jsxs(Box, { flexDirection: "row", justifyContent: "space-between", children: [_jsx(Text, { color: HEADER_COLOR, bold: true, children: title }), subtitle && _jsx(Text, { color: "gray", children: subtitle })] }), _jsx(Box, { flexDirection: "row", marginTop: 0, children: search ? (
15
+ // Search mode
16
+ _jsxs(_Fragment, { children: [_jsx(Text, { color: "green", children: '> ' }), search.isActive ? (_jsxs(_Fragment, { children: [_jsx(Text, { color: "white", children: search.query }), _jsx(Text, { inverse: true, color: "gray", children: " " })] })) : (_jsx(Text, { color: "gray", children: search.query || search.placeholder || '/' }))] })) : statusLine ? (
17
+ // Custom status line
18
+ statusLine) : (
19
+ // Default empty status
20
+ _jsx(Text, { color: "gray", children: "\u2500" })) })] }), _jsxs(Box, { flexDirection: "row", height: panelHeight, children: [_jsx(Box, { flexDirection: "column", width: "50%", height: panelHeight, paddingRight: 1, borderStyle: "single", borderTop: false, borderBottom: false, borderColor: "gray", overflow: "hidden", children: listPanel }), _jsx(Box, { flexDirection: "column", width: "50%", height: panelHeight, paddingLeft: 1, overflow: "hidden", children: detailPanel })] }), _jsxs(Box, { height: 1, borderStyle: "single", borderTop: true, borderBottom: false, borderLeft: false, borderRight: false, borderColor: "gray", flexDirection: "row", justifyContent: "space-between", children: [_jsx(Text, { dimColor: true, children: footerHints }), _jsx(TabBar, { currentScreen: currentScreen })] })] }));
21
+ }
22
+ export default ScreenLayout;
23
+ //# sourceMappingURL=ScreenLayout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ScreenLayout.js","sourceRoot":"","sources":["../../../../src/ui/components/layout/ScreenLayout.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export { Header } from './Header.js';
2
+ export { Footer } from './Footer.js';
3
+ export { Panel } from './Panel.js';
4
+ export { ScopeTabs } from './ScopeTabs.js';
5
+ export { ProgressBar } from './ProgressBar.js';
6
+ export { ScreenLayout } from './ScreenLayout.js';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/ui/components/layout/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,7 @@
1
+ export { Header } from './Header.js';
2
+ export { Footer } from './Footer.js';
3
+ export { Panel } from './Panel.js';
4
+ export { ScopeTabs } from './ScopeTabs.js';
5
+ export { ProgressBar } from './ProgressBar.js';
6
+ export { ScreenLayout } from './ScreenLayout.js';
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/ui/components/layout/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,14 @@
1
+ import React from 'react';
2
+ interface ConfirmModalProps {
3
+ /** Modal title */
4
+ title: string;
5
+ /** Modal message */
6
+ message: string;
7
+ /** Callback when confirmed */
8
+ onConfirm: () => void;
9
+ /** Callback when cancelled */
10
+ onCancel: () => void;
11
+ }
12
+ export declare function ConfirmModal({ title, message, onConfirm, onCancel, }: ConfirmModalProps): React.ReactElement;
13
+ export default ConfirmModal;
14
+ //# sourceMappingURL=ConfirmModal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConfirmModal.d.ts","sourceRoot":"","sources":["../../../../src/ui/components/modals/ConfirmModal.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,UAAU,iBAAiB;IACzB,kBAAkB;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,oBAAoB;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,8BAA8B;IAC9B,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,8BAA8B;IAC9B,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,wBAAgB,YAAY,CAAC,EAC3B,KAAK,EACL,OAAO,EACP,SAAS,EACT,QAAQ,GACT,EAAE,iBAAiB,GAAG,KAAK,CAAC,YAAY,CA8BxC;AAED,eAAe,YAAY,CAAC"}
@@ -0,0 +1,15 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box, Text, useInput } from 'ink';
3
+ export function ConfirmModal({ title, message, onConfirm, onCancel, }) {
4
+ useInput((input, key) => {
5
+ if (input === 'y' || input === 'Y') {
6
+ onConfirm();
7
+ }
8
+ else if (input === 'n' || input === 'N' || key.escape) {
9
+ onCancel();
10
+ }
11
+ });
12
+ return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "yellow", paddingX: 2, paddingY: 1, width: 60, children: [_jsx(Text, { bold: true, children: title }), _jsx(Box, { marginY: 1, children: _jsx(Text, { children: message }) }), _jsxs(Box, { children: [_jsx(Text, { color: "green", children: "[Y]" }), _jsx(Text, { children: "es " }), _jsx(Text, { color: "red", children: "[N]" }), _jsx(Text, { children: "o" })] })] }));
13
+ }
14
+ export default ConfirmModal;
15
+ //# sourceMappingURL=ConfirmModal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConfirmModal.js","sourceRoot":"","sources":["../../../../src/ui/components/modals/ConfirmModal.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,KAAK,CAAC;AAa1C,MAAM,UAAU,YAAY,CAAC,EAC3B,KAAK,EACL,OAAO,EACP,SAAS,EACT,QAAQ,GACU;IAClB,QAAQ,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;QACtB,IAAI,KAAK,KAAK,GAAG,IAAI,KAAK,KAAK,GAAG,EAAE,CAAC;YACnC,SAAS,EAAE,CAAC;QACd,CAAC;aAAM,IAAI,KAAK,KAAK,GAAG,IAAI,KAAK,KAAK,GAAG,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;YACxD,QAAQ,EAAE,CAAC;QACb,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,CACL,MAAC,GAAG,IACF,aAAa,EAAC,QAAQ,EACtB,WAAW,EAAC,OAAO,EACnB,WAAW,EAAC,QAAQ,EACpB,QAAQ,EAAE,CAAC,EACX,QAAQ,EAAE,CAAC,EACX,KAAK,EAAE,EAAE,aAET,KAAC,IAAI,IAAC,IAAI,kBAAE,KAAK,GAAQ,EACzB,KAAC,GAAG,IAAC,OAAO,EAAE,CAAC,YACb,KAAC,IAAI,cAAE,OAAO,GAAQ,GAClB,EACN,MAAC,GAAG,eACF,KAAC,IAAI,IAAC,KAAK,EAAC,OAAO,oBAAW,EAC9B,KAAC,IAAI,sBAAW,EAChB,KAAC,IAAI,IAAC,KAAK,EAAC,KAAK,oBAAW,EAC5B,KAAC,IAAI,oBAAS,IACV,IACF,CACP,CAAC;AACJ,CAAC;AAED,eAAe,YAAY,CAAC"}
@@ -0,0 +1,16 @@
1
+ import React from 'react';
2
+ interface InputModalProps {
3
+ /** Modal title */
4
+ title: string;
5
+ /** Input label */
6
+ label: string;
7
+ /** Default input value */
8
+ defaultValue?: string;
9
+ /** Callback when submitted */
10
+ onSubmit: (value: string) => void;
11
+ /** Callback when cancelled */
12
+ onCancel: () => void;
13
+ }
14
+ export declare function InputModal({ title, label, defaultValue, onSubmit, onCancel, }: InputModalProps): React.ReactElement;
15
+ export default InputModal;
16
+ //# sourceMappingURL=InputModal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InputModal.d.ts","sourceRoot":"","sources":["../../../../src/ui/components/modals/InputModal.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAGxC,UAAU,eAAe;IACvB,kBAAkB;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,kBAAkB;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,0BAA0B;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,8BAA8B;IAC9B,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,8BAA8B;IAC9B,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,wBAAgB,UAAU,CAAC,EACzB,KAAK,EACL,KAAK,EACL,YAAiB,EACjB,QAAQ,EACR,QAAQ,GACT,EAAE,eAAe,GAAG,KAAK,CAAC,YAAY,CA+CtC;AAED,eAAe,UAAU,CAAC"}
@@ -0,0 +1,23 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState } from 'react';
3
+ import { Box, Text, useInput } from 'ink';
4
+ export function InputModal({ title, label, defaultValue = '', onSubmit, onCancel, }) {
5
+ const [value, setValue] = useState(defaultValue);
6
+ useInput((input, key) => {
7
+ if (key.return) {
8
+ onSubmit(value);
9
+ }
10
+ else if (key.escape) {
11
+ onCancel();
12
+ }
13
+ else if (key.backspace || key.delete) {
14
+ setValue((prev) => prev.slice(0, -1));
15
+ }
16
+ else if (input && !key.ctrl && !key.meta) {
17
+ setValue((prev) => prev + input);
18
+ }
19
+ });
20
+ return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 2, paddingY: 1, width: 60, children: [_jsx(Text, { bold: true, children: title }), _jsx(Box, { marginY: 1, children: _jsx(Text, { children: label }) }), _jsx(Box, { borderStyle: "single", borderColor: "green", paddingX: 1, width: 56, children: _jsxs(Text, { children: [value, _jsx(Text, { inverse: true, children: " " })] }) }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { color: "gray", children: "Enter to confirm \u2022 Escape to cancel" }) })] }));
21
+ }
22
+ export default InputModal;
23
+ //# sourceMappingURL=InputModal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InputModal.js","sourceRoot":"","sources":["../../../../src/ui/components/modals/InputModal.tsx"],"names":[],"mappings":";AAAA,OAAc,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACxC,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,KAAK,CAAC;AAe1C,MAAM,UAAU,UAAU,CAAC,EACzB,KAAK,EACL,KAAK,EACL,YAAY,GAAG,EAAE,EACjB,QAAQ,EACR,QAAQ,GACQ;IAChB,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAC,YAAY,CAAC,CAAC;IAEjD,QAAQ,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;QACtB,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;YACf,QAAQ,CAAC,KAAK,CAAC,CAAC;QAClB,CAAC;aAAM,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;YACtB,QAAQ,EAAE,CAAC;QACb,CAAC;aAAM,IAAI,GAAG,CAAC,SAAS,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;YACvC,QAAQ,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACxC,CAAC;aAAM,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;YAC3C,QAAQ,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,GAAG,KAAK,CAAC,CAAC;QACnC,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,CACL,MAAC,GAAG,IACF,aAAa,EAAC,QAAQ,EACtB,WAAW,EAAC,OAAO,EACnB,WAAW,EAAC,MAAM,EAClB,QAAQ,EAAE,CAAC,EACX,QAAQ,EAAE,CAAC,EACX,KAAK,EAAE,EAAE,aAET,KAAC,IAAI,IAAC,IAAI,kBAAE,KAAK,GAAQ,EAEzB,KAAC,GAAG,IAAC,OAAO,EAAE,CAAC,YACb,KAAC,IAAI,cAAE,KAAK,GAAQ,GAChB,EAEN,KAAC,GAAG,IACF,WAAW,EAAC,QAAQ,EACpB,WAAW,EAAC,OAAO,EACnB,QAAQ,EAAE,CAAC,EACX,KAAK,EAAE,EAAE,YAET,MAAC,IAAI,eACF,KAAK,EACN,KAAC,IAAI,IAAC,OAAO,wBAAS,IACjB,GACH,EAEN,KAAC,GAAG,IAAC,SAAS,EAAE,CAAC,YACf,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,yDAA2C,GACzD,IACF,CACP,CAAC;AACJ,CAAC;AAED,eAAe,UAAU,CAAC"}
@@ -0,0 +1,8 @@
1
+ import React from 'react';
2
+ interface LoadingModalProps {
3
+ /** Loading message */
4
+ message: string;
5
+ }
6
+ export declare function LoadingModal({ message }: LoadingModalProps): React.ReactElement;
7
+ export default LoadingModal;
8
+ //# sourceMappingURL=LoadingModal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LoadingModal.d.ts","sourceRoot":"","sources":["../../../../src/ui/components/modals/LoadingModal.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,UAAU,iBAAiB;IACzB,sBAAsB;IACtB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,YAAY,CAAC,EAAE,OAAO,EAAE,EAAE,iBAAiB,GAAG,KAAK,CAAC,YAAY,CAe/E;AAED,eAAe,YAAY,CAAC"}
@@ -0,0 +1,8 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box, Text } from 'ink';
3
+ import Spinner from 'ink-spinner';
4
+ export function LoadingModal({ message }) {
5
+ return (_jsxs(Box, { flexDirection: "row", borderStyle: "round", borderColor: "cyan", paddingX: 2, paddingY: 1, children: [_jsx(Text, { color: "cyan", children: _jsx(Spinner, { type: "dots" }) }), _jsxs(Text, { children: [" ", message] })] }));
6
+ }
7
+ export default LoadingModal;
8
+ //# sourceMappingURL=LoadingModal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LoadingModal.js","sourceRoot":"","sources":["../../../../src/ui/components/modals/LoadingModal.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAChC,OAAO,OAAO,MAAM,aAAa,CAAC;AAOlC,MAAM,UAAU,YAAY,CAAC,EAAE,OAAO,EAAqB;IACzD,OAAO,CACL,MAAC,GAAG,IACF,aAAa,EAAC,KAAK,EACnB,WAAW,EAAC,OAAO,EACnB,WAAW,EAAC,MAAM,EAClB,QAAQ,EAAE,CAAC,EACX,QAAQ,EAAE,CAAC,aAEX,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,YAChB,KAAC,OAAO,IAAC,IAAI,EAAC,MAAM,GAAG,GAClB,EACP,MAAC,IAAI,oBAAG,OAAO,IAAQ,IACnB,CACP,CAAC;AACJ,CAAC;AAED,eAAe,YAAY,CAAC"}
@@ -0,0 +1,14 @@
1
+ import React from 'react';
2
+ interface MessageModalProps {
3
+ /** Modal title */
4
+ title: string;
5
+ /** Modal message */
6
+ message: string;
7
+ /** Message variant */
8
+ variant: 'info' | 'success' | 'error';
9
+ /** Callback when dismissed */
10
+ onDismiss: () => void;
11
+ }
12
+ export declare function MessageModal({ title, message, variant, onDismiss, }: MessageModalProps): React.ReactElement;
13
+ export default MessageModal;
14
+ //# sourceMappingURL=MessageModal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MessageModal.d.ts","sourceRoot":"","sources":["../../../../src/ui/components/modals/MessageModal.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,UAAU,iBAAiB;IACzB,kBAAkB;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,oBAAoB;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,sBAAsB;IACtB,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC;IACtC,8BAA8B;IAC9B,SAAS,EAAE,MAAM,IAAI,CAAC;CACvB;AAQD,wBAAgB,YAAY,CAAC,EAC3B,KAAK,EACL,OAAO,EACP,OAAO,EACP,SAAS,GACV,EAAE,iBAAiB,GAAG,KAAK,CAAC,YAAY,CA+BxC;AAED,eAAe,YAAY,CAAC"}
@@ -0,0 +1,17 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box, Text, useInput } from 'ink';
3
+ const variantConfig = {
4
+ info: { icon: 'ℹ', color: 'cyan' },
5
+ success: { icon: '✓', color: 'green' },
6
+ error: { icon: '✗', color: 'red' },
7
+ };
8
+ export function MessageModal({ title, message, variant, onDismiss, }) {
9
+ const config = variantConfig[variant];
10
+ useInput(() => {
11
+ // Any key dismisses
12
+ onDismiss();
13
+ });
14
+ return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: config.color, paddingX: 2, paddingY: 1, width: 60, children: [_jsxs(Box, { children: [_jsx(Text, { color: config.color, children: config.icon }), _jsxs(Text, { bold: true, children: [" ", title] })] }), _jsx(Box, { marginY: 1, children: _jsx(Text, { children: message }) }), _jsx(Box, { children: _jsx(Text, { color: "gray", children: "Press any key to continue" }) })] }));
15
+ }
16
+ export default MessageModal;
17
+ //# sourceMappingURL=MessageModal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MessageModal.js","sourceRoot":"","sources":["../../../../src/ui/components/modals/MessageModal.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,KAAK,CAAC;AAa1C,MAAM,aAAa,GAAG;IACpB,IAAI,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE;IAClC,OAAO,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE;IACtC,KAAK,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE;CAC1B,CAAC;AAEX,MAAM,UAAU,YAAY,CAAC,EAC3B,KAAK,EACL,OAAO,EACP,OAAO,EACP,SAAS,GACS;IAClB,MAAM,MAAM,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;IAEtC,QAAQ,CAAC,GAAG,EAAE;QACZ,oBAAoB;QACpB,SAAS,EAAE,CAAC;IACd,CAAC,CAAC,CAAC;IAEH,OAAO,CACL,MAAC,GAAG,IACF,aAAa,EAAC,QAAQ,EACtB,WAAW,EAAC,OAAO,EACnB,WAAW,EAAE,MAAM,CAAC,KAAK,EACzB,QAAQ,EAAE,CAAC,EACX,QAAQ,EAAE,CAAC,EACX,KAAK,EAAE,EAAE,aAET,MAAC,GAAG,eACF,KAAC,IAAI,IAAC,KAAK,EAAE,MAAM,CAAC,KAAK,YAAG,MAAM,CAAC,IAAI,GAAQ,EAC/C,MAAC,IAAI,IAAC,IAAI,wBAAG,KAAK,IAAQ,IACtB,EAEN,KAAC,GAAG,IAAC,OAAO,EAAE,CAAC,YACb,KAAC,IAAI,cAAE,OAAO,GAAQ,GAClB,EAEN,KAAC,GAAG,cACF,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,0CAAiC,GAC/C,IACF,CACP,CAAC;AACJ,CAAC;AAED,eAAe,YAAY,CAAC"}
@@ -0,0 +1,7 @@
1
+ import React from 'react';
2
+ /**
3
+ * Container that renders the active modal as an overlay
4
+ */
5
+ export declare function ModalContainer(): React.ReactElement | null;
6
+ export default ModalContainer;
7
+ //# sourceMappingURL=ModalContainer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ModalContainer.d.ts","sourceRoot":"","sources":["../../../../src/ui/components/modals/ModalContainer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAS1B;;GAEG;AACH,wBAAgB,cAAc,IAAI,KAAK,CAAC,YAAY,GAAG,IAAI,CAwE1D;AAED,eAAe,cAAc,CAAC"}
@@ -0,0 +1,38 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Box } from 'ink';
3
+ import { useApp } from '../../state/AppContext.js';
4
+ import { ConfirmModal } from './ConfirmModal.js';
5
+ import { InputModal } from './InputModal.js';
6
+ import { SelectModal } from './SelectModal.js';
7
+ import { MessageModal } from './MessageModal.js';
8
+ import { LoadingModal } from './LoadingModal.js';
9
+ /**
10
+ * Container that renders the active modal as an overlay
11
+ */
12
+ export function ModalContainer() {
13
+ const { state } = useApp();
14
+ const { modal } = state;
15
+ if (!modal) {
16
+ return null;
17
+ }
18
+ const renderModal = () => {
19
+ switch (modal.type) {
20
+ case 'confirm':
21
+ return (_jsx(ConfirmModal, { title: modal.title, message: modal.message, onConfirm: modal.onConfirm, onCancel: modal.onCancel }));
22
+ case 'input':
23
+ return (_jsx(InputModal, { title: modal.title, label: modal.label, defaultValue: modal.defaultValue, onSubmit: modal.onSubmit, onCancel: modal.onCancel }));
24
+ case 'select':
25
+ return (_jsx(SelectModal, { title: modal.title, message: modal.message, options: modal.options, onSelect: modal.onSelect, onCancel: modal.onCancel }));
26
+ case 'message':
27
+ return (_jsx(MessageModal, { title: modal.title, message: modal.message, variant: modal.variant, onDismiss: modal.onDismiss }));
28
+ case 'loading':
29
+ return _jsx(LoadingModal, { message: modal.message });
30
+ default:
31
+ return null;
32
+ }
33
+ };
34
+ // Center the modal on screen
35
+ return (_jsx(Box, { position: "absolute", width: "100%", height: "100%", justifyContent: "center", alignItems: "center", children: renderModal() }));
36
+ }
37
+ export default ModalContainer;
38
+ //# sourceMappingURL=ModalContainer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ModalContainer.js","sourceRoot":"","sources":["../../../../src/ui/components/modals/ModalContainer.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAC1B,OAAO,EAAE,MAAM,EAAE,MAAM,2BAA2B,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD;;GAEG;AACH,MAAM,UAAU,cAAc;IAC5B,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,EAAE,CAAC;IAC3B,MAAM,EAAE,KAAK,EAAE,GAAG,KAAK,CAAC;IAExB,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,WAAW,GAAG,GAAG,EAAE;QACvB,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;YACnB,KAAK,SAAS;gBACZ,OAAO,CACL,KAAC,YAAY,IACX,KAAK,EAAE,KAAK,CAAC,KAAK,EAClB,OAAO,EAAE,KAAK,CAAC,OAAO,EACtB,SAAS,EAAE,KAAK,CAAC,SAAS,EAC1B,QAAQ,EAAE,KAAK,CAAC,QAAQ,GACxB,CACH,CAAC;YAEJ,KAAK,OAAO;gBACV,OAAO,CACL,KAAC,UAAU,IACT,KAAK,EAAE,KAAK,CAAC,KAAK,EAClB,KAAK,EAAE,KAAK,CAAC,KAAK,EAClB,YAAY,EAAE,KAAK,CAAC,YAAY,EAChC,QAAQ,EAAE,KAAK,CAAC,QAAQ,EACxB,QAAQ,EAAE,KAAK,CAAC,QAAQ,GACxB,CACH,CAAC;YAEJ,KAAK,QAAQ;gBACX,OAAO,CACL,KAAC,WAAW,IACV,KAAK,EAAE,KAAK,CAAC,KAAK,EAClB,OAAO,EAAE,KAAK,CAAC,OAAO,EACtB,OAAO,EAAE,KAAK,CAAC,OAAO,EACtB,QAAQ,EAAE,KAAK,CAAC,QAAQ,EACxB,QAAQ,EAAE,KAAK,CAAC,QAAQ,GACxB,CACH,CAAC;YAEJ,KAAK,SAAS;gBACZ,OAAO,CACL,KAAC,YAAY,IACX,KAAK,EAAE,KAAK,CAAC,KAAK,EAClB,OAAO,EAAE,KAAK,CAAC,OAAO,EACtB,OAAO,EAAE,KAAK,CAAC,OAAO,EACtB,SAAS,EAAE,KAAK,CAAC,SAAS,GAC1B,CACH,CAAC;YAEJ,KAAK,SAAS;gBACZ,OAAO,KAAC,YAAY,IAAC,OAAO,EAAE,KAAK,CAAC,OAAO,GAAI,CAAC;YAElD;gBACE,OAAO,IAAI,CAAC;QAChB,CAAC;IACH,CAAC,CAAC;IAEF,6BAA6B;IAC7B,OAAO,CACL,KAAC,GAAG,IACF,QAAQ,EAAC,UAAU,EACnB,KAAK,EAAC,MAAM,EACZ,MAAM,EAAC,MAAM,EACb,cAAc,EAAC,QAAQ,EACvB,UAAU,EAAC,QAAQ,YAElB,WAAW,EAAE,GACV,CACP,CAAC;AACJ,CAAC;AAED,eAAe,cAAc,CAAC"}
@@ -0,0 +1,17 @@
1
+ import React from 'react';
2
+ import type { SelectOption } from '../../state/types.js';
3
+ interface SelectModalProps {
4
+ /** Modal title */
5
+ title: string;
6
+ /** Modal message */
7
+ message: string;
8
+ /** Select options */
9
+ options: SelectOption[];
10
+ /** Callback when option selected */
11
+ onSelect: (value: string) => void;
12
+ /** Callback when cancelled */
13
+ onCancel: () => void;
14
+ }
15
+ export declare function SelectModal({ title, message, options, onSelect, onCancel, }: SelectModalProps): React.ReactElement;
16
+ export default SelectModal;
17
+ //# sourceMappingURL=SelectModal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SelectModal.d.ts","sourceRoot":"","sources":["../../../../src/ui/components/modals/SelectModal.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAExC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEzD,UAAU,gBAAgB;IACxB,kBAAkB;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,oBAAoB;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,qBAAqB;IACrB,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,oCAAoC;IACpC,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,8BAA8B;IAC9B,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,wBAAgB,WAAW,CAAC,EAC1B,KAAK,EACL,OAAO,EACP,OAAO,EACP,QAAQ,EACR,QAAQ,GACT,EAAE,gBAAgB,GAAG,KAAK,CAAC,YAAY,CA+DvC;AAED,eAAe,WAAW,CAAC"}
@@ -0,0 +1,33 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState } from 'react';
3
+ import { Box, Text, useInput } from 'ink';
4
+ export function SelectModal({ title, message, options, onSelect, onCancel, }) {
5
+ const [selectedIndex, setSelectedIndex] = useState(0);
6
+ useInput((input, key) => {
7
+ if (key.return) {
8
+ onSelect(options[selectedIndex].value);
9
+ }
10
+ else if (key.escape || input === 'q') {
11
+ onCancel();
12
+ }
13
+ else if (key.upArrow || input === 'k') {
14
+ setSelectedIndex((prev) => Math.max(0, prev - 1));
15
+ }
16
+ else if (key.downArrow || input === 'j') {
17
+ setSelectedIndex((prev) => Math.min(options.length - 1, prev + 1));
18
+ }
19
+ });
20
+ // Height: top padding(1) + title(1) + spacing(2) + message(1) + spacing(1) + options + spacing(1) + footer(1) + bottom padding(1) + border(2)
21
+ const boxHeight = options.length + 11;
22
+ const innerWidth = 46; // 50 - 2 (paddingX) - 2 (border)
23
+ // Create background fill for each line
24
+ const bgFill = ' '.repeat(innerWidth);
25
+ const bg = '#1a1a1a';
26
+ return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1, width: 50, height: boxHeight, children: [_jsx(Text, { backgroundColor: bg, children: bgFill }), _jsx(Text, { bold: true, backgroundColor: bg, children: ` ${title}`.padEnd(innerWidth) }), _jsx(Text, { backgroundColor: bg, children: bgFill }), _jsx(Text, { backgroundColor: bg, children: ` ${message}`.padEnd(innerWidth) }), _jsx(Text, { backgroundColor: bg, children: bgFill }), options.map((option, idx) => {
27
+ const isSelected = idx === selectedIndex;
28
+ const label = isSelected ? ` > ${option.label}` : ` ${option.label}`;
29
+ return (_jsx(Text, { backgroundColor: bg, color: isSelected ? 'cyan' : 'gray', bold: isSelected, children: label.padEnd(innerWidth) }, option.value));
30
+ }), _jsx(Text, { backgroundColor: bg, children: bgFill }), _jsx(Text, { color: "gray", backgroundColor: bg, children: ' ↑↓ Select • Enter • Esc'.padEnd(innerWidth) }), _jsx(Text, { backgroundColor: bg, children: bgFill })] }));
31
+ }
32
+ export default SelectModal;
33
+ //# sourceMappingURL=SelectModal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SelectModal.js","sourceRoot":"","sources":["../../../../src/ui/components/modals/SelectModal.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export { ConfirmModal } from './ConfirmModal.js';
2
+ export { InputModal } from './InputModal.js';
3
+ export { SelectModal } from './SelectModal.js';
4
+ export { MessageModal } from './MessageModal.js';
5
+ export { LoadingModal } from './LoadingModal.js';
6
+ export { ModalContainer } from './ModalContainer.js';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/ui/components/modals/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1,7 @@
1
+ export { ConfirmModal } from './ConfirmModal.js';
2
+ export { InputModal } from './InputModal.js';
3
+ export { SelectModal } from './SelectModal.js';
4
+ export { MessageModal } from './MessageModal.js';
5
+ export { LoadingModal } from './LoadingModal.js';
6
+ export { ModalContainer } from './ModalContainer.js';
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/ui/components/modals/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { useKeyboardNavigation, useGlobalKeyboard } from './useKeyboardNavigation.js';
2
+ export { useAsyncData, useDebouncedAsyncData } from './useAsyncData.js';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ui/hooks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AACtF,OAAO,EAAE,YAAY,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { useKeyboardNavigation, useGlobalKeyboard } from './useKeyboardNavigation.js';
2
+ export { useAsyncData, useDebouncedAsyncData } from './useAsyncData.js';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/ui/hooks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AACtF,OAAO,EAAE,YAAY,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,40 @@
1
+ import type { AsyncData } from '../state/types.js';
2
+ interface UseAsyncDataOptions<T> {
3
+ /** Function that fetches data */
4
+ fetcher: () => Promise<T>;
5
+ /** Dependencies that trigger refetch when changed */
6
+ deps?: unknown[];
7
+ /** Whether to fetch immediately on mount */
8
+ immediate?: boolean;
9
+ }
10
+ interface UseAsyncDataResult<T> {
11
+ /** Current async data state */
12
+ data: AsyncData<T>;
13
+ /** Whether data is currently loading */
14
+ isLoading: boolean;
15
+ /** Whether data has been successfully loaded */
16
+ isSuccess: boolean;
17
+ /** Whether there was an error loading data */
18
+ isError: boolean;
19
+ /** Error if any */
20
+ error: Error | null;
21
+ /** Trigger a manual refetch */
22
+ refetch: () => Promise<void>;
23
+ /** Raw data if available */
24
+ value: T | null;
25
+ }
26
+ /**
27
+ * Hook for fetching async data with loading/error states
28
+ */
29
+ export declare function useAsyncData<T>({ fetcher, deps, immediate, }: UseAsyncDataOptions<T>): UseAsyncDataResult<T>;
30
+ /**
31
+ * Hook for fetching async data with debounced query
32
+ */
33
+ export declare function useDebouncedAsyncData<T>({ fetcher, query, debounceMs, minQueryLength, }: {
34
+ fetcher: (query: string) => Promise<T>;
35
+ query: string;
36
+ debounceMs?: number;
37
+ minQueryLength?: number;
38
+ }): UseAsyncDataResult<T>;
39
+ export {};
40
+ //# sourceMappingURL=useAsyncData.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useAsyncData.d.ts","sourceRoot":"","sources":["../../../src/ui/hooks/useAsyncData.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAEnD,UAAU,mBAAmB,CAAC,CAAC;IAC7B,iCAAiC;IACjC,OAAO,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,CAAC;IAC1B,qDAAqD;IACrD,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC;IACjB,4CAA4C;IAC5C,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,UAAU,kBAAkB,CAAC,CAAC;IAC5B,+BAA+B;IAC/B,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;IACnB,wCAAwC;IACxC,SAAS,EAAE,OAAO,CAAC;IACnB,gDAAgD;IAChD,SAAS,EAAE,OAAO,CAAC;IACnB,8CAA8C;IAC9C,OAAO,EAAE,OAAO,CAAC;IACjB,mBAAmB;IACnB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,+BAA+B;IAC/B,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7B,4BAA4B;IAC5B,KAAK,EAAE,CAAC,GAAG,IAAI,CAAC;CACjB;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,EAC9B,OAAO,EACP,IAAS,EACT,SAAgB,GACjB,EAAE,mBAAmB,CAAC,CAAC,CAAC,GAAG,kBAAkB,CAAC,CAAC,CAAC,CAgChD;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,CAAC,EAAE,EACvC,OAAO,EACP,KAAK,EACL,UAAgB,EAChB,cAAkB,GACnB,EAAE;IACD,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;IACvC,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,GAAG,kBAAkB,CAAC,CAAC,CAAC,CA2CxB"}
@@ -0,0 +1,78 @@
1
+ import { useState, useEffect, useCallback } from 'react';
2
+ /**
3
+ * Hook for fetching async data with loading/error states
4
+ */
5
+ export function useAsyncData({ fetcher, deps = [], immediate = true, }) {
6
+ const [data, setData] = useState({ status: 'idle' });
7
+ const refetch = useCallback(async () => {
8
+ setData({ status: 'loading' });
9
+ try {
10
+ const result = await fetcher();
11
+ setData({ status: 'success', data: result });
12
+ }
13
+ catch (err) {
14
+ setData({
15
+ status: 'error',
16
+ error: err instanceof Error ? err : new Error(String(err)),
17
+ });
18
+ }
19
+ }, [fetcher]);
20
+ useEffect(() => {
21
+ if (immediate) {
22
+ refetch();
23
+ }
24
+ // eslint-disable-next-line react-hooks/exhaustive-deps
25
+ }, deps);
26
+ return {
27
+ data,
28
+ isLoading: data.status === 'loading',
29
+ isSuccess: data.status === 'success',
30
+ isError: data.status === 'error',
31
+ error: data.status === 'error' ? data.error : null,
32
+ refetch,
33
+ value: data.status === 'success' ? data.data : null,
34
+ };
35
+ }
36
+ /**
37
+ * Hook for fetching async data with debounced query
38
+ */
39
+ export function useDebouncedAsyncData({ fetcher, query, debounceMs = 300, minQueryLength = 1, }) {
40
+ const [data, setData] = useState({ status: 'idle' });
41
+ const refetch = useCallback(async () => {
42
+ if (query.length < minQueryLength) {
43
+ setData({ status: 'idle' });
44
+ return;
45
+ }
46
+ setData({ status: 'loading' });
47
+ try {
48
+ const result = await fetcher(query);
49
+ setData({ status: 'success', data: result });
50
+ }
51
+ catch (err) {
52
+ setData({
53
+ status: 'error',
54
+ error: err instanceof Error ? err : new Error(String(err)),
55
+ });
56
+ }
57
+ }, [fetcher, query, minQueryLength]);
58
+ useEffect(() => {
59
+ if (query.length < minQueryLength) {
60
+ setData({ status: 'idle' });
61
+ return;
62
+ }
63
+ const timeoutId = setTimeout(() => {
64
+ refetch();
65
+ }, debounceMs);
66
+ return () => clearTimeout(timeoutId);
67
+ }, [query, debounceMs, minQueryLength, refetch]);
68
+ return {
69
+ data,
70
+ isLoading: data.status === 'loading',
71
+ isSuccess: data.status === 'success',
72
+ isError: data.status === 'error',
73
+ error: data.status === 'error' ? data.error : null,
74
+ refetch,
75
+ value: data.status === 'success' ? data.data : null,
76
+ };
77
+ }
78
+ //# sourceMappingURL=useAsyncData.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useAsyncData.js","sourceRoot":"","sources":["../../../src/ui/hooks/useAsyncData.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ interface KeyboardOptions {
2
+ /** Total number of items in the list */
3
+ itemCount: number;
4
+ /** Current selected index */
5
+ selectedIndex: number;
6
+ /** Callback to update selected index */
7
+ onSelect: (index: number) => void;
8
+ /** Callback when Enter is pressed on selected item */
9
+ onEnter?: (index: number) => void;
10
+ /** Callback when Escape/q is pressed */
11
+ onBack?: () => void;
12
+ /** Callback for custom key handlers */
13
+ customKeys?: Record<string, () => void>;
14
+ /** Disabled keyboard input (e.g., during modal) */
15
+ disabled?: boolean;
16
+ }
17
+ /**
18
+ * Hook for handling keyboard navigation in lists
19
+ * Provides j/k/up/down for navigation, Enter for selection, Escape/q for back
20
+ */
21
+ export declare function useKeyboardNavigation({ itemCount, selectedIndex, onSelect, onEnter, onBack, customKeys, disabled, }: KeyboardOptions): void;
22
+ /**
23
+ * Hook for global keyboard shortcuts (screen navigation)
24
+ */
25
+ export declare function useGlobalKeyboard(): void;
26
+ export {};
27
+ //# sourceMappingURL=useKeyboardNavigation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useKeyboardNavigation.d.ts","sourceRoot":"","sources":["../../../src/ui/hooks/useKeyboardNavigation.ts"],"names":[],"mappings":"AAGA,UAAU,eAAe;IACvB,wCAAwC;IACxC,SAAS,EAAE,MAAM,CAAC;IAClB,6BAA6B;IAC7B,aAAa,EAAE,MAAM,CAAC;IACtB,wCAAwC;IACxC,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,sDAAsD;IACtD,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,wCAAwC;IACxC,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,uCAAuC;IACvC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,IAAI,CAAC,CAAC;IACxC,mDAAmD;IACnD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,EACpC,SAAS,EACT,aAAa,EACb,QAAQ,EACR,OAAO,EACP,MAAM,EACN,UAAe,EACf,QAAgB,GACjB,EAAE,eAAe,GAAG,IAAI,CA4CxB;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,IAAI,CAmCxC"}