agentool 0.0.1 → 1.0.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 (115) hide show
  1. package/README.md +627 -52
  2. package/dist/ask-user/index.cjs +8 -0
  3. package/dist/ask-user/index.d.cts +68 -0
  4. package/dist/ask-user/index.d.ts +68 -0
  5. package/dist/ask-user/index.js +8 -0
  6. package/dist/bash/index.cjs +8 -0
  7. package/dist/bash/index.d.cts +63 -0
  8. package/dist/bash/index.d.ts +63 -0
  9. package/dist/bash/index.js +8 -0
  10. package/dist/chunk-3EPGFWZV.cjs +30 -0
  11. package/dist/chunk-3VO6NETR.cjs +79 -0
  12. package/dist/chunk-4YI2H55A.js +142 -0
  13. package/dist/chunk-5NW4OGRI.cjs +99 -0
  14. package/dist/chunk-6MDPYALY.js +196 -0
  15. package/dist/chunk-6PQLFDGT.js +117 -0
  16. package/dist/chunk-7QL4BQCH.js +40 -0
  17. package/dist/chunk-CAEVLIQB.cjs +117 -0
  18. package/dist/chunk-CGTPF6IS.js +90 -0
  19. package/dist/chunk-EA3YV7ZG.js +79 -0
  20. package/dist/chunk-FAEGCFTO.js +136 -0
  21. package/dist/chunk-FV2R5FFQ.cjs +102 -0
  22. package/dist/chunk-FW3UJ622.cjs +59 -0
  23. package/dist/chunk-G3ITTPGX.js +99 -0
  24. package/dist/chunk-HDKXSKMO.js +30 -0
  25. package/dist/chunk-HZAQRHBT.js +99 -0
  26. package/dist/chunk-I3ONDY7P.js +46 -0
  27. package/dist/chunk-I6KFFQPV.cjs +58 -0
  28. package/dist/chunk-IMZQ7ELK.cjs +196 -0
  29. package/dist/chunk-JCTBB7H2.cjs +40 -0
  30. package/dist/chunk-K77GC2QI.js +59 -0
  31. package/dist/chunk-LPV5CN2K.js +58 -0
  32. package/dist/chunk-MF7CJVIZ.js +40 -0
  33. package/dist/chunk-MIYA7TNR.cjs +123 -0
  34. package/dist/chunk-MJCAXASI.js +123 -0
  35. package/dist/chunk-MXFW3XY6.cjs +73 -0
  36. package/dist/chunk-ONBH74ZV.cjs +90 -0
  37. package/dist/chunk-OXLQ7QVL.cjs +40 -0
  38. package/dist/chunk-QEJV2KZ4.cjs +159 -0
  39. package/dist/chunk-QZ5GS6HW.cjs +46 -0
  40. package/dist/chunk-S6QEY7UY.js +73 -0
  41. package/dist/chunk-SUSAPI5W.cjs +142 -0
  42. package/dist/chunk-TBVHHF3H.cjs +47 -0
  43. package/dist/chunk-U2YMJM25.cjs +115 -0
  44. package/dist/chunk-VLNDEVKS.js +102 -0
  45. package/dist/chunk-XKG2A3EW.js +159 -0
  46. package/dist/chunk-XLD2Y3SS.cjs +136 -0
  47. package/dist/chunk-Y7KOKDFP.js +115 -0
  48. package/dist/chunk-YPPPGGLA.cjs +99 -0
  49. package/dist/chunk-ZHCMEQJJ.js +47 -0
  50. package/dist/context-compaction/index.cjs +8 -0
  51. package/dist/context-compaction/index.d.cts +77 -0
  52. package/dist/context-compaction/index.d.ts +77 -0
  53. package/dist/context-compaction/index.js +8 -0
  54. package/dist/diff/index.cjs +9 -0
  55. package/dist/diff/index.d.cts +72 -0
  56. package/dist/diff/index.d.ts +72 -0
  57. package/dist/diff/index.js +9 -0
  58. package/dist/edit/index.cjs +10 -0
  59. package/dist/edit/index.d.cts +53 -0
  60. package/dist/edit/index.d.ts +53 -0
  61. package/dist/edit/index.js +10 -0
  62. package/dist/glob/index.cjs +10 -0
  63. package/dist/glob/index.d.cts +47 -0
  64. package/dist/glob/index.d.ts +47 -0
  65. package/dist/glob/index.js +10 -0
  66. package/dist/grep/index.cjs +10 -0
  67. package/dist/grep/index.d.cts +50 -0
  68. package/dist/grep/index.d.ts +50 -0
  69. package/dist/grep/index.js +10 -0
  70. package/dist/http-request/index.cjs +8 -0
  71. package/dist/http-request/index.d.cts +60 -0
  72. package/dist/http-request/index.d.ts +60 -0
  73. package/dist/http-request/index.js +8 -0
  74. package/dist/index.cjs +102 -0
  75. package/dist/index.d.cts +18 -0
  76. package/dist/index.d.ts +18 -0
  77. package/dist/index.js +102 -0
  78. package/dist/lsp/index.cjs +10 -0
  79. package/dist/lsp/index.d.cts +38 -0
  80. package/dist/lsp/index.d.ts +38 -0
  81. package/dist/lsp/index.js +10 -0
  82. package/dist/memory/index.cjs +9 -0
  83. package/dist/memory/index.d.cts +63 -0
  84. package/dist/memory/index.d.ts +63 -0
  85. package/dist/memory/index.js +9 -0
  86. package/dist/multi-edit/index.cjs +11 -0
  87. package/dist/multi-edit/index.d.cts +72 -0
  88. package/dist/multi-edit/index.d.ts +72 -0
  89. package/dist/multi-edit/index.js +11 -0
  90. package/dist/read/index.cjs +10 -0
  91. package/dist/read/index.d.cts +67 -0
  92. package/dist/read/index.d.ts +67 -0
  93. package/dist/read/index.js +10 -0
  94. package/dist/sleep/index.cjs +8 -0
  95. package/dist/sleep/index.d.cts +60 -0
  96. package/dist/sleep/index.d.ts +60 -0
  97. package/dist/sleep/index.js +8 -0
  98. package/dist/task/index.cjs +8 -0
  99. package/dist/task/index.d.cts +67 -0
  100. package/dist/task/index.d.ts +67 -0
  101. package/dist/task/index.js +8 -0
  102. package/dist/types-3QPDuCXN.d.cts +45 -0
  103. package/dist/types-3QPDuCXN.d.ts +45 -0
  104. package/dist/web-fetch/index.cjs +8 -0
  105. package/dist/web-fetch/index.d.cts +56 -0
  106. package/dist/web-fetch/index.d.ts +56 -0
  107. package/dist/web-fetch/index.js +8 -0
  108. package/dist/write/index.cjs +10 -0
  109. package/dist/write/index.d.cts +47 -0
  110. package/dist/write/index.d.ts +47 -0
  111. package/dist/write/index.js +10 -0
  112. package/package.json +145 -20
  113. package/dist/core/index.d.ts +0 -20
  114. package/dist/core/index.js +0 -1
  115. package/dist/core/index.js.map +0 -1
package/README.md CHANGED
@@ -1,80 +1,655 @@
1
+ <div align="center">
2
+
1
3
  # agentool
2
4
 
3
- Lightweight, provider-agnostic AI agent toolkit for CI/CD. Built-in bash, edit, grep, git, and HTTP tools with modular add-ons for Docker, test runners, and MCP.
5
+ **16 AI agent tools as standalone [Vercel AI SDK](https://sdk.vercel.ai/) modules.**
6
+
7
+ <p>
8
+ <a href="https://www.npmjs.com/package/agentool"><img src="https://img.shields.io/npm/v/agentool?style=flat-square&color=cb3837&logo=npm" alt="npm version" /></a>
9
+ <a href="https://www.npmjs.com/package/agentool"><img src="https://img.shields.io/npm/dm/agentool?style=flat-square&color=cb3837&logo=npm" alt="npm downloads" /></a>
10
+ <a href="https://github.com/Z-M-Huang/agentool"><img src="https://img.shields.io/github/stars/Z-M-Huang/agentool?style=flat-square&logo=github" alt="GitHub stars" /></a>
11
+ <a href="https://github.com/Z-M-Huang/agentool/issues"><img src="https://img.shields.io/github/issues/Z-M-Huang/agentool?style=flat-square&logo=github" alt="GitHub issues" /></a>
12
+ <a href="https://github.com/Z-M-Huang/agentool/blob/main/LICENSE"><img src="https://img.shields.io/github/license/Z-M-Huang/agentool?style=flat-square" alt="License" /></a>
13
+ </p>
14
+ <p>
15
+ <img src="https://img.shields.io/badge/node-%3E%3D18.0.0-339933?style=flat-square&logo=node.js&logoColor=white" alt="Node.js" />
16
+ <img src="https://img.shields.io/badge/TypeScript-5.7+-3178c6?style=flat-square&logo=typescript&logoColor=white" alt="TypeScript" />
17
+ <img src="https://img.shields.io/badge/Vercel%20AI%20SDK-v4%2B-000000?style=flat-square&logo=vercel&logoColor=white" alt="Vercel AI SDK" />
18
+ <img src="https://img.shields.io/badge/ESM%20%2B%20CJS-supported-22c55e?style=flat-square" alt="ESM + CJS" />
19
+ <img src="https://img.shields.io/badge/coverage-96%25-brightgreen?style=flat-square" alt="Test Coverage" />
20
+ <img src="https://visitor-badge.laobi.icu/badge?page_id=Z-M-Huang.agentool&style=flat-square" alt="Visitors" />
21
+ </p>
22
+ </div>
23
+
24
+ File operations, shell execution, code search, web fetching, and more -- everything an AI agent needs to interact with a codebase and system.
25
+
26
+ ---
4
27
 
5
- ## What it is
28
+ ## Features
6
29
 
7
- A single npm package that gives AI agents a complete set of system tools for CI/CD automation. It wraps Vercel AI SDK v6 (`ai` package) and provides prebuilt tools, a simple agent runner, and modular add-ons via Node.js subpath exports.
30
+ - **16 production-ready tools** -- bash, grep, glob, read, edit, write, web-fetch, memory, multi-edit, diff, task, lsp, http-request, context-compaction, ask-user, sleep
31
+ - **Vercel AI SDK compatible** -- works with `generateText()`, `streamText()`, and any AI SDK provider (OpenAI, Anthropic, Google, etc.)
32
+ - **Factory + default pattern** -- `createBash({ cwd: '/my/project' })` for custom config, or just use `bash` with zero config
33
+ - **Dual ESM/CJS** -- works everywhere with proper `exports` map
34
+ - **TypeScript-first** -- full type declarations, strict mode, no `any`
35
+ - **Never throws** -- every `execute()` returns a descriptive error string instead of throwing
36
+ - **Tree-shakeable** -- 17 subpath exports, only import what you need
37
+
38
+ ## Installation
39
+
40
+ ```bash
41
+ npm install agentool ai zod
42
+ ```
8
43
 
9
- The problem: if you want an AI agent that can run bash, edit files, grep code, call APIs, and interact with GitHub in a CI pipeline, you either use Claude Code (locked to Anthropic) or wire up a dozen libraries yourself. agentool gives you all of that out of the box, with any LLM provider OpenAI, Anthropic, LiteLLM, or any OpenAI-compatible endpoint.
44
+ > `ai` and `zod` are peer dependencies. You also need an AI SDK provider like `@ai-sdk/openai`, `@ai-sdk/anthropic`, etc.
10
45
 
11
- ## Tech stack
46
+ ### Prerequisites
12
47
 
13
- - TypeScript (strict), Node.js 20+
14
- - Build: tsup
15
- - AI SDK: Vercel AI SDK v6 (`ai`) as peer dependency
16
- - Testing: vitest
17
- - Package manager: pnpm
18
- - License: Apache-2.0
48
+ - **Node.js >= 18**
49
+ - **[ripgrep](https://github.com/BurntSushi/ripgrep#installation)** (`rg`) -- required for `grep` and `glob` tools
19
50
 
20
- ## Package structure
51
+ ```bash
52
+ # macOS
53
+ brew install ripgrep
21
54
 
22
- Single npm package, multiple entry points via subpath exports. Users install once (`npm install agentool`) and import only what they need.
55
+ # Ubuntu/Debian
56
+ sudo apt install ripgrep
57
+
58
+ # Windows
59
+ choco install ripgrep
60
+ ```
61
+
62
+ ## Quick Start
23
63
 
24
64
  ```typescript
25
- import { createAgent, coreTools } from "agentool/core";
26
- import { dockerTools } from "agentool/docker";
27
- import { testRunnerTools } from "agentool/test-runner";
65
+ import { generateText } from 'ai';
66
+ import { openai } from '@ai-sdk/openai';
67
+ import { bash, read, edit, glob, grep } from 'agentool';
68
+
69
+ const { text } = await generateText({
70
+ model: openai('gpt-4o'),
71
+ tools: { bash, read, edit, glob, grep },
72
+ maxSteps: 10,
73
+ prompt: 'Find all TypeScript files with TODO comments and list them',
74
+ });
28
75
  ```
29
76
 
30
- ## Modules
77
+ ### Tree-shake with subpath imports
31
78
 
32
- **agentool/core** (must-have, zero optional deps)
33
- - `createAgent` agent runner wrapping AI SDK ToolLoopAgent, auto-assembles system prompt from tool descriptions
34
- - `bash` shell command execution via child_process
35
- - `read_file` read file contents with optional line range
36
- - `write_file` — create/overwrite files
37
- - `edit` — str_replace style find-and-replace (oldStr must be unique in file)
38
- - `grep` — structured search, uses ripgrep if available, falls back to native grep
39
- - `find` — find files by glob pattern
40
- - `git` diff, log, status, blame, show
41
- - `gh` — GitHub CLI wrapper (pr, issue, workflow, api)
42
- - `http` — structured HTTP requests via native fetch
79
+ ```typescript
80
+ // Only import what you need -- no unused code loaded
81
+ import { bash } from 'agentool/bash';
82
+ import { grep } from 'agentool/grep';
83
+ ```
84
+
85
+ ### Custom configuration
86
+
87
+ Use factory functions when you need to configure tools (custom `cwd`, timeouts, etc.):
88
+
89
+ ```typescript
90
+ import { createBash } from 'agentool/bash';
91
+ import { createRead } from 'agentool/read';
92
+
93
+ const myBash = createBash({ cwd: '/my/project', timeout: 60000 });
94
+ const myRead = createRead({ cwd: '/my/project' });
43
95
 
44
- **agentool/docker** (add-on)
45
- - docker build, run, compose, logs
96
+ // Use them like any other tool
97
+ const { text } = await generateText({
98
+ model: openai('gpt-4o'),
99
+ tools: { bash: myBash, read: myRead },
100
+ maxSteps: 10,
101
+ prompt: 'List all files and read package.json',
102
+ });
103
+ ```
104
+
105
+ ## Tools Reference
46
106
 
47
- **agentool/test-runner** (add-on)
48
- - Generic test runner with structured output parsing (jest, vitest, pytest)
107
+ ### bash
49
108
 
50
- **agentool/data-parse** (add-on)
51
- - jq, yq, csv parsing
109
+ Execute shell commands with timeout and signal handling.
52
110
 
53
- **agentool/code-intel** (add-on)
54
- - ast-grep, directory tree, symbol extraction
111
+ ```typescript
112
+ import { bash } from 'agentool/bash';
55
113
 
56
- **agentool/mcp** (add-on)
57
- - Generic MCP client bridge connect to any MCP server and expose its tools
114
+ const result = await bash.execute(
115
+ { command: 'echo hello && ls -la' },
116
+ { toolCallId: 'id', messages: [] },
117
+ );
118
+ ```
58
119
 
59
- ## Usage
120
+ With custom config:
60
121
 
61
122
  ```typescript
62
- import { createAgent, coreTools } from "agentool/core";
123
+ import { createBash } from 'agentool/bash';
63
124
 
64
- const agent = createAgent({
65
- model: "openai/gpt-4o",
66
- // Or LiteLLM: baseURL: "http://localhost:4000/v1"
67
- tools: { ...coreTools() },
125
+ const bash = createBash({
126
+ cwd: '/my/project',
127
+ timeout: 60000, // 60s timeout (default: 120s)
128
+ shell: '/bin/zsh', // custom shell
68
129
  });
130
+ ```
131
+
132
+ **Parameters:** `command` (string), `timeout?` (number), `description?` (string)
133
+
134
+ ---
135
+
136
+ ### read
137
+
138
+ Read files with line numbers, offset/limit pagination, and dual-path reading (fast for <10MB, streaming for larger).
139
+
140
+ ```typescript
141
+ import { read } from 'agentool/read';
142
+
143
+ // Read entire file
144
+ const content = await read.execute(
145
+ { file_path: '/app/src/index.ts' },
146
+ { toolCallId: 'id', messages: [] },
147
+ );
148
+ // Returns: "1\texport function hello() {\n2\t return 'world';\n3\t}"
149
+
150
+ // Read specific range
151
+ const range = await read.execute(
152
+ { file_path: '/app/src/index.ts', offset: 10, limit: 20 },
153
+ { toolCallId: 'id', messages: [] },
154
+ );
155
+ ```
156
+
157
+ **Parameters:** `file_path` (string), `offset?` (number), `limit?` (number)
158
+
159
+ ---
160
+
161
+ ### edit
162
+
163
+ Exact string replacement with curly-quote normalization fallback.
164
+
165
+ ```typescript
166
+ import { edit } from 'agentool/edit';
167
+
168
+ const result = await edit.execute(
169
+ {
170
+ file_path: '/app/src/config.ts',
171
+ old_string: 'const PORT = 3000;',
172
+ new_string: 'const PORT = 8080;',
173
+ },
174
+ { toolCallId: 'id', messages: [] },
175
+ );
176
+
177
+ // Replace all occurrences
178
+ const resultAll = await edit.execute(
179
+ {
180
+ file_path: '/app/src/config.ts',
181
+ old_string: 'localhost',
182
+ new_string: '0.0.0.0',
183
+ replace_all: true,
184
+ },
185
+ { toolCallId: 'id', messages: [] },
186
+ );
187
+ ```
188
+
189
+ **Parameters:** `file_path` (string), `old_string` (string), `new_string` (string), `replace_all?` (boolean)
190
+
191
+ ---
192
+
193
+ ### write
194
+
195
+ Write files with automatic parent directory creation.
196
+
197
+ ```typescript
198
+ import { write } from 'agentool/write';
199
+
200
+ const result = await write.execute(
201
+ {
202
+ file_path: '/app/src/utils/helpers.ts',
203
+ content: 'export function add(a: number, b: number) {\n return a + b;\n}\n',
204
+ },
205
+ { toolCallId: 'id', messages: [] },
206
+ );
207
+ // Returns: "Created file: /app/src/utils/helpers.ts (62 bytes)"
208
+ ```
209
+
210
+ **Parameters:** `file_path` (string), `content` (string)
211
+
212
+ ---
213
+
214
+ ### grep
215
+
216
+ Search file contents with ripgrep. Three output modes, context lines, pagination.
217
+
218
+ ```typescript
219
+ import { grep } from 'agentool/grep';
220
+
221
+ // Find matching lines with context
222
+ const content = await grep.execute(
223
+ { pattern: 'TODO|FIXME', output_mode: 'content', '-C': 2 },
224
+ { toolCallId: 'id', messages: [] },
225
+ );
226
+
227
+ // List files containing matches (sorted by mtime)
228
+ const files = await grep.execute(
229
+ { pattern: 'import.*react', output_mode: 'files_with_matches', glob: '*.tsx' },
230
+ { toolCallId: 'id', messages: [] },
231
+ );
232
+
233
+ // Count matches per file
234
+ const counts = await grep.execute(
235
+ { pattern: 'console\\.log', output_mode: 'count' },
236
+ { toolCallId: 'id', messages: [] },
237
+ );
238
+ ```
239
+
240
+ **Parameters:** `pattern` (string), `path?` (string), `output_mode?` (`'content'` | `'files_with_matches'` | `'count'`), `glob?` (string), `type?` (string), `-i?` (boolean), `-n?` (boolean), `-A?` (number), `-B?` (number), `-C?` / `context?` (number), `head_limit?` (number), `offset?` (number), `multiline?` (boolean)
241
+
242
+ ---
243
+
244
+ ### glob
245
+
246
+ Find files by pattern with ripgrep, sorted by modification time.
247
+
248
+ ```typescript
249
+ import { glob } from 'agentool/glob';
250
+
251
+ const result = await glob.execute(
252
+ { pattern: '**/*.test.ts' },
253
+ { toolCallId: 'id', messages: [] },
254
+ );
255
+ // Returns: "Found 27 files\n/app/tests/unit/bash.test.ts\n..."
256
+
257
+ // Search in specific directory
258
+ const result2 = await glob.execute(
259
+ { pattern: '*.json', path: '/app/config' },
260
+ { toolCallId: 'id', messages: [] },
261
+ );
262
+ ```
263
+
264
+ **Parameters:** `pattern` (string), `path?` (string)
265
+
266
+ ---
267
+
268
+ ### multi-edit
269
+
270
+ Atomically apply multiple edits to a single file. All succeed or none are applied.
271
+
272
+ ```typescript
273
+ import { multiEdit } from 'agentool/multi-edit';
69
274
 
70
- const result = await agent.run("Find why the tests are failing and fix it");
275
+ const result = await multiEdit.execute(
276
+ {
277
+ file_path: '/app/src/config.ts',
278
+ edits: [
279
+ { old_string: 'const PORT = 3000;', new_string: 'const PORT = 8080;' },
280
+ { old_string: "const HOST = 'localhost';", new_string: "const HOST = '0.0.0.0';" },
281
+ ],
282
+ },
283
+ { toolCallId: 'id', messages: [] },
284
+ );
71
285
  ```
72
286
 
73
- ## Implementation priorities
287
+ **Parameters:** `file_path` (string), `edits` (array of `{ old_string, new_string }`)
288
+
289
+ ---
290
+
291
+ ### diff
292
+
293
+ Generate unified diffs between files or strings.
294
+
295
+ ```typescript
296
+ import { diff } from 'agentool/diff';
297
+
298
+ // Compare two files
299
+ const fileDiff = await diff.execute(
300
+ { file_path: '/app/old.ts', other_file_path: '/app/new.ts' },
301
+ { toolCallId: 'id', messages: [] },
302
+ );
303
+
304
+ // Compare strings
305
+ const stringDiff = await diff.execute(
306
+ { old_content: 'hello world', new_content: 'hello universe' },
307
+ { toolCallId: 'id', messages: [] },
308
+ );
309
+ ```
310
+
311
+ **Parameters:** `file_path?` (string), `other_file_path?` (string), `old_content?` (string), `new_content?` (string)
312
+
313
+ ---
314
+
315
+ ### web-fetch
316
+
317
+ Fetch URLs with automatic HTML-to-markdown conversion.
318
+
319
+ ```typescript
320
+ import { webFetch } from 'agentool/web-fetch';
321
+
322
+ const result = await webFetch.execute(
323
+ { url: 'https://example.com' },
324
+ { toolCallId: 'id', messages: [] },
325
+ );
326
+ // Returns markdown content (HTML converted via Turndown, truncated at 100K chars)
327
+ ```
328
+
329
+ **Parameters:** `url` (string), `prompt?` (string)
330
+
331
+ ---
332
+
333
+ ### http-request
334
+
335
+ Make raw HTTP requests without markdown conversion.
336
+
337
+ ```typescript
338
+ import { httpRequest } from 'agentool/http-request';
339
+
340
+ const result = await httpRequest.execute(
341
+ {
342
+ method: 'POST',
343
+ url: 'https://api.example.com/data',
344
+ headers: { 'Content-Type': 'application/json' },
345
+ body: JSON.stringify({ key: 'value' }),
346
+ timeout: 5000,
347
+ },
348
+ { toolCallId: 'id', messages: [] },
349
+ );
350
+ // Returns JSON: { status, statusText, headers, body }
351
+ ```
352
+
353
+ **Parameters:** `method` (`'GET'` | `'POST'` | `'PUT'` | `'PATCH'` | `'DELETE'` | `'HEAD'`), `url` (string), `headers?` (object), `body?` (string), `timeout?` (number)
354
+
355
+ ---
356
+
357
+ ### memory
358
+
359
+ File-based key-value store for persistent agent memory.
360
+
361
+ ```typescript
362
+ import { memory } from 'agentool/memory';
363
+
364
+ // Write
365
+ await memory.execute(
366
+ { action: 'write', key: 'user-prefs', content: 'Prefers dark mode' },
367
+ { toolCallId: 'id', messages: [] },
368
+ );
369
+
370
+ // Read
371
+ const data = await memory.execute(
372
+ { action: 'read', key: 'user-prefs' },
373
+ { toolCallId: 'id', messages: [] },
374
+ );
375
+
376
+ // List all keys
377
+ const keys = await memory.execute(
378
+ { action: 'list' },
379
+ { toolCallId: 'id', messages: [] },
380
+ );
381
+
382
+ // Delete
383
+ await memory.execute(
384
+ { action: 'delete', key: 'user-prefs' },
385
+ { toolCallId: 'id', messages: [] },
386
+ );
387
+ ```
388
+
389
+ **Parameters:** `action` (`'read'` | `'write'` | `'list'` | `'delete'`), `key?` (string), `content?` (string)
390
+
391
+ ---
392
+
393
+ ### task
394
+
395
+ JSON file-based task tracker for agent workflows.
396
+
397
+ ```typescript
398
+ import { task } from 'agentool/task';
399
+
400
+ // Create
401
+ const created = await task.execute(
402
+ { action: 'create', subject: 'Fix login bug', description: 'Auth fails on refresh' },
403
+ { toolCallId: 'id', messages: [] },
404
+ );
405
+
406
+ // List all
407
+ const list = await task.execute(
408
+ { action: 'list' },
409
+ { toolCallId: 'id', messages: [] },
410
+ );
411
+
412
+ // Update status
413
+ await task.execute(
414
+ { action: 'update', id: 'abc123', status: 'completed' },
415
+ { toolCallId: 'id', messages: [] },
416
+ );
417
+ ```
418
+
419
+ **Parameters:** `action` (`'create'` | `'get'` | `'update'` | `'list'` | `'delete'`), `id?` (string), `subject?` (string), `description?` (string), `status?` (`'pending'` | `'in_progress'` | `'completed'`)
420
+
421
+ ---
422
+
423
+ ### lsp
424
+
425
+ Language Server Protocol operations for code intelligence.
426
+
427
+ ```typescript
428
+ import { createLsp } from 'agentool/lsp';
429
+
430
+ const lsp = createLsp({
431
+ servers: {
432
+ '.ts': { command: 'typescript-language-server', args: ['--stdio'] },
433
+ '.py': { command: 'pylsp' },
434
+ },
435
+ });
436
+
437
+ const result = await lsp.execute(
438
+ { operation: 'goToDefinition', filePath: 'src/index.ts', line: 10, character: 5 },
439
+ { toolCallId: 'id', messages: [] },
440
+ );
441
+ ```
442
+
443
+ **Parameters:** `operation` (`'goToDefinition'` | `'findReferences'` | `'hover'` | `'documentSymbol'` | `'workspaceSymbol'` | `'goToImplementation'` | `'incomingCalls'` | `'outgoingCalls'`), `filePath` (string), `line?` (number), `character?` (number), `query?` (string)
444
+
445
+ ---
446
+
447
+ ### context-compaction
448
+
449
+ Compact conversation history to fit within token budgets.
450
+
451
+ ```typescript
452
+ import { createContextCompaction } from 'agentool/context-compaction';
453
+
454
+ const compact = createContextCompaction({
455
+ maxTokens: 4096,
456
+ summarize: async (messages) => {
457
+ // Call your LLM to summarize
458
+ return 'Summary of previous conversation...';
459
+ },
460
+ });
461
+
462
+ const result = await compact.execute(
463
+ {
464
+ messages: [
465
+ { role: 'user', content: 'Long conversation...' },
466
+ { role: 'assistant', content: 'Long response...' },
467
+ ],
468
+ },
469
+ { toolCallId: 'id', messages: [] },
470
+ );
471
+ ```
472
+
473
+ **Parameters:** `messages` (array of `{ role, content }`), `maxTokens?` (number)
474
+
475
+ ---
476
+
477
+ ### ask-user
478
+
479
+ Prompt the user for input during agent execution.
480
+
481
+ ```typescript
482
+ import { createAskUser } from 'agentool/ask-user';
483
+
484
+ const askUser = createAskUser({
485
+ onQuestion: async (question, options) => {
486
+ // Your UI logic to prompt the user
487
+ return 'User response here';
488
+ },
489
+ });
490
+
491
+ const answer = await askUser.execute(
492
+ { question: 'Which database should I use?', options: ['PostgreSQL', 'MySQL', 'SQLite'] },
493
+ { toolCallId: 'id', messages: [] },
494
+ );
495
+ ```
496
+
497
+ **Parameters:** `question` (string), `options?` (string[])
498
+
499
+ ---
500
+
501
+ ### sleep
502
+
503
+ Pause execution for rate limiting or polling intervals.
504
+
505
+ ```typescript
506
+ import { sleep } from 'agentool/sleep';
507
+
508
+ const result = await sleep.execute(
509
+ { durationMs: 2000, reason: 'Waiting for deployment' },
510
+ { toolCallId: 'id', messages: [] },
511
+ );
512
+ // Returns: "Slept for 2001ms. Reason: Waiting for deployment"
513
+ ```
514
+
515
+ **Parameters:** `durationMs` (number, max 300000), `reason?` (string)
516
+
517
+ ## Configuration
518
+
519
+ Every tool follows the **factory + default** pattern:
520
+
521
+ ```typescript
522
+ // Default instance -- uses process.cwd(), default timeouts
523
+ import { bash } from 'agentool/bash';
524
+
525
+ // Custom instance -- configure cwd, timeouts, and tool-specific options
526
+ import { createBash } from 'agentool/bash';
527
+ const myBash = createBash({
528
+ cwd: '/my/project',
529
+ timeout: 60000,
530
+ shell: '/bin/zsh',
531
+ });
532
+ ```
533
+
534
+ ### Base configuration
535
+
536
+ All tools accept `BaseToolConfig`:
537
+
538
+ | Option | Type | Default | Description |
539
+ |--------|------|---------|-------------|
540
+ | `cwd` | `string` | `process.cwd()` | Working directory for file operations |
541
+
542
+ Tools that support timeouts extend `TimeoutConfig`:
543
+
544
+ | Option | Type | Default | Description |
545
+ |--------|------|---------|-------------|
546
+ | `timeout` | `number` | varies | Timeout in milliseconds |
547
+
548
+ ### Tool-specific configuration
549
+
550
+ | Tool | Extra Config |
551
+ |------|-------------|
552
+ | `bash` | `shell?: string` -- shell binary path |
553
+ | `read` | `maxLines?: number` -- max lines to return (default: 2000) |
554
+ | `memory` | `memoryDir?: string` -- storage directory |
555
+ | `task` | `tasksFile?: string` -- JSON file path |
556
+ | `lsp` | `servers?: Record<string, LspServerConfig>` -- LSP servers by file extension |
557
+ | `http-request` | `defaultHeaders?: Record<string, string>` -- headers merged into every request |
558
+ | `web-fetch` | `maxContentLength?: number`, `userAgent?: string` |
559
+ | `context-compaction` | `summarize?: (messages) => Promise<string>`, `maxTokens?: number` |
560
+ | `ask-user` | `onQuestion?: (question, options?) => Promise<string>` |
561
+ | `sleep` | `maxDuration?: number` -- cap in ms (default: 300000) |
562
+
563
+ ## Error Handling
564
+
565
+ Every tool's `execute()` catches errors internally and returns a descriptive string -- **it never throws**:
566
+
567
+ ```typescript
568
+ const result = await read.execute(
569
+ { file_path: '/nonexistent/file.ts' },
570
+ { toolCallId: 'id', messages: [] },
571
+ );
572
+ // Returns: "Error [read]: Failed to read file: ENOENT: no such file or directory..."
573
+ ```
574
+
575
+ Error strings follow the format: `Error [tool-name]: {description}` with actionable context to help the AI model recover.
576
+
577
+ ## Imports
578
+
579
+ ### Barrel import (all tools)
580
+
581
+ ```typescript
582
+ import {
583
+ bash, createBash,
584
+ read, createRead,
585
+ edit, createEdit,
586
+ write, createWrite,
587
+ grep, createGrep,
588
+ glob, createGlob,
589
+ webFetch, createWebFetch,
590
+ httpRequest, createHttpRequest,
591
+ memory, createMemory,
592
+ multiEdit, createMultiEdit,
593
+ diff, createDiff,
594
+ task, createTask,
595
+ lsp, createLsp,
596
+ contextCompaction, createContextCompaction,
597
+ askUser, createAskUser,
598
+ sleep, createSleep,
599
+ } from 'agentool';
600
+ ```
601
+
602
+ ### Subpath imports (tree-shakeable)
603
+
604
+ ```typescript
605
+ import { bash } from 'agentool/bash';
606
+ import { grep } from 'agentool/grep';
607
+ import { glob } from 'agentool/glob';
608
+ import { read } from 'agentool/read';
609
+ import { edit } from 'agentool/edit';
610
+ import { write } from 'agentool/write';
611
+ import { webFetch } from 'agentool/web-fetch';
612
+ import { httpRequest } from 'agentool/http-request';
613
+ import { memory } from 'agentool/memory';
614
+ import { multiEdit } from 'agentool/multi-edit';
615
+ import { diff } from 'agentool/diff';
616
+ import { task } from 'agentool/task';
617
+ import { lsp } from 'agentool/lsp';
618
+ import { contextCompaction } from 'agentool/context-compaction';
619
+ import { askUser } from 'agentool/ask-user';
620
+ import { sleep } from 'agentool/sleep';
621
+ ```
622
+
623
+ ## Full Example: AI Coding Agent
624
+
625
+ ```typescript
626
+ import { generateText } from 'ai';
627
+ import { openai } from '@ai-sdk/openai';
628
+ import { bash, read, edit, write, glob, grep, diff } from 'agentool';
629
+
630
+ const { text, steps } = await generateText({
631
+ model: openai('gpt-4o'),
632
+ tools: { bash, read, edit, write, glob, grep, diff },
633
+ maxSteps: 20,
634
+ system: `You are a coding assistant. You can read, search, edit, and write files.
635
+ Always read a file before editing it. Use grep to search for patterns.
636
+ Use glob to find files. Use bash for git, build, and test commands.`,
637
+ prompt: 'Find all console.log statements in src/ and replace them with proper logger calls',
638
+ });
639
+
640
+ console.log(`Completed in ${steps.length} steps`);
641
+ console.log(text);
642
+ ```
643
+
644
+ ## Requirements
645
+
646
+ | Dependency | Version | Required |
647
+ |-----------|---------|----------|
648
+ | Node.js | >= 18 | Yes |
649
+ | `ai` (Vercel AI SDK) | >= 4.0.0 | Peer dependency |
650
+ | `zod` | >= 3.23.0 | Peer dependency |
651
+ | `ripgrep` (`rg`) | any | For grep/glob tools |
652
+
653
+ ## License
74
654
 
75
- 1. Core types (ToolDefinition, ToolResult, ToolPack interfaces)
76
- 2. Core tools (bash, read_file, write_file, edit, grep, find, git, gh, http)
77
- 3. createAgent runner
78
- 4. System prompt auto-assembly
79
- 5. Add-on modules (docker, test-runner, data-parse, code-intel, mcp)
80
- 6. Tests for each tool
655
+ [Apache-2.0](LICENSE)