@papercraneai/sandbox-agent 0.1.17 → 0.1.18
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 +29 -0
- package/package.json +8 -4
package/dist/index.js
CHANGED
|
@@ -15,6 +15,24 @@ import { homedir, networkInterfaces } from "os";
|
|
|
15
15
|
import { z } from "zod";
|
|
16
16
|
import multer from "multer";
|
|
17
17
|
import * as log from "./logger.js";
|
|
18
|
+
// ─── Egress-proxy scoping (sealed GCE sandbox) ────────────────────────────────
|
|
19
|
+
// The sealed GCE sandbox injects HTTPS_PROXY container-wide so Claude Code's Vertex
|
|
20
|
+
// calls reach the US-multi-region endpoint through the egress proxy. But that proxy
|
|
21
|
+
// allow-lists ONLY the Vertex host and 403s everything else — so every OTHER client in
|
|
22
|
+
// the container (the `papercrane` CLI, npm, this agent's own control-plane calls) must
|
|
23
|
+
// NOT be proxied; their targets (cp.papercrane.internal:80, *.pkg.dev) are directly
|
|
24
|
+
// reachable and get denied if sent through the proxy. So: capture the proxy config,
|
|
25
|
+
// strip it from the ambient env so nothing inherits it, and re-apply it to ONLY the
|
|
26
|
+
// Claude Code subprocess via query()'s `options.env` (see buildQuery below).
|
|
27
|
+
// gce.ts injects the proxy as UPPERCASE HTTPS_PROXY/NO_PROXY, and Claude Code reads it via
|
|
28
|
+
// proxy-from-env's getProxyForUrl (confirmed by grepping the bundled SDK) whose lookup is
|
|
29
|
+
// `env[key.toLowerCase()] || env[key.toUpperCase()]` — so uppercase alone is honored. Capture +
|
|
30
|
+
// re-inject uppercase only; the strip below clears both casings just to fully wipe the ambient env.
|
|
31
|
+
const VERTEX_HTTPS_PROXY = process.env.HTTPS_PROXY || "";
|
|
32
|
+
const VERTEX_NO_PROXY = process.env.NO_PROXY || "";
|
|
33
|
+
for (const k of ["HTTPS_PROXY", "https_proxy", "HTTP_PROXY", "http_proxy", "NO_PROXY", "no_proxy"]) {
|
|
34
|
+
delete process.env[k];
|
|
35
|
+
}
|
|
18
36
|
// Get the directory of this file (works for both source and compiled)
|
|
19
37
|
const __filename = fileURLToPath(import.meta.url);
|
|
20
38
|
const __dirname = dirname(__filename);
|
|
@@ -1414,6 +1432,17 @@ app.post("/chat", async (req, res) => {
|
|
|
1414
1432
|
if (effort !== undefined) {
|
|
1415
1433
|
options.effort = effort;
|
|
1416
1434
|
}
|
|
1435
|
+
// Scope the egress proxy to ONLY the Claude Code process (see top-of-file note):
|
|
1436
|
+
// its Vertex calls go through the proxy; everything else in the container stays direct.
|
|
1437
|
+
if (VERTEX_HTTPS_PROXY) {
|
|
1438
|
+
// Claude Code reads HTTPS_PROXY/NO_PROXY via proxy-from-env (honors uppercase), so uppercase
|
|
1439
|
+
// is all that's needed — no lowercase duplicate.
|
|
1440
|
+
options.env = {
|
|
1441
|
+
...process.env,
|
|
1442
|
+
HTTPS_PROXY: VERTEX_HTTPS_PROXY,
|
|
1443
|
+
...(VERTEX_NO_PROXY ? { NO_PROXY: VERTEX_NO_PROXY } : {}),
|
|
1444
|
+
};
|
|
1445
|
+
}
|
|
1417
1446
|
try {
|
|
1418
1447
|
let gotResult = false;
|
|
1419
1448
|
log.debug({ ...ctx, elapsed: Date.now() - requestStartTime }, "Starting Claude SDK query");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@papercraneai/sandbox-agent",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.18",
|
|
4
4
|
"description": "Claude Agent SDK server for sandbox environments",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -17,19 +17,18 @@
|
|
|
17
17
|
"scripts": {
|
|
18
18
|
"start": "node dist/index.js",
|
|
19
19
|
"dev": "tsx watch src/index.ts",
|
|
20
|
-
"dev:local": "PROJECT_DIR=./template/src/app tsx src/index.ts",
|
|
21
20
|
"prepublishOnly": "npm run build",
|
|
22
21
|
"build": "tsc",
|
|
23
22
|
"typecheck": "tsc --noEmit"
|
|
24
23
|
},
|
|
25
24
|
"dependencies": {
|
|
26
25
|
"@anthropic-ai/claude-agent-sdk": "^0.2.128",
|
|
27
|
-
"@papercraneai/cli": "
|
|
26
|
+
"@papercraneai/cli": "^1.10.0",
|
|
28
27
|
"diff": "^5.2.0",
|
|
29
28
|
"express": "^4.21.1",
|
|
30
29
|
"multer": "^2.0.2",
|
|
31
30
|
"tail": "^2.2.6",
|
|
32
|
-
"ws": "^8.
|
|
31
|
+
"ws": "^8.20.1",
|
|
33
32
|
"zod": "^4.0.0"
|
|
34
33
|
},
|
|
35
34
|
"devDependencies": {
|
|
@@ -41,5 +40,10 @@
|
|
|
41
40
|
"@types/ws": "^8.18.1",
|
|
42
41
|
"tsx": "^4.20.6",
|
|
43
42
|
"typescript": "^5.8.3"
|
|
43
|
+
},
|
|
44
|
+
"overrides": {
|
|
45
|
+
"hono": "^4.12.25",
|
|
46
|
+
"form-data": "^4.0.6",
|
|
47
|
+
"qs": "^6.15.2"
|
|
44
48
|
}
|
|
45
49
|
}
|