bashkit 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.
Files changed (41) hide show
  1. package/AGENTS.md +442 -0
  2. package/LICENSE +21 -0
  3. package/README.md +713 -0
  4. package/dist/cli/init.d.ts +2 -0
  5. package/dist/cli/init.js +179 -0
  6. package/dist/index.d.ts +14 -0
  7. package/dist/index.js +1805 -0
  8. package/dist/middleware/anthropic-cache.d.ts +17 -0
  9. package/dist/middleware/index.d.ts +1 -0
  10. package/dist/sandbox/e2b.d.ts +9 -0
  11. package/dist/sandbox/index.d.ts +4 -0
  12. package/dist/sandbox/interface.d.ts +21 -0
  13. package/dist/sandbox/local.d.ts +5 -0
  14. package/dist/sandbox/vercel.d.ts +13 -0
  15. package/dist/setup/index.d.ts +2 -0
  16. package/dist/setup/setup-environment.d.ts +36 -0
  17. package/dist/setup/types.d.ts +47 -0
  18. package/dist/skills/discovery.d.ts +9 -0
  19. package/dist/skills/fetch.d.ts +56 -0
  20. package/dist/skills/index.d.ts +6 -0
  21. package/dist/skills/loader.d.ts +11 -0
  22. package/dist/skills/types.d.ts +29 -0
  23. package/dist/skills/xml.d.ts +26 -0
  24. package/dist/tools/bash.d.ts +18 -0
  25. package/dist/tools/edit.d.ts +16 -0
  26. package/dist/tools/exit-plan-mode.d.ts +11 -0
  27. package/dist/tools/glob.d.ts +14 -0
  28. package/dist/tools/grep.d.ts +42 -0
  29. package/dist/tools/index.d.ts +45 -0
  30. package/dist/tools/read.d.ts +25 -0
  31. package/dist/tools/task.d.ts +50 -0
  32. package/dist/tools/todo-write.d.ts +28 -0
  33. package/dist/tools/web-fetch.d.ts +20 -0
  34. package/dist/tools/web-search.d.ts +24 -0
  35. package/dist/tools/write.d.ts +14 -0
  36. package/dist/types.d.ts +32 -0
  37. package/dist/utils/compact-conversation.d.ts +85 -0
  38. package/dist/utils/context-status.d.ts +71 -0
  39. package/dist/utils/index.d.ts +3 -0
  40. package/dist/utils/prune-messages.d.ts +32 -0
  41. package/package.json +84 -0
package/AGENTS.md ADDED
@@ -0,0 +1,442 @@
1
+ # AGENTS.md - Using bashkit
2
+
3
+ bashkit provides agentic coding tools for the Vercel AI SDK. This guide helps AI agents use bashkit when building applications.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install bashkit ai @ai-sdk/anthropic
9
+ # or
10
+ pnpm add bashkit ai @ai-sdk/anthropic
11
+ # or
12
+ yarn add bashkit ai @ai-sdk/anthropic
13
+ # or
14
+ bun add bashkit ai @ai-sdk/anthropic
15
+ ```
16
+
17
+ ## Quick Setup
18
+
19
+ ### LocalSandbox (Development)
20
+
21
+ Runs commands directly on the local machine. Use for development/testing only.
22
+
23
+ ```typescript
24
+ import { createAgentTools, LocalSandbox } from "bashkit";
25
+
26
+ const sandbox = new LocalSandbox("/tmp/workspace");
27
+ const tools = createAgentTools(sandbox);
28
+ ```
29
+
30
+ ### VercelSandbox (Production)
31
+
32
+ Runs in isolated Firecracker microVMs on Vercel's infrastructure.
33
+
34
+ ```typescript
35
+ import { createAgentTools, VercelSandbox } from "bashkit";
36
+
37
+ const sandbox = new VercelSandbox({
38
+ runtime: "node22",
39
+ resources: { vcpus: 2 },
40
+ });
41
+ const tools = createAgentTools(sandbox);
42
+
43
+ // Don't forget to cleanup
44
+ await sandbox.destroy();
45
+ ```
46
+
47
+ ## Available Tools
48
+
49
+ ### Sandbox-based Tools (from createAgentTools)
50
+
51
+ | Tool | Purpose | Key Inputs |
52
+ |------|---------|------------|
53
+ | `Bash` | Execute shell commands | `command`, `timeout?`, `description?` |
54
+ | `Read` | Read files or list directories | `file_path`, `offset?`, `limit?` |
55
+ | `Write` | Create/overwrite files | `file_path`, `content` |
56
+ | `Edit` | Replace strings in files | `file_path`, `old_string`, `new_string`, `replace_all?` |
57
+ | `Glob` | Find files by pattern | `pattern`, `path?` |
58
+ | `Grep` | Search file contents | `pattern`, `path?`, `output_mode?`, `-i?`, `-C?` |
59
+
60
+ ### Workflow Tools (created separately)
61
+
62
+ | Tool | Purpose | Factory |
63
+ |------|---------|---------|
64
+ | `Task` | Spawn sub-agents | `createTaskTool({ model, tools, subagentTypes? })` |
65
+ | `TodoWrite` | Track task progress | `createTodoWriteTool(state, config?, onUpdate?)` |
66
+ | `ExitPlanMode` | Exit planning mode | `createExitPlanModeTool(config?, onPlanSubmit?)` |
67
+
68
+ ### Web Tools (require `parallel-web` peer dependency)
69
+
70
+ | Tool | Purpose | Factory |
71
+ |------|---------|---------|
72
+ | `WebSearch` | Search the web | `createWebSearchTool({ apiKey })` |
73
+ | `WebFetch` | Fetch URL and process with AI | `createWebFetchTool({ apiKey, model })` |
74
+
75
+ ## Using with AI SDK generateText
76
+
77
+ ```typescript
78
+ import { generateText, wrapLanguageModel, stepCountIs } from "ai";
79
+ import { anthropic } from "@ai-sdk/anthropic";
80
+ import {
81
+ createAgentTools,
82
+ LocalSandbox,
83
+ anthropicPromptCacheMiddleware,
84
+ } from "bashkit";
85
+
86
+ const sandbox = new LocalSandbox("/tmp/workspace");
87
+ const tools = createAgentTools(sandbox);
88
+
89
+ // Wrap model with prompt caching (recommended)
90
+ const model = wrapLanguageModel({
91
+ model: anthropic("claude-sonnet-4-20250514"),
92
+ middleware: anthropicPromptCacheMiddleware,
93
+ });
94
+
95
+ const result = await generateText({
96
+ model,
97
+ tools,
98
+ system: "You are a helpful coding assistant.",
99
+ prompt: "Create a hello world TypeScript file and run it",
100
+ stopWhen: stepCountIs(10), // Allow up to 10 tool-call rounds
101
+ onStepFinish: ({ finishReason, toolCalls, toolResults, usage }) => {
102
+ // Log progress
103
+ console.log(`Step finished: ${finishReason}`);
104
+ for (const call of toolCalls || []) {
105
+ console.log(` Tool: ${call.toolName}`);
106
+ }
107
+ },
108
+ });
109
+
110
+ await sandbox.destroy();
111
+ ```
112
+
113
+ ## Sub-agents with Task Tool
114
+
115
+ The Task tool spawns new `generateText` calls for complex subtasks:
116
+
117
+ ```typescript
118
+ import { createTaskTool } from "bashkit";
119
+
120
+ const taskTool = createTaskTool({
121
+ model: anthropic("claude-sonnet-4-20250514"),
122
+ tools: sandboxTools,
123
+ subagentTypes: {
124
+ research: {
125
+ model: anthropic("claude-haiku-3"), // Cheaper model for research
126
+ systemPrompt: "You are a research specialist. Find information only.",
127
+ tools: ["Read", "Grep", "Glob"], // Limited tools
128
+ },
129
+ coding: {
130
+ systemPrompt: "You are a coding expert. Write clean code.",
131
+ tools: ["Read", "Write", "Edit", "Bash"],
132
+ },
133
+ },
134
+ });
135
+
136
+ // Add to tools
137
+ const allTools = { ...sandboxTools, Task: taskTool };
138
+ ```
139
+
140
+ The parent agent calls Task like any other tool:
141
+ ```typescript
142
+ // Agent decides to delegate:
143
+ { tool: "Task", args: {
144
+ description: "Research API patterns",
145
+ prompt: "Find best practices for REST APIs",
146
+ subagent_type: "research"
147
+ }}
148
+ ```
149
+
150
+ ## Prompt Caching
151
+
152
+ Enable Anthropic prompt caching to reduce costs on repeated prefixes:
153
+
154
+ ```typescript
155
+ import { wrapLanguageModel } from "ai";
156
+ import { anthropicPromptCacheMiddleware } from "bashkit";
157
+
158
+ const model = wrapLanguageModel({
159
+ model: anthropic("claude-sonnet-4-20250514"),
160
+ middleware: anthropicPromptCacheMiddleware,
161
+ });
162
+
163
+ // Check cache stats in result
164
+ console.log({
165
+ cacheCreation: result.providerMetadata?.anthropic?.cacheCreationInputTokens,
166
+ cacheRead: result.providerMetadata?.anthropic?.cacheReadInputTokens,
167
+ });
168
+ ```
169
+
170
+ ## Web Tools
171
+
172
+ WebSearch and WebFetch tools provide web access capabilities using the [Parallel API](https://docs.parallel.ai).
173
+
174
+ ### Setup
175
+
176
+ ```bash
177
+ # Install the parallel-web peer dependency
178
+ bun add parallel-web
179
+
180
+ # Set your API key
181
+ export PARALLEL_API_KEY="your_api_key"
182
+ ```
183
+
184
+ ### WebSearch
185
+
186
+ Search the web and get formatted results:
187
+
188
+ ```typescript
189
+ import { createWebSearchTool } from "bashkit";
190
+
191
+ const webSearch = createWebSearchTool({
192
+ apiKey: process.env.PARALLEL_API_KEY!,
193
+ });
194
+
195
+ // Add to your tools
196
+ const tools = {
197
+ ...sandboxTools,
198
+ WebSearch: webSearch,
199
+ };
200
+ ```
201
+
202
+ **Input:**
203
+ - `query` - The search query
204
+ - `allowed_domains?` - Only include results from these domains
205
+ - `blocked_domains?` - Exclude results from these domains
206
+
207
+ **Output:**
208
+ ```typescript
209
+ {
210
+ results: Array<{ title: string; url: string; snippet: string; metadata?: Record<string, any> }>;
211
+ total_results: number;
212
+ query: string;
213
+ }
214
+ ```
215
+
216
+ ### WebFetch
217
+
218
+ Fetch a URL and process the content with an AI model:
219
+
220
+ ```typescript
221
+ import { createWebFetchTool } from "bashkit";
222
+ import { anthropic } from "@ai-sdk/anthropic";
223
+
224
+ const webFetch = createWebFetchTool({
225
+ apiKey: process.env.PARALLEL_API_KEY!,
226
+ model: anthropic("claude-haiku-3"), // Use a fast/cheap model for processing
227
+ });
228
+
229
+ // Add to your tools
230
+ const tools = {
231
+ ...sandboxTools,
232
+ WebFetch: webFetch,
233
+ };
234
+ ```
235
+
236
+ **Input:**
237
+ - `url` - The URL to fetch
238
+ - `prompt` - The prompt to run on the fetched content
239
+
240
+ **Output:**
241
+ ```typescript
242
+ {
243
+ response: string; // AI model's response to the prompt
244
+ url: string;
245
+ final_url?: string; // Final URL after redirects
246
+ status_code?: number;
247
+ }
248
+ ```
249
+
250
+ ## Agent Skills
251
+
252
+ bashkit supports the [Agent Skills](https://agentskills.io) standard for progressive skill loading.
253
+
254
+ > **Note:** Skill discovery is for **LocalSandbox** use cases where the agent has filesystem access. For cloud sandboxes, bundle skills with your app directly.
255
+
256
+ ### Discovering Skills (LocalSandbox)
257
+
258
+ When using LocalSandbox, discover project and user-global skills:
259
+
260
+ ```typescript
261
+ import { discoverSkills, skillsToXml } from "bashkit";
262
+
263
+ // Discovers from .skills/ (project) and ~/.bashkit/skills/ (user-global)
264
+ const skills = await discoverSkills();
265
+ ```
266
+
267
+ ### Using Skills with Agents
268
+
269
+ ```typescript
270
+ import { discoverSkills, skillsToXml, createAgentTools, LocalSandbox } from "bashkit";
271
+ import { generateText, stepCountIs } from "ai";
272
+ import { anthropic } from "@ai-sdk/anthropic";
273
+
274
+ const skills = await discoverSkills();
275
+ const sandbox = new LocalSandbox("/tmp/workspace");
276
+ const tools = createAgentTools(sandbox);
277
+
278
+ const result = await generateText({
279
+ model: anthropic("claude-sonnet-4-20250514"),
280
+ tools,
281
+ system: `You are a coding assistant.
282
+
283
+ ${skillsToXml(skills)}
284
+
285
+ When a task matches a skill, use the Read tool to load its full instructions from the location path.`,
286
+ prompt: "Extract text from invoice.pdf",
287
+ stopWhen: stepCountIs(10),
288
+ });
289
+ ```
290
+
291
+ ### How It Works
292
+
293
+ 1. `discoverSkills()` loads only metadata (name, description, path) - ~50-100 tokens per skill
294
+ 2. `skillsToXml()` generates XML listing available skills
295
+ 3. Agent decides when to activate a skill by reading its SKILL.md with the Read tool
296
+ 4. Full instructions enter context only when the skill is actually used
297
+
298
+ ### Creating Skills
299
+
300
+ Create `.skills/<skill-name>/SKILL.md`:
301
+
302
+ ```markdown
303
+ ---
304
+ name: pdf-processing
305
+ description: Extract text and tables from PDF files.
306
+ ---
307
+
308
+ # PDF Processing
309
+
310
+ Instructions for the agent...
311
+ ```
312
+
313
+ ### Using Remote Skills
314
+
315
+ Fetch complete skill folders from GitHub repositories (e.g., Anthropic's official skills):
316
+
317
+ ```typescript
318
+ import { fetchSkill, fetchSkills, setupAgentEnvironment } from "bashkit";
319
+
320
+ // Fetch a single skill (gets all files: SKILL.md, scripts/, etc.)
321
+ const pdfSkill = await fetchSkill('anthropics/skills/pdf');
322
+
323
+ // Or batch fetch multiple
324
+ const remoteSkills = await fetchSkills([
325
+ 'anthropics/skills/pdf',
326
+ 'anthropics/skills/web-research',
327
+ ]);
328
+
329
+ // Use with setupAgentEnvironment
330
+ const config = {
331
+ skills: {
332
+ ...remoteSkills,
333
+ 'my-custom': myContent,
334
+ },
335
+ };
336
+ const { skills } = await setupAgentEnvironment(sandbox, config);
337
+ ```
338
+
339
+ **Format:** `owner/repo/skillName` (fetches entire skill folder from GitHub)
340
+
341
+ ## Setting Up Agent Environments
342
+
343
+ For cloud sandboxes, use `setupAgentEnvironment` to create workspace directories and seed skills:
344
+
345
+ ```typescript
346
+ import { setupAgentEnvironment, skillsToXml, createAgentTools, createVercelSandbox } from "bashkit";
347
+
348
+ const config = {
349
+ workspace: {
350
+ notes: 'files/notes/',
351
+ outputs: 'files/outputs/',
352
+ },
353
+ skills: {
354
+ 'web-research': webResearchSkillContent,
355
+ },
356
+ };
357
+
358
+ const sandbox = createVercelSandbox({});
359
+ const { skills } = await setupAgentEnvironment(sandbox, config);
360
+
361
+ // Use same config in prompt - stays in sync!
362
+ const systemPrompt = `Save notes to: ${config.workspace.notes}
363
+ ${skillsToXml(skills)}
364
+ `;
365
+
366
+ const tools = createAgentTools(sandbox);
367
+ ```
368
+
369
+ ## Common Patterns
370
+
371
+ ### Full Agent Setup
372
+
373
+ ```typescript
374
+ import { generateText, wrapLanguageModel, stepCountIs } from "ai";
375
+ import { anthropic } from "@ai-sdk/anthropic";
376
+ import {
377
+ createAgentTools,
378
+ createTaskTool,
379
+ createTodoWriteTool,
380
+ LocalSandbox,
381
+ anthropicPromptCacheMiddleware,
382
+ type TodoState,
383
+ } from "bashkit";
384
+
385
+ // 1. Create sandbox
386
+ const sandbox = new LocalSandbox("/tmp/workspace");
387
+
388
+ // 2. Create sandbox tools
389
+ const sandboxTools = createAgentTools(sandbox);
390
+
391
+ // 3. Create model with caching
392
+ const model = wrapLanguageModel({
393
+ model: anthropic("claude-sonnet-4-20250514"),
394
+ middleware: anthropicPromptCacheMiddleware,
395
+ });
396
+
397
+ // 4. Create workflow tools
398
+ const todoState: TodoState = { todos: [] };
399
+ const todoTool = createTodoWriteTool(todoState);
400
+ const taskTool = createTaskTool({ model, tools: sandboxTools });
401
+
402
+ // 5. Combine all tools
403
+ const tools = {
404
+ ...sandboxTools,
405
+ TodoWrite: todoTool,
406
+ Task: taskTool,
407
+ };
408
+
409
+ // 6. Run agent
410
+ const result = await generateText({
411
+ model,
412
+ tools,
413
+ system: "You are a coding assistant. Use TodoWrite to plan tasks.",
414
+ prompt: "Build a REST API with Express",
415
+ stopWhen: stepCountIs(15),
416
+ });
417
+
418
+ // 7. Cleanup
419
+ await sandbox.destroy();
420
+ ```
421
+
422
+ ### Tool Configuration
423
+
424
+ Restrict tools with configuration:
425
+
426
+ ```typescript
427
+ const tools = createAgentTools(sandbox, {
428
+ tools: {
429
+ Bash: {
430
+ enabled: true,
431
+ blockedCommands: ["rm -rf", "sudo"],
432
+ maxOutputLength: 30000,
433
+ },
434
+ Write: {
435
+ enabled: true,
436
+ allowedPaths: ["/tmp/workspace"],
437
+ maxFileSize: 1_000_000,
438
+ },
439
+ },
440
+ });
441
+ ```
442
+
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 jbreite
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.