@papercraneai/sandbox-agent 0.1.9 → 0.1.11
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 +22 -7
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -4,6 +4,7 @@ import { createServer } from "http";
|
|
|
4
4
|
import { WebSocketServer, WebSocket } from "ws";
|
|
5
5
|
import { Tail } from "tail";
|
|
6
6
|
import { query, tool, createSdkMcpServer } from "@anthropic-ai/claude-agent-sdk";
|
|
7
|
+
import { realpathSync } from "fs";
|
|
7
8
|
import { readdir, stat, mkdir, readFile, writeFile, access, unlink, rm } from "fs/promises";
|
|
8
9
|
import { join, dirname, resolve } from "path";
|
|
9
10
|
import { fileURLToPath } from "url";
|
|
@@ -372,6 +373,8 @@ const app = express();
|
|
|
372
373
|
app.use(express.json());
|
|
373
374
|
const PORT = cliArgs.agentPort;
|
|
374
375
|
let PROJECT_DIR = getProjectDir(); // Will be updated after template setup
|
|
376
|
+
// Per-request UI context for GetContext tool (keyed by requestId, cleaned up after each turn)
|
|
377
|
+
const sessionContext = {};
|
|
375
378
|
// Registration state
|
|
376
379
|
let environmentId = null;
|
|
377
380
|
let connectionToken = null;
|
|
@@ -389,10 +392,17 @@ const showPreviewTool = tool("ShowPreview", "Shows the preview iframe for a spec
|
|
|
389
392
|
});
|
|
390
393
|
// Factory to create a fresh MCP server per chat session
|
|
391
394
|
// (each Protocol instance can only be connected to one transport at a time)
|
|
392
|
-
|
|
395
|
+
// contextKey links to the per-request entry in sessionContext for GetContext
|
|
396
|
+
function createClientToolsServer(contextKey) {
|
|
397
|
+
const getContextTool = tool("GetContext", "Returns the current UI context — which dashboard the user is viewing in the preview panel. Use this when the user's request is ambiguous about which dashboard they're referring to.", {}, async () => ({
|
|
398
|
+
content: [{
|
|
399
|
+
type: "text",
|
|
400
|
+
text: JSON.stringify(sessionContext[contextKey] || { selectedDashboard: null })
|
|
401
|
+
}]
|
|
402
|
+
}));
|
|
393
403
|
return createSdkMcpServer({
|
|
394
404
|
name: "client-tools",
|
|
395
|
-
tools: [showPreviewTool]
|
|
405
|
+
tools: [showPreviewTool, getContextTool]
|
|
396
406
|
});
|
|
397
407
|
}
|
|
398
408
|
// Recursively build file tree
|
|
@@ -895,7 +905,8 @@ function encodeSessionPath(path) {
|
|
|
895
905
|
// Get the directory where Claude stores sessions for this project
|
|
896
906
|
function getSessionsDir() {
|
|
897
907
|
const claudeConfigDir = process.env.CLAUDE_CONFIG_DIR || join(homedir(), ".claude");
|
|
898
|
-
const
|
|
908
|
+
const resolvedDir = realpathSync(PROJECT_DIR);
|
|
909
|
+
const encodedPath = encodeSessionPath(resolvedDir);
|
|
899
910
|
return join(claudeConfigDir, "projects", encodedPath);
|
|
900
911
|
}
|
|
901
912
|
// Parse a JSONL file to extract session metadata
|
|
@@ -1123,7 +1134,7 @@ const buildHooks = (res, verbose, requestId, requestStartTime) => {
|
|
|
1123
1134
|
app.post("/chat", async (req, res) => {
|
|
1124
1135
|
const requestStartTime = Date.now();
|
|
1125
1136
|
const requestId = Math.random().toString(36).substring(7);
|
|
1126
|
-
const { message, sessionId, systemPrompt, verbose = false, subdir,
|
|
1137
|
+
const { message, sessionId, systemPrompt, verbose = false, subdir, selectedDashboard,
|
|
1127
1138
|
// Configurable agent options
|
|
1128
1139
|
maxTurns = 40, allowedTools, disallowedTools, model, maxBudgetUsd } = req.body;
|
|
1129
1140
|
const ctx = { requestId, sessionId };
|
|
@@ -1185,9 +1196,12 @@ app.post("/chat", async (req, res) => {
|
|
|
1185
1196
|
"WebSearch",
|
|
1186
1197
|
"AgentOutput",
|
|
1187
1198
|
"KillShell",
|
|
1188
|
-
"mcp__client-tools__ShowPreview"
|
|
1199
|
+
"mcp__client-tools__ShowPreview",
|
|
1200
|
+
"mcp__client-tools__GetContext"
|
|
1189
1201
|
];
|
|
1190
|
-
|
|
1202
|
+
// Store UI context for GetContext tool
|
|
1203
|
+
sessionContext[requestId] = { selectedDashboard: selectedDashboard || null };
|
|
1204
|
+
const clientTools = createClientToolsServer(requestId);
|
|
1191
1205
|
const options = {
|
|
1192
1206
|
maxTurns,
|
|
1193
1207
|
cwd,
|
|
@@ -1276,7 +1290,8 @@ app.post("/chat", async (req, res) => {
|
|
|
1276
1290
|
}
|
|
1277
1291
|
}
|
|
1278
1292
|
finally {
|
|
1279
|
-
//
|
|
1293
|
+
// Clean up per-request context and close MCP server
|
|
1294
|
+
delete sessionContext[requestId];
|
|
1280
1295
|
await clientTools.instance?.close().catch(() => { });
|
|
1281
1296
|
}
|
|
1282
1297
|
});
|