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/README.md ADDED
@@ -0,0 +1,713 @@
1
+ # bashkit
2
+
3
+ Agentic coding tools for Vercel AI SDK. Give AI agents the ability to execute code, read/write files, and perform coding tasks in a sandboxed environment.
4
+
5
+ ## Overview
6
+
7
+ `bashkit` provides a set of tools that work with the Vercel AI SDK to enable agentic coding capabilities. It gives AI models like Claude the ability to:
8
+
9
+ - Execute bash commands in a persistent shell
10
+ - Read files and list directories
11
+ - Create and write files
12
+ - Edit existing files with string replacement
13
+ - Search for files by pattern
14
+ - Search file contents with regex
15
+ - Spawn sub-agents for complex tasks
16
+ - Track task progress with todos
17
+ - Search the web and fetch URLs
18
+ - Load skills on-demand via the [Agent Skills](https://agentskills.io) standard
19
+
20
+ ## Installation
21
+
22
+ ```bash
23
+ bun add bashkit ai zod
24
+ ```
25
+
26
+ For web tools, also install:
27
+ ```bash
28
+ bun add parallel-web
29
+ ```
30
+
31
+ ## Quick Start
32
+
33
+ ### With Filesystem Access (Desktop Apps, Local Scripts, Servers)
34
+
35
+ When you have direct filesystem access, use `LocalSandbox`:
36
+
37
+ ```typescript
38
+ import { createAgentTools, createLocalSandbox } from 'bashkit';
39
+ import { anthropic } from '@ai-sdk/anthropic';
40
+ import { generateText, stepCountIs } from 'ai';
41
+
42
+ // Create a local sandbox (runs directly on your filesystem)
43
+ const sandbox = createLocalSandbox({ cwd: '/tmp/workspace' });
44
+
45
+ // Create tools bound to the sandbox
46
+ const tools = createAgentTools(sandbox);
47
+
48
+ // Use with Vercel AI SDK
49
+ const result = await generateText({
50
+ model: anthropic('claude-sonnet-4-5'),
51
+ tools,
52
+ prompt: 'Create a simple Express server in server.js',
53
+ stopWhen: stepCountIs(10),
54
+ });
55
+
56
+ console.log(result.text);
57
+
58
+ // Cleanup
59
+ await sandbox.destroy();
60
+ ```
61
+
62
+ ### Without Filesystem Access (Web/Serverless Environments)
63
+
64
+ When you're in a web or serverless environment without filesystem access, use `VercelSandbox` or `E2BSandbox`:
65
+
66
+ ```typescript
67
+ import { createAgentTools, createVercelSandbox } from 'bashkit';
68
+ import { anthropic } from '@ai-sdk/anthropic';
69
+ import { streamText, stepCountIs } from 'ai';
70
+
71
+ // Create a Vercel sandbox (isolated Firecracker microVM)
72
+ const sandbox = createVercelSandbox({
73
+ runtime: 'node22',
74
+ resources: { vcpus: 2 },
75
+ });
76
+
77
+ const tools = createAgentTools(sandbox);
78
+
79
+ const result = streamText({
80
+ model: anthropic('claude-sonnet-4-5'),
81
+ messages,
82
+ tools,
83
+ stopWhen: stepCountIs(10),
84
+ });
85
+
86
+ // Cleanup
87
+ await sandbox.destroy();
88
+ ```
89
+
90
+ ## Available Tools
91
+
92
+ ### Sandbox-based Tools (from `createAgentTools`)
93
+
94
+ | Tool | Purpose | Key Inputs |
95
+ |------|---------|------------|
96
+ | `Bash` | Execute shell commands | `command`, `timeout?`, `description?` |
97
+ | `Read` | Read files or list directories | `file_path`, `offset?`, `limit?` |
98
+ | `Write` | Create/overwrite files | `file_path`, `content` |
99
+ | `Edit` | Replace strings in files | `file_path`, `old_string`, `new_string`, `replace_all?` |
100
+ | `Glob` | Find files by pattern | `pattern`, `path?` |
101
+ | `Grep` | Search file contents | `pattern`, `path?`, `output_mode?`, `-i?`, `-C?` |
102
+
103
+ ### Workflow Tools (created separately)
104
+
105
+ | Tool | Purpose | Factory |
106
+ |------|---------|---------|
107
+ | `Task` | Spawn sub-agents | `createTaskTool({ model, tools, subagentTypes? })` |
108
+ | `TodoWrite` | Track task progress | `createTodoWriteTool(state, config?, onUpdate?)` |
109
+ | `ExitPlanMode` | Exit planning mode | `createExitPlanModeTool(config?, onPlanSubmit?)` |
110
+
111
+ ### Web Tools (require `parallel-web` peer dependency)
112
+
113
+ | Tool | Purpose | Factory |
114
+ |------|---------|---------|
115
+ | `WebSearch` | Search the web | `createWebSearchTool({ apiKey })` |
116
+ | `WebFetch` | Fetch URL and process with AI | `createWebFetchTool({ apiKey, model })` |
117
+
118
+ ## Sandbox Types
119
+
120
+ ### LocalSandbox
121
+
122
+ Runs commands directly on your filesystem. **Use when you have filesystem access** (desktop apps, local scripts, servers you control).
123
+
124
+ ```typescript
125
+ import { createLocalSandbox } from 'bashkit';
126
+
127
+ const sandbox = createLocalSandbox({ cwd: '/tmp/workspace' });
128
+ ```
129
+
130
+ ### VercelSandbox
131
+
132
+ Runs in isolated Firecracker microVMs on Vercel's infrastructure. **Use when you don't have filesystem access** (web apps, serverless functions, browser environments).
133
+
134
+ ```typescript
135
+ import { createVercelSandbox } from 'bashkit';
136
+
137
+ const sandbox = createVercelSandbox({
138
+ runtime: 'node22',
139
+ resources: { vcpus: 2 },
140
+ });
141
+ ```
142
+
143
+ ### E2BSandbox
144
+
145
+ Runs in E2B's cloud sandboxes. Requires `@e2b/code-interpreter` peer dependency. **Use when you don't have filesystem access** and need E2B's features.
146
+
147
+ ```typescript
148
+ import { createE2BSandbox } from 'bashkit';
149
+
150
+ const sandbox = createE2BSandbox({
151
+ // E2B config
152
+ });
153
+ ```
154
+
155
+ ## Configuration
156
+
157
+ You can configure tools with security restrictions and limits:
158
+
159
+ ```typescript
160
+ const tools = createAgentTools(sandbox, {
161
+ tools: {
162
+ Bash: {
163
+ timeout: 30000,
164
+ blockedCommands: ['rm -rf', 'curl'],
165
+ maxOutputLength: 10000,
166
+ },
167
+ Read: {
168
+ allowedPaths: ['/workspace/**'],
169
+ },
170
+ Write: {
171
+ maxFileSize: 1_000_000, // 1MB limit
172
+ },
173
+ },
174
+ webSearch: {
175
+ apiKey: process.env.PARALLEL_API_KEY,
176
+ },
177
+ webFetch: {
178
+ apiKey: process.env.PARALLEL_API_KEY,
179
+ model: anthropic('claude-haiku-4'),
180
+ },
181
+ });
182
+ ```
183
+
184
+ ### Configuration Options
185
+
186
+ #### Global Config
187
+ - `defaultTimeout` (number): Default timeout for all tools in milliseconds
188
+ - `workingDirectory` (string): Default working directory for the sandbox
189
+
190
+ #### Per-Tool Config
191
+ - `timeout` (number): Tool-specific timeout
192
+ - `maxFileSize` (number): Maximum file size in bytes (Write)
193
+ - `maxOutputLength` (number): Maximum output length (Bash)
194
+ - `allowedPaths` (string[]): Restrict file operations to specific paths
195
+ - `blockedCommands` (string[]): Block commands containing these strings (Bash)
196
+
197
+ ## Sub-agents with Task Tool
198
+
199
+ The Task tool spawns new `generateText` calls for complex subtasks:
200
+
201
+ ```typescript
202
+ import { createTaskTool } from 'bashkit';
203
+
204
+ const taskTool = createTaskTool({
205
+ model: anthropic('claude-sonnet-4-5'),
206
+ tools: sandboxTools,
207
+ subagentTypes: {
208
+ research: {
209
+ model: anthropic('claude-haiku-4'), // Cheaper model for research
210
+ systemPrompt: 'You are a research specialist. Find information only.',
211
+ tools: ['Read', 'Grep', 'Glob'], // Limited tools
212
+ },
213
+ coding: {
214
+ systemPrompt: 'You are a coding expert. Write clean code.',
215
+ tools: ['Read', 'Write', 'Edit', 'Bash'],
216
+ },
217
+ },
218
+ });
219
+
220
+ // Add to tools
221
+ const allTools = { ...sandboxTools, Task: taskTool };
222
+ ```
223
+
224
+ The parent agent calls Task like any other tool:
225
+ ```typescript
226
+ // Agent decides to delegate:
227
+ { tool: "Task", args: {
228
+ description: "Research API patterns",
229
+ prompt: "Find best practices for REST APIs",
230
+ subagent_type: "research"
231
+ }}
232
+ ```
233
+
234
+ ## Context Management
235
+
236
+ ### Conversation Compaction
237
+
238
+ Automatically summarize conversations when they exceed token limits:
239
+
240
+ ```typescript
241
+ import { compactConversation, MODEL_CONTEXT_LIMITS } from 'bashkit';
242
+
243
+ let compactState = { conversationSummary: '' };
244
+
245
+ const result = await compactConversation(messages, {
246
+ maxTokens: MODEL_CONTEXT_LIMITS['claude-sonnet-4-5'],
247
+ summarizerModel: anthropic('claude-haiku-4'), // Fast/cheap model
248
+ compactionThreshold: 0.85, // Trigger at 85% usage
249
+ protectRecentMessages: 10, // Keep last 10 messages intact
250
+ }, compactState);
251
+
252
+ messages = result.messages;
253
+ compactState = result.state;
254
+ ```
255
+
256
+ ### Context Status Monitoring
257
+
258
+ Monitor context usage and inject guidance to prevent agents from rushing:
259
+
260
+ ```typescript
261
+ import { getContextStatus, contextNeedsCompaction } from 'bashkit';
262
+
263
+ const status = getContextStatus(messages, MODEL_CONTEXT_LIMITS['claude-sonnet-4-5']);
264
+
265
+ if (status.guidance) {
266
+ // Inject into system prompt
267
+ system = `${system}\n\n<context_status>${status.guidance}</context_status>`;
268
+ }
269
+
270
+ if (contextNeedsCompaction(status)) {
271
+ // Trigger compaction
272
+ const compacted = await compactConversation(messages, config, state);
273
+ }
274
+ ```
275
+
276
+ ## Prompt Caching
277
+
278
+ Enable Anthropic prompt caching to reduce costs on repeated prefixes:
279
+
280
+ ```typescript
281
+ import { wrapLanguageModel } from 'ai';
282
+ import { anthropicPromptCacheMiddleware } from 'bashkit';
283
+
284
+ const model = wrapLanguageModel({
285
+ model: anthropic('claude-sonnet-4-5'),
286
+ middleware: anthropicPromptCacheMiddleware,
287
+ });
288
+
289
+ // Check cache stats in result
290
+ console.log({
291
+ cacheCreation: result.providerMetadata?.anthropic?.cacheCreationInputTokens,
292
+ cacheRead: result.providerMetadata?.anthropic?.cacheReadInputTokens,
293
+ });
294
+ ```
295
+
296
+ ## Agent Skills
297
+
298
+ bashkit supports the [Agent Skills](https://agentskills.io) standard - an open format for giving agents new capabilities and expertise. Skills are folders containing a `SKILL.md` file with instructions that agents can load on-demand.
299
+
300
+ > **Note:** Skill discovery is designed for **LocalSandbox** use cases where the agent has access to the user's filesystem. For cloud sandboxes (VercelSandbox/E2B), you would bundle skills with your app and inject them directly into the system prompt.
301
+
302
+ ### Progressive Disclosure
303
+
304
+ Skills use progressive disclosure to keep context lean:
305
+ 1. **At startup**: Only skill metadata (name, description, path) is loaded (~50-100 tokens per skill)
306
+ 2. **On activation**: Agent reads the full `SKILL.md` via the Read tool when needed
307
+
308
+ ### Discovering Skills
309
+
310
+ When using LocalSandbox, skills are discovered from:
311
+ 1. `.skills/` in the project directory (highest priority)
312
+ 2. `~/.bashkit/skills/` for user-global skills
313
+
314
+ This allows agents to pick up project-specific skills and user-installed skills automatically.
315
+
316
+ ```typescript
317
+ import { discoverSkills, skillsToXml } from 'bashkit';
318
+
319
+ // Discover skills (metadata only - fast, low context)
320
+ const skills = await discoverSkills();
321
+
322
+ // Or with custom paths
323
+ const skills = await discoverSkills({
324
+ paths: ['.skills', '/path/to/shared/skills'],
325
+ cwd: '/my/project',
326
+ });
327
+ ```
328
+
329
+ ### Using Skills with Agents
330
+
331
+ Inject skill metadata into the system prompt using XML format (recommended for Claude):
332
+
333
+ ```typescript
334
+ import { discoverSkills, skillsToXml, createAgentTools, createLocalSandbox } from 'bashkit';
335
+
336
+ const skills = await discoverSkills();
337
+ const sandbox = createLocalSandbox({ cwd: '/tmp/workspace' });
338
+ const tools = createAgentTools(sandbox);
339
+
340
+ const result = await generateText({
341
+ model: anthropic('claude-sonnet-4-5'),
342
+ tools,
343
+ system: `You are a coding assistant.
344
+
345
+ ${skillsToXml(skills)}
346
+
347
+ When a task matches a skill, use the Read tool to load its full instructions from the location path.`,
348
+ prompt: 'Extract text from invoice.pdf',
349
+ stopWhen: stepCountIs(10),
350
+ });
351
+
352
+ // Agent will call Read({ file_path: "/path/to/.skills/pdf-processing/SKILL.md" })
353
+ // when it decides to use the pdf-processing skill
354
+ ```
355
+
356
+ ### Creating Skills
357
+
358
+ Create a folder with a `SKILL.md` file:
359
+
360
+ ```
361
+ .skills/
362
+ └── pdf-processing/
363
+ └── SKILL.md
364
+ ```
365
+
366
+ The `SKILL.md` file has YAML frontmatter and markdown instructions:
367
+
368
+ ```markdown
369
+ ---
370
+ name: pdf-processing
371
+ description: Extract text and tables from PDF files, fill forms, merge documents.
372
+ license: MIT
373
+ compatibility: Requires poppler-utils
374
+ metadata:
375
+ author: my-org
376
+ version: "1.0"
377
+ ---
378
+
379
+ # PDF Processing
380
+
381
+ ## When to use this skill
382
+ Use when the user needs to work with PDF files...
383
+
384
+ ## How to extract text
385
+ 1. Use pdftotext for text extraction...
386
+ ```
387
+
388
+ **Required fields:**
389
+ - `name`: 1-64 chars, lowercase letters, numbers, and hyphens. Must match folder name.
390
+ - `description`: 1-1024 chars. Describes when to use this skill.
391
+
392
+ **Optional fields:**
393
+ - `license`: License info
394
+ - `compatibility`: Environment requirements
395
+ - `metadata`: Arbitrary key-value pairs
396
+ - `allowed-tools`: Space-delimited list of pre-approved tools (experimental)
397
+
398
+ ### Using Remote Skills
399
+
400
+ Fetch complete skill folders from GitHub repositories, including all scripts and resources:
401
+
402
+ ```typescript
403
+ import { fetchSkill, fetchSkills, setupAgentEnvironment } from 'bashkit';
404
+
405
+ // Fetch a complete skill folder from Anthropic's official skills repo
406
+ const pdfSkill = await fetchSkill('anthropics/skills/pdf');
407
+ // Returns a SkillBundle:
408
+ // {
409
+ // name: 'pdf',
410
+ // files: {
411
+ // 'SKILL.md': '...',
412
+ // 'scripts/extract_text.py': '...',
413
+ // 'forms.md': '...',
414
+ // // ... all files in the skill folder
415
+ // }
416
+ // }
417
+
418
+ // Or batch fetch multiple skills
419
+ const remoteSkills = await fetchSkills([
420
+ 'anthropics/skills/pdf',
421
+ 'anthropics/skills/web-research',
422
+ ]);
423
+ // Returns: { 'pdf': SkillBundle, 'web-research': SkillBundle }
424
+
425
+ // Use with setupAgentEnvironment - writes all files to .skills/
426
+ const config = {
427
+ skills: {
428
+ ...remoteSkills, // SkillBundles (all files)
429
+ 'my-custom': myCustomSkillContent, // Inline string (just SKILL.md)
430
+ },
431
+ };
432
+
433
+ const { skills } = await setupAgentEnvironment(sandbox, config);
434
+ // Creates: .skills/pdf/SKILL.md, .skills/pdf/scripts/*, etc.
435
+ ```
436
+
437
+ **GitHub reference format:** `owner/repo/skillName`
438
+ - `anthropics/skills/pdf` → fetches all files from `https://github.com/anthropics/skills/tree/main/skills/pdf`
439
+
440
+ ### API Reference
441
+
442
+ ```typescript
443
+ // Discover skills from filesystem
444
+ discoverSkills(options?: DiscoverSkillsOptions): Promise<SkillMetadata[]>
445
+
446
+ // Fetch complete skill folders from GitHub
447
+ fetchSkill(ref: string): Promise<SkillBundle>
448
+ fetchSkills(refs: string[]): Promise<Record<string, SkillBundle>>
449
+
450
+ // SkillBundle type
451
+ interface SkillBundle {
452
+ name: string;
453
+ files: Record<string, string>; // relative path -> content
454
+ }
455
+
456
+ // Generate XML for system prompts
457
+ skillsToXml(skills: SkillMetadata[]): string
458
+
459
+ // Parse a single SKILL.md file
460
+ parseSkillMetadata(content: string, skillPath: string): SkillMetadata
461
+ ```
462
+
463
+ ## Setting Up Agent Environments
464
+
465
+ For cloud sandboxes (VercelSandbox/E2B), use `setupAgentEnvironment` to create workspace directories and seed skills.
466
+
467
+ ```typescript
468
+ import {
469
+ setupAgentEnvironment,
470
+ skillsToXml,
471
+ createAgentTools,
472
+ createVercelSandbox
473
+ } from 'bashkit';
474
+
475
+ // Define your environment config
476
+ const config = {
477
+ workspace: {
478
+ notes: 'files/notes/',
479
+ outputs: 'files/outputs/',
480
+ },
481
+ skills: {
482
+ 'web-research': `---
483
+ name: web-research
484
+ description: Research topics using web search and save findings.
485
+ ---
486
+ # Web Research
487
+ Use WebSearch to find information...
488
+ `,
489
+ },
490
+ };
491
+
492
+ // Create sandbox and set up environment
493
+ const sandbox = createVercelSandbox({});
494
+ const { skills } = await setupAgentEnvironment(sandbox, config);
495
+
496
+ // Build prompt using the same config (stays in sync!)
497
+ const systemPrompt = `You are a research assistant.
498
+
499
+ **ENVIRONMENT:**
500
+ - Save notes to: ${config.workspace.notes}
501
+ - Save outputs to: ${config.workspace.outputs}
502
+
503
+ ${skillsToXml(skills)}
504
+ `;
505
+
506
+ // Create tools and run
507
+ const tools = createAgentTools(sandbox);
508
+
509
+ const result = await generateText({
510
+ model: anthropic('claude-sonnet-4-5'),
511
+ tools,
512
+ system: systemPrompt,
513
+ messages,
514
+ });
515
+ ```
516
+
517
+ ### What setupAgentEnvironment Does
518
+
519
+ 1. **Creates workspace directories** - All paths in `config.workspace` are created
520
+ 2. **Seeds skills** - Skills in `config.skills` are written to `.skills/` directory
521
+ 3. **Returns skill metadata** - For use with `skillsToXml()`
522
+
523
+ ### Using with Subagents
524
+
525
+ Use the same config for subagent prompts:
526
+
527
+ ```typescript
528
+ const taskTool = createTaskTool({
529
+ model,
530
+ tools,
531
+ subagentTypes: {
532
+ researcher: {
533
+ systemPrompt: `You are a researcher.
534
+ Save findings to: ${config.workspace.notes}`,
535
+ tools: ['WebSearch', 'Write'],
536
+ },
537
+ 'report-writer': {
538
+ systemPrompt: `Read from: ${config.workspace.notes}
539
+ Save reports to: ${config.workspace.outputs}`,
540
+ tools: ['Read', 'Glob', 'Write'],
541
+ },
542
+ },
543
+ });
544
+ ```
545
+
546
+ ## Sandbox Interface
547
+
548
+ `bashkit` uses a bring-your-own-sandbox architecture. You can implement custom sandboxes:
549
+
550
+ ```typescript
551
+ interface Sandbox {
552
+ exec(command: string, options?: ExecOptions): Promise<ExecResult>;
553
+ readFile(path: string): Promise<string>;
554
+ writeFile(path: string, content: string): Promise<void>;
555
+ readDir(path: string): Promise<string[]>;
556
+ fileExists(path: string): Promise<boolean>;
557
+ destroy(): Promise<void>;
558
+ }
559
+ ```
560
+
561
+ ### Custom Sandbox Example
562
+
563
+ ```typescript
564
+ import type { Sandbox } from 'bashkit';
565
+
566
+ class DockerSandbox implements Sandbox {
567
+ // Your implementation
568
+ async exec(command: string) { /* ... */ }
569
+ async readFile(path: string) { /* ... */ }
570
+ // ... other methods
571
+ }
572
+
573
+ const sandbox = new DockerSandbox();
574
+ const tools = createAgentTools(sandbox);
575
+ ```
576
+
577
+ ## Architecture
578
+
579
+ ```
580
+ ┌─────────────────────────────────────┐
581
+ │ Your Next.js App / Script │
582
+ │ │
583
+ │ ┌─────────────────────────────┐ │
584
+ │ │ Vercel AI SDK │ │
585
+ │ │ (streamText/generateText) │ │
586
+ │ └──────────┬──────────────────┘ │
587
+ │ │ │
588
+ │ ┌──────────▼──────────────────┐ │
589
+ │ │ bashkit Tools │ │
590
+ │ │ (Bash, Read, Write, etc) │ │
591
+ │ └──────────┬──────────────────┘ │
592
+ │ │ │
593
+ │ ┌──────────▼──────────────────┐ │
594
+ │ │ Sandbox │ │
595
+ │ │ (Local/Vercel/E2B/Custom) │ │
596
+ │ └─────────────────────────────┘ │
597
+ └─────────────────────────────────────┘
598
+ ```
599
+
600
+ **Flow:**
601
+ 1. User sends prompt to AI via Vercel AI SDK
602
+ 2. AI decides it needs to use a tool (e.g., create a file)
603
+ 3. Tool receives the call and executes via the Sandbox
604
+ 4. Result returns to AI, which continues or completes
605
+
606
+ ## Design Principles
607
+
608
+ 1. **Bring Your Own Sandbox**: Start with LocalSandbox for dev, swap in VercelSandbox/E2BSandbox for production
609
+ 2. **Type-Safe**: Full TypeScript support with proper type inference
610
+ 3. **Configurable**: Security controls and limits at the tool level
611
+ 4. **Vercel AI SDK Native**: Uses standard `tool()` format
612
+ 5. **Composable**: Mix and match tools, utilities, and middleware as needed
613
+
614
+ ## Examples
615
+
616
+ See the `examples/` directory for complete working examples:
617
+
618
+ - `basic.ts` - Full example with todos, sub-agents, and prompt caching
619
+ - `test-tools.ts` - Testing individual tools
620
+ - `test-web-tools.ts` - Web search and fetch examples
621
+
622
+ ## API Reference
623
+
624
+ ### `createAgentTools(sandbox, config?)`
625
+
626
+ Creates a set of agent tools bound to a sandbox instance.
627
+
628
+ **Parameters:**
629
+ - `sandbox` (Sandbox): Sandbox instance for code execution
630
+ - `config` (AgentConfig, optional): Configuration for tools and web tools
631
+
632
+ **Returns:** Object with tool definitions compatible with Vercel AI SDK
633
+
634
+ ### Sandbox Factories
635
+
636
+ - `createLocalSandbox(config?)` - Local execution sandbox
637
+ - `createVercelSandbox(config?)` - Vercel Firecracker sandbox
638
+ - `createE2BSandbox(config?)` - E2B cloud sandbox
639
+
640
+ ### Workflow Tools
641
+
642
+ - `createTaskTool(config)` - Spawn sub-agents for complex tasks
643
+ - `createTodoWriteTool(state, config?, onUpdate?)` - Track task progress
644
+ - `createExitPlanModeTool(config?, onPlanSubmit?)` - Exit planning mode
645
+
646
+ ### Utilities
647
+
648
+ - `compactConversation(messages, config, state)` - Summarize long conversations
649
+ - `getContextStatus(messages, maxTokens, config?)` - Monitor context usage
650
+ - `pruneMessagesByTokens(messages, config?)` - Remove old messages
651
+ - `estimateMessagesTokens(messages)` - Estimate token count
652
+
653
+ ### Skills
654
+
655
+ - `discoverSkills(options?)` - Discover skills from filesystem (metadata only)
656
+ - `skillsToXml(skills)` - Generate XML for system prompts
657
+ - `parseSkillMetadata(content, path)` - Parse a SKILL.md file
658
+
659
+ ### Setup
660
+
661
+ - `setupAgentEnvironment(sandbox, config)` - Set up workspace directories and seed skills
662
+
663
+ ### Middleware
664
+
665
+ - `anthropicPromptCacheMiddleware` - Enable prompt caching for Anthropic models
666
+
667
+ ## Future Roadmap
668
+
669
+ The following features are planned for future releases:
670
+
671
+ ### Agent Profiles Loader
672
+
673
+ Load pre-configured subagent types from JSON/TypeScript configs:
674
+
675
+ ```json
676
+ // .bashkit/agents.json
677
+ {
678
+ "subagentTypes": {
679
+ "research": {
680
+ "systemPrompt": "You are a research specialist...",
681
+ "tools": ["Read", "Grep", "Glob", "WebSearch"]
682
+ },
683
+ "coding": {
684
+ "systemPrompt": "You are a coding expert...",
685
+ "tools": ["Read", "Write", "Edit", "Bash"]
686
+ }
687
+ }
688
+ }
689
+ ```
690
+
691
+ Helper function to auto-load profiles:
692
+ ```typescript
693
+ import { createTaskToolWithProfiles } from 'bashkit';
694
+
695
+ const taskTool = createTaskToolWithProfiles({
696
+ model,
697
+ tools,
698
+ profilesPath: '.bashkit/agents.json', // Auto-loads
699
+ });
700
+ ```
701
+
702
+ This will make it easy to:
703
+ - Share agent configurations across projects
704
+ - Standardize agent patterns within teams
705
+ - Quickly set up specialized agents for different tasks
706
+
707
+ ## Contributing
708
+
709
+ Contributions welcome! Please open an issue or PR.
710
+
711
+ ## License
712
+
713
+ MIT
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};