@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.
Files changed (2) hide show
  1. package/dist/index.js +22 -7
  2. 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
- function createClientToolsServer() {
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 encodedPath = encodeSessionPath(PROJECT_DIR);
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
- const clientTools = createClientToolsServer();
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
- // Close the per-session MCP server to free resources
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
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@papercraneai/sandbox-agent",
3
- "version": "0.1.9",
3
+ "version": "0.1.11",
4
4
  "description": "Claude Agent SDK server for sandbox environments",
5
5
  "license": "MIT",
6
6
  "type": "module",