@sisu-ai/tool-terminal 7.0.1 → 7.1.0

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.d.ts CHANGED
@@ -28,6 +28,26 @@ export interface TerminalToolConfig {
28
28
  export declare const DEFAULT_CONFIG: TerminalToolConfig;
29
29
  export declare const TERMINAL_COMMANDS_ALLOW: ReadonlyArray<string>;
30
30
  export declare function defaultTerminalConfig(overrides?: Partial<TerminalToolConfig>): TerminalToolConfig;
31
+ interface TerminalPolicy {
32
+ allowed: boolean;
33
+ reason?: string;
34
+ allowedCommands?: string[];
35
+ allowedRoots?: string[];
36
+ }
37
+ interface TerminalRunResult {
38
+ exitCode: number;
39
+ stdout: string;
40
+ stderr: string;
41
+ durationMs: number;
42
+ policy: TerminalPolicy;
43
+ message?: string;
44
+ cwd: string;
45
+ }
46
+ interface TerminalReadResult {
47
+ contents: string;
48
+ policy: TerminalPolicy;
49
+ message?: string;
50
+ }
31
51
  export declare function createTerminalTool(config?: Partial<TerminalToolConfig>): {
32
52
  start_session: (args?: {
33
53
  cwd?: string;
@@ -42,17 +62,7 @@ export declare function createTerminalTool(config?: Partial<TerminalToolConfig>)
42
62
  env?: Record<string, string>;
43
63
  stdin?: string;
44
64
  sessionId?: string;
45
- }) => Promise<{
46
- exitCode: number;
47
- stdout: string;
48
- stderr: string;
49
- durationMs: number;
50
- policy: {
51
- allowed: boolean;
52
- reason?: string;
53
- };
54
- cwd: string;
55
- }>;
65
+ }) => Promise<TerminalRunResult>;
56
66
  cd: (args: {
57
67
  path: string;
58
68
  sessionId?: string;
@@ -64,16 +74,14 @@ export declare function createTerminalTool(config?: Partial<TerminalToolConfig>)
64
74
  path: string;
65
75
  encoding?: "utf8" | "base64";
66
76
  sessionId?: string;
67
- }) => Promise<{
68
- contents: string;
69
- }>;
77
+ }) => Promise<TerminalReadResult>;
70
78
  tools: (Tool<{
71
79
  command: string;
72
80
  cwd?: string;
73
81
  env?: Record<string, string>;
74
82
  stdin?: string;
75
83
  sessionId?: string;
76
- }, any> | Tool<{
84
+ }, TerminalRunResult> | Tool<{
77
85
  path: string;
78
86
  sessionId?: string;
79
87
  }, {
@@ -83,8 +91,7 @@ export declare function createTerminalTool(config?: Partial<TerminalToolConfig>)
83
91
  path: string;
84
92
  encoding?: "utf8" | "base64";
85
93
  sessionId?: string;
86
- }, {
87
- contents: string;
88
- }>)[];
94
+ }, TerminalReadResult>)[];
89
95
  };
90
96
  export type TerminalTool = ReturnType<typeof createTerminalTool>;
97
+ export {};
package/dist/index.js CHANGED
@@ -87,6 +87,8 @@ function isPathAllowed(absPath, cfg, mode) {
87
87
  return true;
88
88
  }
89
89
  function looksLikePath(arg) {
90
+ if (/^https?:\/\//i.test(arg))
91
+ return false;
90
92
  return (arg.startsWith(".") ||
91
93
  arg.includes("/") ||
92
94
  /^(?:[A-Za-z]:[\\/]|\\\\)/.test(arg));
@@ -240,7 +242,7 @@ function commandPolicyCheck(args, cfg) {
240
242
  found.push("`...`");
241
243
  if (/>/.test(cmdStr))
242
244
  found.push(">");
243
- if (/<\<?/.test(cmdStr))
245
+ if (/<<?/.test(cmdStr))
244
246
  found.push("<");
245
247
  if (/(^|\s)&(\s|$)/.test(cmdStr))
246
248
  found.push("&");
@@ -373,7 +375,12 @@ export function createTerminalTool(config) {
373
375
  stdout: "",
374
376
  stderr: "",
375
377
  durationMs: 0,
376
- policy: pre,
378
+ policy: {
379
+ allowed: false,
380
+ reason: pre.reason,
381
+ allowedCommands: cfg.commands.allow,
382
+ },
383
+ message: `Command denied by policy. Allowed commands: ${cfg.commands.allow.join(", ")}.`,
377
384
  cwd,
378
385
  };
379
386
  }
@@ -431,7 +438,9 @@ export function createTerminalTool(config) {
431
438
  try {
432
439
  c.kill("SIGKILL");
433
440
  }
434
- catch { }
441
+ catch {
442
+ // ignore kill errors
443
+ }
435
444
  }
436
445
  };
437
446
  const onStdout = (d) => {
@@ -547,14 +556,14 @@ export function createTerminalTool(config) {
547
556
  }
548
557
  function cd(args) {
549
558
  let session = getSession(args.sessionId);
559
+ let createdSessionId;
550
560
  // If no valid session is provided, create one anchored at the first root
551
561
  if (!session) {
552
562
  const cwd = canonicalize(cfg.roots[0]);
553
- const sessionId = randomUUID();
563
+ createdSessionId = randomUUID();
554
564
  const expiresAt = Date.now() + cfg.sessions.ttlMs;
555
565
  session = { cwd, env: {}, expiresAt };
556
- sessions.set(sessionId, session);
557
- args._createdSessionId = sessionId;
566
+ sessions.set(createdSessionId, session);
558
567
  }
559
568
  const newPath = canonicalize(path.resolve(session.cwd, args.path));
560
569
  if (!isPathAllowed(newPath, cfg, "exec")) {
@@ -564,7 +573,7 @@ export function createTerminalTool(config) {
564
573
  session.expiresAt = Date.now() + cfg.sessions.ttlMs;
565
574
  return {
566
575
  cwd: session.cwd,
567
- sessionId: args._createdSessionId ?? args.sessionId,
576
+ sessionId: createdSessionId ?? args.sessionId,
568
577
  };
569
578
  }
570
579
  async function read_file(args) {
@@ -573,12 +582,21 @@ export function createTerminalTool(config) {
573
582
  const session = getSession(args.sessionId);
574
583
  const cwd = session?.cwd ?? cfg.roots[0];
575
584
  const abs = canonicalize(path.resolve(cwd, args.path));
576
- if (!isPathAllowed(abs, cfg, "read"))
577
- throw new Error("path outside allowed roots");
585
+ if (!isPathAllowed(abs, cfg, "read")) {
586
+ return {
587
+ contents: "",
588
+ policy: {
589
+ allowed: false,
590
+ reason: "path outside allowed roots",
591
+ allowedRoots: cfg.roots,
592
+ },
593
+ message: `Path denied by policy. Allowed roots: ${cfg.roots.join(", ")}.`,
594
+ };
595
+ }
578
596
  const buf = await fs.readFile(abs);
579
597
  const encoding = args.encoding ?? "utf8";
580
598
  const contents = encoding === "base64" ? buf.toString("base64") : buf.toString("utf8");
581
- return { contents };
599
+ return { contents, policy: { allowed: true } };
582
600
  }
583
601
  const runCommandTool = {
584
602
  name: "terminalRun",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sisu-ai/tool-terminal",
3
- "version": "7.0.1",
3
+ "version": "7.1.0",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",