@easynet/agent-tool-buildin 0.0.3 → 0.0.5

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 (114) hide show
  1. package/dist/core-tools-manifest.json +4 -0
  2. package/dist/exec/defaults.d.ts +8 -0
  3. package/dist/exec/defaults.d.ts.map +1 -0
  4. package/dist/exec/defaults.js +20 -0
  5. package/dist/exec/defaults.js.map +1 -0
  6. package/dist/exec/runCommand.d.ts +2 -2
  7. package/dist/exec/runCommand.d.ts.map +1 -1
  8. package/dist/exec/runCommand.js +120 -0
  9. package/dist/exec/runCommand.js.map +1 -0
  10. package/dist/fs/deletePath.d.ts +2 -2
  11. package/dist/fs/deletePath.d.ts.map +1 -1
  12. package/dist/fs/deletePath.js +63 -0
  13. package/dist/fs/deletePath.js.map +1 -0
  14. package/dist/fs/listDir.d.ts +2 -2
  15. package/dist/fs/listDir.d.ts.map +1 -1
  16. package/dist/fs/listDir.js +105 -0
  17. package/dist/fs/listDir.js.map +1 -0
  18. package/dist/fs/readText.d.ts +2 -2
  19. package/dist/fs/readText.d.ts.map +1 -1
  20. package/dist/fs/readText.js +40 -0
  21. package/dist/fs/readText.js.map +1 -0
  22. package/dist/fs/searchText.d.ts +2 -2
  23. package/dist/fs/searchText.d.ts.map +1 -1
  24. package/dist/fs/searchText.js +152 -0
  25. package/dist/fs/searchText.js.map +1 -0
  26. package/dist/fs/sha256.d.ts +2 -2
  27. package/dist/fs/sha256.d.ts.map +1 -1
  28. package/dist/fs/sha256.js +43 -0
  29. package/dist/fs/sha256.js.map +1 -0
  30. package/dist/fs/writeText.d.ts +2 -2
  31. package/dist/fs/writeText.d.ts.map +1 -1
  32. package/dist/fs/writeText.js +62 -0
  33. package/dist/fs/writeText.js.map +1 -0
  34. package/dist/http/defaults.d.ts +10 -0
  35. package/dist/http/defaults.d.ts.map +1 -0
  36. package/dist/http/defaults.js +19 -0
  37. package/dist/http/defaults.js.map +1 -0
  38. package/dist/http/downloadFile.d.ts +2 -2
  39. package/dist/http/downloadFile.d.ts.map +1 -1
  40. package/dist/http/downloadFile.js +127 -0
  41. package/dist/http/downloadFile.js.map +1 -0
  42. package/dist/http/duckduckgoSearch.d.ts +2 -2
  43. package/dist/http/duckduckgoSearch.d.ts.map +1 -1
  44. package/dist/http/duckduckgoSearch.js +100 -0
  45. package/dist/http/duckduckgoSearch.js.map +1 -0
  46. package/dist/http/fetchJson.d.ts +2 -2
  47. package/dist/http/fetchJson.d.ts.map +1 -1
  48. package/dist/http/fetchJson.js +86 -0
  49. package/dist/http/fetchJson.js.map +1 -0
  50. package/dist/http/fetchPageMainContent.d.ts +2 -2
  51. package/dist/http/fetchPageMainContent.d.ts.map +1 -1
  52. package/dist/http/fetchPageMainContent.js +135 -0
  53. package/dist/http/fetchPageMainContent.js.map +1 -0
  54. package/dist/http/fetchText.d.ts +2 -2
  55. package/dist/http/fetchText.d.ts.map +1 -1
  56. package/dist/http/fetchText.js +105 -0
  57. package/dist/http/fetchText.js.map +1 -0
  58. package/dist/http/fetchText.tool.yaml +6 -0
  59. package/dist/http/head.d.ts +2 -2
  60. package/dist/http/head.d.ts.map +1 -1
  61. package/dist/http/head.js +66 -0
  62. package/dist/http/head.js.map +1 -0
  63. package/dist/http/yahooFinance.d.ts +2 -2
  64. package/dist/http/yahooFinance.d.ts.map +1 -1
  65. package/dist/http/yahooFinance.js +117 -0
  66. package/dist/http/yahooFinance.js.map +1 -0
  67. package/dist/index.d.ts +10 -13
  68. package/dist/index.d.ts.map +1 -1
  69. package/dist/index.js +10 -1967
  70. package/dist/index.js.map +1 -1
  71. package/dist/util/hashText.d.ts +2 -2
  72. package/dist/util/hashText.d.ts.map +1 -1
  73. package/dist/util/hashText.js +22 -0
  74. package/dist/util/hashText.js.map +1 -0
  75. package/dist/util/jsonSelect.d.ts +2 -2
  76. package/dist/util/jsonSelect.d.ts.map +1 -1
  77. package/dist/util/jsonSelect.js +38 -0
  78. package/dist/util/jsonSelect.js.map +1 -0
  79. package/dist/util/now.d.ts +2 -2
  80. package/dist/util/now.d.ts.map +1 -1
  81. package/dist/util/now.js +43 -0
  82. package/dist/util/now.js.map +1 -0
  83. package/dist/util/templateRender.d.ts +2 -2
  84. package/dist/util/templateRender.d.ts.map +1 -1
  85. package/dist/util/templateRender.js +37 -0
  86. package/dist/util/templateRender.js.map +1 -0
  87. package/dist/util/truncate.d.ts +2 -2
  88. package/dist/util/truncate.d.ts.map +1 -1
  89. package/dist/util/truncate.js +37 -0
  90. package/dist/util/truncate.js.map +1 -0
  91. package/package.json +6 -7
  92. package/README.md +0 -64
  93. package/dist/CoreAdapter.d.ts +0 -37
  94. package/dist/CoreAdapter.d.ts.map +0 -1
  95. package/dist/CoreToolsModule.d.ts +0 -49
  96. package/dist/CoreToolsModule.d.ts.map +0 -1
  97. package/dist/chunk-BUSYA2B4.js +0 -9
  98. package/dist/chunk-BUSYA2B4.js.map +0 -1
  99. package/dist/context.d.ts +0 -9
  100. package/dist/context.d.ts.map +0 -1
  101. package/dist/index.cjs +0 -4018
  102. package/dist/index.cjs.map +0 -1
  103. package/dist/jmespath-6W7SK7AH.js +0 -1514
  104. package/dist/jmespath-6W7SK7AH.js.map +0 -1
  105. package/dist/mustache-CS7KHA4H.js +0 -467
  106. package/dist/mustache-CS7KHA4H.js.map +0 -1
  107. package/dist/security/sandbox.d.ts +0 -9
  108. package/dist/security/sandbox.d.ts.map +0 -1
  109. package/dist/security/ssrf.d.ts +0 -12
  110. package/dist/security/ssrf.d.ts.map +0 -1
  111. package/dist/types.d.ts +0 -55
  112. package/dist/types.d.ts.map +0 -1
  113. package/dist/vitest.config.d.ts +0 -3
  114. package/dist/vitest.config.d.ts.map +0 -1
@@ -0,0 +1,4 @@
1
+ {
2
+ "kind": "core",
3
+ "tools": []
4
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Exec tool defaults (allowed commands, max output bytes, timeout).
3
+ * Used by runCommand.
4
+ */
5
+ export declare const DEFAULT_ALLOWED_COMMANDS: string[];
6
+ export declare const DEFAULT_MAX_COMMAND_OUTPUT_BYTES: number;
7
+ export declare const DEFAULT_COMMAND_TIMEOUT_MS = 10000;
8
+ //# sourceMappingURL=defaults.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"defaults.d.ts","sourceRoot":"","sources":["../../exec/defaults.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,eAAO,MAAM,wBAAwB,UAYpC,CAAC;AAEF,eAAO,MAAM,gCAAgC,QAAc,CAAC;AAC5D,eAAO,MAAM,0BAA0B,QAAS,CAAC"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Exec tool defaults (allowed commands, max output bytes, timeout).
3
+ * Used by runCommand.
4
+ */
5
+ export const DEFAULT_ALLOWED_COMMANDS = [
6
+ "cat",
7
+ "echo",
8
+ "env",
9
+ "find",
10
+ "grep",
11
+ "head",
12
+ "ls",
13
+ "pwd",
14
+ "tail",
15
+ "wc",
16
+ "whoami",
17
+ ];
18
+ export const DEFAULT_MAX_COMMAND_OUTPUT_BYTES = 1024 * 1024;
19
+ export const DEFAULT_COMMAND_TIMEOUT_MS = 10_000;
20
+ //# sourceMappingURL=defaults.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"defaults.js","sourceRoot":"","sources":["../../exec/defaults.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG;IACtC,KAAK;IACL,MAAM;IACN,KAAK;IACL,MAAM;IACN,MAAM;IACN,MAAM;IACN,IAAI;IACJ,KAAK;IACL,MAAM;IACN,IAAI;IACJ,QAAQ;CACT,CAAC;AAEF,MAAM,CAAC,MAAM,gCAAgC,GAAG,IAAI,GAAG,IAAI,CAAC;AAC5D,MAAM,CAAC,MAAM,0BAA0B,GAAG,MAAM,CAAC"}
@@ -1,9 +1,9 @@
1
- import type { CoreToolHandler } from "../types.js";
1
+ import type { ExtensionToolHandler } from "@easynet/agent-tool";
2
2
  /**
3
3
  * Run a Linux command in the sandbox with an allowlist and timeout.
4
4
  * Uses spawn (no shell) to avoid injection; command and args are separate.
5
5
  * @tool
6
6
  * @effect local_write
7
7
  */
8
- export declare const runCommandHandler: CoreToolHandler;
8
+ export declare const runCommandHandler: ExtensionToolHandler;
9
9
  //# sourceMappingURL=runCommand.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"runCommand.d.ts","sourceRoot":"","sources":["../../exec/runCommand.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAKnD;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,EA2IxB,eAAe,CAAC"}
1
+ {"version":3,"file":"runCommand.d.ts","sourceRoot":"","sources":["../../exec/runCommand.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAUhE;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,EAqJxB,oBAAoB,CAAC"}
@@ -0,0 +1,120 @@
1
+ import { spawn } from "node:child_process";
2
+ import { resolve as pathResolve } from "node:path";
3
+ import { getBuiltinContext } from "../index.js";
4
+ import { DEFAULT_ALLOWED_COMMANDS, DEFAULT_MAX_COMMAND_OUTPUT_BYTES, DEFAULT_COMMAND_TIMEOUT_MS, } from "./defaults.js";
5
+ import { resolveSandboxedPath } from "@easynet/agent-tool";
6
+ import { createTaggedError } from "@easynet/agent-tool";
7
+ /**
8
+ * Run a Linux command in the sandbox with an allowlist and timeout.
9
+ * Uses spawn (no shell) to avoid injection; command and args are separate.
10
+ * @tool
11
+ * @effect local_write
12
+ */
13
+ export const runCommandHandler = (async (args) => {
14
+ const ctx = getBuiltinContext();
15
+ const a = args;
16
+ const allowedCommands = (Array.isArray(a.allowedCommands) ? a.allowedCommands : undefined) ??
17
+ DEFAULT_ALLOWED_COMMANDS;
18
+ const maxCommandOutputBytes = (typeof a.maxCommandOutputBytes === "number" ? a.maxCommandOutputBytes : undefined) ??
19
+ DEFAULT_MAX_COMMAND_OUTPUT_BYTES;
20
+ const commandTimeoutMs = (typeof a.commandTimeoutMs === "number" ? a.commandTimeoutMs : undefined) ??
21
+ DEFAULT_COMMAND_TIMEOUT_MS;
22
+ if (!allowedCommands.length) {
23
+ throw createTaggedError("EXEC_DISABLED", "Exec is disabled: allowedCommands is empty", {});
24
+ }
25
+ const rawCommand = (args.command ?? args.cmd)?.trim();
26
+ if (!rawCommand) {
27
+ throw createTaggedError("EXEC_INVALID", "command is required (pass 'command' or 'cmd')", {});
28
+ }
29
+ // Only allow bare command name (no path, no shell metacharacters)
30
+ const baseName = rawCommand.replace(/^.*\//, "").trim();
31
+ if (baseName !== rawCommand || /[;&|$`\s]/.test(rawCommand)) {
32
+ throw createTaggedError("EXEC_INVALID", "command must be a single executable name (no path, no shell chars)", { command: rawCommand });
33
+ }
34
+ if (!allowedCommands.includes(baseName)) {
35
+ throw createTaggedError("EXEC_NOT_ALLOWED", `Command "${baseName}" is not in allowedCommands`, { command: baseName, allowed: allowedCommands });
36
+ }
37
+ const cmdArgs = Array.isArray(args.args)
38
+ ? args.args
39
+ : Array.isArray(args.arguments)
40
+ ? args.arguments
41
+ : [];
42
+ const timeoutMs = args.timeoutMs ?? commandTimeoutMs;
43
+ const sandboxRoot = ctx.config.sandboxRoot ?? "";
44
+ let cwd = pathResolve(sandboxRoot);
45
+ if (args.cwd != null && args.cwd !== "") {
46
+ cwd = await resolveSandboxedPath(args.cwd, sandboxRoot);
47
+ }
48
+ return new Promise((resolvePromise, rejectPromise) => {
49
+ const proc = spawn(baseName, cmdArgs, {
50
+ cwd,
51
+ shell: false,
52
+ stdio: ["ignore", "pipe", "pipe"],
53
+ env: { ...process.env },
54
+ });
55
+ let stdout = "";
56
+ let stderr = "";
57
+ let totalBytes = 0;
58
+ const append = (chunk, dest) => {
59
+ const len = Buffer.byteLength(chunk, "utf-8");
60
+ if (totalBytes + len > maxCommandOutputBytes) {
61
+ proc.kill("SIGKILL");
62
+ rejectPromise(createTaggedError("EXEC_OUTPUT_TOO_LARGE", `Command output exceeded ${maxCommandOutputBytes} bytes`, { maxBytes: maxCommandOutputBytes }));
63
+ return;
64
+ }
65
+ totalBytes += len;
66
+ if (dest === "stdout")
67
+ stdout += chunk;
68
+ else
69
+ stderr += chunk;
70
+ };
71
+ proc.stdout?.setEncoding("utf-8");
72
+ proc.stderr?.setEncoding("utf-8");
73
+ proc.stdout?.on("data", (chunk) => append(chunk, "stdout"));
74
+ proc.stderr?.on("data", (chunk) => append(chunk, "stderr"));
75
+ const timeout = setTimeout(() => {
76
+ proc.kill("SIGKILL");
77
+ resolvePromise({
78
+ result: {
79
+ stdout,
80
+ stderr,
81
+ exitCode: null,
82
+ timedOut: true,
83
+ signal: "SIGKILL",
84
+ },
85
+ evidence: [
86
+ {
87
+ type: "exec",
88
+ summary: `Command "${baseName}" timed out after ${timeoutMs}ms`,
89
+ createdAt: new Date().toISOString(),
90
+ },
91
+ ],
92
+ });
93
+ }, timeoutMs);
94
+ proc.on("error", (err) => {
95
+ clearTimeout(timeout);
96
+ rejectPromise(createTaggedError("EXEC_SPAWN_ERROR", err.message, { command: baseName }));
97
+ });
98
+ proc.on("close", (code, signal) => {
99
+ clearTimeout(timeout);
100
+ resolvePromise({
101
+ result: {
102
+ stdout,
103
+ stderr,
104
+ exitCode: code,
105
+ timedOut: false,
106
+ signal: signal ?? undefined,
107
+ },
108
+ evidence: [
109
+ {
110
+ type: "exec",
111
+ ref: baseName,
112
+ summary: `Ran ${baseName} (exit ${code ?? signal})`,
113
+ createdAt: new Date().toISOString(),
114
+ },
115
+ ],
116
+ });
117
+ });
118
+ });
119
+ });
120
+ //# sourceMappingURL=runCommand.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runCommand.js","sourceRoot":"","sources":["../../exec/runCommand.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,8 @@
1
- import type { CoreToolHandler } from "../types.js";
1
+ import type { ExtensionToolHandler } from "@easynet/agent-tool";
2
2
  /**
3
3
  * Delete a file or directory in the sandbox (dangerous, requires explicit confirmation).
4
4
  * @tool
5
5
  * @effect destructive
6
6
  */
7
- export declare const deletePathHandler: CoreToolHandler;
7
+ export declare const deletePathHandler: ExtensionToolHandler;
8
8
  //# sourceMappingURL=deletePath.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"deletePath.d.ts","sourceRoot":"","sources":["../../fs/deletePath.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAInD;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,EA+DxB,eAAe,CAAC"}
1
+ {"version":3,"file":"deletePath.d.ts","sourceRoot":"","sources":["../../fs/deletePath.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAIhE;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,EAgExB,oBAAoB,CAAC"}
@@ -0,0 +1,63 @@
1
+ import { rm, unlink, rmdir, stat } from "node:fs/promises";
2
+ import { getBuiltinContext } from "../index.js";
3
+ import { resolveSandboxedPath } from "@easynet/agent-tool";
4
+ /**
5
+ * Delete a file or directory in the sandbox (dangerous, requires explicit confirmation).
6
+ * @tool
7
+ * @effect destructive
8
+ */
9
+ export const deletePathHandler = (async (args) => {
10
+ const ctx = getBuiltinContext();
11
+ const inputPath = (args.path ?? args.filePath)?.trim();
12
+ if (!inputPath) {
13
+ throw new Error("path is required (pass 'path' or 'filePath')");
14
+ }
15
+ const recursive = args.recursive ?? false;
16
+ const confirm = args.confirm;
17
+ if (!confirm) {
18
+ throw new Error("Deletion not confirmed. Set confirm=true to proceed with deletion.");
19
+ }
20
+ const sandboxRoot = ctx.config.sandboxRoot ?? "";
21
+ const resolvedPath = await resolveSandboxedPath(inputPath, sandboxRoot);
22
+ // Prevent deleting the sandbox root itself (compare resolved paths)
23
+ let realSandboxRoot;
24
+ try {
25
+ const { realpath: rp } = await import("node:fs/promises");
26
+ realSandboxRoot = await rp(sandboxRoot);
27
+ }
28
+ catch {
29
+ realSandboxRoot = sandboxRoot;
30
+ }
31
+ if (resolvedPath === realSandboxRoot) {
32
+ throw new Error("Cannot delete the sandbox root directory.");
33
+ }
34
+ const fileStat = await stat(resolvedPath);
35
+ const isDirectory = fileStat.isDirectory();
36
+ if (isDirectory) {
37
+ if (recursive) {
38
+ await rm(resolvedPath, { recursive: true, force: true });
39
+ }
40
+ else {
41
+ await rmdir(resolvedPath);
42
+ }
43
+ }
44
+ else {
45
+ await unlink(resolvedPath);
46
+ }
47
+ return {
48
+ result: {
49
+ path: resolvedPath,
50
+ deleted: true,
51
+ type: isDirectory ? "directory" : "file",
52
+ },
53
+ evidence: [
54
+ {
55
+ type: "file",
56
+ ref: resolvedPath,
57
+ summary: `Deleted ${isDirectory ? "directory" : "file"}: ${resolvedPath}${recursive ? " (recursive)" : ""}`,
58
+ createdAt: new Date().toISOString(),
59
+ },
60
+ ],
61
+ };
62
+ });
63
+ //# sourceMappingURL=deletePath.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deletePath.js","sourceRoot":"","sources":["../../fs/deletePath.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAE3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAE3D;;;;GAIG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,KAAK,EAAE,IAMxC,EAAE,EAAE;IACH,MAAM,GAAG,GAAG,iBAAiB,EAAE,CAAC;IAChC,MAAM,SAAS,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,CAAC;IACvD,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;IAClE,CAAC;IACD,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,KAAK,CAAC;IAC1C,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;IAE7B,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CACb,oEAAoE,CACrE,CAAC;IACJ,CAAC;IAED,MAAM,WAAW,GAAI,GAAG,CAAC,MAAmC,CAAC,WAAW,IAAI,EAAE,CAAC;IAC/E,MAAM,YAAY,GAAG,MAAM,oBAAoB,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;IAExE,oEAAoE;IACpE,IAAI,eAAuB,CAAC;IAC5B,IAAI,CAAC;QACH,MAAM,EAAE,QAAQ,EAAE,EAAE,EAAE,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAC;QAC1D,eAAe,GAAG,MAAM,EAAE,CAAC,WAAW,CAAC,CAAC;IAC1C,CAAC;IAAC,MAAM,CAAC;QACP,eAAe,GAAG,WAAW,CAAC;IAChC,CAAC;IACD,IAAI,YAAY,KAAK,eAAe,EAAE,CAAC;QACrC,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;IAC/D,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,CAAC;IAC1C,MAAM,WAAW,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;IAE3C,IAAI,WAAW,EAAE,CAAC;QAChB,IAAI,SAAS,EAAE,CAAC;YACd,MAAM,EAAE,CAAC,YAAY,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAC3D,CAAC;aAAM,CAAC;YACN,MAAM,KAAK,CAAC,YAAY,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC;SAAM,CAAC;QACN,MAAM,MAAM,CAAC,YAAY,CAAC,CAAC;IAC7B,CAAC;IAED,OAAO;QACL,MAAM,EAAE;YACN,IAAI,EAAE,YAAY;YAClB,OAAO,EAAE,IAAI;YACb,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM;SACzC;QACD,QAAQ,EAAE;YACR;gBACE,IAAI,EAAE,MAAM;gBACZ,GAAG,EAAE,YAAY;gBACjB,OAAO,EAAE,WAAW,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,KAAK,YAAY,GAAG,SAAS,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,EAAE;gBAC3G,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;aACpC;SACF;KACF,CAAC;AACJ,CAAC,CAAyB,CAAC"}
@@ -1,8 +1,8 @@
1
- import type { CoreToolHandler } from "../types.js";
1
+ import type { ExtensionToolHandler } from "@easynet/agent-tool";
2
2
  /**
3
3
  * List directory contents in the sandbox.
4
4
  * @tool
5
5
  * @effect none
6
6
  */
7
- export declare const listDirHandler: CoreToolHandler;
7
+ export declare const listDirHandler: ExtensionToolHandler;
8
8
  //# sourceMappingURL=listDir.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"listDir.d.ts","sourceRoot":"","sources":["../../fs/listDir.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAWnD;;;;GAIG;AACH,eAAO,MAAM,cAAc,EAmDrB,eAAe,CAAC"}
1
+ {"version":3,"file":"listDir.d.ts","sourceRoot":"","sources":["../../fs/listDir.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAWhE;;;;GAIG;AACH,eAAO,MAAM,cAAc,EAmDrB,oBAAoB,CAAC"}
@@ -0,0 +1,105 @@
1
+ import { readdir, stat } from "node:fs/promises";
2
+ import { resolve, join } from "node:path";
3
+ import { getBuiltinContext } from "../index.js";
4
+ import { resolveSandboxedPath } from "@easynet/agent-tool";
5
+ /**
6
+ * List directory contents in the sandbox.
7
+ * @tool
8
+ * @effect none
9
+ */
10
+ export const listDirHandler = (async (args) => {
11
+ const ctx = getBuiltinContext();
12
+ const inputPath = (args.path ?? args.filePath ?? args.dir ?? args.directory)?.trim();
13
+ if (!inputPath) {
14
+ throw new Error("path is required (pass 'path', 'filePath', 'dir', or 'directory')");
15
+ }
16
+ const maxEntries = args.maxEntries ?? 2000;
17
+ const includeHidden = args.includeHidden ?? false;
18
+ const recursive = args.recursive ?? false;
19
+ const maxDepth = args.maxDepth ?? 5;
20
+ const resolvedPath = await resolveSandboxedPath(inputPath, ctx.config.sandboxRoot ?? "");
21
+ const entries = [];
22
+ let truncated = false;
23
+ await walkDir(resolvedPath, "", entries, {
24
+ maxEntries,
25
+ includeHidden,
26
+ recursive,
27
+ maxDepth,
28
+ currentDepth: 0,
29
+ onTruncate: () => { truncated = true; },
30
+ });
31
+ return {
32
+ result: {
33
+ path: resolvedPath,
34
+ entries,
35
+ totalEntries: entries.length,
36
+ truncated,
37
+ },
38
+ evidence: [
39
+ {
40
+ type: "tool",
41
+ ref: `core/fs.listDir:${resolvedPath}`,
42
+ summary: `Listed ${entries.length} entries in ${resolvedPath}${truncated ? " (truncated)" : ""}`,
43
+ createdAt: new Date().toISOString(),
44
+ },
45
+ ],
46
+ };
47
+ });
48
+ async function walkDir(basePath, relativePath, entries, options) {
49
+ if (entries.length >= options.maxEntries) {
50
+ options.onTruncate();
51
+ return;
52
+ }
53
+ const fullPath = relativePath ? resolve(basePath, relativePath) : basePath;
54
+ const dirEntries = await readdir(fullPath, { withFileTypes: true });
55
+ for (const dirent of dirEntries) {
56
+ if (entries.length >= options.maxEntries) {
57
+ options.onTruncate();
58
+ return;
59
+ }
60
+ if (!options.includeHidden && dirent.name.startsWith(".")) {
61
+ continue;
62
+ }
63
+ const entryPath = join(fullPath, dirent.name);
64
+ const entryRelative = relativePath ? join(relativePath, dirent.name) : dirent.name;
65
+ let entryType;
66
+ if (dirent.isSymbolicLink()) {
67
+ entryType = "symlink";
68
+ }
69
+ else if (dirent.isDirectory()) {
70
+ entryType = "directory";
71
+ }
72
+ else if (dirent.isFile()) {
73
+ entryType = "file";
74
+ }
75
+ else {
76
+ entryType = "other";
77
+ }
78
+ let size = 0;
79
+ let mtime = "";
80
+ try {
81
+ const entryStat = await stat(entryPath);
82
+ size = entryStat.size;
83
+ mtime = entryStat.mtime.toISOString();
84
+ }
85
+ catch {
86
+ // Best effort stat
87
+ }
88
+ entries.push({
89
+ name: entryRelative,
90
+ type: entryType,
91
+ size,
92
+ mtime,
93
+ });
94
+ // Recurse into directories
95
+ if (options.recursive &&
96
+ entryType === "directory" &&
97
+ options.currentDepth < options.maxDepth) {
98
+ await walkDir(basePath, entryRelative, entries, {
99
+ ...options,
100
+ currentDepth: options.currentDepth + 1,
101
+ });
102
+ }
103
+ }
104
+ }
105
+ //# sourceMappingURL=listDir.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"listDir.js","sourceRoot":"","sources":["../../fs/listDir.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,8 @@
1
- import type { CoreToolHandler } from "../types.js";
1
+ import type { ExtensionToolHandler } from "@easynet/agent-tool";
2
2
  /**
3
3
  * Read a UTF-8 text file from the sandbox.
4
4
  * @tool
5
5
  * @effect none
6
6
  */
7
- export declare const readTextHandler: CoreToolHandler;
7
+ export declare const readTextHandler: ExtensionToolHandler;
8
8
  //# sourceMappingURL=readText.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"readText.d.ts","sourceRoot":"","sources":["../../fs/readText.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAKnD;;;;GAIG;AACH,eAAO,MAAM,eAAe,EAyCtB,eAAe,CAAC"}
1
+ {"version":3,"file":"readText.d.ts","sourceRoot":"","sources":["../../fs/readText.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAOhE;;;;GAIG;AACH,eAAO,MAAM,eAAe,EAyCtB,oBAAoB,CAAC"}
@@ -0,0 +1,40 @@
1
+ import { readFile, stat } from "node:fs/promises";
2
+ import { getBuiltinContext } from "../index.js";
3
+ import { resolveSandboxedPath } from "@easynet/agent-tool";
4
+ import { createTaggedError } from "@easynet/agent-tool";
5
+ const DEFAULT_MAX_READ_BYTES = 5 * 1024 * 1024;
6
+ /**
7
+ * Read a UTF-8 text file from the sandbox.
8
+ * @tool
9
+ * @effect none
10
+ */
11
+ export const readTextHandler = (async (args) => {
12
+ const ctx = getBuiltinContext();
13
+ const inputPath = (args.path ?? args.filePath)?.trim();
14
+ if (!inputPath) {
15
+ throw createTaggedError("FS_INVALID", "path is required (pass 'path' or 'filePath')", {});
16
+ }
17
+ const maxBytes = args.maxBytes ?? DEFAULT_MAX_READ_BYTES;
18
+ const resolvedPath = await resolveSandboxedPath(inputPath, ctx.config.sandboxRoot ?? "");
19
+ const fileStat = await stat(resolvedPath);
20
+ if (fileStat.size > maxBytes) {
21
+ throw createTaggedError("FILE_TOO_LARGE", `File size ${fileStat.size} bytes exceeds limit of ${maxBytes} bytes`, { path: resolvedPath, size: fileStat.size, limit: maxBytes });
22
+ }
23
+ const text = await readFile(resolvedPath, "utf-8");
24
+ return {
25
+ result: {
26
+ path: resolvedPath,
27
+ text,
28
+ bytes: fileStat.size,
29
+ },
30
+ evidence: [
31
+ {
32
+ type: "file",
33
+ ref: resolvedPath,
34
+ summary: `Read ${fileStat.size} bytes from ${resolvedPath}`,
35
+ createdAt: new Date().toISOString(),
36
+ },
37
+ ],
38
+ };
39
+ });
40
+ //# sourceMappingURL=readText.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"readText.js","sourceRoot":"","sources":["../../fs/readText.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAElD,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAExD,MAAM,sBAAsB,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC;AAE/C;;;;GAIG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,KAAK,EAAE,IAKtC,EAAE,EAAE;IACH,MAAM,GAAG,GAAG,iBAAiB,EAAE,CAAC;IAChC,MAAM,SAAS,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,CAAC;IACvD,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,MAAM,iBAAiB,CAAC,YAAY,EAAE,8CAA8C,EAAE,EAAE,CAAC,CAAC;IAC5F,CAAC;IACD,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,sBAAsB,CAAC;IAEzD,MAAM,YAAY,GAAG,MAAM,oBAAoB,CAAC,SAAS,EAAG,GAAG,CAAC,MAAmC,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC;IAEvH,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,CAAC;IAC1C,IAAI,QAAQ,CAAC,IAAI,GAAG,QAAQ,EAAE,CAAC;QAC7B,MAAM,iBAAiB,CACrB,gBAAgB,EAChB,aAAa,QAAQ,CAAC,IAAI,2BAA2B,QAAQ,QAAQ,EACrE,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,CAC7D,CAAC;IACJ,CAAC;IAED,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IAEnD,OAAO;QACL,MAAM,EAAE;YACN,IAAI,EAAE,YAAY;YAClB,IAAI;YACJ,KAAK,EAAE,QAAQ,CAAC,IAAI;SACrB;QACD,QAAQ,EAAE;YACR;gBACE,IAAI,EAAE,MAAM;gBACZ,GAAG,EAAE,YAAY;gBACjB,OAAO,EAAE,QAAQ,QAAQ,CAAC,IAAI,eAAe,YAAY,EAAE;gBAC3D,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;aACpC;SACF;KACF,CAAC;AACJ,CAAC,CAAyB,CAAC"}
@@ -1,8 +1,8 @@
1
- import type { CoreToolHandler } from "../types.js";
1
+ import type { ExtensionToolHandler } from "@easynet/agent-tool";
2
2
  /**
3
3
  * Search for text patterns in files within the sandbox.
4
4
  * @tool
5
5
  * @effect none
6
6
  */
7
- export declare const searchTextHandler: CoreToolHandler;
7
+ export declare const searchTextHandler: ExtensionToolHandler;
8
8
  //# sourceMappingURL=searchText.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"searchText.d.ts","sourceRoot":"","sources":["../../fs/searchText.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAUnD;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,EAgFxB,eAAe,CAAC"}
1
+ {"version":3,"file":"searchText.d.ts","sourceRoot":"","sources":["../../fs/searchText.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAUhE;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,EAgFxB,oBAAoB,CAAC"}
@@ -0,0 +1,152 @@
1
+ import { readdir, stat } from "node:fs/promises";
2
+ import { createReadStream } from "node:fs";
3
+ import { createInterface } from "node:readline";
4
+ import { join, relative } from "node:path";
5
+ import { getBuiltinContext } from "../index.js";
6
+ import { resolveSandboxedPath } from "@easynet/agent-tool";
7
+ /**
8
+ * Search for text patterns in files within the sandbox.
9
+ * @tool
10
+ * @effect none
11
+ */
12
+ export const searchTextHandler = (async (args) => {
13
+ const ctx = getBuiltinContext();
14
+ const rootPath = (args.root ?? args.path ?? args.dir ?? args.directory)?.trim();
15
+ if (!rootPath) {
16
+ throw new Error("root is required (pass 'root', 'path', 'dir', or 'directory')");
17
+ }
18
+ const query = (args.query ?? args.q)?.trim();
19
+ if (!query) {
20
+ throw new Error("query is required (pass 'query' or 'q')");
21
+ }
22
+ const glob = args.glob ?? "**/*.{md,txt,log,json,ts,js,py,java,scala}";
23
+ const maxMatches = args.maxMatches ?? 100;
24
+ const maxFiles = args.maxFiles ?? 500;
25
+ const resolvedRoot = await resolveSandboxedPath(rootPath, ctx.config.sandboxRoot ?? "");
26
+ // Build regex from query
27
+ let regex;
28
+ try {
29
+ regex = new RegExp(query, "i");
30
+ }
31
+ catch {
32
+ // If not a valid regex, escape and use as literal
33
+ regex = new RegExp(escapeRegExp(query), "i");
34
+ }
35
+ // Collect matching file extensions from glob
36
+ const extensions = parseGlobExtensions(glob);
37
+ // Walk directory and collect files
38
+ const files = [];
39
+ await collectFiles(resolvedRoot, files, { maxFiles, extensions });
40
+ // Search through files
41
+ const matches = [];
42
+ let filesScanned = 0;
43
+ let truncated = false;
44
+ for (const filePath of files) {
45
+ if (matches.length >= maxMatches) {
46
+ truncated = true;
47
+ break;
48
+ }
49
+ filesScanned++;
50
+ await searchFile(filePath, resolvedRoot, regex, matches, maxMatches);
51
+ }
52
+ if (matches.length >= maxMatches) {
53
+ truncated = true;
54
+ }
55
+ return {
56
+ result: {
57
+ root: resolvedRoot,
58
+ query,
59
+ matches,
60
+ totalMatches: matches.length,
61
+ filesScanned,
62
+ truncated,
63
+ },
64
+ evidence: [
65
+ {
66
+ type: "tool",
67
+ ref: `core/fs.searchText:${resolvedRoot}`,
68
+ summary: `Found ${matches.length} matches in ${filesScanned} files under ${resolvedRoot}${truncated ? " (truncated)" : ""}`,
69
+ createdAt: new Date().toISOString(),
70
+ },
71
+ ],
72
+ };
73
+ });
74
+ async function collectFiles(dirPath, files, options) {
75
+ if (files.length >= options.maxFiles)
76
+ return;
77
+ let entries;
78
+ try {
79
+ entries = await readdir(dirPath, { withFileTypes: true });
80
+ }
81
+ catch {
82
+ return;
83
+ }
84
+ for (const entry of entries) {
85
+ if (files.length >= options.maxFiles)
86
+ return;
87
+ const fullPath = join(dirPath, entry.name);
88
+ if (entry.isDirectory()) {
89
+ if (entry.name.startsWith(".") || entry.name === "node_modules")
90
+ continue;
91
+ await collectFiles(fullPath, files, options);
92
+ }
93
+ else if (entry.isFile()) {
94
+ if (options.extensions.size > 0) {
95
+ const ext = getExtension(entry.name);
96
+ if (!ext || !options.extensions.has(ext))
97
+ continue;
98
+ }
99
+ files.push(fullPath);
100
+ }
101
+ }
102
+ }
103
+ async function searchFile(filePath, root, regex, matches, maxMatches) {
104
+ const fileStat = await stat(filePath).catch(() => null);
105
+ // Skip large files (>1MB)
106
+ if (!fileStat || fileStat.size > 1024 * 1024)
107
+ return;
108
+ const stream = createReadStream(filePath, { encoding: "utf-8" });
109
+ const rl = createInterface({ input: stream, crlfDelay: Infinity });
110
+ let lineNo = 0;
111
+ for await (const line of rl) {
112
+ lineNo++;
113
+ if (matches.length >= maxMatches) {
114
+ stream.destroy();
115
+ break;
116
+ }
117
+ if (regex.test(line)) {
118
+ matches.push({
119
+ file: relative(root, filePath),
120
+ lineNo,
121
+ excerpt: line.slice(0, 200),
122
+ });
123
+ }
124
+ }
125
+ }
126
+ function parseGlobExtensions(glob) {
127
+ const extensions = new Set();
128
+ // Match patterns like *.{ts,js,py} or *.ts
129
+ const braceMatch = glob.match(/\*\.\{([^}]+)\}/);
130
+ if (braceMatch) {
131
+ for (const ext of braceMatch[1].split(",")) {
132
+ extensions.add(ext.trim());
133
+ }
134
+ }
135
+ else {
136
+ const simpleMatch = glob.match(/\*\.(\w+)/);
137
+ if (simpleMatch) {
138
+ extensions.add(simpleMatch[1]);
139
+ }
140
+ }
141
+ return extensions;
142
+ }
143
+ function getExtension(filename) {
144
+ const dotIdx = filename.lastIndexOf(".");
145
+ if (dotIdx === -1 || dotIdx === 0)
146
+ return null;
147
+ return filename.slice(dotIdx + 1);
148
+ }
149
+ function escapeRegExp(str) {
150
+ return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
151
+ }
152
+ //# sourceMappingURL=searchText.js.map