@ebowwa/coder 0.7.64 → 0.7.65

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 (101) hide show
  1. package/dist/index.js +36168 -32
  2. package/dist/interfaces/ui/terminal/cli/index.js +34253 -158
  3. package/dist/interfaces/ui/terminal/native/README.md +53 -0
  4. package/dist/interfaces/ui/terminal/native/claude_code_native.darwin-x64.node +0 -0
  5. package/dist/interfaces/ui/terminal/native/claude_code_native.dylib +0 -0
  6. package/dist/interfaces/ui/terminal/native/index.d.ts +0 -0
  7. package/dist/interfaces/ui/terminal/native/index.darwin-arm64.node +0 -0
  8. package/dist/interfaces/ui/terminal/native/index.js +43 -0
  9. package/dist/interfaces/ui/terminal/native/index.node +0 -0
  10. package/dist/interfaces/ui/terminal/native/package.json +34 -0
  11. package/dist/native/README.md +53 -0
  12. package/dist/native/claude_code_native.darwin-x64.node +0 -0
  13. package/dist/native/claude_code_native.dylib +0 -0
  14. package/dist/native/index.d.ts +0 -480
  15. package/dist/native/index.darwin-arm64.node +0 -0
  16. package/dist/native/index.js +43 -1625
  17. package/dist/native/index.node +0 -0
  18. package/dist/native/package.json +34 -0
  19. package/native/index.darwin-arm64.node +0 -0
  20. package/native/index.js +33 -19
  21. package/package.json +3 -2
  22. package/packages/src/core/agent-loop/__tests__/compaction.test.ts +17 -14
  23. package/packages/src/core/agent-loop/compaction.ts +6 -2
  24. package/packages/src/core/agent-loop/index.ts +2 -0
  25. package/packages/src/core/agent-loop/loop-state.ts +1 -1
  26. package/packages/src/core/agent-loop/turn-executor.ts +4 -0
  27. package/packages/src/core/agent-loop/types.ts +4 -0
  28. package/packages/src/core/api-client-impl.ts +283 -173
  29. package/packages/src/core/cognitive-security/hooks.ts +2 -1
  30. package/packages/src/core/config/todo +7 -0
  31. package/packages/src/core/context/__tests__/integration.test.ts +334 -0
  32. package/packages/src/core/context/compaction.ts +170 -0
  33. package/packages/src/core/context/constants.ts +58 -0
  34. package/packages/src/core/context/extraction.ts +85 -0
  35. package/packages/src/core/context/index.ts +66 -0
  36. package/packages/src/core/context/summarization.ts +251 -0
  37. package/packages/src/core/context/token-estimation.ts +98 -0
  38. package/packages/src/core/context/types.ts +59 -0
  39. package/packages/src/core/models.ts +81 -4
  40. package/packages/src/core/normalizers/todo +5 -1
  41. package/packages/src/core/providers/README.md +230 -0
  42. package/packages/src/core/providers/__tests__/providers.test.ts +135 -0
  43. package/packages/src/core/providers/index.ts +419 -0
  44. package/packages/src/core/providers/types.ts +132 -0
  45. package/packages/src/core/retry.ts +10 -0
  46. package/packages/src/ecosystem/tools/index.ts +174 -0
  47. package/packages/src/index.ts +23 -2
  48. package/packages/src/interfaces/ui/index.ts +17 -20
  49. package/packages/src/interfaces/ui/spinner.ts +2 -2
  50. package/packages/src/interfaces/ui/terminal/bridge/index.ts +370 -0
  51. package/packages/src/interfaces/ui/terminal/bridge/ipc.ts +829 -0
  52. package/packages/src/interfaces/ui/terminal/bridge/screen-export.ts +968 -0
  53. package/packages/src/interfaces/ui/terminal/bridge/types.ts +226 -0
  54. package/packages/src/interfaces/ui/terminal/bridge/useBridge.ts +210 -0
  55. package/packages/src/interfaces/ui/terminal/cli/bootstrap.ts +132 -0
  56. package/packages/src/interfaces/ui/terminal/cli/index.ts +200 -13
  57. package/packages/src/interfaces/ui/terminal/cli/interactive/index.ts +110 -0
  58. package/packages/src/interfaces/ui/terminal/cli/interactive/input-handler.ts +393 -0
  59. package/packages/src/interfaces/ui/terminal/cli/interactive/interactive-runner.ts +820 -0
  60. package/packages/src/interfaces/ui/terminal/cli/interactive/message-store.ts +299 -0
  61. package/packages/src/interfaces/ui/terminal/cli/interactive/types.ts +274 -0
  62. package/packages/src/interfaces/ui/terminal/shared/index.ts +13 -0
  63. package/packages/src/interfaces/ui/terminal/shared/query.ts +9 -3
  64. package/packages/src/interfaces/ui/terminal/shared/setup.ts +5 -1
  65. package/packages/src/interfaces/ui/terminal/shared/spinner-frames.ts +73 -0
  66. package/packages/src/interfaces/ui/terminal/shared/status-line.ts +10 -2
  67. package/packages/src/native/index.ts +404 -27
  68. package/packages/src/native/tui_v2_types.ts +39 -0
  69. package/packages/src/teammates/coordination.test.ts +279 -0
  70. package/packages/src/teammates/coordination.ts +646 -0
  71. package/packages/src/teammates/index.ts +95 -25
  72. package/packages/src/teammates/integration.test.ts +272 -0
  73. package/packages/src/teammates/runner.test.ts +235 -0
  74. package/packages/src/teammates/runner.ts +750 -0
  75. package/packages/src/teammates/schemas.ts +673 -0
  76. package/packages/src/types/index.ts +1 -0
  77. package/packages/src/core/context-compaction.ts +0 -578
  78. package/packages/src/interfaces/ui/Screenshot 2026-03-02 at 9.23.10/342/200/257PM.png +0 -0
  79. package/packages/src/interfaces/ui/Screenshot 2026-03-03 at 10.55.11/342/200/257AM.png +0 -0
  80. package/packages/src/interfaces/ui/terminal/tui/HelpPanel.tsx +0 -262
  81. package/packages/src/interfaces/ui/terminal/tui/InputContext.tsx +0 -232
  82. package/packages/src/interfaces/ui/terminal/tui/InputField.tsx +0 -62
  83. package/packages/src/interfaces/ui/terminal/tui/InteractiveTUI.tsx +0 -537
  84. package/packages/src/interfaces/ui/terminal/tui/MessageArea.tsx +0 -107
  85. package/packages/src/interfaces/ui/terminal/tui/MessageStore.tsx +0 -240
  86. package/packages/src/interfaces/ui/terminal/tui/StatusBar.tsx +0 -54
  87. package/packages/src/interfaces/ui/terminal/tui/commands.ts +0 -438
  88. package/packages/src/interfaces/ui/terminal/tui/components/InteractiveElements.tsx +0 -584
  89. package/packages/src/interfaces/ui/terminal/tui/components/MultilineInput.tsx +0 -614
  90. package/packages/src/interfaces/ui/terminal/tui/components/PaneManager.tsx +0 -333
  91. package/packages/src/interfaces/ui/terminal/tui/components/Sidebar.tsx +0 -604
  92. package/packages/src/interfaces/ui/terminal/tui/components/index.ts +0 -118
  93. package/packages/src/interfaces/ui/terminal/tui/console.ts +0 -49
  94. package/packages/src/interfaces/ui/terminal/tui/index.ts +0 -90
  95. package/packages/src/interfaces/ui/terminal/tui/run.tsx +0 -42
  96. package/packages/src/interfaces/ui/terminal/tui/spinner.ts +0 -69
  97. package/packages/src/interfaces/ui/terminal/tui/tui-app.tsx +0 -390
  98. package/packages/src/interfaces/ui/terminal/tui/tui-footer.ts +0 -422
  99. package/packages/src/interfaces/ui/terminal/tui/types.ts +0 -186
  100. package/packages/src/interfaces/ui/terminal/tui/useInputHandler.ts +0 -104
  101. package/packages/src/interfaces/ui/terminal/tui/useNativeInput.ts +0 -239
@@ -0,0 +1,393 @@
1
+ /**
2
+ * Input Handler - Non-React Implementation
3
+ *
4
+ * Centralized keyboard input management extracted from v1 TUI patterns.
5
+ * This is a pure TypeScript class without React dependency.
6
+ *
7
+ * Features:
8
+ * - Priority-based handler registration
9
+ * - Focus system for exclusive input
10
+ * - Block/unblock for loading states
11
+ * - Native key event support
12
+ */
13
+
14
+ import type { InputManager, InputHandler, InputHandlerOptions, NativeKeyEvent } from "./types.js";
15
+ import type { InputEvent } from "../../../../../native/index.js";
16
+ import { InputPriority } from "./types.js";
17
+
18
+ // Re-export for convenience
19
+ export type { InputEvent } from "../../../../../native/index.js";
20
+
21
+ // ============================================
22
+ // INPUT EVENT CONVERSION
23
+ // ============================================
24
+
25
+ /**
26
+ * Convert native InputEvent to NativeKeyEvent format
27
+ *
28
+ * The native module returns InputEvent with:
29
+ * - eventType: "key" | "resize" | "none"
30
+ * - key?: string
31
+ * - modifiers?: string (comma-separated like "ctrl,shift")
32
+ *
33
+ * Input handlers expect NativeKeyEvent with:
34
+ * - code: string
35
+ * - ctrl: boolean
36
+ * - alt: boolean
37
+ * - shift: boolean
38
+ * - is_special: boolean
39
+ * - kind: "press" | "release" | "repeat"
40
+ */
41
+ export function inputEventToNativeKeyEvent(event: InputEvent): NativeKeyEvent | null {
42
+ // Only convert key events
43
+ if (event.eventType !== "key" || !event.key) {
44
+ return null;
45
+ }
46
+
47
+ // Parse modifiers string
48
+ const modifiers = (event.modifiers ?? "").toLowerCase();
49
+ const hasCtrl = modifiers.includes("ctrl") || modifiers.includes("control");
50
+ const hasAlt = modifiers.includes("alt") || modifiers.includes("meta");
51
+ const hasShift = modifiers.includes("shift");
52
+
53
+ // Detect special keys
54
+ const specialKeys = new Set([
55
+ "return", "enter", "escape", "tab", "backspace", "delete",
56
+ "up", "down", "left", "right",
57
+ "pageup", "pagedown", "home", "end",
58
+ "f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9", "f10", "f11", "f12"
59
+ ]);
60
+
61
+ const keyLower = event.key.toLowerCase();
62
+ const isSpecial = specialKeys.has(keyLower) || hasCtrl || hasAlt;
63
+
64
+ // Normalize key names
65
+ let code = event.key;
66
+ if (keyLower === "return" || keyLower === "enter") code = "Enter";
67
+ else if (keyLower === "escape") code = "Escape";
68
+ else if (keyLower === " ") code = "Space";
69
+ else if (keyLower === "backspace") code = "Backspace";
70
+ else if (keyLower === "delete") code = "Delete";
71
+ else if (keyLower === "tab") code = "Tab";
72
+ else if (keyLower === "up") code = "Up";
73
+ else if (keyLower === "down") code = "Down";
74
+ else if (keyLower === "left") code = "Left";
75
+ else if (keyLower === "right") code = "Right";
76
+ else if (keyLower === "home") code = "Home";
77
+ else if (keyLower === "end") code = "End";
78
+ else if (keyLower === "pageup") code = "PageUp";
79
+ else if (keyLower === "pagedown") code = "PageDown";
80
+
81
+ return {
82
+ code,
83
+ is_special: isSpecial,
84
+ ctrl: hasCtrl,
85
+ alt: hasAlt,
86
+ shift: hasShift,
87
+ kind: "press", // Default to press since native doesn't provide this
88
+ };
89
+ }
90
+
91
+ // ============================================
92
+ // KEY EVENT DETECTION UTILITIES
93
+ // ============================================
94
+
95
+ /**
96
+ * Static utilities for detecting key events
97
+ * Pattern from v1 TUI's KeyEvents class
98
+ *
99
+ * Note: Native module's NativeKeyEvent has * - code: string (key code/char)
100
+ * - is_special: boolean
101
+ * - ctrl: boolean
102
+ * - kind: "press" | "release" | "repeat"
103
+ */
104
+ export const KeyEvents = {
105
+ /** Check if event is Enter key */
106
+ isEnter(event: NativeKeyEvent): boolean {
107
+ return event.code === "return" || event.code === "Enter";
108
+ },
109
+
110
+ /** Check if event is Escape key */
111
+ isEscape(event: NativeKeyEvent): boolean {
112
+ return event.code === "escape" || event.code === "Escape";
113
+ },
114
+
115
+ /** Check if event is Tab key */
116
+ isTab(event: NativeKeyEvent): boolean {
117
+ return event.code === "tab" || event.code === "Tab";
118
+ },
119
+
120
+ /** Check if event is Backspace key */
121
+ isBackspace(event: NativeKeyEvent): boolean {
122
+ return event.code === "backspace" || event.code === "Backspace" || event.code === "DEL";
123
+ },
124
+
125
+ /** Check if event is Delete key */
126
+ isDelete(event: NativeKeyEvent): boolean {
127
+ return event.code === "delete" || event.code === "Delete" || event.code === "DEL";
128
+ },
129
+
130
+ /** Check if event is Up arrow */
131
+ isUp(event: NativeKeyEvent): boolean {
132
+ return event.code === "up" || event.code === "Up";
133
+ },
134
+
135
+ /** Check if event is Down arrow */
136
+ isDown(event: NativeKeyEvent): boolean {
137
+ return event.code === "down" || event.code === "Down";
138
+ },
139
+
140
+ /** Check if event is Left arrow */
141
+ isLeft(event: NativeKeyEvent): boolean {
142
+ return event.code === "left" || event.code === "Left";
143
+ },
144
+
145
+ /** Check if event is Right arrow */
146
+ isRight(event: NativeKeyEvent): boolean {
147
+ return event.code === "right" || event.code === "Right";
148
+ },
149
+
150
+ /** Check if event is Page Up */
151
+ isPageUp(event: NativeKeyEvent): boolean {
152
+ return event.code === "pageup" || event.code === "PageUp";
153
+ },
154
+
155
+ /** Check if event is Page Down */
156
+ isPageDown(event: NativeKeyEvent): boolean {
157
+ return event.code === "pagedown" || event.code === "PageDown";
158
+ },
159
+
160
+ /** Check if event is Home key */
161
+ isHome(event: NativeKeyEvent): boolean {
162
+ return event.code === "home" || event.code === "Home";
163
+ },
164
+
165
+ /** Check if event is End key */
166
+ isEnd(event: NativeKeyEvent): boolean {
167
+ return event.code === "end" || event.code === "End";
168
+ },
169
+
170
+ /** Check if event is Ctrl+C */
171
+ isCtrlC(event: NativeKeyEvent): boolean {
172
+ return event.ctrl === true && (event.code === "c" || event.code === "C");
173
+ },
174
+
175
+ /** Check if event is Ctrl+D */
176
+ isCtrlD(event: NativeKeyEvent): boolean {
177
+ return event.ctrl === true && (event.code === "d" || event.code === "D");
178
+ },
179
+
180
+ /** Check if event is Ctrl+A */
181
+ isCtrlA(event: NativeKeyEvent): boolean {
182
+ return event.ctrl === true && (event.code === "a" || event.code === "A");
183
+ },
184
+
185
+ /** Check if event is Ctrl+E */
186
+ isCtrlE(event: NativeKeyEvent): boolean {
187
+ return event.ctrl === true && (event.code === "e" || event.code === "E");
188
+ },
189
+
190
+ /** Check if event is Shift+Up */
191
+ isShiftUp(event: NativeKeyEvent): boolean {
192
+ // Note: Native module doesn't have shift modifier in NativeKeyEvent
193
+ // For now, check if up arrow (without ctrl check since we can't detect shift)
194
+ return event.code === "up" || event.code === "Up";
195
+ },
196
+
197
+ /** Check if event is Shift+Down */
198
+ isShiftDown(event: NativeKeyEvent): boolean {
199
+ // Note: Similar to Shift+Up
200
+ return event.code === "down" || event.code === "Down";
201
+ },
202
+
203
+ /** Check if event is a printable character */
204
+ isPrintable(event: NativeKeyEvent): boolean {
205
+ if (event.is_special) return false;
206
+ const code = event.code;
207
+ // Single character that is not a control character
208
+ return code.length === 1 && !event.ctrl;
209
+ },
210
+
211
+ /** Get the character from the event */
212
+ getChar(event: NativeKeyEvent): string {
213
+ return event.code;
214
+ },
215
+ };
216
+
217
+ // ============================================
218
+ // INPUT MANAGER CLASS
219
+ // ============================================
220
+
221
+ /**
222
+ * Non-React input manager implementation
223
+ *
224
+ * Usage:
225
+ * ```ts
226
+ * const input = new InputManagerImpl();
227
+ *
228
+ * // Register a handler
229
+ * const unregister = input.register({
230
+ * id: "main-input",
231
+ * priority: InputPriority.INPUT,
232
+ * handler: (event) => {
233
+ * if (KeyEvents.isEnter(event)) {
234
+ * console.log("Enter pressed");
235
+ * return true; // consume
236
+ * }
237
+ * return false; // pass through
238
+ * },
239
+ * });
240
+ *
241
+ * // Dispatch events
242
+ * input.dispatch(nativeKeyEvent);
243
+ *
244
+ * // Cleanup
245
+ * unregister();
246
+ * ```
247
+ */
248
+ export class InputManagerImpl implements InputManager {
249
+ private _handlers: Map<string, InputHandlerOptions> = new Map();
250
+ private _focusedId: string | null = null;
251
+ private _isBlocked = false;
252
+ private _listeners: Set<() => void> = new Set();
253
+
254
+ /** Get currently focused handler ID */
255
+ get focusedId(): string | null {
256
+ return this._focusedId;
257
+ }
258
+
259
+ /** Whether input is currently blocked */
260
+ get isBlocked(): boolean {
261
+ return this._isBlocked;
262
+ }
263
+
264
+ /**
265
+ * Register an input handler
266
+ * Returns unregister function
267
+ */
268
+ register(options: InputHandlerOptions): () => void {
269
+ const { id } = options;
270
+ this._handlers.set(id, options);
271
+
272
+ // If no focus set, focus this handler
273
+ if (!this._focusedId) {
274
+ this._focusedId = id;
275
+ this._notify();
276
+ }
277
+
278
+ // Return unregister function
279
+ return () => {
280
+ this._handlers.delete(id);
281
+ if (this._focusedId === id) {
282
+ // Focus next available handler (highest priority)
283
+ const remaining = Array.from(this._handlers.values())
284
+ .filter((h) => h.isActive !== false)
285
+ .sort((a, b) => (b.priority ?? 1) - (a.priority ?? 1));
286
+ this._focusedId = remaining[0]?.id ?? null;
287
+ this._notify();
288
+ }
289
+ };
290
+ }
291
+
292
+ /**
293
+ * Set focus to a specific handler
294
+ */
295
+ focus(handlerId: string): void {
296
+ if (this._handlers.has(handlerId)) {
297
+ this._focusedId = handlerId;
298
+ this._notify();
299
+ }
300
+ }
301
+
302
+ /**
303
+ * Dispatch a key event to handlers
304
+ * Returns true if consumed, false if not
305
+ */
306
+ dispatch(event: NativeKeyEvent): boolean {
307
+ if (this._isBlocked) return false;
308
+
309
+ // Get all active handlers sorted by priority (highest first)
310
+ const activeHandlers = Array.from(this._handlers.values())
311
+ .filter((h) => h.isActive !== false)
312
+ .sort((a, b) => (b.priority ?? 1) - (a.priority ?? 1));
313
+
314
+ // First, try the focused handler
315
+ if (this._focusedId) {
316
+ const focused = this._handlers.get(this._focusedId);
317
+ if (focused?.isActive !== false && focused?.handler) {
318
+ const consumed = focused.handler(event);
319
+ if (consumed) return true;
320
+ }
321
+ }
322
+
323
+ // Then try other handlers by priority
324
+ for (const h of activeHandlers) {
325
+ if (h.id === this._focusedId) continue; // Already tried
326
+ const consumed = h.handler(event);
327
+ if (consumed) return true;
328
+ }
329
+
330
+ return false;
331
+ }
332
+
333
+ /**
334
+ * Block/unblock input (for loading states)
335
+ */
336
+ setBlocked(blocked: boolean): void {
337
+ this._isBlocked = blocked;
338
+ this._notify();
339
+ }
340
+
341
+ /**
342
+ * Subscribe to focus/blocked state changes
343
+ */
344
+ subscribe(listener: () => void): () => void {
345
+ this._listeners.add(listener);
346
+ return () => {
347
+ this._listeners.delete(listener);
348
+ };
349
+ }
350
+
351
+ /**
352
+ * Notify all listeners of a change
353
+ */
354
+ private _notify(): void {
355
+ for (const listener of this._listeners) {
356
+ try {
357
+ listener();
358
+ } catch (err) {
359
+ console.error("InputManager listener error:", err);
360
+ }
361
+ }
362
+ }
363
+ }
364
+
365
+ // ============================================
366
+ // SINGLETON (optional convenience)
367
+ // ============================================
368
+
369
+ let globalInputManager: InputManagerImpl | null = null;
370
+
371
+ /**
372
+ * Get or create the global input manager
373
+ */
374
+ export function getInputManager(): InputManagerImpl {
375
+ if (!globalInputManager) {
376
+ globalInputManager = new InputManagerImpl();
377
+ }
378
+ return globalInputManager;
379
+ }
380
+
381
+ /**
382
+ * Reset the global input manager (for testing)
383
+ */
384
+ export function resetInputManager(): void {
385
+ globalInputManager = null;
386
+ }
387
+
388
+ // ============================================
389
+ // EXPORTS
390
+ // ============================================
391
+
392
+ export { InputPriority };
393
+ export type { InputManager, InputHandler, InputHandlerOptions, NativeKeyEvent } from "./types.js";