@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,279 @@
1
+ /**
2
+ * Tests for Coordination Callbacks
3
+ */
4
+
5
+ import { describe, it, expect, beforeEach, afterEach } from "bun:test";
6
+ import { existsSync, rmSync, mkdirSync } from "fs";
7
+ import { join } from "path";
8
+ import { TeammateManager } from "./index.js";
9
+ import {
10
+ CoordinationManager,
11
+ createCoordinationMessage,
12
+ parseCoordinationMessage,
13
+ type CoordinationEvent,
14
+ type ProgressReport,
15
+ type FileClaim,
16
+ } from "./coordination.js";
17
+
18
+ // Helper to clean up claims directory
19
+ const CLAIMS_PATH = join(process.env.HOME || "", ".claude", "teams", "_coordination", "claims");
20
+
21
+ function cleanupClaims(): void {
22
+ if (existsSync(CLAIMS_PATH)) {
23
+ try {
24
+ rmSync(CLAIMS_PATH, { recursive: true, force: true });
25
+ } catch {
26
+ // Ignore errors
27
+ }
28
+ }
29
+ }
30
+
31
+ describe("Coordination Callbacks", () => {
32
+ let manager: TeammateManager;
33
+ let coordination: CoordinationManager;
34
+ const events: CoordinationEvent[] = [];
35
+
36
+ beforeEach(() => {
37
+ // Clean up any stale claims before each test
38
+ cleanupClaims();
39
+
40
+ manager = new TeammateManager();
41
+ coordination = new CoordinationManager(manager, {
42
+ enableFileLocking: true,
43
+ enableHeartbeat: false,
44
+ onCoordinationEvent: (event) => {
45
+ events.push(event);
46
+ },
47
+ });
48
+ events.length = 0;
49
+ });
50
+
51
+ afterEach(() => {
52
+ coordination.shutdown();
53
+ // Clean up claims after each test
54
+ cleanupClaims();
55
+ });
56
+
57
+ describe("Progress Reporting", () => {
58
+ it("should report progress to team", () => {
59
+ coordination.initialize("teammate-1", "test-team");
60
+
61
+ const progress: ProgressReport = {
62
+ step: "Building CSS styles",
63
+ stepNumber: 2,
64
+ totalSteps: 5,
65
+ percentage: 40,
66
+ files: ["styles.css"],
67
+ };
68
+
69
+ coordination.reportProgress(progress);
70
+
71
+ expect(events.length).toBe(1);
72
+ expect(events[0]!.type).toBe("task_progress");
73
+ expect(events[0]!.payload.progress).toEqual(progress);
74
+ });
75
+
76
+ it("should track current progress", () => {
77
+ coordination.initialize("teammate-1", "test-team");
78
+
79
+ const progress: ProgressReport = {
80
+ step: "Writing tests",
81
+ stepNumber: 3,
82
+ totalSteps: 4,
83
+ };
84
+
85
+ coordination.reportProgress(progress);
86
+
87
+ // Progress should be emitted
88
+ const progressEvents = events.filter((e) => e.type === "task_progress");
89
+ expect(progressEvents.length).toBe(1);
90
+ });
91
+ });
92
+
93
+ describe("Blocked/Unblocked", () => {
94
+ it("should report blocked status", () => {
95
+ coordination.initialize("teammate-1", "test-team");
96
+
97
+ coordination.reportBlocked("Waiting for CSS file", "css-builder");
98
+
99
+ expect(events.length).toBe(1);
100
+ expect(events[0]!.type).toBe("blocked");
101
+ expect(events[0]!.payload.reason).toBe("Waiting for CSS file");
102
+ expect(events[0]!.payload.blockedBy).toBe("css-builder");
103
+ });
104
+
105
+ it("should report unblocked status", () => {
106
+ coordination.initialize("teammate-1", "test-team");
107
+
108
+ coordination.reportBlocked("Waiting for CSS file");
109
+ coordination.reportUnblocked();
110
+
111
+ const blockedEvents = events.filter((e) => e.type === "blocked");
112
+ const unblockedEvents = events.filter((e) => e.type === "unblocked");
113
+
114
+ expect(blockedEvents.length).toBe(1);
115
+ expect(unblockedEvents.length).toBe(1);
116
+ });
117
+ });
118
+
119
+ describe("File Locking", () => {
120
+ it("should claim a file", () => {
121
+ coordination.initialize("teammate-1", "test-team");
122
+
123
+ const claimed = coordination.claimFile("/path/to/file.ts", "Writing code");
124
+
125
+ expect(claimed).toBe(true);
126
+ expect(coordination.isFileClaimed("/path/to/file.ts")).toBe(false); // We own it
127
+ expect(coordination.getFileClaim("/path/to/file.ts")?.reason).toBe("Writing code");
128
+ });
129
+
130
+ it("should prevent other teammates from claiming", () => {
131
+ coordination.initialize("teammate-1", "test-team");
132
+
133
+ coordination.claimFile("/path/to/file.ts", "Writing code");
134
+
135
+ // Simulate another teammate trying to claim
136
+ const coordination2 = new CoordinationManager(manager, {
137
+ enableFileLocking: true,
138
+ });
139
+ coordination2.initialize("teammate-2", "test-team");
140
+
141
+ const claimed = coordination2.claimFile("/path/to/file.ts", "Also writing");
142
+
143
+ expect(claimed).toBe(false);
144
+ expect(coordination2.isFileClaimed("/path/to/file.ts")).toBe(true);
145
+
146
+ coordination2.shutdown();
147
+ });
148
+
149
+ it("should release a file claim", () => {
150
+ coordination.initialize("teammate-1", "test-team");
151
+
152
+ coordination.claimFile("/path/to/file.ts");
153
+ coordination.releaseFile("/path/to/file.ts");
154
+
155
+ // Create another coordination and try to claim
156
+ const coordination2 = new CoordinationManager(manager, {
157
+ enableFileLocking: true,
158
+ });
159
+ coordination2.initialize("teammate-2", "test-team");
160
+
161
+ const claimed = coordination2.claimFile("/path/to/file.ts");
162
+ expect(claimed).toBe(true);
163
+
164
+ coordination2.shutdown();
165
+ });
166
+
167
+ it("should release all claims on shutdown", () => {
168
+ coordination.initialize("teammate-1", "test-team");
169
+
170
+ coordination.claimFile("/file1.ts");
171
+ coordination.claimFile("/file2.ts");
172
+
173
+ coordination.shutdown();
174
+
175
+ // Re-create and check if files are available
176
+ const coordination2 = new CoordinationManager(manager, {
177
+ enableFileLocking: true,
178
+ });
179
+ coordination2.initialize("teammate-2", "test-team");
180
+
181
+ expect(coordination2.isFileClaimed("/file1.ts")).toBe(false);
182
+ expect(coordination2.isFileClaimed("/file2.ts")).toBe(false);
183
+
184
+ coordination2.shutdown();
185
+ });
186
+
187
+ it("should list all claims", () => {
188
+ coordination.initialize("teammate-1", "test-team");
189
+
190
+ coordination.claimFile("/file1.ts", "Working on file 1");
191
+ coordination.claimFile("/file2.ts", "Working on file 2");
192
+
193
+ const claims = coordination.getAllClaims();
194
+
195
+ expect(claims.length).toBe(2);
196
+ expect(claims.some((c) => c.filePath === "/file1.ts")).toBe(true);
197
+ expect(claims.some((c) => c.filePath === "/file2.ts")).toBe(true);
198
+ });
199
+
200
+ it("should support expiring claims", () => {
201
+ coordination.initialize("teammate-1", "test-team");
202
+
203
+ // Claim with 100ms expiration
204
+ coordination.claimFile("/file.ts", "Quick edit", 100);
205
+
206
+ // Should be claimed initially
207
+ expect(coordination.getFileClaim("/file.ts")).toBeDefined();
208
+
209
+ // Wait for expiration
210
+ // Note: In real tests, we'd use fake timers
211
+ // For now, just test the claim exists
212
+ const claim = coordination.getFileClaim("/file.ts");
213
+ expect(claim?.expiresAt).toBeDefined();
214
+ });
215
+ });
216
+
217
+ describe("Coordination Messages", () => {
218
+ it("should create coordination messages", () => {
219
+ const msg = createCoordinationMessage("task_progress", "50% complete");
220
+ expect(msg).toBe("[COORD:TASK_PROGRESS] 50% complete");
221
+ });
222
+
223
+ it("should parse coordination messages", () => {
224
+ const result = parseCoordinationMessage("[COORD:FILE_CLAIM] /path/to/file.ts");
225
+ expect(result.isCoordination).toBe(true);
226
+ expect(result.type).toBe("file_claim");
227
+ expect(result.content).toBe("/path/to/file.ts");
228
+ });
229
+
230
+ it("should return false for non-coordination messages", () => {
231
+ const result = parseCoordinationMessage("Hello teammates!");
232
+ expect(result.isCoordination).toBe(false);
233
+ expect(result.type).toBeUndefined();
234
+ });
235
+ });
236
+
237
+ describe("Event Callbacks", () => {
238
+ it("should call onProgress callback", () => {
239
+ const progressReports: Array<{ id: string; progress: ProgressReport }> = [];
240
+
241
+ const coordWithCallbacks = new CoordinationManager(manager, {
242
+ enableProgressReporting: true,
243
+ onProgress: (teammateId, progress) => {
244
+ progressReports.push({ id: teammateId, progress });
245
+ },
246
+ });
247
+
248
+ coordWithCallbacks.initialize("teammate-1", "test-team");
249
+ coordWithCallbacks.reportProgress({
250
+ step: "Test",
251
+ stepNumber: 1,
252
+ });
253
+
254
+ expect(progressReports.length).toBe(1);
255
+ expect(progressReports[0]!.progress.step).toBe("Test");
256
+
257
+ coordWithCallbacks.shutdown();
258
+ });
259
+
260
+ it("should call onFileClaimed callback", () => {
261
+ const claims: FileClaim[] = [];
262
+
263
+ const coordWithCallbacks = new CoordinationManager(manager, {
264
+ enableFileLocking: true,
265
+ onFileClaimed: (claim) => {
266
+ claims.push(claim);
267
+ },
268
+ });
269
+
270
+ coordWithCallbacks.initialize("teammate-1", "test-team");
271
+ coordWithCallbacks.claimFile("/test.ts", "Testing");
272
+
273
+ expect(claims.length).toBe(1);
274
+ expect(claims[0]!.filePath).toBe("/test.ts");
275
+
276
+ coordWithCallbacks.shutdown();
277
+ });
278
+ });
279
+ });