@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
Binary file
@@ -0,0 +1,34 @@
1
+ {
2
+ "name": "@ebowwa/coder-native",
3
+ "version": "0.2.1",
4
+ "description": "Native Rust modules for @ebowwa/coder - provides high-performance search, token counting, and diff operations",
5
+ "author": "ebowwa",
6
+ "license": "MIT",
7
+ "keywords": ["coder", "native", "rust", "napi", "search", "tokens"],
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "https://github.com/ebowwa/coder"
11
+ },
12
+ "main": "index.js",
13
+ "types": "index.d.ts",
14
+ "files": [
15
+ "*.node",
16
+ "index.js",
17
+ "index.d.ts"
18
+ ],
19
+ "napi": {
20
+ "name": "coder_native",
21
+ "triples": {
22
+ "defaults": false,
23
+ "additional": [
24
+ "x86_64-apple-darwin",
25
+ "aarch64-apple-darwin",
26
+ "x86_64-unknown-linux-gnu",
27
+ "x86_64-pc-windows-msvc"
28
+ ]
29
+ }
30
+ },
31
+ "engines": {
32
+ "node": ">= 16"
33
+ }
34
+ }
Binary file
package/native/index.js CHANGED
@@ -2,28 +2,42 @@
2
2
  // Loads the appropriate .node file based on platform
3
3
 
4
4
  const { platform, arch } = process;
5
+ const fs = require('fs');
6
+ const path = require('path');
5
7
 
6
- let nativeBinding;
8
+ // List all .node files in the native directory
9
+ const nativeDir = __dirname;
10
+ const nodeFiles = fs.readdirSync(nativeDir).filter(f => f.endsWith('.node'));
7
11
 
8
- try {
9
- switch (`${platform}-${arch}`) {
10
- case 'darwin-x64':
11
- nativeBinding = require('./claude_code_native.darwin-x64.node');
12
- break;
13
- case 'darwin-arm64':
14
- nativeBinding = require('./index.darwin-arm64.node');
15
- break;
16
- case 'linux-x64':
17
- nativeBinding = require('./claude_code_native.linux-x64-gnu.node');
18
- break;
19
- case 'win32-x64':
20
- nativeBinding = require('./claude_code_native.win32-x64-msvc.node');
21
- break;
22
- default:
23
- throw new Error(`Unsupported platform: ${platform}-${arch}`);
12
+ // Find the matching file for current platform
13
+ let nativeBinding = null;
14
+
15
+ // Try to find a file matching our platform
16
+ for (const file of nodeFiles) {
17
+ // Check for darwin-arm64
18
+ if (platform === 'darwin' && arch === 'arm64' && file.includes('darwin') && file.includes('arm64')) {
19
+ nativeBinding = require(path.join(nativeDir, file));
20
+ break;
21
+ }
22
+ // Check for darwin-x64
23
+ if (platform === 'darwin' && arch === 'x64' && file.includes('darwin') && (file.includes('x64') && !file.includes('arm64'))) {
24
+ nativeBinding = require(path.join(nativeDir, file));
25
+ break;
26
+ }
27
+ // Check for linux-x64
28
+ if (platform === 'linux' && arch === 'x64' && file.includes('linux') && file.includes('x64')) {
29
+ nativeBinding = require(path.join(nativeDir, file));
30
+ break;
24
31
  }
25
- } catch (e) {
26
- throw new Error(`Failed to load native module: ${e.message}`);
32
+ // Check for win32-x64
33
+ if (platform === 'win32' && arch === 'x64' && file.includes('win32') && file.includes('x64')) {
34
+ nativeBinding = require(path.join(nativeDir, file));
35
+ break;
36
+ }
37
+ }
38
+
39
+ if (!nativeBinding) {
40
+ throw new Error(`Unsupported platform: ${platform}-${arch}. Available files: ${nodeFiles.join(', ')}`);
27
41
  }
28
42
 
29
43
  module.exports = nativeBinding;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ebowwa/coder",
3
- "version": "0.7.64",
3
+ "version": "0.7.66",
4
4
  "description": "AI-powered terminal coding assistant",
5
5
  "author": "ebowwa",
6
6
  "license": "MIT",
@@ -24,7 +24,7 @@
24
24
  },
25
25
  "scripts": {
26
26
  "build": "bun run build:native && bun run build:ts && bun run link",
27
- "build:ts": "bun build ./packages/src/index.ts ./packages/src/interfaces/ui/terminal/cli/index.ts --outdir ./dist --target bun",
27
+ "build:ts": "bun build ./packages/src/index.ts ./packages/src/interfaces/ui/terminal/cli/bootstrap.ts --outdir ./dist --target bun --external @ebowwa/coder-native && cp -r native dist/ && mkdir -p dist/interfaces/ui/terminal && cp -r native dist/interfaces/ui/terminal/ && mv dist/interfaces/ui/terminal/cli/bootstrap.js dist/interfaces/ui/terminal/cli/index.js",
28
28
  "build:native": "cd packages/rust && cargo build --release --target-dir ./target && cd ../.. && bun run build:napi-artifacts",
29
29
  "build:napi-artifacts": "napi build --platform --release --target-dir packages/rust/target --manifest-path packages/rust/Cargo.toml --output-dir native --js-package-name @ebowwa/coder-native --const-enum --strip --dts index.d.ts",
30
30
  "link": "bun link || npm link",
@@ -55,6 +55,7 @@
55
55
  "ora": "^8.2.0",
56
56
  "react": "^18.3.1",
57
57
  "react-devtools-core": "^7.0.1",
58
+ "react-dom": "^19.2.4",
58
59
  "sharp": "^0.34.5",
59
60
  "viem": "^2.46.3",
60
61
  "wagmi": "^3.5.0",
@@ -70,18 +70,20 @@ describe("needsCompaction", () => {
70
70
  });
71
71
 
72
72
  it("should respect custom threshold", () => {
73
- // Create messages that are exactly at a specific token count
74
- // 10 messages * 200 tokens = 2000 tokens total
73
+ // Create messages with known token count
74
+ // Note: createMessages adds " Message ${i}" suffix and role overhead
75
+ // So actual tokens per message = tokensPerMessage + ~2 (suffix) + 4 (role)
76
+ // For 10 messages at 200 target tokens: ~2060 actual tokens
75
77
  const messages = createMessages(10, 200);
76
- // Total ~2000 tokens, at 90% of 2000 = 1800 threshold
77
- // 2000 >= 1800, so needs compaction at 0.9 threshold
78
- expect(needsCompaction(messages, 2000, 0.9)).toBe(true);
79
78
 
80
- // At 99% threshold (1980), 2000 >= 1980, so still needs compaction
81
- expect(needsCompaction(messages, 2000, 0.99)).toBe(true);
79
+ // At 2000 max with 1.05 threshold (2100), 2060 < 2100, so no compaction needed
80
+ expect(needsCompaction(messages, 2000, 1.05)).toBe(false);
81
+
82
+ // At 2000 max with 1.00 threshold (2000), 2060 >= 2000, so needs compaction
83
+ expect(needsCompaction(messages, 2000, 1.0)).toBe(true);
82
84
 
83
- // At 101% threshold (2020), 2000 < 2020, so no compaction needed
84
- expect(needsCompaction(messages, 2000, 1.01)).toBe(false);
85
+ // At 2000 max with 0.9 threshold (1800), 2060 >= 1800, so needs compaction
86
+ expect(needsCompaction(messages, 2000, 0.9)).toBe(true);
85
87
  });
86
88
  });
87
89
 
@@ -104,7 +106,7 @@ describe("handleProactiveCompaction", () => {
104
106
  });
105
107
 
106
108
  it("should apply compaction when needed", async () => {
107
- const result = await handleProactiveCompaction(state, 4096);
109
+ const result = await handleProactiveCompaction(state, 4096, { useLLMSummarization: false });
108
110
 
109
111
  // May or may not compact depending on actual token counts
110
112
  // Just verify it doesn't throw
@@ -116,6 +118,7 @@ describe("handleProactiveCompaction", () => {
116
118
  keepFirst: 2,
117
119
  keepLast: 5,
118
120
  preserveToolPairs: false,
121
+ useLLMSummarization: false,
119
122
  };
120
123
 
121
124
  const result = await handleProactiveCompaction(state, 4096, customOptions);
@@ -133,7 +136,7 @@ describe("handleReactiveCompaction", () => {
133
136
  });
134
137
 
135
138
  it("should attempt compaction on any message set", async () => {
136
- const result = await handleReactiveCompaction(state, 4096);
139
+ const result = await handleReactiveCompaction(state, 4096, { useLLMSummarization: false });
137
140
 
138
141
  expect(typeof result).toBe("boolean");
139
142
  });
@@ -150,7 +153,7 @@ describe("handleReactiveCompaction", () => {
150
153
  it("should increment compaction count on success", async () => {
151
154
  const initialCount = state.compactionCount;
152
155
 
153
- await handleReactiveCompaction(state, 1000); // Force compaction with low limit
156
+ await handleReactiveCompaction(state, 1000, { useLLMSummarization: false }); // Force compaction with low limit
154
157
 
155
158
  // If compaction succeeded, count should increase
156
159
  // (depends on actual token counts)
@@ -190,7 +193,7 @@ describe("compaction state updates", () => {
190
193
  const state = new LoopState(messages);
191
194
  const originalLength = state.messages.length;
192
195
 
193
- await handleProactiveCompaction(state, 2000); // Force compaction
196
+ await handleProactiveCompaction(state, 2000, { useLLMSummarization: false }); // Force compaction
194
197
 
195
198
  // If compaction occurred, message count should decrease
196
199
  // (depends on actual implementation)
@@ -202,7 +205,7 @@ describe("compaction state updates", () => {
202
205
 
203
206
  const initialCompacted = state.totalTokensCompacted;
204
207
 
205
- await handleProactiveCompaction(state, 2000);
208
+ await handleProactiveCompaction(state, 2000, { useLLMSummarization: false });
206
209
 
207
210
  // If compaction succeeded, this should increase
208
211
  // (depends on actual implementation)
@@ -8,7 +8,7 @@ import {
8
8
  compactMessages,
9
9
  getCompactionStats,
10
10
  type CompactionResult,
11
- } from "../context-compaction.js";
11
+ } from "../context/index.js";
12
12
  import type { LoopState } from "./loop-state.js";
13
13
 
14
14
  /**
@@ -21,6 +21,8 @@ export interface CompactionOptions {
21
21
  keepLast?: number;
22
22
  /** Preserve tool use/result pairs */
23
23
  preserveToolPairs?: boolean;
24
+ /** Use LLM for summarization (default: true) */
25
+ useLLMSummarization?: boolean;
24
26
  }
25
27
 
26
28
  /** Default compaction options for proactive compaction */
@@ -54,6 +56,7 @@ export async function handleProactiveCompaction(
54
56
  keepFirst: options.keepFirst ?? 0,
55
57
  keepLast: options.keepLast ?? 3,
56
58
  preserveToolPairs: options.preserveToolPairs ?? true,
59
+ useLLMSummarization: options.useLLMSummarization ?? true,
57
60
  });
58
61
 
59
62
  return state.applyCompaction(compactionResult, getCompactionStats);
@@ -72,6 +75,7 @@ export async function handleReactiveCompaction(
72
75
  keepFirst: options.keepFirst ?? 0,
73
76
  keepLast: options.keepLast ?? 3,
74
77
  preserveToolPairs: options.preserveToolPairs ?? true,
78
+ useLLMSummarization: options.useLLMSummarization ?? true,
75
79
  });
76
80
 
77
81
  return state.applyCompaction(compactionResult, getCompactionStats);
@@ -85,4 +89,4 @@ export { needsCompaction };
85
89
  /**
86
90
  * Get token estimate for messages
87
91
  */
88
- export { estimateMessagesTokens } from "../context-compaction.js";
92
+ export { estimateMessagesTokens } from "../context/index.js";
@@ -64,6 +64,7 @@ export async function agentLoop(
64
64
  onToolResult,
65
65
  onMetrics,
66
66
  onReminder,
67
+ onRetryStart,
67
68
  onPermissionRequest,
68
69
  signal,
69
70
  } = options;
@@ -107,6 +108,7 @@ export async function agentLoop(
107
108
  onThinking,
108
109
  onToolUse,
109
110
  onReminder,
111
+ onRetryStart,
110
112
  permissionMode,
111
113
  permissionManager,
112
114
  onMetrics,
@@ -9,7 +9,7 @@ import type {
9
9
  CacheMetrics,
10
10
  UsageMetrics,
11
11
  } from "../../types/index.js";
12
- import type { CompactionResult, getCompactionStats } from "../context-compaction.js";
12
+ import type { CompactionResult, getCompactionStats } from "../context/index.js";
13
13
 
14
14
  /**
15
15
  * Creates an initial cache metrics object
@@ -40,6 +40,8 @@ export interface TurnExecutorOptions {
40
40
  onThinking?: (thinking: string) => void;
41
41
  onToolUse?: (toolUse: { id: string; name: string; input: unknown }) => void;
42
42
  onReminder?: (reminder: string) => void;
43
+ /** Called when API retry starts - UI should reset streaming state */
44
+ onRetryStart?: () => void;
43
45
  permissionMode: PermissionMode;
44
46
  permissionManager: PermissionManager;
45
47
  onMetrics?: (metrics: import("../../types/index.js").QueryMetrics) => void;
@@ -84,6 +86,7 @@ export async function executeTurn(
84
86
  onThinking,
85
87
  onToolUse,
86
88
  onReminder,
89
+ onRetryStart,
87
90
  permissionMode,
88
91
  permissionManager,
89
92
  onToolResult,
@@ -134,6 +137,7 @@ export async function executeTurn(
134
137
  onToken: onText,
135
138
  onThinking,
136
139
  onToolUse,
140
+ onRetryStart,
137
141
  signal,
138
142
  });
139
143
 
@@ -29,6 +29,8 @@ export interface AgentLoopCallbacks {
29
29
  onToolResult?: (result: { id: string; result: ToolResult }) => void;
30
30
  onMetrics?: (metrics: QueryMetrics) => void;
31
31
  onReminder?: (reminder: string) => void;
32
+ /** Called when API retry starts - UI should reset streaming state */
33
+ onRetryStart?: () => void;
32
34
  }
33
35
 
34
36
  /**
@@ -116,6 +118,8 @@ export interface TurnOptions {
116
118
  onThinking?: (thinking: string) => void;
117
119
  onToolUse?: (toolUse: { id: string; name: string; input: unknown }) => void;
118
120
  onReminder?: (reminder: string) => void;
121
+ /** Called when API retry starts - UI should reset streaming state */
122
+ onRetryStart?: () => void;
119
123
  }
120
124
 
121
125
  /**