@ebowwa/coder 0.7.64 → 0.7.66

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 +36233 -32
  2. package/dist/interfaces/ui/terminal/cli/index.js +34318 -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 +377 -176
  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 +402 -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,402 @@
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 Space key */
204
+ isSpace(event: NativeKeyEvent): boolean {
205
+ return event.code === " " || event.code === "Space";
206
+ },
207
+
208
+ /** Check if event is a printable character */
209
+ isPrintable(event: NativeKeyEvent): boolean {
210
+ if (event.is_special) return false;
211
+ const code = event.code;
212
+ // Space is printable (normalized to "Space" but should work in text input)
213
+ if (code === " " || code === "Space") return true;
214
+ // Single character that is not a control character
215
+ return code.length === 1 && !event.ctrl;
216
+ },
217
+
218
+ /** Get the character from the event */
219
+ getChar(event: NativeKeyEvent): string {
220
+ // Handle normalized space
221
+ if (event.code === "Space") return " ";
222
+ return event.code;
223
+ },
224
+ };
225
+
226
+ // ============================================
227
+ // INPUT MANAGER CLASS
228
+ // ============================================
229
+
230
+ /**
231
+ * Non-React input manager implementation
232
+ *
233
+ * Usage:
234
+ * ```ts
235
+ * const input = new InputManagerImpl();
236
+ *
237
+ * // Register a handler
238
+ * const unregister = input.register({
239
+ * id: "main-input",
240
+ * priority: InputPriority.INPUT,
241
+ * handler: (event) => {
242
+ * if (KeyEvents.isEnter(event)) {
243
+ * console.log("Enter pressed");
244
+ * return true; // consume
245
+ * }
246
+ * return false; // pass through
247
+ * },
248
+ * });
249
+ *
250
+ * // Dispatch events
251
+ * input.dispatch(nativeKeyEvent);
252
+ *
253
+ * // Cleanup
254
+ * unregister();
255
+ * ```
256
+ */
257
+ export class InputManagerImpl implements InputManager {
258
+ private _handlers: Map<string, InputHandlerOptions> = new Map();
259
+ private _focusedId: string | null = null;
260
+ private _isBlocked = false;
261
+ private _listeners: Set<() => void> = new Set();
262
+
263
+ /** Get currently focused handler ID */
264
+ get focusedId(): string | null {
265
+ return this._focusedId;
266
+ }
267
+
268
+ /** Whether input is currently blocked */
269
+ get isBlocked(): boolean {
270
+ return this._isBlocked;
271
+ }
272
+
273
+ /**
274
+ * Register an input handler
275
+ * Returns unregister function
276
+ */
277
+ register(options: InputHandlerOptions): () => void {
278
+ const { id } = options;
279
+ this._handlers.set(id, options);
280
+
281
+ // If no focus set, focus this handler
282
+ if (!this._focusedId) {
283
+ this._focusedId = id;
284
+ this._notify();
285
+ }
286
+
287
+ // Return unregister function
288
+ return () => {
289
+ this._handlers.delete(id);
290
+ if (this._focusedId === id) {
291
+ // Focus next available handler (highest priority)
292
+ const remaining = Array.from(this._handlers.values())
293
+ .filter((h) => h.isActive !== false)
294
+ .sort((a, b) => (b.priority ?? 1) - (a.priority ?? 1));
295
+ this._focusedId = remaining[0]?.id ?? null;
296
+ this._notify();
297
+ }
298
+ };
299
+ }
300
+
301
+ /**
302
+ * Set focus to a specific handler
303
+ */
304
+ focus(handlerId: string): void {
305
+ if (this._handlers.has(handlerId)) {
306
+ this._focusedId = handlerId;
307
+ this._notify();
308
+ }
309
+ }
310
+
311
+ /**
312
+ * Dispatch a key event to handlers
313
+ * Returns true if consumed, false if not
314
+ */
315
+ dispatch(event: NativeKeyEvent): boolean {
316
+ if (this._isBlocked) return false;
317
+
318
+ // Get all active handlers sorted by priority (highest first)
319
+ const activeHandlers = Array.from(this._handlers.values())
320
+ .filter((h) => h.isActive !== false)
321
+ .sort((a, b) => (b.priority ?? 1) - (a.priority ?? 1));
322
+
323
+ // First, try the focused handler
324
+ if (this._focusedId) {
325
+ const focused = this._handlers.get(this._focusedId);
326
+ if (focused?.isActive !== false && focused?.handler) {
327
+ const consumed = focused.handler(event);
328
+ if (consumed) return true;
329
+ }
330
+ }
331
+
332
+ // Then try other handlers by priority
333
+ for (const h of activeHandlers) {
334
+ if (h.id === this._focusedId) continue; // Already tried
335
+ const consumed = h.handler(event);
336
+ if (consumed) return true;
337
+ }
338
+
339
+ return false;
340
+ }
341
+
342
+ /**
343
+ * Block/unblock input (for loading states)
344
+ */
345
+ setBlocked(blocked: boolean): void {
346
+ this._isBlocked = blocked;
347
+ this._notify();
348
+ }
349
+
350
+ /**
351
+ * Subscribe to focus/blocked state changes
352
+ */
353
+ subscribe(listener: () => void): () => void {
354
+ this._listeners.add(listener);
355
+ return () => {
356
+ this._listeners.delete(listener);
357
+ };
358
+ }
359
+
360
+ /**
361
+ * Notify all listeners of a change
362
+ */
363
+ private _notify(): void {
364
+ for (const listener of this._listeners) {
365
+ try {
366
+ listener();
367
+ } catch (err) {
368
+ console.error("InputManager listener error:", err);
369
+ }
370
+ }
371
+ }
372
+ }
373
+
374
+ // ============================================
375
+ // SINGLETON (optional convenience)
376
+ // ============================================
377
+
378
+ let globalInputManager: InputManagerImpl | null = null;
379
+
380
+ /**
381
+ * Get or create the global input manager
382
+ */
383
+ export function getInputManager(): InputManagerImpl {
384
+ if (!globalInputManager) {
385
+ globalInputManager = new InputManagerImpl();
386
+ }
387
+ return globalInputManager;
388
+ }
389
+
390
+ /**
391
+ * Reset the global input manager (for testing)
392
+ */
393
+ export function resetInputManager(): void {
394
+ globalInputManager = null;
395
+ }
396
+
397
+ // ============================================
398
+ // EXPORTS
399
+ // ============================================
400
+
401
+ export { InputPriority };
402
+ export type { InputManager, InputHandler, InputHandlerOptions, NativeKeyEvent } from "./types.js";