@steerable/agent-shell 0.6.52 → 0.6.53

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.
@@ -20,6 +20,7 @@ import { buildEgressProxyPlan, decideEgressProxy, ensureEgressProxyExecutable, d
20
20
  import { WEB_TOOL_RPC_TIMEOUT_MS, webToolsEnabled } from '../tool-router.js';
21
21
  import { sidecarWebSearchEnv } from '../storage/web-search-settings.js';
22
22
  import { executeHostedWebSearch } from '../hosted-web-search.js';
23
+ import { getProductConfig } from '../product-config.js';
23
24
  let egressProxyRef = null;
24
25
  let supervisorRef = null;
25
26
  let sidecarGeneration = 0;
@@ -121,6 +122,9 @@ async function startEgressProxyIfEnabled(store) {
121
122
  ? {
122
123
  STEERABLE_EGRESS_CONTROL_PORT: String(egressProxyRef.controlPort),
123
124
  [plan.control.tokenEnv]: plan.control.tokenValue,
125
+ ...(getProductConfig().egressApproval === 'off'
126
+ ? { STEERABLE_EGRESS_APPROVAL: 'off' }
127
+ : {}),
124
128
  }
125
129
  : {};
126
130
  return {
@@ -172,7 +172,8 @@ export class ToolRouter {
172
172
  return [
173
173
  {
174
174
  name: 'local_exec_shell',
175
- description: 'Execute a local shell command',
175
+ description: 'Execute a shell command in a pseudo-terminal. Set pty to false for a plain pipe. ' +
176
+ 'When this host is configured with a remote endpoint, the command runs on that host instead of this machine.',
176
177
  mode: 'destructive',
177
178
  inputSchema: {
178
179
  type: 'object',
@@ -180,6 +181,7 @@ export class ToolRouter {
180
181
  command: { type: 'string' },
181
182
  cwd: { type: 'string' },
182
183
  timeout: { type: 'number', description: 'Timeout in milliseconds (e.g. 30000). If a small number like 15 or 30 is provided, it is assumed to be in seconds and automatically multiplied by 1000.' },
184
+ pty: { type: 'boolean', description: 'Run in a pseudo-terminal. Defaults to true.' },
183
185
  },
184
186
  required: ['command'],
185
187
  },
@@ -377,32 +379,35 @@ export class ToolRouter {
377
379
  },
378
380
  {
379
381
  name: 'mcp_list_tools',
380
- description: 'List tools from one MCP server',
382
+ description: 'List tools from one MCP server. Pass command for stdio or url for unauthenticated Streamable HTTP.',
381
383
  mode: 'external',
382
384
  inputSchema: {
383
385
  type: 'object',
384
386
  properties: {
385
387
  command: { type: 'string' },
388
+ url: { type: 'string' },
386
389
  args: { type: 'array', items: { type: 'string' } },
387
390
  cwd: { type: 'string' },
388
391
  },
389
- required: ['command'],
392
+ additionalProperties: false,
390
393
  },
391
394
  },
392
395
  {
393
396
  name: 'mcp_tool_exec',
394
- description: 'Execute one MCP tool',
397
+ description: 'Execute one MCP tool. Pass command for stdio or url for unauthenticated Streamable HTTP.',
395
398
  mode: 'external',
396
399
  inputSchema: {
397
400
  type: 'object',
398
401
  properties: {
399
402
  command: { type: 'string' },
403
+ url: { type: 'string' },
400
404
  args: { type: 'array', items: { type: 'string' } },
401
405
  cwd: { type: 'string' },
402
406
  toolName: { type: 'string' },
403
407
  toolArgs: { type: 'object' },
404
408
  },
405
- required: ['command', 'toolName'],
409
+ required: ['toolName'],
410
+ additionalProperties: false,
406
411
  },
407
412
  },
408
413
  // deferred 层的发现缝(Wave 2 工具分层):MCP 动态工具不占每轮
@@ -890,6 +895,7 @@ export class ToolRouter {
890
895
  command: String(args.command || ''),
891
896
  cwd: typeof args.cwd === 'string' ? args.cwd : undefined,
892
897
  timeout: typeof args.timeout === 'number' ? args.timeout : undefined,
898
+ pty: args.pty !== false,
893
899
  }, projectRoot, context?.additionalWriteRoots ?? null);
894
900
  case 'local_read_file':
895
901
  return await this.localExecutor.readLocalFile({
@@ -1257,8 +1263,17 @@ export class ToolRouter {
1257
1263
  return { path: resolved };
1258
1264
  }
1259
1265
  resolveMcpConfig(args) {
1266
+ const command = typeof args.command === 'string' ? args.command.trim() : '';
1267
+ const url = typeof args.url === 'string' ? args.url.trim() : '';
1268
+ if (command && url)
1269
+ throw new Error('MCP 调用只能提供 command 或 url 之一');
1270
+ if (url)
1271
+ return { transport: 'streamable-http', url };
1272
+ if (!command)
1273
+ throw new Error('MCP 调用需要 command(stdio)或 url(Streamable HTTP)');
1260
1274
  return {
1261
- command: String(args.command || ''),
1275
+ transport: 'stdio',
1276
+ command,
1262
1277
  args: Array.isArray(args.args) ? args.args.map(item => String(item)) : undefined,
1263
1278
  cwd: typeof args.cwd === 'string' ? args.cwd : undefined,
1264
1279
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@steerable/agent-shell",
3
- "version": "0.6.52",
3
+ "version": "0.6.53",
4
4
  "description": "Steerable framework — product-neutral Node HostRuntime and headless HTTP server shared by Tauri desktop and browser deployments; scenario packs extend it through @steerable/pack-sdk.",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://steerableframework.com/",
@@ -45,7 +45,7 @@
45
45
  "node": ">=20"
46
46
  },
47
47
  "dependencies": {
48
- "@modelcontextprotocol/sdk": "^1.29.0",
48
+ "@modelcontextprotocol/sdk": "1.30.0",
49
49
  "better-sqlite3": "^11.9.1",
50
50
  "conf": "10.2.0",
51
51
  "dotenv": "^17.4.2",
@@ -55,9 +55,9 @@
55
55
  "he": "^1.2.0",
56
56
  "node-pty": "^1.1.0",
57
57
  "semver": "^7.8.0",
58
- "@steerable/agent-harness": "0.6.52",
59
- "@steerable/agent-protocol": "0.6.52",
60
- "@steerable/pack-sdk": "0.6.52"
58
+ "@steerable/agent-protocol": "0.6.53",
59
+ "@steerable/pack-sdk": "0.6.53",
60
+ "@steerable/agent-harness": "0.6.53"
61
61
  },
62
62
  "devDependencies": {
63
63
  "@types/better-sqlite3": "^7.6.13",