bash-tool 0.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/LICENSE +21 -0
- package/README.md +112 -0
- package/dist/files/loader.d.ts +14 -0
- package/dist/files/loader.d.ts.map +1 -0
- package/dist/files/loader.js +35 -0
- package/dist/files/loader.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/sandbox/just-bash.d.ts +24 -0
- package/dist/sandbox/just-bash.d.ts.map +1 -0
- package/dist/sandbox/just-bash.js +93 -0
- package/dist/sandbox/just-bash.js.map +1 -0
- package/dist/sandbox/vercel.d.ts +33 -0
- package/dist/sandbox/vercel.d.ts.map +1 -0
- package/dist/sandbox/vercel.js +55 -0
- package/dist/sandbox/vercel.js.map +1 -0
- package/dist/tool.d.ts +29 -0
- package/dist/tool.d.ts.map +1 -0
- package/dist/tool.js +95 -0
- package/dist/tool.js.map +1 -0
- package/dist/tools/bash.d.ts +23 -0
- package/dist/tools/bash.d.ts.map +1 -0
- package/dist/tools/bash.js +50 -0
- package/dist/tools/bash.js.map +1 -0
- package/dist/tools/read-file.d.ts +22 -0
- package/dist/tools/read-file.d.ts.map +1 -0
- package/dist/tools/read-file.js +18 -0
- package/dist/tools/read-file.js.map +1 -0
- package/dist/tools/write-file.d.ts +26 -0
- package/dist/tools/write-file.d.ts.map +1 -0
- package/dist/tools/write-file.js +19 -0
- package/dist/tools/write-file.js.map +1 -0
- package/dist/types.d.ts +83 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +82 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Vercel, Inc.
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# bash-tool
|
|
2
|
+
|
|
3
|
+
Generic bash tool for AI agents, compatible with [AI SDK](https://ai-sdk.dev/).
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install bash-tool just-bash
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
For full VM support, install `@vercel/sandbox` or another sandbox product instead of `just-bash`.
|
|
12
|
+
|
|
13
|
+
## Usage
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
import { createBashTool } from "bash-tool";
|
|
17
|
+
import { generateText } from "ai";
|
|
18
|
+
|
|
19
|
+
const { bash, tools } = await createBashTool({
|
|
20
|
+
files: {
|
|
21
|
+
"src/index.ts": "export const hello = 'world';",
|
|
22
|
+
"package.json": '{"name": "my-project"}',
|
|
23
|
+
},
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
// Use just the bash tool
|
|
27
|
+
const result = await generateText({
|
|
28
|
+
model: yourModel,
|
|
29
|
+
tools: { bash },
|
|
30
|
+
prompt: "Summarize the data",
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
// Or use all tools (bash, readFile, writeFile)
|
|
34
|
+
const result2 = await generateText({
|
|
35
|
+
model: yourModel,
|
|
36
|
+
tools,
|
|
37
|
+
prompt: "Generate a markdown table of shirt colors",
|
|
38
|
+
});
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Advanced Usage
|
|
42
|
+
|
|
43
|
+
### Upload a local directory
|
|
44
|
+
|
|
45
|
+
```typescript
|
|
46
|
+
const { bash } = await createBashTool({
|
|
47
|
+
uploadDirectory: {
|
|
48
|
+
source: "./my-project",
|
|
49
|
+
include: "**/*.{ts,json}", // optional glob filter
|
|
50
|
+
},
|
|
51
|
+
});
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Use @vercel/sandbox for full VM
|
|
55
|
+
|
|
56
|
+
```typescript
|
|
57
|
+
import { Sandbox } from "@vercel/sandbox";
|
|
58
|
+
|
|
59
|
+
const sandbox = await Sandbox.create();
|
|
60
|
+
// Files are written to /workspace by default
|
|
61
|
+
const { tools } = await createBashTool({
|
|
62
|
+
sandbox,
|
|
63
|
+
files: { "index.ts": "console.log('hello');" },
|
|
64
|
+
});
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Use a custom just-bash instance
|
|
68
|
+
|
|
69
|
+
```typescript
|
|
70
|
+
import { Bash } from "just-bash";
|
|
71
|
+
|
|
72
|
+
const sandbox = new Bash({ cwd: "/app" });
|
|
73
|
+
const { tools } = await createBashTool({
|
|
74
|
+
sandbox,
|
|
75
|
+
destination: "/app",
|
|
76
|
+
});
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Track tool calls
|
|
80
|
+
|
|
81
|
+
```typescript
|
|
82
|
+
const { tools } = await createBashTool({
|
|
83
|
+
files: { "index.ts": "export const x = 1;" },
|
|
84
|
+
onCall: (toolName, args) => {
|
|
85
|
+
console.log(`Tool called: ${toolName}`, args);
|
|
86
|
+
},
|
|
87
|
+
});
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### Custom sandbox implementation
|
|
91
|
+
|
|
92
|
+
```typescript
|
|
93
|
+
import { createBashTool, Sandbox } from "bash-tool";
|
|
94
|
+
|
|
95
|
+
const customSandbox: Sandbox = {
|
|
96
|
+
async executeCommand(command) {
|
|
97
|
+
// Return { stdout, stderr, exitCode }
|
|
98
|
+
},
|
|
99
|
+
async readFile(path) {
|
|
100
|
+
// Return file contents
|
|
101
|
+
},
|
|
102
|
+
async writeFile(path, content) {
|
|
103
|
+
// Write file
|
|
104
|
+
},
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
const { tools } = await createBashTool({ sandbox: customSandbox });
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## License
|
|
111
|
+
|
|
112
|
+
MIT
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface LoadFilesOptions {
|
|
2
|
+
files?: Record<string, string>;
|
|
3
|
+
uploadDirectory?: {
|
|
4
|
+
source: string;
|
|
5
|
+
include?: string;
|
|
6
|
+
};
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Load files from inline definitions and/or a directory on disk.
|
|
10
|
+
* Returns a record of relative paths to file contents.
|
|
11
|
+
* If both are provided, inline files take precedence (override directory files).
|
|
12
|
+
*/
|
|
13
|
+
export declare function loadFiles(options: LoadFilesOptions): Promise<Record<string, string>>;
|
|
14
|
+
//# sourceMappingURL=loader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/files/loader.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,gBAAgB;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,eAAe,CAAC,EAAE;QAChB,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;CACH;AAED;;;;GAIG;AACH,wBAAsB,SAAS,CAC7B,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAgCjC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import fg from "fast-glob";
|
|
4
|
+
/**
|
|
5
|
+
* Load files from inline definitions and/or a directory on disk.
|
|
6
|
+
* Returns a record of relative paths to file contents.
|
|
7
|
+
* If both are provided, inline files take precedence (override directory files).
|
|
8
|
+
*/
|
|
9
|
+
export async function loadFiles(options) {
|
|
10
|
+
const result = {};
|
|
11
|
+
// Load from directory first (so inline can override)
|
|
12
|
+
if (options.uploadDirectory) {
|
|
13
|
+
const { source, include = "**/*" } = options.uploadDirectory;
|
|
14
|
+
const absoluteSource = path.resolve(source);
|
|
15
|
+
const files = await fg(include, {
|
|
16
|
+
cwd: absoluteSource,
|
|
17
|
+
dot: true,
|
|
18
|
+
onlyFiles: true,
|
|
19
|
+
ignore: ["**/node_modules/**", "**/.git/**"],
|
|
20
|
+
});
|
|
21
|
+
await Promise.all(files.map(async (relativePath) => {
|
|
22
|
+
const absolutePath = path.join(absoluteSource, relativePath);
|
|
23
|
+
const content = await fs.readFile(absolutePath, "utf-8");
|
|
24
|
+
result[relativePath] = content;
|
|
25
|
+
}));
|
|
26
|
+
}
|
|
27
|
+
// Merge inline files (override directory files)
|
|
28
|
+
if (options.files) {
|
|
29
|
+
for (const [relativePath, content] of Object.entries(options.files)) {
|
|
30
|
+
result[relativePath] = content;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return result;
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/files/loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,WAAW,CAAC;AAU3B;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,OAAyB;IAEzB,MAAM,MAAM,GAA2B,EAAE,CAAC;IAE1C,qDAAqD;IACrD,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC;QAC5B,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,MAAM,EAAE,GAAG,OAAO,CAAC,eAAe,CAAC;QAC7D,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAE5C,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,OAAO,EAAE;YAC9B,GAAG,EAAE,cAAc;YACnB,GAAG,EAAE,IAAI;YACT,SAAS,EAAE,IAAI;YACf,MAAM,EAAE,CAAC,oBAAoB,EAAE,YAAY,CAAC;SAC7C,CAAC,CAAC;QAEH,MAAM,OAAO,CAAC,GAAG,CACf,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,YAAY,EAAE,EAAE;YAC/B,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,YAAY,CAAC,CAAC;YAC7D,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;YACzD,MAAM,CAAC,YAAY,CAAC,GAAG,OAAO,CAAC;QACjC,CAAC,CAAC,CACH,CAAC;IACJ,CAAC;IAED,gDAAgD;IAChD,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QAClB,KAAK,MAAM,CAAC,YAAY,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACpE,MAAM,CAAC,YAAY,CAAC,GAAG,OAAO,CAAC;QACjC,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3C,YAAY,EACV,WAAW,EACX,aAAa,EACb,qBAAqB,EACrB,gBAAgB,EAChB,OAAO,EACP,qBAAqB,GACtB,MAAM,YAAY,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { JustBashInstance, Sandbox } from "../types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Options for creating a just-bash sandbox.
|
|
4
|
+
*/
|
|
5
|
+
export interface JustBashSandboxOptions {
|
|
6
|
+
/** Initial files to populate the virtual filesystem */
|
|
7
|
+
files?: Record<string, string>;
|
|
8
|
+
/** Working directory */
|
|
9
|
+
cwd?: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Creates a Sandbox implementation using just-bash (virtual bash environment).
|
|
13
|
+
* Dynamically imports just-bash to keep it as an optional peer dependency.
|
|
14
|
+
*/
|
|
15
|
+
export declare function createJustBashSandbox(options?: JustBashSandboxOptions): Promise<Sandbox>;
|
|
16
|
+
/**
|
|
17
|
+
* Check if an object is a just-bash Bash instance using duck-typing.
|
|
18
|
+
*/
|
|
19
|
+
export declare function isJustBash(obj: unknown): obj is JustBashInstance;
|
|
20
|
+
/**
|
|
21
|
+
* Wraps a just-bash Bash instance to conform to our Sandbox interface.
|
|
22
|
+
*/
|
|
23
|
+
export declare function wrapJustBash(bashInstance: JustBashInstance): Sandbox;
|
|
24
|
+
//# sourceMappingURL=just-bash.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"just-bash.d.ts","sourceRoot":"","sources":["../../src/sandbox/just-bash.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAiB,gBAAgB,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE5E;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,uDAAuD;IACvD,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,wBAAwB;IACxB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;;GAGG;AACH,wBAAsB,qBAAqB,CACzC,OAAO,GAAE,sBAA2B,GACnC,OAAO,CAAC,OAAO,CAAC,CAoDlB;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,gBAAgB,CAKhE;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,YAAY,EAAE,gBAAgB,GAAG,OAAO,CAoCpE"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Creates a Sandbox implementation using just-bash (virtual bash environment).
|
|
3
|
+
* Dynamically imports just-bash to keep it as an optional peer dependency.
|
|
4
|
+
*/
|
|
5
|
+
export async function createJustBashSandbox(options = {}) {
|
|
6
|
+
// Dynamic import to handle optional peer dependency
|
|
7
|
+
let Bash;
|
|
8
|
+
try {
|
|
9
|
+
const module = await import("just-bash");
|
|
10
|
+
Bash = module.Bash;
|
|
11
|
+
}
|
|
12
|
+
catch {
|
|
13
|
+
throw new Error('just-bash is not installed. Either install it with "npm install just-bash" or provide your own sandbox via the sandbox option.');
|
|
14
|
+
}
|
|
15
|
+
const bashEnv = new Bash({
|
|
16
|
+
files: options.files,
|
|
17
|
+
cwd: options.cwd,
|
|
18
|
+
});
|
|
19
|
+
return {
|
|
20
|
+
async executeCommand(command) {
|
|
21
|
+
const result = await bashEnv.exec(command);
|
|
22
|
+
return {
|
|
23
|
+
stdout: result.stdout,
|
|
24
|
+
stderr: result.stderr,
|
|
25
|
+
exitCode: result.exitCode,
|
|
26
|
+
};
|
|
27
|
+
},
|
|
28
|
+
async readFile(filePath) {
|
|
29
|
+
const result = await bashEnv.exec(`cat "${filePath}"`);
|
|
30
|
+
if (result.exitCode !== 0) {
|
|
31
|
+
throw new Error(`Failed to read file: ${filePath}\n${result.stderr}`);
|
|
32
|
+
}
|
|
33
|
+
return result.stdout;
|
|
34
|
+
},
|
|
35
|
+
async writeFile(filePath, content) {
|
|
36
|
+
// Ensure parent directory exists
|
|
37
|
+
const dir = filePath.substring(0, filePath.lastIndexOf("/"));
|
|
38
|
+
if (dir) {
|
|
39
|
+
await bashEnv.exec(`mkdir -p "${dir}"`);
|
|
40
|
+
}
|
|
41
|
+
// Write file using heredoc to handle special characters
|
|
42
|
+
const result = await bashEnv.exec(`cat > "${filePath}" << 'BASH_TOOL_EOF'\n${content}\nBASH_TOOL_EOF`);
|
|
43
|
+
if (result.exitCode !== 0) {
|
|
44
|
+
throw new Error(`Failed to write file: ${filePath}\n${result.stderr}`);
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Check if an object is a just-bash Bash instance using duck-typing.
|
|
51
|
+
*/
|
|
52
|
+
export function isJustBash(obj) {
|
|
53
|
+
if (!obj || typeof obj !== "object")
|
|
54
|
+
return false;
|
|
55
|
+
const candidate = obj;
|
|
56
|
+
// just-bash Bash class has an exec method
|
|
57
|
+
return typeof candidate.exec === "function";
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Wraps a just-bash Bash instance to conform to our Sandbox interface.
|
|
61
|
+
*/
|
|
62
|
+
export function wrapJustBash(bashInstance) {
|
|
63
|
+
return {
|
|
64
|
+
async executeCommand(command) {
|
|
65
|
+
const result = await bashInstance.exec(command);
|
|
66
|
+
return {
|
|
67
|
+
stdout: result.stdout,
|
|
68
|
+
stderr: result.stderr,
|
|
69
|
+
exitCode: result.exitCode,
|
|
70
|
+
};
|
|
71
|
+
},
|
|
72
|
+
async readFile(filePath) {
|
|
73
|
+
const result = await bashInstance.exec(`cat "${filePath}"`);
|
|
74
|
+
if (result.exitCode !== 0) {
|
|
75
|
+
throw new Error(`Failed to read file: ${filePath}\n${result.stderr}`);
|
|
76
|
+
}
|
|
77
|
+
return result.stdout;
|
|
78
|
+
},
|
|
79
|
+
async writeFile(filePath, content) {
|
|
80
|
+
// Ensure parent directory exists
|
|
81
|
+
const dir = filePath.substring(0, filePath.lastIndexOf("/"));
|
|
82
|
+
if (dir) {
|
|
83
|
+
await bashInstance.exec(`mkdir -p "${dir}"`);
|
|
84
|
+
}
|
|
85
|
+
// Write file using heredoc to handle special characters
|
|
86
|
+
const result = await bashInstance.exec(`cat > "${filePath}" << 'BASH_TOOL_EOF'\n${content}\nBASH_TOOL_EOF`);
|
|
87
|
+
if (result.exitCode !== 0) {
|
|
88
|
+
throw new Error(`Failed to write file: ${filePath}\n${result.stderr}`);
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=just-bash.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"just-bash.js","sourceRoot":"","sources":["../../src/sandbox/just-bash.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { Sandbox } from "../types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Minimal interface for the @vercel/sandbox methods we actually use.
|
|
4
|
+
* This allows proper typing without requiring the full class.
|
|
5
|
+
*/
|
|
6
|
+
export interface VercelSandboxLike {
|
|
7
|
+
sandboxId: string;
|
|
8
|
+
runCommand: (command: string, args?: string[]) => Promise<{
|
|
9
|
+
exitCode: number;
|
|
10
|
+
stdout: (opts?: {
|
|
11
|
+
signal?: AbortSignal;
|
|
12
|
+
}) => Promise<string>;
|
|
13
|
+
stderr: (opts?: {
|
|
14
|
+
signal?: AbortSignal;
|
|
15
|
+
}) => Promise<string>;
|
|
16
|
+
}>;
|
|
17
|
+
readFile: (file: {
|
|
18
|
+
path: string;
|
|
19
|
+
}) => Promise<NodeJS.ReadableStream | null>;
|
|
20
|
+
writeFiles: (files: {
|
|
21
|
+
path: string;
|
|
22
|
+
content: Buffer;
|
|
23
|
+
}[]) => Promise<void>;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Check if an object is a @vercel/sandbox instance using duck-typing.
|
|
27
|
+
*/
|
|
28
|
+
export declare function isVercelSandbox(obj: unknown): obj is VercelSandboxLike;
|
|
29
|
+
/**
|
|
30
|
+
* Wraps a @vercel/sandbox instance to conform to our Sandbox interface.
|
|
31
|
+
*/
|
|
32
|
+
export declare function wrapVercelSandbox(vercelSandbox: VercelSandboxLike): Sandbox;
|
|
33
|
+
//# sourceMappingURL=vercel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vercel.d.ts","sourceRoot":"","sources":["../../src/sandbox/vercel.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAiB,OAAO,EAAE,MAAM,aAAa,CAAC;AAE1D;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,CACV,OAAO,EAAE,MAAM,EACf,IAAI,CAAC,EAAE,MAAM,EAAE,KACZ,OAAO,CAAC;QACX,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE;YAAE,MAAM,CAAC,EAAE,WAAW,CAAA;SAAE,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;QAC7D,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE;YAAE,MAAM,CAAC,EAAE,WAAW,CAAA;SAAE,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;KAC9D,CAAC,CAAC;IACH,QAAQ,EAAE,CAAC,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,MAAM,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IAC5E,UAAU,EAAE,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3E;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,iBAAiB,CAUtE;AAaD;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,aAAa,EAAE,iBAAiB,GAAG,OAAO,CA6B3E"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Check if an object is a @vercel/sandbox instance using duck-typing.
|
|
3
|
+
*/
|
|
4
|
+
export function isVercelSandbox(obj) {
|
|
5
|
+
if (!obj || typeof obj !== "object")
|
|
6
|
+
return false;
|
|
7
|
+
const candidate = obj;
|
|
8
|
+
// @vercel/sandbox Sandbox class has these characteristic properties
|
|
9
|
+
return (typeof candidate.sandboxId === "string" &&
|
|
10
|
+
typeof candidate.runCommand === "function" &&
|
|
11
|
+
typeof candidate.readFile === "function" &&
|
|
12
|
+
typeof candidate.writeFiles === "function");
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Helper to read a stream into a string.
|
|
16
|
+
*/
|
|
17
|
+
async function streamToString(stream) {
|
|
18
|
+
const chunks = [];
|
|
19
|
+
for await (const chunk of stream) {
|
|
20
|
+
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
|
|
21
|
+
}
|
|
22
|
+
return Buffer.concat(chunks).toString("utf-8");
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Wraps a @vercel/sandbox instance to conform to our Sandbox interface.
|
|
26
|
+
*/
|
|
27
|
+
export function wrapVercelSandbox(vercelSandbox) {
|
|
28
|
+
return {
|
|
29
|
+
async executeCommand(command) {
|
|
30
|
+
const result = await vercelSandbox.runCommand("bash", ["-c", command]);
|
|
31
|
+
const [stdout, stderr] = await Promise.all([
|
|
32
|
+
result.stdout(),
|
|
33
|
+
result.stderr(),
|
|
34
|
+
]);
|
|
35
|
+
return {
|
|
36
|
+
stdout,
|
|
37
|
+
stderr,
|
|
38
|
+
exitCode: result.exitCode,
|
|
39
|
+
};
|
|
40
|
+
},
|
|
41
|
+
async readFile(filePath) {
|
|
42
|
+
const stream = await vercelSandbox.readFile({ path: filePath });
|
|
43
|
+
if (stream === null) {
|
|
44
|
+
throw new Error(`File not found: ${filePath}`);
|
|
45
|
+
}
|
|
46
|
+
return streamToString(stream);
|
|
47
|
+
},
|
|
48
|
+
async writeFile(filePath, content) {
|
|
49
|
+
await vercelSandbox.writeFiles([
|
|
50
|
+
{ path: filePath, content: Buffer.from(content, "utf-8") },
|
|
51
|
+
]);
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=vercel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vercel.js","sourceRoot":"","sources":["../../src/sandbox/vercel.ts"],"names":[],"mappings":"AAoBA;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,GAAY;IAC1C,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAClD,MAAM,SAAS,GAAG,GAA8B,CAAC;IACjD,oEAAoE;IACpE,OAAO,CACL,OAAO,SAAS,CAAC,SAAS,KAAK,QAAQ;QACvC,OAAO,SAAS,CAAC,UAAU,KAAK,UAAU;QAC1C,OAAO,SAAS,CAAC,QAAQ,KAAK,UAAU;QACxC,OAAO,SAAS,CAAC,UAAU,KAAK,UAAU,CAC3C,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,cAAc,CAAC,MAA6B;IACzD,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QACjC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IACnE,CAAC;IACD,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;AACjD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,aAAgC;IAChE,OAAO;QACL,KAAK,CAAC,cAAc,CAAC,OAAe;YAClC,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;YACvE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;gBACzC,MAAM,CAAC,MAAM,EAAE;gBACf,MAAM,CAAC,MAAM,EAAE;aAChB,CAAC,CAAC;YACH,OAAO;gBACL,MAAM;gBACN,MAAM;gBACN,QAAQ,EAAE,MAAM,CAAC,QAAQ;aAC1B,CAAC;QACJ,CAAC;QAED,KAAK,CAAC,QAAQ,CAAC,QAAgB;YAC7B,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;YAChE,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;gBACpB,MAAM,IAAI,KAAK,CAAC,mBAAmB,QAAQ,EAAE,CAAC,CAAC;YACjD,CAAC;YACD,OAAO,cAAc,CAAC,MAAM,CAAC,CAAC;QAChC,CAAC;QAED,KAAK,CAAC,SAAS,CAAC,QAAgB,EAAE,OAAe;YAC/C,MAAM,aAAa,CAAC,UAAU,CAAC;gBAC7B,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE;aAC3D,CAAC,CAAC;QACL,CAAC;KACF,CAAC;AACJ,CAAC"}
|
package/dist/tool.d.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { BashToolkit, CreateBashToolOptions } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Creates a bash tool with tools for AI agents.
|
|
4
|
+
*
|
|
5
|
+
* @example
|
|
6
|
+
* ```typescript
|
|
7
|
+
* // Simple usage with inline files
|
|
8
|
+
* const { tools, sandbox } = await createBashTool({
|
|
9
|
+
* files: { "src/index.ts": "export const x = 1;" },
|
|
10
|
+
* });
|
|
11
|
+
*
|
|
12
|
+
* // Upload a directory from disk
|
|
13
|
+
* const { tools, sandbox } = await createBashTool({
|
|
14
|
+
* uploadDirectory: { source: "./my-project" },
|
|
15
|
+
* });
|
|
16
|
+
*
|
|
17
|
+
* // Use with AI SDK
|
|
18
|
+
* const result = await generateText({
|
|
19
|
+
* model,
|
|
20
|
+
* tools,
|
|
21
|
+
* prompt: "List all TypeScript files",
|
|
22
|
+
* });
|
|
23
|
+
*
|
|
24
|
+
* // Cleanup
|
|
25
|
+
* await sandbox.stop();
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
export declare function createBashTool(options?: CreateBashToolOptions): Promise<BashToolkit>;
|
|
29
|
+
//# sourceMappingURL=tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool.d.ts","sourceRoot":"","sources":["../src/tool.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,WAAW,EAAE,qBAAqB,EAAW,MAAM,YAAY,CAAC;AAI9E;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAsB,cAAc,CAClC,OAAO,GAAE,qBAA0B,GAClC,OAAO,CAAC,WAAW,CAAC,CAiEtB"}
|
package/dist/tool.js
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { loadFiles } from "./files/loader.js";
|
|
3
|
+
import { createJustBashSandbox, isJustBash, wrapJustBash, } from "./sandbox/just-bash.js";
|
|
4
|
+
import { isVercelSandbox, wrapVercelSandbox } from "./sandbox/vercel.js";
|
|
5
|
+
import { createBashExecuteTool } from "./tools/bash.js";
|
|
6
|
+
import { createReadFileTool } from "./tools/read-file.js";
|
|
7
|
+
import { createWriteFileTool } from "./tools/write-file.js";
|
|
8
|
+
const DEFAULT_DESTINATION = "/workspace";
|
|
9
|
+
/**
|
|
10
|
+
* Creates a bash tool with tools for AI agents.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* // Simple usage with inline files
|
|
15
|
+
* const { tools, sandbox } = await createBashTool({
|
|
16
|
+
* files: { "src/index.ts": "export const x = 1;" },
|
|
17
|
+
* });
|
|
18
|
+
*
|
|
19
|
+
* // Upload a directory from disk
|
|
20
|
+
* const { tools, sandbox } = await createBashTool({
|
|
21
|
+
* uploadDirectory: { source: "./my-project" },
|
|
22
|
+
* });
|
|
23
|
+
*
|
|
24
|
+
* // Use with AI SDK
|
|
25
|
+
* const result = await generateText({
|
|
26
|
+
* model,
|
|
27
|
+
* tools,
|
|
28
|
+
* prompt: "List all TypeScript files",
|
|
29
|
+
* });
|
|
30
|
+
*
|
|
31
|
+
* // Cleanup
|
|
32
|
+
* await sandbox.stop();
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
export async function createBashTool(options = {}) {
|
|
36
|
+
const destination = options.destination ?? DEFAULT_DESTINATION;
|
|
37
|
+
// 1. Load files from disk and/or inline
|
|
38
|
+
const loadedFiles = await loadFiles({
|
|
39
|
+
files: options.files,
|
|
40
|
+
uploadDirectory: options.uploadDirectory,
|
|
41
|
+
});
|
|
42
|
+
// 2. Prefix all file paths with destination
|
|
43
|
+
const filesWithDestination = {};
|
|
44
|
+
for (const [relativePath, content] of Object.entries(loadedFiles)) {
|
|
45
|
+
const absolutePath = path.posix.join(destination, relativePath);
|
|
46
|
+
filesWithDestination[absolutePath] = content;
|
|
47
|
+
}
|
|
48
|
+
// 3. Create or wrap sandbox
|
|
49
|
+
let sandbox;
|
|
50
|
+
if (options.sandbox) {
|
|
51
|
+
// Check @vercel/sandbox first (more specific check)
|
|
52
|
+
if (isVercelSandbox(options.sandbox)) {
|
|
53
|
+
sandbox = wrapVercelSandbox(options.sandbox);
|
|
54
|
+
}
|
|
55
|
+
else if (isJustBash(options.sandbox)) {
|
|
56
|
+
sandbox = wrapJustBash(options.sandbox);
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
sandbox = options.sandbox;
|
|
60
|
+
}
|
|
61
|
+
// Write files to existing sandbox
|
|
62
|
+
for (const [filePath, content] of Object.entries(filesWithDestination)) {
|
|
63
|
+
await sandbox.writeFile(filePath, content);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
// Create just-bash sandbox with files
|
|
68
|
+
sandbox = await createJustBashSandbox({
|
|
69
|
+
files: filesWithDestination,
|
|
70
|
+
cwd: destination,
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
// 4. Create tools
|
|
74
|
+
const fileList = Object.keys(loadedFiles);
|
|
75
|
+
const bash = createBashExecuteTool({
|
|
76
|
+
sandbox,
|
|
77
|
+
cwd: destination,
|
|
78
|
+
files: fileList,
|
|
79
|
+
extraInstructions: options.extraInstructions,
|
|
80
|
+
onCall: options.onCall,
|
|
81
|
+
});
|
|
82
|
+
const tools = {
|
|
83
|
+
bash,
|
|
84
|
+
readFile: createReadFileTool({
|
|
85
|
+
sandbox,
|
|
86
|
+
onCall: options.onCall,
|
|
87
|
+
}),
|
|
88
|
+
writeFile: createWriteFileTool({
|
|
89
|
+
sandbox,
|
|
90
|
+
onCall: options.onCall,
|
|
91
|
+
}),
|
|
92
|
+
};
|
|
93
|
+
return { bash, tools, sandbox };
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=tool.js.map
|
package/dist/tool.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool.js","sourceRoot":"","sources":["../src/tool.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { CommandResult, Sandbox } from "../types.js";
|
|
3
|
+
export interface CreateBashToolOptions {
|
|
4
|
+
sandbox: Sandbox;
|
|
5
|
+
/** Working directory for command execution */
|
|
6
|
+
cwd: string;
|
|
7
|
+
/** List of file paths available in the sandbox (relative to cwd) */
|
|
8
|
+
files?: string[];
|
|
9
|
+
extraInstructions?: string;
|
|
10
|
+
onCall?: (toolName: string, args: unknown) => void;
|
|
11
|
+
}
|
|
12
|
+
export declare function createBashExecuteTool(options: CreateBashToolOptions): import("ai").Tool<z.ZodObject<{
|
|
13
|
+
command: z.ZodString;
|
|
14
|
+
}, "strip", z.ZodTypeAny, {
|
|
15
|
+
command: string;
|
|
16
|
+
}, {
|
|
17
|
+
command: string;
|
|
18
|
+
}>, CommandResult> & {
|
|
19
|
+
execute: (args: {
|
|
20
|
+
command: string;
|
|
21
|
+
}, options: import("ai").ToolExecutionOptions) => PromiseLike<CommandResult>;
|
|
22
|
+
};
|
|
23
|
+
//# sourceMappingURL=bash.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bash.d.ts","sourceRoot":"","sources":["../../src/tools/bash.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAM1D,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,OAAO,CAAC;IACjB,8CAA8C;IAC9C,GAAG,EAAE,MAAM,CAAC;IACZ,oEAAoE;IACpE,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;CACpD;AA0CD,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,qBAAqB;;;;;;;;;;EAWnE"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { tool } from "ai";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
const bashSchema = z.object({
|
|
4
|
+
command: z.string().describe("The bash command to execute"),
|
|
5
|
+
});
|
|
6
|
+
function generateDescription(options) {
|
|
7
|
+
const { cwd, files, extraInstructions } = options;
|
|
8
|
+
const lines = [
|
|
9
|
+
"Execute bash commands in the sandbox environment.",
|
|
10
|
+
"",
|
|
11
|
+
`WORKING DIRECTORY: ${cwd}`,
|
|
12
|
+
"All commands execute from this directory. Use relative paths from here.",
|
|
13
|
+
"",
|
|
14
|
+
];
|
|
15
|
+
// Add file discovery hints if files are provided
|
|
16
|
+
if (files && files.length > 0) {
|
|
17
|
+
const sampleFiles = files.slice(0, 8);
|
|
18
|
+
lines.push("Available files:");
|
|
19
|
+
for (const file of sampleFiles) {
|
|
20
|
+
lines.push(` ${file}`);
|
|
21
|
+
}
|
|
22
|
+
if (files.length > 8) {
|
|
23
|
+
lines.push(` ... and ${files.length - 8} more files`);
|
|
24
|
+
}
|
|
25
|
+
lines.push("");
|
|
26
|
+
}
|
|
27
|
+
lines.push("Common operations:");
|
|
28
|
+
lines.push(" ls -la # List files with details");
|
|
29
|
+
lines.push(" find . -name '*.ts' # Find files by pattern");
|
|
30
|
+
lines.push(" grep -r 'pattern' . # Search file contents");
|
|
31
|
+
lines.push(" cat <file> # View file contents");
|
|
32
|
+
lines.push("");
|
|
33
|
+
if (extraInstructions) {
|
|
34
|
+
lines.push(extraInstructions);
|
|
35
|
+
lines.push("");
|
|
36
|
+
}
|
|
37
|
+
return lines.join("\n").trim();
|
|
38
|
+
}
|
|
39
|
+
export function createBashExecuteTool(options) {
|
|
40
|
+
const { sandbox, onCall } = options;
|
|
41
|
+
return tool({
|
|
42
|
+
description: generateDescription(options),
|
|
43
|
+
parameters: bashSchema,
|
|
44
|
+
execute: async ({ command }) => {
|
|
45
|
+
onCall?.("bash", { command });
|
|
46
|
+
return sandbox.executeCommand(command);
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=bash.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bash.js","sourceRoot":"","sources":["../../src/tools/bash.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;AAC1B,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,MAAM,UAAU,GAAG,CAAC,CAAC,MAAM,CAAC;IAC1B,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,6BAA6B,CAAC;CAC5D,CAAC,CAAC;AAYH,SAAS,mBAAmB,CAAC,OAA8B;IACzD,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,iBAAiB,EAAE,GAAG,OAAO,CAAC;IAElD,MAAM,KAAK,GAAa;QACtB,mDAAmD;QACnD,EAAE;QACF,sBAAsB,GAAG,EAAE;QAC3B,yEAAyE;QACzE,EAAE;KACH,CAAC;IAEF,iDAAiD;IACjD,IAAI,KAAK,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9B,MAAM,WAAW,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAEtC,KAAK,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;QAC/B,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;YAC/B,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;QAC1B,CAAC;QACD,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrB,KAAK,CAAC,IAAI,CAAC,aAAa,KAAK,CAAC,MAAM,GAAG,CAAC,aAAa,CAAC,CAAC;QACzD,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjB,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;IACjC,KAAK,CAAC,IAAI,CAAC,iDAAiD,CAAC,CAAC;IAC9D,KAAK,CAAC,IAAI,CAAC,+CAA+C,CAAC,CAAC;IAC5D,KAAK,CAAC,IAAI,CAAC,8CAA8C,CAAC,CAAC;IAC3D,KAAK,CAAC,IAAI,CAAC,4CAA4C,CAAC,CAAC;IACzD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,IAAI,iBAAiB,EAAE,CAAC;QACtB,KAAK,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;QAC9B,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjB,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;AACjC,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,OAA8B;IAClE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IAEpC,OAAO,IAAI,CAAC;QACV,WAAW,EAAE,mBAAmB,CAAC,OAAO,CAAC;QACzC,UAAU,EAAE,UAAU;QACtB,OAAO,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,EAA0B,EAAE;YACrD,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;YAC9B,OAAO,OAAO,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;QACzC,CAAC;KACF,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { Sandbox } from "../types.js";
|
|
3
|
+
export interface CreateReadFileToolOptions {
|
|
4
|
+
sandbox: Sandbox;
|
|
5
|
+
onCall?: (toolName: string, args: unknown) => void;
|
|
6
|
+
}
|
|
7
|
+
export declare function createReadFileTool(options: CreateReadFileToolOptions): import("ai").Tool<z.ZodObject<{
|
|
8
|
+
path: z.ZodString;
|
|
9
|
+
}, "strip", z.ZodTypeAny, {
|
|
10
|
+
path: string;
|
|
11
|
+
}, {
|
|
12
|
+
path: string;
|
|
13
|
+
}>, {
|
|
14
|
+
content: string;
|
|
15
|
+
}> & {
|
|
16
|
+
execute: (args: {
|
|
17
|
+
path: string;
|
|
18
|
+
}, options: import("ai").ToolExecutionOptions) => PromiseLike<{
|
|
19
|
+
content: string;
|
|
20
|
+
}>;
|
|
21
|
+
};
|
|
22
|
+
//# sourceMappingURL=read-file.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"read-file.d.ts","sourceRoot":"","sources":["../../src/tools/read-file.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAM3C,MAAM,WAAW,yBAAyB;IACxC,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;CACpD;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,yBAAyB;;;;;;;aAMnB,MAAM;;;;;iBAAN,MAAM;;EAMvD"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { tool } from "ai";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
const readFileSchema = z.object({
|
|
4
|
+
path: z.string().describe("The path to the file to read"),
|
|
5
|
+
});
|
|
6
|
+
export function createReadFileTool(options) {
|
|
7
|
+
const { sandbox, onCall } = options;
|
|
8
|
+
return tool({
|
|
9
|
+
description: "Read the contents of a file from the sandbox.",
|
|
10
|
+
parameters: readFileSchema,
|
|
11
|
+
execute: async ({ path }) => {
|
|
12
|
+
onCall?.("readFile", { path });
|
|
13
|
+
const content = await sandbox.readFile(path);
|
|
14
|
+
return { content };
|
|
15
|
+
},
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=read-file.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"read-file.js","sourceRoot":"","sources":["../../src/tools/read-file.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;AAC1B,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,CAAC;IAC9B,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,8BAA8B,CAAC;CAC1D,CAAC,CAAC;AAOH,MAAM,UAAU,kBAAkB,CAAC,OAAkC;IACnE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IAEpC,OAAO,IAAI,CAAC;QACV,WAAW,EAAE,+CAA+C;QAC5D,UAAU,EAAE,cAAc;QAC1B,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,EAAgC,EAAE;YACxD,MAAM,EAAE,CAAC,UAAU,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;YAC/B,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YAC7C,OAAO,EAAE,OAAO,EAAE,CAAC;QACrB,CAAC;KACF,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { Sandbox } from "../types.js";
|
|
3
|
+
export interface CreateWriteFileToolOptions {
|
|
4
|
+
sandbox: Sandbox;
|
|
5
|
+
onCall?: (toolName: string, args: unknown) => void;
|
|
6
|
+
}
|
|
7
|
+
export declare function createWriteFileTool(options: CreateWriteFileToolOptions): import("ai").Tool<z.ZodObject<{
|
|
8
|
+
path: z.ZodString;
|
|
9
|
+
content: z.ZodString;
|
|
10
|
+
}, "strip", z.ZodTypeAny, {
|
|
11
|
+
content: string;
|
|
12
|
+
path: string;
|
|
13
|
+
}, {
|
|
14
|
+
content: string;
|
|
15
|
+
path: string;
|
|
16
|
+
}>, {
|
|
17
|
+
success: boolean;
|
|
18
|
+
}> & {
|
|
19
|
+
execute: (args: {
|
|
20
|
+
content: string;
|
|
21
|
+
path: string;
|
|
22
|
+
}, options: import("ai").ToolExecutionOptions) => PromiseLike<{
|
|
23
|
+
success: boolean;
|
|
24
|
+
}>;
|
|
25
|
+
};
|
|
26
|
+
//# sourceMappingURL=write-file.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"write-file.d.ts","sourceRoot":"","sources":["../../src/tools/write-file.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAO3C,MAAM,WAAW,0BAA0B;IACzC,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;CACpD;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,0BAA0B;;;;;;;;;;aAOZ,OAAO;;;;;;iBAAP,OAAO;;EAMjE"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { tool } from "ai";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
const writeFileSchema = z.object({
|
|
4
|
+
path: z.string().describe("The path where the file should be written"),
|
|
5
|
+
content: z.string().describe("The content to write to the file"),
|
|
6
|
+
});
|
|
7
|
+
export function createWriteFileTool(options) {
|
|
8
|
+
const { sandbox, onCall } = options;
|
|
9
|
+
return tool({
|
|
10
|
+
description: "Write content to a file in the sandbox. Creates parent directories if needed.",
|
|
11
|
+
parameters: writeFileSchema,
|
|
12
|
+
execute: async ({ path, content }) => {
|
|
13
|
+
onCall?.("writeFile", { path, content });
|
|
14
|
+
await sandbox.writeFile(path, content);
|
|
15
|
+
return { success: true };
|
|
16
|
+
},
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=write-file.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"write-file.js","sourceRoot":"","sources":["../../src/tools/write-file.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;AAC1B,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,MAAM,eAAe,GAAG,CAAC,CAAC,MAAM,CAAC;IAC/B,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,2CAA2C,CAAC;IACtE,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,kCAAkC,CAAC;CACjE,CAAC,CAAC;AAOH,MAAM,UAAU,mBAAmB,CAAC,OAAmC;IACrE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IAEpC,OAAO,IAAI,CAAC;QACV,WAAW,EACT,+EAA+E;QACjF,UAAU,EAAE,eAAe;QAC3B,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAAiC,EAAE;YAClE,MAAM,EAAE,CAAC,WAAW,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;YACzC,MAAM,OAAO,CAAC,SAAS,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;YACvC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAC3B,CAAC;KACF,CAAC,CAAC;AACL,CAAC"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import type { Sandbox as VercelSandbox } from "@vercel/sandbox";
|
|
2
|
+
export interface CommandResult {
|
|
3
|
+
stdout: string;
|
|
4
|
+
stderr: string;
|
|
5
|
+
exitCode: number;
|
|
6
|
+
}
|
|
7
|
+
export interface Sandbox {
|
|
8
|
+
executeCommand(command: string): Promise<CommandResult>;
|
|
9
|
+
readFile(path: string): Promise<string>;
|
|
10
|
+
writeFile(path: string, content: string): Promise<void>;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Duck-typed just-bash Bash instance.
|
|
14
|
+
* We detect this by checking for the exec method.
|
|
15
|
+
*/
|
|
16
|
+
export interface JustBashInstance {
|
|
17
|
+
exec: (command: string) => Promise<{
|
|
18
|
+
stdout: string;
|
|
19
|
+
stderr: string;
|
|
20
|
+
exitCode: number;
|
|
21
|
+
}>;
|
|
22
|
+
[key: string]: unknown;
|
|
23
|
+
}
|
|
24
|
+
export interface CreateBashToolOptions {
|
|
25
|
+
/**
|
|
26
|
+
* Destination directory on the sandbox for files.
|
|
27
|
+
* Both `files` and `uploadDirectory` are written relative to this.
|
|
28
|
+
* Also used as the working directory for commands.
|
|
29
|
+
* @default "/workspace"
|
|
30
|
+
*/
|
|
31
|
+
destination?: string;
|
|
32
|
+
/**
|
|
33
|
+
* Inline files to write to the sandbox.
|
|
34
|
+
* Keys are relative paths within `destination`.
|
|
35
|
+
* @example { "src/index.ts": "export const x = 1;" }
|
|
36
|
+
*/
|
|
37
|
+
files?: Record<string, string>;
|
|
38
|
+
/**
|
|
39
|
+
* Upload a directory from disk to the sandbox.
|
|
40
|
+
*/
|
|
41
|
+
uploadDirectory?: {
|
|
42
|
+
/** Path on disk (local machine) */
|
|
43
|
+
source: string;
|
|
44
|
+
/**
|
|
45
|
+
* Glob pattern to filter files.
|
|
46
|
+
* @default "**\/*"
|
|
47
|
+
*/
|
|
48
|
+
include?: string;
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Override the default just-bash sandbox.
|
|
52
|
+
* Accepts a @vercel/sandbox instance, just-bash Bash instance,
|
|
53
|
+
* or any object implementing Sandbox.
|
|
54
|
+
*/
|
|
55
|
+
sandbox?: Sandbox | VercelSandbox | JustBashInstance;
|
|
56
|
+
/**
|
|
57
|
+
* Additional instructions to append to tool descriptions.
|
|
58
|
+
*/
|
|
59
|
+
extraInstructions?: string;
|
|
60
|
+
/**
|
|
61
|
+
* Callback invoked before each tool execution.
|
|
62
|
+
*/
|
|
63
|
+
onCall?: (toolName: string, args: unknown) => void;
|
|
64
|
+
}
|
|
65
|
+
import type { createBashExecuteTool } from "./tools/bash.js";
|
|
66
|
+
import type { createReadFileTool } from "./tools/read-file.js";
|
|
67
|
+
import type { createWriteFileTool } from "./tools/write-file.js";
|
|
68
|
+
export interface BashToolkit {
|
|
69
|
+
/** The bash tool for direct use */
|
|
70
|
+
bash: ReturnType<typeof createBashExecuteTool>;
|
|
71
|
+
/** All tools (bash, readFile, writeFile) for passing to AI SDK */
|
|
72
|
+
tools: {
|
|
73
|
+
bash: ReturnType<typeof createBashExecuteTool>;
|
|
74
|
+
readFile: ReturnType<typeof createReadFileTool>;
|
|
75
|
+
writeFile: ReturnType<typeof createWriteFileTool>;
|
|
76
|
+
};
|
|
77
|
+
sandbox: Sandbox;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Re-export @vercel/sandbox Sandbox type for convenience.
|
|
81
|
+
*/
|
|
82
|
+
export type { Sandbox as VercelSandboxInstance } from "@vercel/sandbox";
|
|
83
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEhE,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,OAAO;IACtB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;IACxD,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACxC,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACzD;AAED;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC;QACjC,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC,CAAC;IACH,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,qBAAqB;IACpC;;;;;OAKG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAE/B;;OAEG;IACH,eAAe,CAAC,EAAE;QAChB,mCAAmC;QACnC,MAAM,EAAE,MAAM,CAAC;QACf;;;WAGG;QACH,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;IAEF;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,GAAG,aAAa,GAAG,gBAAgB,CAAC;IAErD;;OAEG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAE3B;;OAEG;IACH,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;CACpD;AAGD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAC7D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC/D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAEjE,MAAM,WAAW,WAAW;IAC1B,mCAAmC;IACnC,IAAI,EAAE,UAAU,CAAC,OAAO,qBAAqB,CAAC,CAAC;IAC/C,kEAAkE;IAClE,KAAK,EAAE;QACL,IAAI,EAAE,UAAU,CAAC,OAAO,qBAAqB,CAAC,CAAC;QAC/C,QAAQ,EAAE,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAAC;QAChD,SAAS,EAAE,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAC;KACnD,CAAC;IACF,OAAO,EAAE,OAAO,CAAC;CAClB;AAED;;GAEG;AACH,YAAY,EAAE,OAAO,IAAI,qBAAqB,EAAE,MAAM,iBAAiB,CAAC"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/package.json
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "bash-tool",
|
|
3
|
+
"publishConfig": {
|
|
4
|
+
"access": "public"
|
|
5
|
+
},
|
|
6
|
+
"version": "0.1.0",
|
|
7
|
+
"description": "Generic bash tool for AI agents, compatible with AI SDK",
|
|
8
|
+
"type": "module",
|
|
9
|
+
"main": "dist/index.js",
|
|
10
|
+
"types": "dist/index.d.ts",
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"types": "./dist/index.d.ts",
|
|
14
|
+
"import": "./dist/index.js"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"dist",
|
|
19
|
+
"LICENSE",
|
|
20
|
+
"README.md"
|
|
21
|
+
],
|
|
22
|
+
"sideEffects": false,
|
|
23
|
+
"keywords": [
|
|
24
|
+
"bash",
|
|
25
|
+
"ai",
|
|
26
|
+
"tool",
|
|
27
|
+
"agent",
|
|
28
|
+
"ai-sdk",
|
|
29
|
+
"sandbox",
|
|
30
|
+
"vercel"
|
|
31
|
+
],
|
|
32
|
+
"author": "Vercel, Inc.",
|
|
33
|
+
"license": "MIT",
|
|
34
|
+
"repository": {
|
|
35
|
+
"type": "git",
|
|
36
|
+
"url": "git+https://github.com/vercel/bash-tool.git"
|
|
37
|
+
},
|
|
38
|
+
"bugs": {
|
|
39
|
+
"url": "https://github.com/vercel/bash-tool/issues"
|
|
40
|
+
},
|
|
41
|
+
"homepage": "https://github.com/vercel/bash-tool#readme",
|
|
42
|
+
"engines": {
|
|
43
|
+
"node": ">=18"
|
|
44
|
+
},
|
|
45
|
+
"dependencies": {
|
|
46
|
+
"fast-glob": "^3.3.2",
|
|
47
|
+
"zod": "^3.23.8"
|
|
48
|
+
},
|
|
49
|
+
"devDependencies": {
|
|
50
|
+
"@biomejs/biome": "^2.3.11",
|
|
51
|
+
"@types/node": "^22.10.0",
|
|
52
|
+
"@vercel/sandbox": "^1.1.2",
|
|
53
|
+
"ai": "^4.0.0",
|
|
54
|
+
"knip": "^5.80.0",
|
|
55
|
+
"typescript": "^5.7.0",
|
|
56
|
+
"vitest": "^2.1.0"
|
|
57
|
+
},
|
|
58
|
+
"peerDependencies": {
|
|
59
|
+
"@vercel/sandbox": "*",
|
|
60
|
+
"ai": "^4.0.0",
|
|
61
|
+
"just-bash": "*"
|
|
62
|
+
},
|
|
63
|
+
"peerDependenciesMeta": {
|
|
64
|
+
"just-bash": {
|
|
65
|
+
"optional": true
|
|
66
|
+
},
|
|
67
|
+
"@vercel/sandbox": {
|
|
68
|
+
"optional": true
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
"scripts": {
|
|
72
|
+
"build": "tsc -p tsconfig.build.json",
|
|
73
|
+
"typecheck": "tsc --noEmit",
|
|
74
|
+
"test": "vitest",
|
|
75
|
+
"test:run": "vitest run",
|
|
76
|
+
"lint": "biome check .",
|
|
77
|
+
"lint:fix": "biome check --write .",
|
|
78
|
+
"format": "biome format --write .",
|
|
79
|
+
"knip": "knip",
|
|
80
|
+
"validate": "pnpm run lint && pnpm run knip && pnpm run typecheck && pnpm run test"
|
|
81
|
+
}
|
|
82
|
+
}
|