@allternit/gizzi-code 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (158) hide show
  1. package/bin/gizzi +4 -0
  2. package/bin/gizzi-ink +5 -0
  3. package/package.json +137 -31
  4. package/src/Tool.ts +26 -0
  5. package/src/bootstrap/state.ts +165 -322
  6. package/src/commands.ts +209 -0
  7. package/src/context/QueuedMessageContext.tsx +63 -0
  8. package/src/context/fpsMetrics.tsx +30 -0
  9. package/src/context/mailbox.tsx +38 -0
  10. package/src/context/modalContext.tsx +58 -0
  11. package/src/context/notifications.tsx +240 -0
  12. package/src/context/overlayContext.tsx +151 -0
  13. package/src/context/promptOverlayContext.tsx +125 -0
  14. package/src/context/stats.tsx +220 -0
  15. package/src/context/voice.tsx +88 -0
  16. package/src/hooks/useCanUseTool.ts +11 -0
  17. package/src/hooks/useExitOnCtrlCD.ts +40 -187
  18. package/src/hooks/useExitOnCtrlCDWithKeybindings.ts +68 -0
  19. package/src/hooks/useKeybinding.ts +68 -209
  20. package/src/hooks/useTerminalSize.ts +31 -99
  21. package/src/hooks.ts +37 -0
  22. package/src/ink.ts +204 -0
  23. package/src/main.ts +7 -0
  24. package/src/types/command.ts +216 -0
  25. package/src/types/connectorText.ts +39 -0
  26. package/src/types/fileSuggestion.ts +15 -0
  27. package/src/types/generated/events_mono/claude_code/v1/claude_code_internal_event.ts +865 -0
  28. package/src/types/generated/events_mono/common/v1/auth.ts +100 -0
  29. package/src/types/generated/events_mono/growthbook/v1/growthbook_experiment_event.ts +223 -0
  30. package/src/types/generated/google/protobuf/timestamp.ts +187 -0
  31. package/src/types/hooks.ts +319 -0
  32. package/src/types/ids.ts +44 -0
  33. package/src/types/logs.ts +331 -0
  34. package/src/types/merged/index.ts +5 -0
  35. package/src/types/merged/message.ts +552 -0
  36. package/src/types/message.ts +927 -186
  37. package/src/types/messageQueueTypes.ts +21 -0
  38. package/src/types/notebook.ts +72 -0
  39. package/src/types/permissions.ts +447 -0
  40. package/src/types/plugin.ts +363 -0
  41. package/src/types/statusLine.ts +15 -0
  42. package/src/types/textInputTypes.ts +387 -0
  43. package/src/types/tools.ts +149 -0
  44. package/src/types/utils.ts +20 -0
  45. package/src/utils/advisor.ts +12 -0
  46. package/src/utils/api.ts +29 -0
  47. package/src/utils/array.ts +7 -0
  48. package/src/utils/attachments.ts +60 -0
  49. package/src/utils/auth.ts +3 -0
  50. package/src/utils/claudeInChrome/chromeNativeHost.ts +15 -0
  51. package/src/utils/claudeInChrome/common.ts +12 -0
  52. package/src/utils/claudeInChrome/mcpServer.ts +15 -0
  53. package/src/utils/computerUse/common.ts +19 -0
  54. package/src/utils/computerUse/mcpServer.ts +15 -0
  55. package/src/utils/config.ts +35 -0
  56. package/src/utils/context.ts +19 -0
  57. package/src/utils/cwd.ts +3 -0
  58. package/src/utils/debug.ts +3 -0
  59. package/src/utils/earlyInput.ts +7 -0
  60. package/src/utils/effort.ts +13 -0
  61. package/src/utils/embeddedTools.ts +12 -0
  62. package/src/utils/envUtils.ts +3 -0
  63. package/src/utils/errors.ts +3 -0
  64. package/src/utils/execFileNoThrow.ts +24 -0
  65. package/src/utils/feature-flags.ts +112 -0
  66. package/src/utils/file.ts +3 -0
  67. package/src/utils/fileHistory.ts +17 -0
  68. package/src/utils/fingerprint.ts +7 -0
  69. package/src/utils/format.ts +75 -305
  70. package/src/utils/frontmatterParser.ts +33 -0
  71. package/src/utils/fsOperations.ts +31 -0
  72. package/src/utils/fullscreen.ts +40 -350
  73. package/src/utils/git.ts +15 -0
  74. package/src/utils/imageResizer.ts +30 -0
  75. package/src/utils/lazySchema.ts +9 -0
  76. package/src/utils/log.ts +3 -0
  77. package/src/utils/markdownConfigLoader.ts +12 -0
  78. package/src/utils/messages.ts +13 -0
  79. package/src/utils/migration.ts +137 -0
  80. package/src/utils/model/providers.ts +15 -0
  81. package/src/utils/path.ts +3 -0
  82. package/src/utils/permissions/PermissionResult.ts +14 -0
  83. package/src/utils/permissions/autoModeState.ts +12 -0
  84. package/src/utils/permissions/filesystem.ts +12 -0
  85. package/src/utils/plugins/loadPluginOutputStyles.ts +12 -0
  86. package/src/utils/plugins/schemas.ts +25 -0
  87. package/src/utils/process.ts +16 -0
  88. package/src/utils/sandbox/sandbox-adapter.ts +19 -0
  89. package/src/utils/sessionStorage.ts +238 -472
  90. package/src/utils/settings/constants.ts +10 -0
  91. package/src/utils/settings/settings.ts +19 -0
  92. package/src/utils/settings/types.ts +18 -0
  93. package/src/utils/shell/shellToolUtils.ts +9 -0
  94. package/src/utils/sinks.ts +11 -0
  95. package/src/utils/sleep.ts +7 -0
  96. package/src/utils/sliceAnsi.ts +7 -0
  97. package/src/utils/slowOperations.ts +3 -0
  98. package/src/utils/startupProfiler.ts +11 -0
  99. package/src/utils/stringUtils.ts +106 -0
  100. package/src/utils/systemPromptType.ts +9 -0
  101. package/src/utils/teleport/api.ts +15 -0
  102. package/src/utils/textHighlighting.ts +16 -0
  103. package/src/utils/theme.ts +17 -0
  104. package/src/utils/thinking.ts +58 -0
  105. package/src/utils/tokens.ts +11 -0
  106. package/src/utils/toolResultStorage.ts +17 -0
  107. package/src/utils/worktreeModeEnabled.ts +7 -0
  108. package/WORKSPACE_INTEGRATION.md +0 -290
  109. package/chat-sessions/sessions-index.json +0 -98
  110. package/package.json.original +0 -31
  111. package/package.json.publish +0 -47
  112. package/src/bootstrap/state.d.ts +0 -169
  113. package/src/bootstrap/state.js +0 -261
  114. package/src/context/pack-builder.d.ts +0 -24
  115. package/src/context/pack-builder.js +0 -281
  116. package/src/hooks/useExitOnCtrlCD.d.ts +0 -86
  117. package/src/hooks/useExitOnCtrlCD.js +0 -130
  118. package/src/hooks/useKeybinding.d.ts +0 -89
  119. package/src/hooks/useKeybinding.js +0 -163
  120. package/src/hooks/useTerminalSize.d.ts +0 -41
  121. package/src/hooks/useTerminalSize.js +0 -90
  122. package/src/index.d.ts +0 -23
  123. package/src/index.js +0 -24
  124. package/src/runtime/brand/brand.d.ts +0 -488
  125. package/src/runtime/brand/brand.js +0 -464
  126. package/src/runtime/brand/brand.ts +0 -667
  127. package/src/runtime/services/tokenEstimation.d.ts +0 -187
  128. package/src/runtime/services/tokenEstimation.js +0 -423
  129. package/src/runtime/services/tokenEstimation.ts +0 -547
  130. package/src/runtime/tools/Tool.d.ts +0 -239
  131. package/src/runtime/tools/Tool.js +0 -285
  132. package/src/runtime/tools/Tool.ts +0 -524
  133. package/src/scheduler/TaskScheduler.d.ts +0 -98
  134. package/src/scheduler/TaskScheduler.js +0 -201
  135. package/src/scheduler/TaskScheduler.ts +0 -259
  136. package/src/state/AppStateStore.d.ts +0 -347
  137. package/src/state/AppStateStore.js +0 -439
  138. package/src/state/AppStateStore.ts +0 -658
  139. package/src/state/WorkspaceStateStore.d.ts +0 -43
  140. package/src/state/WorkspaceStateStore.js +0 -224
  141. package/src/state/WorkspaceStateStore.ts +0 -297
  142. package/src/types/message.d.ts +0 -190
  143. package/src/types/message.js +0 -77
  144. package/src/utils/format.d.ts +0 -126
  145. package/src/utils/format.js +0 -230
  146. package/src/utils/fullscreen.d.ts +0 -161
  147. package/src/utils/fullscreen.js +0 -277
  148. package/src/utils/sessionStorage.d.ts +0 -210
  149. package/src/utils/sessionStorage.js +0 -435
  150. package/src/watcher/WorkspaceWatcher.d.ts +0 -70
  151. package/src/watcher/WorkspaceWatcher.js +0 -191
  152. package/src/watcher/WorkspaceWatcher.ts +0 -251
  153. package/src/workspace/loader.d.ts +0 -30
  154. package/src/workspace/loader.js +0 -117
  155. package/src/workspace/types.d.ts +0 -91
  156. package/src/workspace/types.js +0 -7
  157. package/threads/thread_1775361175022.json +0 -9
  158. package/tsconfig.json +0 -14
@@ -1,226 +1,85 @@
1
1
  /**
2
- * @fileoverview Keybinding hook for gizzi-code integration
3
- * @module hooks/useKeybinding
4
- *
5
- * Provides a React hook for registering keyboard shortcuts and key combinations.
6
- * Supports modifier keys (Ctrl, Alt, Shift, Meta) and automatic cleanup on unmount.
2
+ * useKeybinding hook
3
+ * Registers keyboard shortcuts
7
4
  */
8
5
 
9
- import { useEffect, useCallback, useRef } from 'react';
10
-
11
- /**
12
- * Key combination configuration
13
- * @interface KeybindingConfig
14
- */
15
- export interface KeybindingConfig {
16
- /** The main key (e.g., 'c', 'Enter', 'Escape') */
17
- readonly key: string;
18
- /** Require Ctrl key to be pressed */
19
- readonly ctrl?: boolean;
20
- /** Require Alt/Option key to be pressed */
21
- readonly alt?: boolean;
22
- /** Require Shift key to be pressed */
23
- readonly shift?: boolean;
24
- /** Require Meta/Command key to be pressed */
25
- readonly meta?: boolean;
26
- /** Prevent default browser behavior */
27
- readonly preventDefault?: boolean;
28
- /** Stop event propagation */
29
- readonly stopPropagation?: boolean;
30
- }
31
-
32
- /**
33
- * Mutable version for internal parsing
34
- * @interface MutableKeybindingConfig
35
- */
36
- interface MutableKeybindingConfig {
37
- key: string;
38
- ctrl?: boolean;
39
- alt?: boolean;
40
- shift?: boolean;
41
- meta?: boolean;
42
- preventDefault?: boolean;
43
- stopPropagation?: boolean;
44
- }
45
-
46
- /**
47
- * Normalized key combination string for comparison
48
- * @param {KeybindingConfig} config - Keybinding configuration
49
- * @returns {string} Normalized key combination string
50
- */
51
- function normalizeKeyCombo(config: KeybindingConfig): string {
52
- const parts: string[] = [];
53
- if (config.ctrl) parts.push('ctrl');
54
- if (config.alt) parts.push('alt');
55
- if (config.shift) parts.push('shift');
56
- if (config.meta) parts.push('meta');
57
- parts.push(config.key.toLowerCase());
58
- return parts.join('+');
6
+ import { useEffect, useCallback } from 'react'
7
+ import { useInput } from 'ink'
8
+
9
+ export type KeyHandler = (input: string, key: Key) => void
10
+
11
+ export interface Key {
12
+ upArrow: boolean
13
+ downArrow: boolean
14
+ leftArrow: boolean
15
+ rightArrow: boolean
16
+ pageDown: boolean
17
+ pageUp: boolean
18
+ return: boolean
19
+ escape: boolean
20
+ ctrl: boolean
21
+ shift: boolean
22
+ tab: boolean
23
+ backspace: boolean
24
+ delete: boolean
25
+ meta: boolean
59
26
  }
60
27
 
61
- /**
62
- * Parses a keybinding string into a config object
63
- *
64
- * @param {string} keybinding - Keybinding string (e.g., "Ctrl+C", "Escape", "Ctrl+Shift+A")
65
- * @returns {KeybindingConfig} Parsed keybinding configuration
66
- * @example
67
- * ```typescript
68
- * parseKeybinding("Ctrl+C"); // { key: 'c', ctrl: true }
69
- * parseKeybinding("Escape"); // { key: 'escape' }
70
- * parseKeybinding("Ctrl+Shift+A"); // { key: 'a', ctrl: true, shift: true }
71
- * ```
72
- */
73
- export function parseKeybinding(keybinding: string): KeybindingConfig {
74
- const parts = keybinding.split('+').map((p) => p.trim().toLowerCase());
75
-
76
- const config: MutableKeybindingConfig = {
77
- key: '',
78
- ctrl: false,
79
- alt: false,
80
- shift: false,
81
- meta: false,
82
- };
83
-
84
- for (const part of parts) {
85
- switch (part) {
86
- case 'ctrl':
87
- case 'control':
88
- config.ctrl = true;
89
- break;
90
- case 'alt':
91
- case 'option':
92
- config.alt = true;
93
- break;
94
- case 'shift':
95
- config.shift = true;
96
- break;
97
- case 'meta':
98
- case 'cmd':
99
- case 'command':
100
- case 'win':
101
- case 'windows':
102
- config.meta = true;
103
- break;
104
- default:
105
- config.key = part;
106
- break;
28
+ export function useKeybinding(key: string, handler: () => void, deps: React.DependencyList = []): void {
29
+ const memoizedHandler = useCallback(handler, deps)
30
+
31
+ useInput((input, keyEvent) => {
32
+ const keyMatch = key.toLowerCase()
33
+
34
+ if (keyMatch === 'ctrl+c' && keyEvent.ctrl && input === 'c') {
35
+ memoizedHandler()
36
+ } else if (keyMatch === 'ctrl+d' && keyEvent.ctrl && input === 'd') {
37
+ memoizedHandler()
38
+ } else if (keyMatch === 'ctrl+z' && keyEvent.ctrl && input === 'z') {
39
+ memoizedHandler()
40
+ } else if (keyMatch === 'escape' && keyEvent.escape) {
41
+ memoizedHandler()
42
+ } else if (keyMatch === 'return' && keyEvent.return) {
43
+ memoizedHandler()
44
+ } else if (keyMatch === 'tab' && keyEvent.tab) {
45
+ memoizedHandler()
46
+ } else if (keyMatch === 'up' && keyEvent.upArrow) {
47
+ memoizedHandler()
48
+ } else if (keyMatch === 'down' && keyEvent.downArrow) {
49
+ memoizedHandler()
50
+ } else if (keyMatch === 'left' && keyEvent.leftArrow) {
51
+ memoizedHandler()
52
+ } else if (keyMatch === 'right' && keyEvent.rightArrow) {
53
+ memoizedHandler()
54
+ } else if (keyMatch === input.toLowerCase()) {
55
+ memoizedHandler()
107
56
  }
108
- }
109
-
110
- return config;
57
+ })
111
58
  }
112
59
 
113
- /**
114
- * Key event handler type
115
- * @typedef {Function} KeyHandler
116
- */
117
- export type KeyHandler = (event: KeyboardEvent) => void | boolean;
118
-
119
- /**
120
- * React hook for registering keyboard shortcuts
121
- *
122
- * Registers a keyboard shortcut that triggers the provided handler when pressed.
123
- * Automatically cleans up the event listener when the component unmounts or
124
- * when the keybinding changes.
125
- *
126
- * @param {string | KeybindingConfig} key - Key combination (e.g., "Ctrl+C") or config object
127
- * @param {KeyHandler} handler - Function to call when keybinding is triggered
128
- * @param {boolean} [enabled=true] - Whether the keybinding is active
129
- * @example
130
- * ```typescript
131
- * // Using string keybinding
132
- * useKeybinding('Ctrl+C', () => {
133
- * console.log('Copy!');
134
- * });
135
- *
136
- * // Using config object
137
- * useKeybinding({ key: 'k', ctrl: true }, (e) => {
138
- * e.preventDefault();
139
- * console.log('Ctrl+K pressed');
140
- * });
141
- *
142
- * // With conditional enabling
143
- * useKeybinding('Escape', handleClose, isModalOpen);
144
- * ```
145
- */
146
- export function useKeybinding(
147
- key: string | KeybindingConfig,
148
- handler: KeyHandler,
149
- enabled: boolean = true
150
- ): void {
151
- const config = typeof key === 'string' ? parseKeybinding(key) : key;
152
- const expectedCombo = normalizeKeyCombo(config);
153
- const handlerRef = useRef<KeyHandler>(handler);
154
-
155
- // Keep handler reference up to date without re-registering
60
+ export function useGlobalKeybinding(key: string, handler: () => void): void {
156
61
  useEffect(() => {
157
- handlerRef.current = handler;
158
- }, [handler]);
159
-
160
- const handleKeyDown = useCallback(
161
- (event: KeyboardEvent) => {
162
- // Check if this key event matches our expected combination
163
- const actualCombo = normalizeKeyCombo({
164
- key: event.key,
165
- ctrl: event.ctrlKey,
166
- alt: event.altKey,
167
- shift: event.shiftKey,
168
- meta: event.metaKey,
169
- });
170
-
171
- if (actualCombo === expectedCombo) {
172
- if (config.preventDefault) {
173
- event.preventDefault();
174
- }
175
- if (config.stopPropagation) {
176
- event.stopPropagation();
177
- }
178
-
179
- const result = handlerRef.current(event);
180
- // Allow handler to prevent default by returning false
181
- if (result === false) {
182
- event.preventDefault();
183
- }
62
+ const keyHandler = (str: string, keyEvent: { ctrl: boolean; name: string }) => {
63
+ const keyMatch = key.toLowerCase()
64
+
65
+ if (keyMatch === 'ctrl+c' && keyEvent.ctrl && keyEvent.name === 'c') {
66
+ handler()
67
+ } else if (keyMatch === 'escape' && keyEvent.name === 'escape') {
68
+ handler()
69
+ } else if (keyMatch === keyEvent.name) {
70
+ handler()
184
71
  }
185
- },
186
- [config, expectedCombo]
187
- );
188
-
189
- useEffect(() => {
190
- if (!enabled || typeof window === 'undefined') {
191
- return;
192
72
  }
193
73
 
194
- window.addEventListener('keydown', handleKeyDown);
74
+ process.stdin.on('keypress', keyHandler)
195
75
 
196
76
  return () => {
197
- window.removeEventListener('keydown', handleKeyDown);
198
- };
199
- }, [enabled, handleKeyDown]);
77
+ process.stdin.off('keypress', keyHandler)
78
+ }
79
+ }, [key, handler])
200
80
  }
201
81
 
202
- /**
203
- * Hook for registering multiple keybindings at once
204
- *
205
- * @param {Array<[string | KeybindingConfig, KeyHandler]>} bindings - Array of [keybinding, handler] tuples
206
- * @param {boolean} [enabled=true] - Whether all keybindings are active
207
- * @example
208
- * ```typescript
209
- * useKeybindings([
210
- * ['Ctrl+C', handleCopy],
211
- * ['Ctrl+V', handlePaste],
212
- * ['Escape', handleClose],
213
- * ]);
214
- * ```
215
- */
216
- export function useKeybindings(
217
- bindings: Array<[string | KeybindingConfig, KeyHandler]>,
218
- enabled: boolean = true
219
- ): void {
220
- bindings.forEach(([key, handler]) => {
221
- useKeybinding(key, handler, enabled);
222
- });
82
+ export default {
83
+ useKeybinding,
84
+ useGlobalKeybinding,
223
85
  }
224
-
225
- // Default export
226
- export default useKeybinding;
@@ -1,117 +1,49 @@
1
1
  /**
2
- * @fileoverview Terminal size hook for gizzi-code integration
3
- * @module hooks/useTerminalSize
4
- *
5
- * Provides a React hook to track terminal dimensions with resize event handling.
6
- * Returns the current terminal width and height, defaulting to standard terminal
7
- * dimensions when not in a browser environment.
2
+ * useTerminalSize hook
3
+ * Tracks terminal dimensions
8
4
  */
9
5
 
10
- import { useState, useEffect, useCallback } from 'react';
6
+ import { useState, useEffect } from 'react'
11
7
 
12
- /**
13
- * Terminal size state interface
14
- * @interface TerminalSize
15
- */
16
8
  export interface TerminalSize {
17
- /** Current terminal width in columns */
18
- readonly width: number;
19
- /** Current terminal height in rows */
20
- readonly height: number;
21
- }
22
-
23
- /**
24
- * Default terminal dimensions (80x24 is standard terminal size)
25
- * @constant {TerminalSize}
26
- */
27
- const DEFAULT_TERMINAL_SIZE: TerminalSize = {
28
- width: 80,
29
- height: 24,
30
- };
31
-
32
- /**
33
- * Gets the current terminal size from the window object
34
- * Falls back to default dimensions if window is not available
35
- *
36
- * @returns {TerminalSize} Current terminal dimensions
37
- */
38
- function getTerminalSize(): TerminalSize {
39
- if (typeof window === 'undefined') {
40
- return DEFAULT_TERMINAL_SIZE;
41
- }
42
-
43
- // Estimate columns/rows based on window size and average character dimensions
44
- // This is an approximation - actual terminal emulators may vary
45
- const avgCharWidth = 8; // pixels per character (approximate)
46
- const avgLineHeight = 16; // pixels per line (approximate)
47
-
48
- const width = Math.max(20, Math.floor(window.innerWidth / avgCharWidth));
49
- const height = Math.max(5, Math.floor(window.innerHeight / avgLineHeight));
50
-
51
- return { width, height };
9
+ width: number
10
+ height: number
52
11
  }
53
12
 
54
- /**
55
- * React hook for tracking terminal size
56
- *
57
- * Returns the current terminal dimensions and automatically updates
58
- * when the window is resized. Uses debouncing to prevent excessive
59
- * re-renders during resize operations.
60
- *
61
- * @returns {TerminalSize} Current terminal width and height
62
- * @example
63
- * ```typescript
64
- * function MyComponent() {
65
- * const { width, height } = useTerminalSize();
66
- *
67
- * return (
68
- * <div>
69
- * Terminal: {width}×{height}
70
- * </div>
71
- * );
72
- * }
73
- * ```
74
- */
75
13
  export function useTerminalSize(): TerminalSize {
76
- const [size, setSize] = useState<TerminalSize>(getTerminalSize);
77
-
78
- const handleResize = useCallback(() => {
79
- setSize(getTerminalSize());
80
- }, []);
14
+ const [size, setSize] = useState<TerminalSize>({
15
+ width: process.stdout.columns || 80,
16
+ height: process.stdout.rows || 24,
17
+ })
81
18
 
82
19
  useEffect(() => {
83
- // Check if window is available (SSR safety)
84
- if (typeof window === 'undefined') {
85
- return;
20
+ const handleResize = () => {
21
+ setSize({
22
+ width: process.stdout.columns || 80,
23
+ height: process.stdout.rows || 24,
24
+ })
86
25
  }
87
26
 
88
- // Debounced resize handler
89
- let resizeTimeout: ReturnType<typeof setTimeout> | null = null;
90
-
91
- const debouncedHandleResize = (): void => {
92
- if (resizeTimeout) {
93
- clearTimeout(resizeTimeout);
94
- }
95
- resizeTimeout = setTimeout(handleResize, 100);
96
- };
27
+ process.stdout.on('resize', handleResize)
97
28
 
98
- // Set initial size
99
- handleResize();
29
+ return () => {
30
+ process.stdout.off('resize', handleResize)
31
+ }
32
+ }, [])
100
33
 
101
- // Add resize listener
102
- window.addEventListener('resize', debouncedHandleResize);
34
+ return size
35
+ }
103
36
 
104
- // Cleanup
105
- return () => {
106
- window.removeEventListener('resize', debouncedHandleResize);
107
- if (resizeTimeout) {
108
- clearTimeout(resizeTimeout);
109
- }
110
- };
111
- }, [handleResize]);
37
+ export function useTerminalWidth(): number {
38
+ return useTerminalSize().width
39
+ }
112
40
 
113
- return size;
41
+ export function useTerminalHeight(): number {
42
+ return useTerminalSize().height
114
43
  }
115
44
 
116
- // Default export for convenient importing
117
- export default useTerminalSize;
45
+ export default {
46
+ useTerminalSize,
47
+ useTerminalWidth,
48
+ useTerminalHeight,
49
+ }
package/src/hooks.ts ADDED
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Hooks System
3
+ */
4
+
5
+ export interface HookContext {
6
+ event: string
7
+ data: unknown
8
+ }
9
+
10
+ export type HookCallback = (ctx: HookContext) => void | Promise<void>
11
+
12
+ const hooks: Map<string, HookCallback[]> = new Map()
13
+
14
+ export function registerHook(event: string, callback: HookCallback): () => void {
15
+ if (!hooks.has(event)) {
16
+ hooks.set(event, [])
17
+ }
18
+ hooks.get(event)!.push(callback)
19
+ return () => {
20
+ const callbacks = hooks.get(event)
21
+ if (callbacks) {
22
+ const index = callbacks.indexOf(callback)
23
+ if (index >= 0) callbacks.splice(index, 1)
24
+ }
25
+ }
26
+ }
27
+
28
+ export async function executeHooks(event: string, data: unknown): Promise<void> {
29
+ const callbacks = hooks.get(event) || []
30
+ for (const callback of callbacks) {
31
+ await callback({ event, data })
32
+ }
33
+ }
34
+
35
+ export function hasWorktreeCreateHook(): boolean {
36
+ return hooks.has('worktree:create')
37
+ }
package/src/ink.ts ADDED
@@ -0,0 +1,204 @@
1
+ /**
2
+ * Ink CLI rendering utilities
3
+ * React-based CLI UI components
4
+ */
5
+
6
+ import type { ReactNode } from 'react'
7
+
8
+ // Re-export from ink
9
+ export {
10
+ render,
11
+ Box,
12
+ Text,
13
+ useInput,
14
+ useApp,
15
+ useStdout,
16
+ useStdin,
17
+ Spacer,
18
+ Newline,
19
+ Static,
20
+ Transform,
21
+ measureElement,
22
+ useFocus,
23
+ useFocusManager,
24
+ } from 'ink'
25
+
26
+ export type { BoxProps, TextProps, RenderOptions } from 'ink'
27
+
28
+ // Key handling types
29
+ export interface Key {
30
+ name?: string
31
+ ctrl?: boolean
32
+ shift?: boolean
33
+ meta?: boolean
34
+ sequence?: string
35
+ }
36
+
37
+ // String width calculation (for text wrapping)
38
+ export function stringWidth(str: string): number {
39
+ // Strip ANSI codes and count visible characters
40
+ const withoutAnsi = str.replace(/\u001b\[[0-9;]*m/g, '')
41
+ // Approximate width (for proper implementation, use string-width package)
42
+ return [...withoutAnsi].length
43
+ }
44
+
45
+ // Terminal size hook
46
+ export interface TerminalSize {
47
+ width: number
48
+ height: number
49
+ }
50
+
51
+ export function useTerminalSize(): TerminalSize {
52
+ // Default fallback
53
+ return {
54
+ width: process.stdout.columns || 80,
55
+ height: process.stdout.rows || 24,
56
+ }
57
+ }
58
+
59
+ // Color utilities
60
+ export type InkColor =
61
+ | 'black'
62
+ | 'red'
63
+ | 'green'
64
+ | 'yellow'
65
+ | 'blue'
66
+ | 'magenta'
67
+ | 'cyan'
68
+ | 'white'
69
+ | 'gray'
70
+ | 'grey'
71
+ | 'redBright'
72
+ | 'greenBright'
73
+ | 'yellowBright'
74
+ | 'blueBright'
75
+ | 'magentaBright'
76
+ | 'cyanBright'
77
+ | 'whiteBright'
78
+ | string
79
+ | number
80
+ | undefined
81
+
82
+ // Common key codes
83
+ export const KeyCodes = {
84
+ RETURN: '\r',
85
+ ENTER: '\n',
86
+ TAB: '\t',
87
+ ESC: '\u001b',
88
+ BACKSPACE: '\u007f',
89
+ CTRL_C: '\u0003',
90
+ CTRL_D: '\u0004',
91
+ CTRL_Z: '\u001a',
92
+ UP: '\u001b[A',
93
+ DOWN: '\u001b[B',
94
+ RIGHT: '\u001b[C',
95
+ LEFT: '\u001b[D',
96
+ } as const
97
+
98
+ // Spinner states
99
+ export type SpinnerType =
100
+ | 'dots'
101
+ | 'dots2'
102
+ | 'dots3'
103
+ | 'dots4'
104
+ | 'dots5'
105
+ | 'dots6'
106
+ | 'dots7'
107
+ | 'dots8'
108
+ | 'dots9'
109
+ | 'dots10'
110
+ | 'dots11'
111
+ | 'dots12'
112
+ | 'line'
113
+ | 'line2'
114
+ | 'pipe'
115
+ | 'star'
116
+ | 'star2'
117
+ | 'flip'
118
+ | 'hamburger'
119
+ | 'growVertical'
120
+ | 'growHorizontal'
121
+ | 'balloon'
122
+ | 'balloon2'
123
+ | 'noise'
124
+ | 'bounce'
125
+ | 'boxBounce'
126
+ | 'boxBounce2'
127
+ | 'triangle'
128
+ | 'arc'
129
+ | 'circle'
130
+ | 'squareCorners'
131
+ | 'circleQuarters'
132
+ | 'circleHalves'
133
+ | 'squish'
134
+ | 'toggle'
135
+ | 'toggle2'
136
+ | 'toggle3'
137
+ | 'toggle4'
138
+ | 'toggle5'
139
+ | 'toggle6'
140
+ | 'toggle7'
141
+ | 'toggle8'
142
+ | 'toggle9'
143
+ | 'toggle10'
144
+ | 'toggle11'
145
+ | 'toggle12'
146
+ | 'toggle13'
147
+
148
+ export const SPINNER_FRAMES: Record<SpinnerType, string[]> = {
149
+ dots: ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'],
150
+ dots2: ['⣾', '⣽', '⣻', '⢿', '⡿', '⣟', '⣯', '⣷'],
151
+ dots3: ['⠋', '⠙', '⠚', '⠞', '⠖', '⠦', '⠴', '⠲', '⠳', '⠓'],
152
+ dots4: ['⠄', '⠆', '⠇', '⠋', '⠙', '⠸', '⠰', '⠠', '⠰', '⠸', '⠙', '⠋', '⠇', '⠆'],
153
+ dots5: ['⠋', '⠙', '⠚', '⠒', '⠂', '⠂', '⠒', '⠲', '⠴', '⠦', '⠖', '⠒', '⠐', '⠐', '⠒', '⠓', '⠋'],
154
+ dots6: ['⠁', '⠉', '⠙', '⠚', '⠒', '⠂', '⠂', '⠒', '⠲', '⠴', '⠤', '⠄', '⠄', '⠤', '⠴', '⠲', '⠒', '⠂', '⠂', '⠒', '⠚', '⠙', '⠉', '⠁'],
155
+ dots7: ['⠈', '⠉', '⠋', '⠓', '⠒', '⠐', '⠐', '⠒', '⠖', '⠦', '⠤', '⠠', '⠠', '⠤', '⠦', '⠖', '⠒', '⠐', '⠐', '⠒', '⠓', '⠋', '⠉', '⠈'],
156
+ dots8: ['⠁', '⠁', '⠉', '⠙', '⠚', '⠒', '⠂', '⠂', '⠒', '⠲', '⠴', '⠤', '⠄', '⠄', '⠤', '⠠', '⠠', '⠤', '⠦', '⠖', '⠒', '⠐', '⠐', '⠒', '⠓', '⠋', '⠉', '⠈', '⠈'],
157
+ dots9: ['⢹', '⢺', '⢼', '⣸', '⣇', '⡧', '⡗', '⡏'],
158
+ dots10: ['⢄', '⢂', '⢁', '⡁', '⡈', '⡐', '⡠'],
159
+ dots11: ['⠁', '⠂', '⠄', '⡀', '⢀', '⠠', '⠐', '⠈'],
160
+ dots12: ['⢀⠀', '⡀⠀', '⠄⠀', '⢂⠀', '⡂⠀', '⠅⠀', '⢃⠀', '⡃⠀', '⠍⠀', '⢋⠀', '⡋⠀', '⠍⠁', '⢋⠁', '⡋⠁', '⠍⠉', '⢋⠉', '⡋⠉', '⠍⠙', '⢋⠙', '⡋⠙', '⠍⠚', '⢋⠚', '⡋⠚', '⠍⠒', '⢋⠒', '⡋⠒', '⠍⠂', '⢋⠂', '⡋⠂', '⠍⡀', '⢋⡀', '⡋⡀', '⠍⡄', '⢋⡄', '⡋⡄', '⠍⡆', '⢋⡆', '⡋⡆', '⠍⡇', '⢋⡇', '⡋⡇', '⠍⡏', '⢋⡏', '⡋⡏', '⠍⡹', '⢋⡹', '⡋⡹', '⠍⢹', '⢋⢹', '⡋⢹', '⠍⣸', '⢋⣸', '⡋⣸', '⠍⣴', '⢋⣴', '⡋⣴', '⠍⣦', '⢋⣦', '⡋⣦', '⠍⣇', '⢋⣇', '⡋⣇', '⠍⡧', '⢋⡧', '⡋⡧', '⠍⡗', '⢋⡗', '⡋⡗', '⠍⡏'],
161
+ line: ['-', '\\', '|', '/'],
162
+ line2: ['⠂', '-', '–', '—', '–', '-'],
163
+ pipe: ['┤', '┘', '┴', '└', '├', '┌', '┬', '┐'],
164
+ star: ['✶', '✸', '✹', '✺', '✹', '✷'],
165
+ star2: ['+', 'x', '*'],
166
+ flip: ['_', '_', '_', '-', '`', '`', "'", '´', '-', '_', '_', '_'],
167
+ hamburger: ['☱', '☲', '☴'],
168
+ growVertical: ['▁', '▃', '▄', '▅', '▆', '▇', '▆', '▅', '▄', '▃'],
169
+ growHorizontal: ['▏', '▎', '▍', '▌', '▋', '▊', '▉', '▊', '▋', '▌', '▍', '▎'],
170
+ balloon: ['.', 'o', 'O', '@', '*'],
171
+ balloon2: ['.', 'o', 'O', '°', 'O', 'o', '.'],
172
+ noise: ['▓', '▒', '░'],
173
+ bounce: ['⠁', '⠂', '⠄', '⠂'],
174
+ boxBounce: ['▖', '▘', '▝', '▗'],
175
+ boxBounce2: ['▌', '▀', '▐', '▄'],
176
+ triangle: ['◢', '◣', '◤', '◥'],
177
+ arc: ['◜', '◠', '◝', '◞', '◡', '◟'],
178
+ circle: ['◡', '⊙', '◠'],
179
+ squareCorners: ['◰', '◳', '◲', '◱'],
180
+ circleQuarters: ['◴', '◷', '◶', '◵'],
181
+ circleHalves: ['◐', '◓', '◑', '◒'],
182
+ squish: ['╫', '╪'],
183
+ toggle: ['⊶', '⊷'],
184
+ toggle2: ['▫', '▪'],
185
+ toggle3: ['□', '■'],
186
+ toggle4: ['■', '□', '▪', '▫'],
187
+ toggle5: ['▮', '▯'],
188
+ toggle6: ['ဝ', '၀'],
189
+ toggle7: ['⦾', '⦿'],
190
+ toggle8: ['◍', '◌'],
191
+ toggle9: ['◉', '◎'],
192
+ toggle10: ['㊂', '㊀', '㊁'],
193
+ toggle11: ['⬇', '⬆'],
194
+ toggle12: ['▹', '▿', '◃'],
195
+ toggle13: ['▁', '▂', '▃', '▄', '▅', '▆', '▇', '█', '▉', '▊', '▋', '▌', '▍', '▎', '▏', '▎', '▍', '▌', '▋', '▊', '▉', '█', '▇', '▆', '▅', '▄', '▃', '▂', '▁'],
196
+ }
197
+
198
+ // Default export
199
+ export default {
200
+ stringWidth,
201
+ useTerminalSize,
202
+ KeyCodes,
203
+ SPINNER_FRAMES,
204
+ }