@allternit/gizzi-code 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/WORKSPACE_INTEGRATION.md +290 -0
- package/chat-sessions/sessions-index.json +98 -0
- package/package.json +43 -0
- package/package.json.original +31 -0
- package/package.json.publish +47 -0
- package/src/bootstrap/state.d.ts +169 -0
- package/src/bootstrap/state.js +261 -0
- package/src/bootstrap/state.ts +371 -0
- package/src/context/pack-builder.d.ts +24 -0
- package/src/context/pack-builder.js +281 -0
- package/src/context/pack-builder.ts +334 -0
- package/src/hooks/useExitOnCtrlCD.d.ts +86 -0
- package/src/hooks/useExitOnCtrlCD.js +130 -0
- package/src/hooks/useExitOnCtrlCD.ts +202 -0
- package/src/hooks/useKeybinding.d.ts +89 -0
- package/src/hooks/useKeybinding.js +163 -0
- package/src/hooks/useKeybinding.ts +226 -0
- package/src/hooks/useTerminalSize.d.ts +41 -0
- package/src/hooks/useTerminalSize.js +90 -0
- package/src/hooks/useTerminalSize.ts +117 -0
- package/src/index.d.ts +23 -0
- package/src/index.js +24 -0
- package/src/index.ts +132 -0
- package/src/runtime/brand/brand.d.ts +488 -0
- package/src/runtime/brand/brand.js +464 -0
- package/src/runtime/brand/brand.ts +667 -0
- package/src/runtime/services/tokenEstimation.d.ts +187 -0
- package/src/runtime/services/tokenEstimation.js +423 -0
- package/src/runtime/services/tokenEstimation.ts +547 -0
- package/src/runtime/tools/Tool.d.ts +239 -0
- package/src/runtime/tools/Tool.js +285 -0
- package/src/runtime/tools/Tool.ts +524 -0
- package/src/scheduler/TaskScheduler.d.ts +98 -0
- package/src/scheduler/TaskScheduler.js +201 -0
- package/src/scheduler/TaskScheduler.ts +259 -0
- package/src/state/AppStateStore.d.ts +347 -0
- package/src/state/AppStateStore.js +439 -0
- package/src/state/AppStateStore.ts +658 -0
- package/src/state/WorkspaceStateStore.d.ts +43 -0
- package/src/state/WorkspaceStateStore.js +224 -0
- package/src/state/WorkspaceStateStore.ts +297 -0
- package/src/types/message.d.ts +190 -0
- package/src/types/message.js +77 -0
- package/src/types/message.ts +277 -0
- package/src/utils/format.d.ts +126 -0
- package/src/utils/format.js +230 -0
- package/src/utils/format.ts +336 -0
- package/src/utils/fullscreen.d.ts +161 -0
- package/src/utils/fullscreen.js +277 -0
- package/src/utils/fullscreen.ts +382 -0
- package/src/utils/sessionStorage.d.ts +210 -0
- package/src/utils/sessionStorage.js +435 -0
- package/src/utils/sessionStorage.ts +559 -0
- package/src/watcher/WorkspaceWatcher.d.ts +70 -0
- package/src/watcher/WorkspaceWatcher.js +191 -0
- package/src/watcher/WorkspaceWatcher.ts +251 -0
- package/src/workspace/loader.d.ts +30 -0
- package/src/workspace/loader.js +117 -0
- package/src/workspace/loader.ts +171 -0
- package/src/workspace/types.d.ts +91 -0
- package/src/workspace/types.js +7 -0
- package/src/workspace/types.ts +122 -0
- package/threads/thread_1775361175022.json +9 -0
- package/tsconfig.json +14 -0
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Exit handler hook for gizzi-code integration
|
|
3
|
+
* @module hooks/useExitOnCtrlCD
|
|
4
|
+
*
|
|
5
|
+
* Provides a React hook for handling exit key combinations (Ctrl+C and Ctrl+D).
|
|
6
|
+
* Commonly used for CLI applications to handle graceful shutdown or exit actions.
|
|
7
|
+
*/
|
|
8
|
+
import { useCallback } from 'react';
|
|
9
|
+
import { useKeybinding } from './useKeybinding';
|
|
10
|
+
/**
|
|
11
|
+
* Default confirmation message
|
|
12
|
+
* @constant {string}
|
|
13
|
+
*/
|
|
14
|
+
const DEFAULT_CONFIRM_MESSAGE = 'Are you sure you want to exit? (y/N): ';
|
|
15
|
+
/**
|
|
16
|
+
* Default exit message
|
|
17
|
+
* @constant {string}
|
|
18
|
+
*/
|
|
19
|
+
const DEFAULT_EXIT_MESSAGE = 'Goodbye!';
|
|
20
|
+
/**
|
|
21
|
+
* React hook for handling Ctrl+C and Ctrl+D exit combinations
|
|
22
|
+
*
|
|
23
|
+
* Registers keyboard shortcuts for common terminal exit commands and
|
|
24
|
+
* executes the provided callback when triggered. Supports optional
|
|
25
|
+
* confirmation before exit.
|
|
26
|
+
*
|
|
27
|
+
* @param {ExitHandler | UseExitOnCtrlCDOptions} handler - Exit callback or options object
|
|
28
|
+
* @example
|
|
29
|
+
* ```typescript
|
|
30
|
+
* // Simple usage with callback
|
|
31
|
+
* useExitOnCtrlCD(() => {
|
|
32
|
+
* console.log('Exiting...');
|
|
33
|
+
* process.exit(0);
|
|
34
|
+
* });
|
|
35
|
+
*
|
|
36
|
+
* // With options
|
|
37
|
+
* useExitOnCtrlCD({
|
|
38
|
+
* onExit: () => saveAndQuit(),
|
|
39
|
+
* enableCtrlC: true,
|
|
40
|
+
* enableCtrlD: false,
|
|
41
|
+
* exitMessage: '👋 See you later!',
|
|
42
|
+
* confirmBeforeExit: true,
|
|
43
|
+
* });
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
export function useExitOnCtrlCD(handler) {
|
|
47
|
+
// Normalize input to options object
|
|
48
|
+
const options = typeof handler === 'function' ? { onExit: handler } : handler;
|
|
49
|
+
const { onExit, enableCtrlC = true, enableCtrlD = true, enabled = true, exitMessage = DEFAULT_EXIT_MESSAGE, confirmBeforeExit = false, confirmMessage = DEFAULT_CONFIRM_MESSAGE, } = options;
|
|
50
|
+
const handleExit = useCallback(async (event) => {
|
|
51
|
+
// Handle confirmation if enabled
|
|
52
|
+
if (confirmBeforeExit) {
|
|
53
|
+
// Note: In a real CLI environment, you might use readline here
|
|
54
|
+
// For browser/React environments, this is a simplified version
|
|
55
|
+
const confirmed = typeof window !== 'undefined'
|
|
56
|
+
? window.confirm(confirmMessage)
|
|
57
|
+
: true;
|
|
58
|
+
if (!confirmed) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
// Show exit message
|
|
63
|
+
if (exitMessage && typeof console !== 'undefined') {
|
|
64
|
+
console.log(exitMessage);
|
|
65
|
+
}
|
|
66
|
+
// Execute exit handler
|
|
67
|
+
if (onExit) {
|
|
68
|
+
try {
|
|
69
|
+
const result = await onExit();
|
|
70
|
+
// Return false from handler to prevent default exit behavior
|
|
71
|
+
if (result === false && event) {
|
|
72
|
+
event.preventDefault();
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
console.error('Error during exit:', error);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}, [onExit, confirmBeforeExit, confirmMessage, exitMessage]);
|
|
80
|
+
// Wrap handler to match KeyHandler signature
|
|
81
|
+
const keyHandler = useCallback((event) => {
|
|
82
|
+
handleExit(event);
|
|
83
|
+
}, [handleExit]);
|
|
84
|
+
// Register Ctrl+C handler (SIGINT equivalent)
|
|
85
|
+
useKeybinding({ key: 'c', ctrl: true, preventDefault: true }, keyHandler, enabled && enableCtrlC);
|
|
86
|
+
// Register Ctrl+D handler (EOF/exit equivalent)
|
|
87
|
+
useKeybinding({ key: 'd', ctrl: true, preventDefault: true }, keyHandler, enabled && enableCtrlD);
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Convenience hook for just Ctrl+C handling
|
|
91
|
+
*
|
|
92
|
+
* @param {ExitHandler} handler - Exit callback
|
|
93
|
+
* @param {boolean} [enabled=true] - Whether the handler is active
|
|
94
|
+
* @example
|
|
95
|
+
* ```typescript
|
|
96
|
+
* useExitOnCtrlC(() => {
|
|
97
|
+
* console.log('Interrupted');
|
|
98
|
+
* });
|
|
99
|
+
* ```
|
|
100
|
+
*/
|
|
101
|
+
export function useExitOnCtrlC(handler, enabled = true) {
|
|
102
|
+
useExitOnCtrlCD({
|
|
103
|
+
onExit: handler,
|
|
104
|
+
enableCtrlC: true,
|
|
105
|
+
enableCtrlD: false,
|
|
106
|
+
enabled,
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Convenience hook for just Ctrl+D handling
|
|
111
|
+
*
|
|
112
|
+
* @param {ExitHandler} handler - Exit callback
|
|
113
|
+
* @param {boolean} [enabled=true] - Whether the handler is active
|
|
114
|
+
* @example
|
|
115
|
+
* ```typescript
|
|
116
|
+
* useExitOnCtrlD(() => {
|
|
117
|
+
* console.log('EOF received');
|
|
118
|
+
* });
|
|
119
|
+
* ```
|
|
120
|
+
*/
|
|
121
|
+
export function useExitOnCtrlD(handler, enabled = true) {
|
|
122
|
+
useExitOnCtrlCD({
|
|
123
|
+
onExit: handler,
|
|
124
|
+
enableCtrlC: false,
|
|
125
|
+
enableCtrlD: true,
|
|
126
|
+
enabled,
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
// Default export
|
|
130
|
+
export default useExitOnCtrlCD;
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Exit handler hook for gizzi-code integration
|
|
3
|
+
* @module hooks/useExitOnCtrlCD
|
|
4
|
+
*
|
|
5
|
+
* Provides a React hook for handling exit key combinations (Ctrl+C and Ctrl+D).
|
|
6
|
+
* Commonly used for CLI applications to handle graceful shutdown or exit actions.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { useCallback } from 'react';
|
|
10
|
+
import { useKeybinding, type KeyHandler } from './useKeybinding';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Exit handler callback type
|
|
14
|
+
* @typedef {Function} ExitHandler
|
|
15
|
+
*/
|
|
16
|
+
export type ExitHandler = () => void | boolean | Promise<void | boolean>;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Options for the exit handler hook
|
|
20
|
+
* @interface UseExitOnCtrlCDOptions
|
|
21
|
+
*/
|
|
22
|
+
export interface UseExitOnCtrlCDOptions {
|
|
23
|
+
/** Callback function to execute when exit keys are pressed */
|
|
24
|
+
readonly onExit?: ExitHandler;
|
|
25
|
+
/** Whether Ctrl+C triggers exit (default: true) */
|
|
26
|
+
readonly enableCtrlC?: boolean;
|
|
27
|
+
/** Whether Ctrl+D triggers exit (default: true) */
|
|
28
|
+
readonly enableCtrlD?: boolean;
|
|
29
|
+
/** Whether the exit handler is active (default: true) */
|
|
30
|
+
readonly enabled?: boolean;
|
|
31
|
+
/** Custom message to display on exit (optional) */
|
|
32
|
+
readonly exitMessage?: string;
|
|
33
|
+
/** Whether to confirm before exit (default: false) */
|
|
34
|
+
readonly confirmBeforeExit?: boolean;
|
|
35
|
+
/** Custom confirmation message */
|
|
36
|
+
readonly confirmMessage?: string;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Default confirmation message
|
|
41
|
+
* @constant {string}
|
|
42
|
+
*/
|
|
43
|
+
const DEFAULT_CONFIRM_MESSAGE = 'Are you sure you want to exit? (y/N): ';
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Default exit message
|
|
47
|
+
* @constant {string}
|
|
48
|
+
*/
|
|
49
|
+
const DEFAULT_EXIT_MESSAGE = 'Goodbye!';
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* React hook for handling Ctrl+C and Ctrl+D exit combinations
|
|
53
|
+
*
|
|
54
|
+
* Registers keyboard shortcuts for common terminal exit commands and
|
|
55
|
+
* executes the provided callback when triggered. Supports optional
|
|
56
|
+
* confirmation before exit.
|
|
57
|
+
*
|
|
58
|
+
* @param {ExitHandler | UseExitOnCtrlCDOptions} handler - Exit callback or options object
|
|
59
|
+
* @example
|
|
60
|
+
* ```typescript
|
|
61
|
+
* // Simple usage with callback
|
|
62
|
+
* useExitOnCtrlCD(() => {
|
|
63
|
+
* console.log('Exiting...');
|
|
64
|
+
* process.exit(0);
|
|
65
|
+
* });
|
|
66
|
+
*
|
|
67
|
+
* // With options
|
|
68
|
+
* useExitOnCtrlCD({
|
|
69
|
+
* onExit: () => saveAndQuit(),
|
|
70
|
+
* enableCtrlC: true,
|
|
71
|
+
* enableCtrlD: false,
|
|
72
|
+
* exitMessage: '👋 See you later!',
|
|
73
|
+
* confirmBeforeExit: true,
|
|
74
|
+
* });
|
|
75
|
+
* ```
|
|
76
|
+
*/
|
|
77
|
+
export function useExitOnCtrlCD(
|
|
78
|
+
handler: ExitHandler | UseExitOnCtrlCDOptions
|
|
79
|
+
): void {
|
|
80
|
+
// Normalize input to options object
|
|
81
|
+
const options: UseExitOnCtrlCDOptions =
|
|
82
|
+
typeof handler === 'function' ? { onExit: handler } : handler;
|
|
83
|
+
|
|
84
|
+
const {
|
|
85
|
+
onExit,
|
|
86
|
+
enableCtrlC = true,
|
|
87
|
+
enableCtrlD = true,
|
|
88
|
+
enabled = true,
|
|
89
|
+
exitMessage = DEFAULT_EXIT_MESSAGE,
|
|
90
|
+
confirmBeforeExit = false,
|
|
91
|
+
confirmMessage = DEFAULT_CONFIRM_MESSAGE,
|
|
92
|
+
} = options;
|
|
93
|
+
|
|
94
|
+
const handleExit = useCallback(
|
|
95
|
+
async (event?: KeyboardEvent): Promise<void> => {
|
|
96
|
+
// Handle confirmation if enabled
|
|
97
|
+
if (confirmBeforeExit) {
|
|
98
|
+
// Note: In a real CLI environment, you might use readline here
|
|
99
|
+
// For browser/React environments, this is a simplified version
|
|
100
|
+
const confirmed = typeof window !== 'undefined'
|
|
101
|
+
? window.confirm(confirmMessage)
|
|
102
|
+
: true;
|
|
103
|
+
|
|
104
|
+
if (!confirmed) {
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Show exit message
|
|
110
|
+
if (exitMessage && typeof console !== 'undefined') {
|
|
111
|
+
console.log(exitMessage);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// Execute exit handler
|
|
115
|
+
if (onExit) {
|
|
116
|
+
try {
|
|
117
|
+
const result = await onExit();
|
|
118
|
+
// Return false from handler to prevent default exit behavior
|
|
119
|
+
if (result === false && event) {
|
|
120
|
+
event.preventDefault();
|
|
121
|
+
}
|
|
122
|
+
} catch (error) {
|
|
123
|
+
console.error('Error during exit:', error);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
},
|
|
127
|
+
[onExit, confirmBeforeExit, confirmMessage, exitMessage]
|
|
128
|
+
);
|
|
129
|
+
|
|
130
|
+
// Wrap handler to match KeyHandler signature
|
|
131
|
+
const keyHandler: KeyHandler = useCallback(
|
|
132
|
+
(event: KeyboardEvent) => {
|
|
133
|
+
handleExit(event);
|
|
134
|
+
},
|
|
135
|
+
[handleExit]
|
|
136
|
+
);
|
|
137
|
+
|
|
138
|
+
// Register Ctrl+C handler (SIGINT equivalent)
|
|
139
|
+
useKeybinding(
|
|
140
|
+
{ key: 'c', ctrl: true, preventDefault: true },
|
|
141
|
+
keyHandler,
|
|
142
|
+
enabled && enableCtrlC
|
|
143
|
+
);
|
|
144
|
+
|
|
145
|
+
// Register Ctrl+D handler (EOF/exit equivalent)
|
|
146
|
+
useKeybinding(
|
|
147
|
+
{ key: 'd', ctrl: true, preventDefault: true },
|
|
148
|
+
keyHandler,
|
|
149
|
+
enabled && enableCtrlD
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Convenience hook for just Ctrl+C handling
|
|
155
|
+
*
|
|
156
|
+
* @param {ExitHandler} handler - Exit callback
|
|
157
|
+
* @param {boolean} [enabled=true] - Whether the handler is active
|
|
158
|
+
* @example
|
|
159
|
+
* ```typescript
|
|
160
|
+
* useExitOnCtrlC(() => {
|
|
161
|
+
* console.log('Interrupted');
|
|
162
|
+
* });
|
|
163
|
+
* ```
|
|
164
|
+
*/
|
|
165
|
+
export function useExitOnCtrlC(
|
|
166
|
+
handler: ExitHandler,
|
|
167
|
+
enabled: boolean = true
|
|
168
|
+
): void {
|
|
169
|
+
useExitOnCtrlCD({
|
|
170
|
+
onExit: handler,
|
|
171
|
+
enableCtrlC: true,
|
|
172
|
+
enableCtrlD: false,
|
|
173
|
+
enabled,
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Convenience hook for just Ctrl+D handling
|
|
179
|
+
*
|
|
180
|
+
* @param {ExitHandler} handler - Exit callback
|
|
181
|
+
* @param {boolean} [enabled=true] - Whether the handler is active
|
|
182
|
+
* @example
|
|
183
|
+
* ```typescript
|
|
184
|
+
* useExitOnCtrlD(() => {
|
|
185
|
+
* console.log('EOF received');
|
|
186
|
+
* });
|
|
187
|
+
* ```
|
|
188
|
+
*/
|
|
189
|
+
export function useExitOnCtrlD(
|
|
190
|
+
handler: ExitHandler,
|
|
191
|
+
enabled: boolean = true
|
|
192
|
+
): void {
|
|
193
|
+
useExitOnCtrlCD({
|
|
194
|
+
onExit: handler,
|
|
195
|
+
enableCtrlC: false,
|
|
196
|
+
enableCtrlD: true,
|
|
197
|
+
enabled,
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// Default export
|
|
202
|
+
export default useExitOnCtrlCD;
|
|
@@ -0,0 +1,89 @@
|
|
|
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.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Key combination configuration
|
|
10
|
+
* @interface KeybindingConfig
|
|
11
|
+
*/
|
|
12
|
+
export interface KeybindingConfig {
|
|
13
|
+
/** The main key (e.g., 'c', 'Enter', 'Escape') */
|
|
14
|
+
readonly key: string;
|
|
15
|
+
/** Require Ctrl key to be pressed */
|
|
16
|
+
readonly ctrl?: boolean;
|
|
17
|
+
/** Require Alt/Option key to be pressed */
|
|
18
|
+
readonly alt?: boolean;
|
|
19
|
+
/** Require Shift key to be pressed */
|
|
20
|
+
readonly shift?: boolean;
|
|
21
|
+
/** Require Meta/Command key to be pressed */
|
|
22
|
+
readonly meta?: boolean;
|
|
23
|
+
/** Prevent default browser behavior */
|
|
24
|
+
readonly preventDefault?: boolean;
|
|
25
|
+
/** Stop event propagation */
|
|
26
|
+
readonly stopPropagation?: boolean;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Parses a keybinding string into a config object
|
|
30
|
+
*
|
|
31
|
+
* @param {string} keybinding - Keybinding string (e.g., "Ctrl+C", "Escape", "Ctrl+Shift+A")
|
|
32
|
+
* @returns {KeybindingConfig} Parsed keybinding configuration
|
|
33
|
+
* @example
|
|
34
|
+
* ```typescript
|
|
35
|
+
* parseKeybinding("Ctrl+C"); // { key: 'c', ctrl: true }
|
|
36
|
+
* parseKeybinding("Escape"); // { key: 'escape' }
|
|
37
|
+
* parseKeybinding("Ctrl+Shift+A"); // { key: 'a', ctrl: true, shift: true }
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
export declare function parseKeybinding(keybinding: string): KeybindingConfig;
|
|
41
|
+
/**
|
|
42
|
+
* Key event handler type
|
|
43
|
+
* @typedef {Function} KeyHandler
|
|
44
|
+
*/
|
|
45
|
+
export type KeyHandler = (event: KeyboardEvent) => void | boolean;
|
|
46
|
+
/**
|
|
47
|
+
* React hook for registering keyboard shortcuts
|
|
48
|
+
*
|
|
49
|
+
* Registers a keyboard shortcut that triggers the provided handler when pressed.
|
|
50
|
+
* Automatically cleans up the event listener when the component unmounts or
|
|
51
|
+
* when the keybinding changes.
|
|
52
|
+
*
|
|
53
|
+
* @param {string | KeybindingConfig} key - Key combination (e.g., "Ctrl+C") or config object
|
|
54
|
+
* @param {KeyHandler} handler - Function to call when keybinding is triggered
|
|
55
|
+
* @param {boolean} [enabled=true] - Whether the keybinding is active
|
|
56
|
+
* @example
|
|
57
|
+
* ```typescript
|
|
58
|
+
* // Using string keybinding
|
|
59
|
+
* useKeybinding('Ctrl+C', () => {
|
|
60
|
+
* console.log('Copy!');
|
|
61
|
+
* });
|
|
62
|
+
*
|
|
63
|
+
* // Using config object
|
|
64
|
+
* useKeybinding({ key: 'k', ctrl: true }, (e) => {
|
|
65
|
+
* e.preventDefault();
|
|
66
|
+
* console.log('Ctrl+K pressed');
|
|
67
|
+
* });
|
|
68
|
+
*
|
|
69
|
+
* // With conditional enabling
|
|
70
|
+
* useKeybinding('Escape', handleClose, isModalOpen);
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
73
|
+
export declare function useKeybinding(key: string | KeybindingConfig, handler: KeyHandler, enabled?: boolean): void;
|
|
74
|
+
/**
|
|
75
|
+
* Hook for registering multiple keybindings at once
|
|
76
|
+
*
|
|
77
|
+
* @param {Array<[string | KeybindingConfig, KeyHandler]>} bindings - Array of [keybinding, handler] tuples
|
|
78
|
+
* @param {boolean} [enabled=true] - Whether all keybindings are active
|
|
79
|
+
* @example
|
|
80
|
+
* ```typescript
|
|
81
|
+
* useKeybindings([
|
|
82
|
+
* ['Ctrl+C', handleCopy],
|
|
83
|
+
* ['Ctrl+V', handlePaste],
|
|
84
|
+
* ['Escape', handleClose],
|
|
85
|
+
* ]);
|
|
86
|
+
* ```
|
|
87
|
+
*/
|
|
88
|
+
export declare function useKeybindings(bindings: Array<[string | KeybindingConfig, KeyHandler]>, enabled?: boolean): void;
|
|
89
|
+
export default useKeybinding;
|
|
@@ -0,0 +1,163 @@
|
|
|
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.
|
|
7
|
+
*/
|
|
8
|
+
import { useEffect, useCallback, useRef } from 'react';
|
|
9
|
+
/**
|
|
10
|
+
* Normalized key combination string for comparison
|
|
11
|
+
* @param {KeybindingConfig} config - Keybinding configuration
|
|
12
|
+
* @returns {string} Normalized key combination string
|
|
13
|
+
*/
|
|
14
|
+
function normalizeKeyCombo(config) {
|
|
15
|
+
const parts = [];
|
|
16
|
+
if (config.ctrl)
|
|
17
|
+
parts.push('ctrl');
|
|
18
|
+
if (config.alt)
|
|
19
|
+
parts.push('alt');
|
|
20
|
+
if (config.shift)
|
|
21
|
+
parts.push('shift');
|
|
22
|
+
if (config.meta)
|
|
23
|
+
parts.push('meta');
|
|
24
|
+
parts.push(config.key.toLowerCase());
|
|
25
|
+
return parts.join('+');
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Parses a keybinding string into a config object
|
|
29
|
+
*
|
|
30
|
+
* @param {string} keybinding - Keybinding string (e.g., "Ctrl+C", "Escape", "Ctrl+Shift+A")
|
|
31
|
+
* @returns {KeybindingConfig} Parsed keybinding configuration
|
|
32
|
+
* @example
|
|
33
|
+
* ```typescript
|
|
34
|
+
* parseKeybinding("Ctrl+C"); // { key: 'c', ctrl: true }
|
|
35
|
+
* parseKeybinding("Escape"); // { key: 'escape' }
|
|
36
|
+
* parseKeybinding("Ctrl+Shift+A"); // { key: 'a', ctrl: true, shift: true }
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
export function parseKeybinding(keybinding) {
|
|
40
|
+
const parts = keybinding.split('+').map((p) => p.trim().toLowerCase());
|
|
41
|
+
const config = {
|
|
42
|
+
key: '',
|
|
43
|
+
ctrl: false,
|
|
44
|
+
alt: false,
|
|
45
|
+
shift: false,
|
|
46
|
+
meta: false,
|
|
47
|
+
};
|
|
48
|
+
for (const part of parts) {
|
|
49
|
+
switch (part) {
|
|
50
|
+
case 'ctrl':
|
|
51
|
+
case 'control':
|
|
52
|
+
config.ctrl = true;
|
|
53
|
+
break;
|
|
54
|
+
case 'alt':
|
|
55
|
+
case 'option':
|
|
56
|
+
config.alt = true;
|
|
57
|
+
break;
|
|
58
|
+
case 'shift':
|
|
59
|
+
config.shift = true;
|
|
60
|
+
break;
|
|
61
|
+
case 'meta':
|
|
62
|
+
case 'cmd':
|
|
63
|
+
case 'command':
|
|
64
|
+
case 'win':
|
|
65
|
+
case 'windows':
|
|
66
|
+
config.meta = true;
|
|
67
|
+
break;
|
|
68
|
+
default:
|
|
69
|
+
config.key = part;
|
|
70
|
+
break;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return config;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* React hook for registering keyboard shortcuts
|
|
77
|
+
*
|
|
78
|
+
* Registers a keyboard shortcut that triggers the provided handler when pressed.
|
|
79
|
+
* Automatically cleans up the event listener when the component unmounts or
|
|
80
|
+
* when the keybinding changes.
|
|
81
|
+
*
|
|
82
|
+
* @param {string | KeybindingConfig} key - Key combination (e.g., "Ctrl+C") or config object
|
|
83
|
+
* @param {KeyHandler} handler - Function to call when keybinding is triggered
|
|
84
|
+
* @param {boolean} [enabled=true] - Whether the keybinding is active
|
|
85
|
+
* @example
|
|
86
|
+
* ```typescript
|
|
87
|
+
* // Using string keybinding
|
|
88
|
+
* useKeybinding('Ctrl+C', () => {
|
|
89
|
+
* console.log('Copy!');
|
|
90
|
+
* });
|
|
91
|
+
*
|
|
92
|
+
* // Using config object
|
|
93
|
+
* useKeybinding({ key: 'k', ctrl: true }, (e) => {
|
|
94
|
+
* e.preventDefault();
|
|
95
|
+
* console.log('Ctrl+K pressed');
|
|
96
|
+
* });
|
|
97
|
+
*
|
|
98
|
+
* // With conditional enabling
|
|
99
|
+
* useKeybinding('Escape', handleClose, isModalOpen);
|
|
100
|
+
* ```
|
|
101
|
+
*/
|
|
102
|
+
export function useKeybinding(key, handler, enabled = true) {
|
|
103
|
+
const config = typeof key === 'string' ? parseKeybinding(key) : key;
|
|
104
|
+
const expectedCombo = normalizeKeyCombo(config);
|
|
105
|
+
const handlerRef = useRef(handler);
|
|
106
|
+
// Keep handler reference up to date without re-registering
|
|
107
|
+
useEffect(() => {
|
|
108
|
+
handlerRef.current = handler;
|
|
109
|
+
}, [handler]);
|
|
110
|
+
const handleKeyDown = useCallback((event) => {
|
|
111
|
+
// Check if this key event matches our expected combination
|
|
112
|
+
const actualCombo = normalizeKeyCombo({
|
|
113
|
+
key: event.key,
|
|
114
|
+
ctrl: event.ctrlKey,
|
|
115
|
+
alt: event.altKey,
|
|
116
|
+
shift: event.shiftKey,
|
|
117
|
+
meta: event.metaKey,
|
|
118
|
+
});
|
|
119
|
+
if (actualCombo === expectedCombo) {
|
|
120
|
+
if (config.preventDefault) {
|
|
121
|
+
event.preventDefault();
|
|
122
|
+
}
|
|
123
|
+
if (config.stopPropagation) {
|
|
124
|
+
event.stopPropagation();
|
|
125
|
+
}
|
|
126
|
+
const result = handlerRef.current(event);
|
|
127
|
+
// Allow handler to prevent default by returning false
|
|
128
|
+
if (result === false) {
|
|
129
|
+
event.preventDefault();
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}, [config, expectedCombo]);
|
|
133
|
+
useEffect(() => {
|
|
134
|
+
if (!enabled || typeof window === 'undefined') {
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
window.addEventListener('keydown', handleKeyDown);
|
|
138
|
+
return () => {
|
|
139
|
+
window.removeEventListener('keydown', handleKeyDown);
|
|
140
|
+
};
|
|
141
|
+
}, [enabled, handleKeyDown]);
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Hook for registering multiple keybindings at once
|
|
145
|
+
*
|
|
146
|
+
* @param {Array<[string | KeybindingConfig, KeyHandler]>} bindings - Array of [keybinding, handler] tuples
|
|
147
|
+
* @param {boolean} [enabled=true] - Whether all keybindings are active
|
|
148
|
+
* @example
|
|
149
|
+
* ```typescript
|
|
150
|
+
* useKeybindings([
|
|
151
|
+
* ['Ctrl+C', handleCopy],
|
|
152
|
+
* ['Ctrl+V', handlePaste],
|
|
153
|
+
* ['Escape', handleClose],
|
|
154
|
+
* ]);
|
|
155
|
+
* ```
|
|
156
|
+
*/
|
|
157
|
+
export function useKeybindings(bindings, enabled = true) {
|
|
158
|
+
bindings.forEach(([key, handler]) => {
|
|
159
|
+
useKeybinding(key, handler, enabled);
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
// Default export
|
|
163
|
+
export default useKeybinding;
|