@lmnr-ai/claude-code-proxy 0.1.1-alpha.1 → 0.1.2
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/dist/index.js +77 -31
- package/package.json +24 -4
- package/dist/lmnr-claude-code-proxy.node +0 -0
package/dist/index.js
CHANGED
|
@@ -7,15 +7,47 @@ exports.stop = exports.run = void 0;
|
|
|
7
7
|
exports.setCurrentTrace = setCurrentTrace;
|
|
8
8
|
exports.runServer = runServer;
|
|
9
9
|
exports.stopServer = stopServer;
|
|
10
|
-
//
|
|
11
|
-
//
|
|
12
|
-
|
|
13
|
-
const
|
|
10
|
+
// Platform-specific package loading
|
|
11
|
+
// This tries to load the appropriate platform package, falling back to local .node file
|
|
12
|
+
const { join } = require('path');
|
|
13
|
+
const { platform, arch } = require('os');
|
|
14
|
+
function loadNative() {
|
|
15
|
+
// Map of platform/arch to NAPI platform names
|
|
16
|
+
const platformMap = {
|
|
17
|
+
'darwin-arm64': 'darwin-arm64',
|
|
18
|
+
'darwin-x64': 'darwin-x64',
|
|
19
|
+
'win32-x64': 'win32-x64-msvc',
|
|
20
|
+
'linux-x64': process.env.MUSL ? 'linux-x64-musl' : 'linux-x64-gnu',
|
|
21
|
+
'linux-arm64': process.env.MUSL ? 'linux-arm64-musl' : 'linux-arm64-gnu',
|
|
22
|
+
};
|
|
23
|
+
const platformKey = `${platform()}-${arch()}`;
|
|
24
|
+
const platformName = platformMap[platformKey];
|
|
25
|
+
if (platformName) {
|
|
26
|
+
try {
|
|
27
|
+
// Try to load from platform-specific package
|
|
28
|
+
return require(`@lmnr-ai/claude-code-proxy-${platformName}`);
|
|
29
|
+
}
|
|
30
|
+
catch (e) {
|
|
31
|
+
// Platform package not available, try local .node file
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
// Fallback to local .node file (for development builds)
|
|
35
|
+
try {
|
|
36
|
+
return require(join(__dirname, 'lmnr-claude-code-proxy.node'));
|
|
37
|
+
}
|
|
38
|
+
catch (e) {
|
|
39
|
+
throw new Error(`Failed to load native module for ${platformKey}. ` +
|
|
40
|
+
`Platform package: @lmnr-ai/claude-code-proxy-${platformName || 'unknown'}. ` +
|
|
41
|
+
`Error: ${e}`);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
const native = loadNative();
|
|
14
45
|
const HEALTH_CHECK_INTERVAL = 1000;
|
|
15
46
|
// Module-level variables to track the server state
|
|
16
47
|
let serverPort = 45667;
|
|
17
48
|
let targetUrl = '';
|
|
18
49
|
let monitorInterval = null;
|
|
50
|
+
let isHealthCheckRunning = false;
|
|
19
51
|
/**
|
|
20
52
|
* Set the current trace context by sending an HTTP request to the running proxy server.
|
|
21
53
|
*
|
|
@@ -54,42 +86,54 @@ async function setCurrentTrace(context) {
|
|
|
54
86
|
/**
|
|
55
87
|
* Background function that monitors server health and restarts if needed.
|
|
56
88
|
* Polls every HEALTH_CHECK_INTERVAL ms.
|
|
89
|
+
* Uses a flag to prevent concurrent execution, avoiding race conditions.
|
|
57
90
|
*/
|
|
58
91
|
async function healthCheckMonitor() {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
// Force new connection for each health check to avoid interfering with streaming
|
|
63
|
-
headers: {
|
|
64
|
-
'Connection': 'close'
|
|
65
|
-
},
|
|
66
|
-
});
|
|
67
|
-
if (response.status === 200) {
|
|
68
|
-
// Server is healthy
|
|
69
|
-
return;
|
|
70
|
-
}
|
|
92
|
+
// Skip if a health check is already running to prevent concurrent restarts
|
|
93
|
+
if (isHealthCheckRunning) {
|
|
94
|
+
return;
|
|
71
95
|
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
96
|
+
isHealthCheckRunning = true;
|
|
97
|
+
try {
|
|
98
|
+
const url = `http://127.0.0.1:${serverPort}/lmnr-internal/health`;
|
|
75
99
|
try {
|
|
76
|
-
|
|
100
|
+
const response = await fetch(url, {
|
|
101
|
+
// Force new connection for each health check to avoid interfering with streaming
|
|
102
|
+
headers: {
|
|
103
|
+
'Connection': 'close'
|
|
104
|
+
},
|
|
105
|
+
});
|
|
106
|
+
if (response.status === 200) {
|
|
107
|
+
// Server is healthy
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
catch (error) {
|
|
112
|
+
// Server is not responding, try to restart
|
|
113
|
+
console.warn(`Server health check failed: ${error}. Attempting to restart...`);
|
|
77
114
|
try {
|
|
78
|
-
|
|
115
|
+
// Try to stop the existing server (it might be stuck)
|
|
116
|
+
try {
|
|
117
|
+
native.stop();
|
|
118
|
+
}
|
|
119
|
+
catch {
|
|
120
|
+
// Server might already be dead
|
|
121
|
+
}
|
|
122
|
+
// Wait a bit before restarting
|
|
123
|
+
await new Promise(resolve => setTimeout(resolve, 100));
|
|
124
|
+
// Restart the server
|
|
125
|
+
native.run(targetUrl, serverPort);
|
|
126
|
+
console.info('Server restarted successfully');
|
|
79
127
|
}
|
|
80
|
-
catch {
|
|
81
|
-
|
|
128
|
+
catch (restartError) {
|
|
129
|
+
console.error(`Failed to restart server: ${restartError}`);
|
|
82
130
|
}
|
|
83
|
-
// Wait a bit before restarting
|
|
84
|
-
await new Promise(resolve => setTimeout(resolve, 100));
|
|
85
|
-
// Restart the server
|
|
86
|
-
native.run(targetUrl, serverPort);
|
|
87
|
-
console.info('Server restarted successfully');
|
|
88
|
-
}
|
|
89
|
-
catch (restartError) {
|
|
90
|
-
console.error(`Failed to restart server: ${restartError}`);
|
|
91
131
|
}
|
|
92
132
|
}
|
|
133
|
+
finally {
|
|
134
|
+
// Always reset the flag when done, even if an error occurred
|
|
135
|
+
isHealthCheckRunning = false;
|
|
136
|
+
}
|
|
93
137
|
}
|
|
94
138
|
/**
|
|
95
139
|
* Run the proxy server in a background thread with health monitoring.
|
|
@@ -131,6 +175,8 @@ function stopServer() {
|
|
|
131
175
|
clearInterval(monitorInterval);
|
|
132
176
|
monitorInterval = null;
|
|
133
177
|
}
|
|
178
|
+
// Reset the health check flag
|
|
179
|
+
isHealthCheckRunning = false;
|
|
134
180
|
// Stop the server
|
|
135
181
|
try {
|
|
136
182
|
native.stop();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lmnr-ai/claude-code-proxy",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "HTTP proxy for Claude Desktop API requests with Laminar observability",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -8,11 +8,29 @@
|
|
|
8
8
|
"binaryName": "lmnr-claude-code-proxy",
|
|
9
9
|
"package": {
|
|
10
10
|
"name": "@lmnr-ai/claude-code-proxy"
|
|
11
|
-
}
|
|
11
|
+
},
|
|
12
|
+
"targets": [
|
|
13
|
+
"aarch64-apple-darwin",
|
|
14
|
+
"x86_64-apple-darwin",
|
|
15
|
+
"x86_64-pc-windows-msvc",
|
|
16
|
+
"x86_64-unknown-linux-gnu",
|
|
17
|
+
"aarch64-unknown-linux-gnu",
|
|
18
|
+
"x86_64-unknown-linux-musl",
|
|
19
|
+
"aarch64-unknown-linux-musl"
|
|
20
|
+
]
|
|
12
21
|
},
|
|
13
22
|
"files": [
|
|
14
23
|
"dist"
|
|
15
24
|
],
|
|
25
|
+
"optionalDependencies": {
|
|
26
|
+
"@lmnr-ai/claude-code-proxy-darwin-arm64": "0.1.2",
|
|
27
|
+
"@lmnr-ai/claude-code-proxy-darwin-x64": "0.1.2",
|
|
28
|
+
"@lmnr-ai/claude-code-proxy-win32-x64-msvc": "0.1.2",
|
|
29
|
+
"@lmnr-ai/claude-code-proxy-linux-x64-gnu": "0.1.2",
|
|
30
|
+
"@lmnr-ai/claude-code-proxy-linux-arm64-gnu": "0.1.2",
|
|
31
|
+
"@lmnr-ai/claude-code-proxy-linux-x64-musl": "0.1.2",
|
|
32
|
+
"@lmnr-ai/claude-code-proxy-linux-arm64-musl": "0.1.2"
|
|
33
|
+
},
|
|
16
34
|
"keywords": [
|
|
17
35
|
"claude",
|
|
18
36
|
"proxy",
|
|
@@ -36,9 +54,11 @@
|
|
|
36
54
|
"scripts": {
|
|
37
55
|
"artifacts": "napi artifacts",
|
|
38
56
|
"build:cargo": "cd ../bin && cargo build --release --features typescript",
|
|
39
|
-
"build:napi": "cd ../bin && napi build --platform --release
|
|
57
|
+
"build:napi": "cd ../bin && napi build --platform --release",
|
|
40
58
|
"build:ts": "tsc",
|
|
41
59
|
"build": "node scripts/build.js",
|
|
42
|
-
"test": "echo \"Error: no test specified\" && exit
|
|
60
|
+
"test": "echo \"Error: no test specified\" && exit 0",
|
|
61
|
+
"napi": "napi",
|
|
62
|
+
"universalize": "napi universalize"
|
|
43
63
|
}
|
|
44
64
|
}
|
|
Binary file
|