@compilr-dev/agents 0.0.1

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 (160) hide show
  1. package/README.md +1277 -0
  2. package/dist/agent.d.ts +1272 -0
  3. package/dist/agent.js +1912 -0
  4. package/dist/anchors/builtin.d.ts +24 -0
  5. package/dist/anchors/builtin.js +61 -0
  6. package/dist/anchors/index.d.ts +6 -0
  7. package/dist/anchors/index.js +5 -0
  8. package/dist/anchors/manager.d.ts +115 -0
  9. package/dist/anchors/manager.js +412 -0
  10. package/dist/anchors/types.d.ts +168 -0
  11. package/dist/anchors/types.js +10 -0
  12. package/dist/context/index.d.ts +12 -0
  13. package/dist/context/index.js +10 -0
  14. package/dist/context/manager.d.ts +224 -0
  15. package/dist/context/manager.js +770 -0
  16. package/dist/context/types.d.ts +377 -0
  17. package/dist/context/types.js +7 -0
  18. package/dist/costs/index.d.ts +8 -0
  19. package/dist/costs/index.js +7 -0
  20. package/dist/costs/tracker.d.ts +121 -0
  21. package/dist/costs/tracker.js +295 -0
  22. package/dist/costs/types.d.ts +157 -0
  23. package/dist/costs/types.js +8 -0
  24. package/dist/errors.d.ts +178 -0
  25. package/dist/errors.js +249 -0
  26. package/dist/guardrails/builtin.d.ts +27 -0
  27. package/dist/guardrails/builtin.js +223 -0
  28. package/dist/guardrails/index.d.ts +6 -0
  29. package/dist/guardrails/index.js +5 -0
  30. package/dist/guardrails/manager.d.ts +117 -0
  31. package/dist/guardrails/manager.js +288 -0
  32. package/dist/guardrails/types.d.ts +159 -0
  33. package/dist/guardrails/types.js +7 -0
  34. package/dist/hooks/index.d.ts +31 -0
  35. package/dist/hooks/index.js +29 -0
  36. package/dist/hooks/manager.d.ts +147 -0
  37. package/dist/hooks/manager.js +600 -0
  38. package/dist/hooks/types.d.ts +368 -0
  39. package/dist/hooks/types.js +12 -0
  40. package/dist/index.d.ts +45 -0
  41. package/dist/index.js +73 -0
  42. package/dist/mcp/client.d.ts +93 -0
  43. package/dist/mcp/client.js +287 -0
  44. package/dist/mcp/errors.d.ts +60 -0
  45. package/dist/mcp/errors.js +78 -0
  46. package/dist/mcp/index.d.ts +43 -0
  47. package/dist/mcp/index.js +45 -0
  48. package/dist/mcp/manager.d.ts +120 -0
  49. package/dist/mcp/manager.js +276 -0
  50. package/dist/mcp/tools.d.ts +54 -0
  51. package/dist/mcp/tools.js +99 -0
  52. package/dist/mcp/types.d.ts +150 -0
  53. package/dist/mcp/types.js +40 -0
  54. package/dist/memory/index.d.ts +8 -0
  55. package/dist/memory/index.js +7 -0
  56. package/dist/memory/loader.d.ts +114 -0
  57. package/dist/memory/loader.js +463 -0
  58. package/dist/memory/types.d.ts +182 -0
  59. package/dist/memory/types.js +8 -0
  60. package/dist/messages/index.d.ts +82 -0
  61. package/dist/messages/index.js +155 -0
  62. package/dist/permissions/index.d.ts +5 -0
  63. package/dist/permissions/index.js +4 -0
  64. package/dist/permissions/manager.d.ts +125 -0
  65. package/dist/permissions/manager.js +379 -0
  66. package/dist/permissions/types.d.ts +162 -0
  67. package/dist/permissions/types.js +7 -0
  68. package/dist/providers/claude.d.ts +90 -0
  69. package/dist/providers/claude.js +348 -0
  70. package/dist/providers/index.d.ts +8 -0
  71. package/dist/providers/index.js +11 -0
  72. package/dist/providers/mock.d.ts +133 -0
  73. package/dist/providers/mock.js +204 -0
  74. package/dist/providers/types.d.ts +168 -0
  75. package/dist/providers/types.js +4 -0
  76. package/dist/rate-limit/index.d.ts +45 -0
  77. package/dist/rate-limit/index.js +47 -0
  78. package/dist/rate-limit/limiter.d.ts +104 -0
  79. package/dist/rate-limit/limiter.js +326 -0
  80. package/dist/rate-limit/provider-wrapper.d.ts +112 -0
  81. package/dist/rate-limit/provider-wrapper.js +201 -0
  82. package/dist/rate-limit/retry.d.ts +108 -0
  83. package/dist/rate-limit/retry.js +287 -0
  84. package/dist/rate-limit/types.d.ts +181 -0
  85. package/dist/rate-limit/types.js +22 -0
  86. package/dist/rehearsal/file-analyzer.d.ts +22 -0
  87. package/dist/rehearsal/file-analyzer.js +351 -0
  88. package/dist/rehearsal/git-analyzer.d.ts +22 -0
  89. package/dist/rehearsal/git-analyzer.js +472 -0
  90. package/dist/rehearsal/index.d.ts +35 -0
  91. package/dist/rehearsal/index.js +36 -0
  92. package/dist/rehearsal/manager.d.ts +100 -0
  93. package/dist/rehearsal/manager.js +290 -0
  94. package/dist/rehearsal/types.d.ts +235 -0
  95. package/dist/rehearsal/types.js +8 -0
  96. package/dist/skills/index.d.ts +160 -0
  97. package/dist/skills/index.js +282 -0
  98. package/dist/state/agent-state.d.ts +41 -0
  99. package/dist/state/agent-state.js +88 -0
  100. package/dist/state/checkpointer.d.ts +110 -0
  101. package/dist/state/checkpointer.js +362 -0
  102. package/dist/state/errors.d.ts +66 -0
  103. package/dist/state/errors.js +88 -0
  104. package/dist/state/index.d.ts +35 -0
  105. package/dist/state/index.js +37 -0
  106. package/dist/state/serializer.d.ts +55 -0
  107. package/dist/state/serializer.js +172 -0
  108. package/dist/state/types.d.ts +312 -0
  109. package/dist/state/types.js +14 -0
  110. package/dist/tools/builtin/bash-output.d.ts +61 -0
  111. package/dist/tools/builtin/bash-output.js +90 -0
  112. package/dist/tools/builtin/bash.d.ts +150 -0
  113. package/dist/tools/builtin/bash.js +354 -0
  114. package/dist/tools/builtin/edit.d.ts +50 -0
  115. package/dist/tools/builtin/edit.js +215 -0
  116. package/dist/tools/builtin/glob.d.ts +62 -0
  117. package/dist/tools/builtin/glob.js +244 -0
  118. package/dist/tools/builtin/grep.d.ts +74 -0
  119. package/dist/tools/builtin/grep.js +363 -0
  120. package/dist/tools/builtin/index.d.ts +44 -0
  121. package/dist/tools/builtin/index.js +69 -0
  122. package/dist/tools/builtin/kill-shell.d.ts +44 -0
  123. package/dist/tools/builtin/kill-shell.js +80 -0
  124. package/dist/tools/builtin/read-file.d.ts +57 -0
  125. package/dist/tools/builtin/read-file.js +184 -0
  126. package/dist/tools/builtin/shell-manager.d.ts +176 -0
  127. package/dist/tools/builtin/shell-manager.js +337 -0
  128. package/dist/tools/builtin/task.d.ts +202 -0
  129. package/dist/tools/builtin/task.js +350 -0
  130. package/dist/tools/builtin/todo.d.ts +207 -0
  131. package/dist/tools/builtin/todo.js +453 -0
  132. package/dist/tools/builtin/utils.d.ts +27 -0
  133. package/dist/tools/builtin/utils.js +70 -0
  134. package/dist/tools/builtin/web-fetch.d.ts +96 -0
  135. package/dist/tools/builtin/web-fetch.js +290 -0
  136. package/dist/tools/builtin/write-file.d.ts +54 -0
  137. package/dist/tools/builtin/write-file.js +147 -0
  138. package/dist/tools/define.d.ts +60 -0
  139. package/dist/tools/define.js +65 -0
  140. package/dist/tools/index.d.ts +10 -0
  141. package/dist/tools/index.js +37 -0
  142. package/dist/tools/registry.d.ts +79 -0
  143. package/dist/tools/registry.js +151 -0
  144. package/dist/tools/types.d.ts +59 -0
  145. package/dist/tools/types.js +4 -0
  146. package/dist/tracing/hooks.d.ts +58 -0
  147. package/dist/tracing/hooks.js +377 -0
  148. package/dist/tracing/index.d.ts +51 -0
  149. package/dist/tracing/index.js +55 -0
  150. package/dist/tracing/logging.d.ts +78 -0
  151. package/dist/tracing/logging.js +310 -0
  152. package/dist/tracing/manager.d.ts +160 -0
  153. package/dist/tracing/manager.js +468 -0
  154. package/dist/tracing/otel.d.ts +102 -0
  155. package/dist/tracing/otel.js +246 -0
  156. package/dist/tracing/types.d.ts +346 -0
  157. package/dist/tracing/types.js +38 -0
  158. package/dist/utils/index.d.ts +23 -0
  159. package/dist/utils/index.js +44 -0
  160. package/package.json +79 -0
package/README.md ADDED
@@ -0,0 +1,1277 @@
1
+ # @compilr-dev/agents
2
+
3
+ Lightweight multi-LLM agent library for building CLI AI assistants.
4
+
5
+ ## Features
6
+
7
+ - **Multi-LLM Support**: Abstract provider interface supporting Claude, OpenAI, Gemini, and local models
8
+ - **Tool System**: Type-safe tool definitions with JSON Schema validation
9
+ - **Event Streaming**: Real-time execution monitoring with typed events
10
+ - **Abort Support**: Cancel running agents with `AbortSignal`
11
+ - **Built-in Tools**: Ready-to-use file and bash tools
12
+ - **Anchors**: Critical information that survives context compaction
13
+ - **Guardrails**: Pattern-based safety checks (warn/confirm/block dangerous operations)
14
+ - **Permissions**: Tool-level permission management (always/session/once/deny)
15
+ - **Project Memory**: Load project instructions from CLAUDE.md, GEMINI.md, etc.
16
+ - **TypeScript First**: Full type safety throughout
17
+
18
+ ## Installation
19
+
20
+ ```bash
21
+ npm install @compilr-dev/agents
22
+ ```
23
+
24
+ For Claude support:
25
+ ```bash
26
+ npm install @compilr-dev/agents @anthropic-ai/sdk
27
+ ```
28
+
29
+ ## Quick Start
30
+
31
+ ```typescript
32
+ import { Agent, MockProvider } from '@compilr-dev/agents';
33
+
34
+ // Create an agent with a provider
35
+ const provider = new MockProvider();
36
+ provider.addResponse('Hello! How can I help you today?');
37
+
38
+ const agent = new Agent({
39
+ provider,
40
+ systemPrompt: 'You are a helpful assistant.',
41
+ });
42
+
43
+ // Run the agent
44
+ const result = await agent.run('Hello!');
45
+ console.log(result.response); // "Hello! How can I help you today?"
46
+ console.log(result.iterations); // 1
47
+ ```
48
+
49
+ ### With Claude
50
+
51
+ ```typescript
52
+ import { Agent, ClaudeProvider } from '@compilr-dev/agents';
53
+
54
+ const agent = new Agent({
55
+ provider: new ClaudeProvider({ apiKey: process.env.ANTHROPIC_API_KEY }),
56
+ systemPrompt: 'You are a helpful coding assistant.',
57
+ maxIterations: 10,
58
+ });
59
+
60
+ const result = await agent.run('Explain async/await in JavaScript');
61
+ console.log(result.response);
62
+ ```
63
+
64
+ ## Core Concepts
65
+
66
+ ### Agent
67
+
68
+ The `Agent` class orchestrates LLM interactions and tool execution:
69
+
70
+ ```typescript
71
+ import { Agent, ClaudeProvider } from '@compilr-dev/agents';
72
+
73
+ const agent = new Agent({
74
+ provider: new ClaudeProvider({ apiKey: 'your-key' }),
75
+ systemPrompt: 'You are a helpful assistant.',
76
+ maxIterations: 10, // Default: 10
77
+ onEvent: (event) => {
78
+ // Real-time execution monitoring
79
+ console.log(event.type);
80
+ },
81
+ });
82
+ ```
83
+
84
+ ### Messages
85
+
86
+ The library provides utilities for working with conversation messages:
87
+
88
+ ```typescript
89
+ import {
90
+ createUserMessage,
91
+ createAssistantMessage,
92
+ createToolResultMessage,
93
+ getTextContent
94
+ } from '@compilr-dev/agents';
95
+
96
+ // Create messages
97
+ const userMsg = createUserMessage('Hello!');
98
+ const assistantMsg = createAssistantMessage('Hi there!');
99
+
100
+ // Extract text from message with multiple content blocks
101
+ const text = getTextContent(assistantMsg);
102
+ ```
103
+
104
+ ### Tools
105
+
106
+ Define tools that agents can use:
107
+
108
+ ```typescript
109
+ import { defineTool, createSuccessResult, createErrorResult } from '@compilr-dev/agents';
110
+
111
+ const calculatorTool = defineTool({
112
+ name: 'calculator',
113
+ description: 'Perform basic math operations',
114
+ inputSchema: {
115
+ type: 'object',
116
+ properties: {
117
+ operation: { type: 'string', description: 'add, subtract, multiply, divide' },
118
+ a: { type: 'number' },
119
+ b: { type: 'number' },
120
+ },
121
+ required: ['operation', 'a', 'b'],
122
+ },
123
+ execute: async ({ operation, a, b }) => {
124
+ switch (operation) {
125
+ case 'add': return createSuccessResult(a + b);
126
+ case 'subtract': return createSuccessResult(a - b);
127
+ case 'multiply': return createSuccessResult(a * b);
128
+ case 'divide':
129
+ if (b === 0) return createErrorResult('Division by zero');
130
+ return createSuccessResult(a / b);
131
+ default:
132
+ return createErrorResult(`Unknown operation: ${operation}`);
133
+ }
134
+ },
135
+ });
136
+
137
+ // Register with agent
138
+ agent.registerTool(calculatorTool);
139
+ ```
140
+
141
+ ### Tool Registry
142
+
143
+ Manage tools with the registry:
144
+
145
+ ```typescript
146
+ import { DefaultToolRegistry, defineTool } from '@compilr-dev/agents';
147
+
148
+ const registry = new DefaultToolRegistry();
149
+
150
+ // Register tools
151
+ registry.register(myTool);
152
+
153
+ // Get tool definitions for LLM
154
+ const definitions = registry.getDefinitions();
155
+
156
+ // Execute a tool
157
+ const result = await registry.execute('tool_name', { arg: 'value' });
158
+ ```
159
+
160
+ ## Built-in Tools
161
+
162
+ ### File Operations
163
+
164
+ ```typescript
165
+ import { readFileTool, writeFileTool } from '@compilr-dev/agents';
166
+
167
+ agent.registerTool(readFileTool);
168
+ agent.registerTool(writeFileTool);
169
+ ```
170
+
171
+ ### Bash Execution
172
+
173
+ ```typescript
174
+ import { createBashTool } from '@compilr-dev/agents';
175
+
176
+ const bashTool = createBashTool({
177
+ workingDir: '/path/to/project',
178
+ timeout: 30000, // 30 seconds
179
+ allowedCommands: ['git', 'npm', 'ls'], // Optional whitelist
180
+ });
181
+
182
+ agent.registerTool(bashTool);
183
+ ```
184
+
185
+ ## Event System
186
+
187
+ Monitor agent execution in real-time:
188
+
189
+ ```typescript
190
+ import type { AgentEvent } from '@compilr-dev/agents';
191
+
192
+ const agent = new Agent({
193
+ provider,
194
+ onEvent: (event: AgentEvent) => {
195
+ switch (event.type) {
196
+ case 'iteration_start':
197
+ console.log(`Starting iteration ${event.iteration}`);
198
+ break;
199
+ case 'llm_start':
200
+ console.log('LLM thinking...');
201
+ break;
202
+ case 'llm_end':
203
+ console.log(`LLM done, tool uses: ${event.hasToolUses}`);
204
+ break;
205
+ case 'tool_start':
206
+ console.log(`Calling tool: ${event.name}`);
207
+ break;
208
+ case 'tool_end':
209
+ console.log(`Tool result: ${event.result.success}`);
210
+ break;
211
+ case 'done':
212
+ console.log(`Final: ${event.response}`);
213
+ break;
214
+ }
215
+ },
216
+ });
217
+ ```
218
+
219
+ ### Streaming Events
220
+
221
+ For CLI applications, stream events as they happen:
222
+
223
+ ```typescript
224
+ for await (const event of agent.stream('Hello!')) {
225
+ if (event.type === 'llm_chunk') {
226
+ process.stdout.write(event.chunk.text || '');
227
+ }
228
+ }
229
+ ```
230
+
231
+ ## Abort Support
232
+
233
+ Cancel running agents:
234
+
235
+ ```typescript
236
+ const controller = new AbortController();
237
+
238
+ // Cancel after 5 seconds
239
+ setTimeout(() => controller.abort(), 5000);
240
+
241
+ try {
242
+ const result = await agent.run('Complex task...', {
243
+ signal: controller.signal,
244
+ });
245
+ } catch (error) {
246
+ if (error instanceof AbortError) {
247
+ console.log('Agent was cancelled');
248
+ }
249
+ }
250
+ ```
251
+
252
+ ## Error Handling
253
+
254
+ The library provides specific error types:
255
+
256
+ ```typescript
257
+ import {
258
+ AgentError,
259
+ ProviderError,
260
+ ToolError,
261
+ ValidationError,
262
+ MaxIterationsError,
263
+ AbortError,
264
+ isAgentError,
265
+ isProviderError,
266
+ isToolError,
267
+ wrapError,
268
+ } from '@compilr-dev/agents';
269
+
270
+ try {
271
+ await agent.run('...');
272
+ } catch (error) {
273
+ if (isProviderError(error)) {
274
+ console.log(`Provider ${error.provider} failed: ${error.message}`);
275
+ } else if (isToolError(error)) {
276
+ console.log(`Tool ${error.toolName} failed: ${error.message}`);
277
+ } else if (error instanceof MaxIterationsError) {
278
+ console.log(`Reached max iterations: ${error.maxIterations}`);
279
+ }
280
+ }
281
+ ```
282
+
283
+ ## Providers
284
+
285
+ ### ClaudeProvider
286
+
287
+ ```typescript
288
+ import { ClaudeProvider } from '@compilr-dev/agents';
289
+
290
+ const provider = new ClaudeProvider({
291
+ apiKey: process.env.ANTHROPIC_API_KEY,
292
+ model: 'claude-sonnet-4-20250514', // Default
293
+ maxTokens: 4096,
294
+ });
295
+ ```
296
+
297
+ ### MockProvider (for testing)
298
+
299
+ ```typescript
300
+ import { MockProvider } from '@compilr-dev/agents';
301
+
302
+ const provider = new MockProvider();
303
+
304
+ // Queue responses
305
+ provider.addResponse('Simple text response');
306
+ provider.addResponse({
307
+ text: 'Using a tool...',
308
+ toolCalls: [{ id: 'call_1', name: 'my_tool', input: { arg: 'value' } }],
309
+ });
310
+
311
+ // Queue an error
312
+ provider.addError(new Error('API failed'));
313
+
314
+ // Add delay
315
+ provider.addResponse('Delayed response', 1000);
316
+
317
+ // Access history
318
+ console.log(provider.history); // All chat() calls
319
+ ```
320
+
321
+ ### Custom Providers
322
+
323
+ Implement the `LLMProvider` interface:
324
+
325
+ ```typescript
326
+ import type { LLMProvider, Message, ChatOptions, StreamChunk } from '@compilr-dev/agents';
327
+
328
+ class MyProvider implements LLMProvider {
329
+ readonly name = 'my-provider';
330
+
331
+ async *chat(
332
+ messages: Message[],
333
+ options?: ChatOptions
334
+ ): AsyncIterable<StreamChunk> {
335
+ // Your implementation
336
+ yield { type: 'text', text: 'Response text' };
337
+ yield { type: 'end', stopReason: 'end_turn' };
338
+ }
339
+
340
+ async countTokens(messages: Message[]): Promise<number> {
341
+ // Optional token counting
342
+ return messages.length * 100;
343
+ }
344
+ }
345
+ ```
346
+
347
+ ## API Reference
348
+
349
+ ### Agent
350
+
351
+ ```typescript
352
+ class Agent {
353
+ constructor(options: AgentOptions);
354
+
355
+ // Run agent and return final result
356
+ run(userMessage: string, options?: RunOptions): Promise<AgentResult>;
357
+
358
+ // Stream events during execution
359
+ stream(userMessage: string, options?: RunOptions): AsyncIterable<AgentEvent>;
360
+
361
+ // Tool management
362
+ registerTool(tool: Tool): void;
363
+ registerTools(tools: Tool[]): void;
364
+ getToolDefinitions(): ToolDefinition[];
365
+ }
366
+ ```
367
+
368
+ ### Types
369
+
370
+ ```typescript
371
+ interface AgentOptions {
372
+ provider: LLMProvider;
373
+ systemPrompt?: string;
374
+ maxIterations?: number;
375
+ onEvent?: (event: AgentEvent) => void;
376
+ }
377
+
378
+ interface RunOptions {
379
+ signal?: AbortSignal;
380
+ }
381
+
382
+ interface AgentResult {
383
+ response: string;
384
+ iterations: number;
385
+ toolCalls: ToolCallInfo[];
386
+ }
387
+
388
+ type AgentEvent =
389
+ | { type: 'iteration_start'; iteration: number }
390
+ | { type: 'llm_start' }
391
+ | { type: 'llm_chunk'; chunk: StreamChunk }
392
+ | { type: 'llm_end'; text: string; hasToolUses: boolean }
393
+ | { type: 'tool_start'; name: string; input: Record<string, unknown> }
394
+ | { type: 'tool_end'; name: string; result: ToolExecutionResult }
395
+ | { type: 'iteration_end'; iteration: number }
396
+ | { type: 'done'; response: string };
397
+ ```
398
+
399
+ ## Context Management
400
+
401
+ Manage context windows in long-running agent sessions:
402
+
403
+ ```typescript
404
+ import { ContextManager, DEFAULT_CONTEXT_CONFIG } from '@compilr-dev/agents';
405
+
406
+ const contextManager = new ContextManager({
407
+ provider,
408
+ config: {
409
+ maxContextTokens: 200000, // Claude's limit
410
+ compaction: {
411
+ triggerThreshold: 0.5, // Compact at 50% utilization
412
+ preserveRecentTurns: 10, // Keep last 10 turns
413
+ },
414
+ summarization: {
415
+ triggerThreshold: 0.9, // Summarize at 90%
416
+ preserveRecentMessages: 6,
417
+ },
418
+ },
419
+ onEvent: (event) => {
420
+ if (event.type === 'context_warning') {
421
+ console.log(`Context at ${event.utilization * 100}%`);
422
+ }
423
+ },
424
+ });
425
+
426
+ // Track token usage
427
+ await contextManager.updateTokenCount(messages);
428
+ console.log(`Utilization: ${contextManager.getUtilization() * 100}%`);
429
+
430
+ // Check if action needed
431
+ if (contextManager.needsSummarization()) {
432
+ const { messages: summarized } = await contextManager.summarize(
433
+ messages,
434
+ async (msgs) => 'Summary of conversation...' // Your LLM call
435
+ );
436
+ }
437
+
438
+ // Filter large content before adding
439
+ const { content, filtered } = contextManager.filterContent(
440
+ largeToolResult,
441
+ 'tool_result'
442
+ );
443
+ ```
444
+
445
+ ### Context Strategies
446
+
447
+ | Strategy | Trigger | Reversible | Description |
448
+ |----------|---------|------------|-------------|
449
+ | **Filtering** | Before add | N/A | Truncate large content (>80K tokens) |
450
+ | **Compaction** | 50% or 20 turns | Yes | Save old results to files |
451
+ | **Summarization** | 90% | No | Compress entire history |
452
+
453
+ ## Anchors (Critical Information Persistence)
454
+
455
+ Anchors are critical pieces of information that survive context compaction. They're automatically re-injected into every LLM call:
456
+
457
+ ```typescript
458
+ import { Agent, AnchorManager, ClaudeProvider } from '@compilr-dev/agents';
459
+
460
+ const agent = new Agent({
461
+ provider: new ClaudeProvider({ apiKey: process.env.ANTHROPIC_API_KEY }),
462
+ systemPrompt: 'You are a helpful assistant.',
463
+ anchors: {
464
+ maxAnchors: 20, // Maximum number of anchors
465
+ maxTokens: 2000, // Token budget for anchors
466
+ includeDefaults: true, // Include safety anchors (git, file operations)
467
+ },
468
+ });
469
+
470
+ // Add a session anchor (survives until session ends)
471
+ agent.addAnchor({
472
+ content: 'User prefers TypeScript with strict mode',
473
+ priority: 'critical',
474
+ scope: 'session',
475
+ });
476
+
477
+ // Add a persistent anchor (saved to disk)
478
+ agent.addAnchor({
479
+ content: 'Never modify files in /etc',
480
+ priority: 'safety',
481
+ scope: 'persistent',
482
+ tags: ['filesystem'],
483
+ });
484
+
485
+ // Add a temporary anchor (expires after a time)
486
+ agent.addAnchor({
487
+ content: 'Currently debugging the auth module',
488
+ priority: 'info',
489
+ scope: 'temporary',
490
+ expiresAt: new Date(Date.now() + 3600000), // 1 hour
491
+ });
492
+ ```
493
+
494
+ ### Anchor Priorities
495
+
496
+ | Priority | Description | Format in LLM |
497
+ |----------|-------------|---------------|
498
+ | `critical` | Must remember | `### CRITICAL (Must Remember)` |
499
+ | `safety` | Check before acting | `### SAFETY (Check Before Acting)` |
500
+ | `info` | Contextual information | `### INFO` |
501
+
502
+ ### Standalone AnchorManager
503
+
504
+ ```typescript
505
+ import { AnchorManager } from '@compilr-dev/agents';
506
+
507
+ const anchors = new AnchorManager({
508
+ maxAnchors: 20,
509
+ maxTokens: 2000,
510
+ persistPath: '~/.myapp/anchors.json', // Optional persistence
511
+ includeDefaults: true,
512
+ });
513
+
514
+ // Add anchors
515
+ anchors.add({ content: 'Important info', priority: 'critical', scope: 'session' });
516
+
517
+ // Query anchors
518
+ const critical = anchors.getAll({ priority: 'critical' });
519
+ const tagged = anchors.getAll({ tags: ['git'] });
520
+
521
+ // Format for LLM injection
522
+ const formatted = anchors.format();
523
+ // Returns:
524
+ // ### CRITICAL (Must Remember)
525
+ // - Important info
526
+
527
+ // Monitor token usage
528
+ console.log(`Utilization: ${anchors.getUtilization() * 100}%`);
529
+ ```
530
+
531
+ ## Guardrails (Safety Checks)
532
+
533
+ Guardrails are pattern-based safety checks that run before tool execution. They can warn, require confirmation, or block dangerous operations:
534
+
535
+ ```typescript
536
+ import { Agent, ClaudeProvider } from '@compilr-dev/agents';
537
+
538
+ const agent = new Agent({
539
+ provider: new ClaudeProvider({ apiKey: process.env.ANTHROPIC_API_KEY }),
540
+ systemPrompt: 'You are a helpful assistant.',
541
+ guardrails: {
542
+ enabled: true,
543
+ includeDefaults: true, // 15 built-in patterns for git, rm, DROP TABLE, etc.
544
+ custom: [
545
+ {
546
+ id: 'no-prod-db',
547
+ name: 'Production Database Protection',
548
+ description: 'Prevent operations on production database',
549
+ patterns: [/prod.*db/i, /production.*database/i],
550
+ action: 'block', // 'warn' | 'confirm' | 'block'
551
+ message: 'Operations on production database are blocked',
552
+ scope: ['bash'], // Optional: limit to specific tools
553
+ tags: ['database', 'production'],
554
+ },
555
+ ],
556
+ onTriggered: async (result, context) => {
557
+ // Handle 'confirm' actions
558
+ if (result.action === 'confirm') {
559
+ return await askUserConfirmation(result.guardrail.message);
560
+ }
561
+ return result.action !== 'block';
562
+ },
563
+ },
564
+ });
565
+ ```
566
+
567
+ ### Built-in Guardrails
568
+
569
+ | ID | Action | Pattern | Description |
570
+ |----|--------|---------|-------------|
571
+ | `git-reset-hard` | confirm | `git reset --hard` | Prevents accidental loss of uncommitted changes |
572
+ | `git-push-force` | confirm | `git push --force` | Prevents force pushing to branches |
573
+ | `rm-rf` | confirm | `rm -rf` | Prevents recursive deletion |
574
+ | `rm-root` | block | `rm -rf /` | Blocks deletion of root filesystem |
575
+ | `drop-table` | confirm | `DROP TABLE` | Prevents accidental table deletion |
576
+ | `truncate-table` | confirm | `TRUNCATE` | Prevents data loss |
577
+ | `delete-where-all` | warn | `DELETE FROM` without WHERE | Warns about deleting all rows |
578
+ | `secrets-env` | warn | API keys, passwords | Warns about exposing secrets |
579
+ | `chmod-777` | warn | `chmod 777` | Warns about insecure permissions |
580
+ | `curl-pipe-bash` | block | `curl | bash` | Blocks unsafe remote execution |
581
+ | `eval-code` | warn | `eval()` patterns | Warns about code injection risks |
582
+ | `sudo-rm` | confirm | `sudo rm` | Confirms privileged deletion |
583
+ | `git-clean` | confirm | `git clean -fd` | Confirms removing untracked files |
584
+ | `format-disk` | block | `mkfs`, `dd` | Blocks disk formatting |
585
+ | `kill-all` | confirm | `killall`, `pkill` | Confirms killing processes |
586
+
587
+ ### Standalone GuardrailManager
588
+
589
+ ```typescript
590
+ import { GuardrailManager, getGuardrailsByTag } from '@compilr-dev/agents';
591
+
592
+ const guardrails = new GuardrailManager({
593
+ enabled: true,
594
+ includeDefaults: true,
595
+ });
596
+
597
+ // Check before tool execution
598
+ const result = guardrails.check('bash', { command: 'rm -rf /tmp/test' });
599
+ if (result.triggered) {
600
+ console.log(`Guardrail triggered: ${result.guardrail.name}`);
601
+ console.log(`Action: ${result.action}`); // 'warn' | 'confirm' | 'block'
602
+ console.log(`Message: ${result.guardrail.message}`);
603
+ }
604
+
605
+ // Check and handle (with confirmation callback)
606
+ const { proceed, result } = await guardrails.checkAndHandle('bash', input);
607
+ if (!proceed) {
608
+ console.log('Operation blocked by guardrail');
609
+ }
610
+
611
+ // Get guardrails by tag
612
+ const gitGuardrails = getGuardrailsByTag('git');
613
+ const destructiveGuardrails = getGuardrailsByTag('destructive');
614
+
615
+ // Enable/disable individual guardrails
616
+ guardrails.disable('rm-rf');
617
+ guardrails.enable('rm-rf');
618
+ ```
619
+
620
+ ### Guardrail Events
621
+
622
+ Monitor guardrail activity:
623
+
624
+ ```typescript
625
+ guardrails.onEvent((event) => {
626
+ switch (event.type) {
627
+ case 'guardrail:triggered':
628
+ console.log(`Guardrail ${event.result.guardrail.name} triggered`);
629
+ break;
630
+ case 'guardrail:blocked':
631
+ console.log('Operation blocked');
632
+ break;
633
+ case 'guardrail:warning':
634
+ console.log('Warning issued');
635
+ break;
636
+ case 'guardrail:confirmed':
637
+ console.log('User confirmed dangerous operation');
638
+ break;
639
+ case 'guardrail:cancelled':
640
+ console.log('User cancelled operation');
641
+ break;
642
+ }
643
+ });
644
+ ```
645
+
646
+ ## Permissions (Tool-level Access Control)
647
+
648
+ Permissions provide fine-grained control over which tools can execute and when user approval is required:
649
+
650
+ ```typescript
651
+ import { Agent, ClaudeProvider } from '@compilr-dev/agents';
652
+
653
+ const agent = new Agent({
654
+ provider: new ClaudeProvider({ apiKey: process.env.ANTHROPIC_API_KEY }),
655
+ systemPrompt: 'You are a helpful assistant.',
656
+ permissions: {
657
+ enabled: true,
658
+ defaultLevel: 'always', // Default for tools without rules
659
+ includeDefaults: true, // Include default rules for bash, write_file, edit
660
+ rules: [
661
+ { toolName: 'bash', level: 'once', description: 'Shell commands' },
662
+ { toolName: 'write_file', level: 'session', description: 'File writes' },
663
+ { toolName: 'delete_*', level: 'deny', description: 'Delete operations' },
664
+ ],
665
+ onPermissionRequest: async (request) => {
666
+ // Handle permission requests (e.g., prompt user)
667
+ console.log(`Tool: ${request.toolName}`);
668
+ console.log(`Preview: ${request.preview}`);
669
+ return await askUser(`Allow ${request.toolName}?`);
670
+ },
671
+ },
672
+ });
673
+ ```
674
+
675
+ ### Permission Levels
676
+
677
+ | Level | Description | Behavior |
678
+ |-------|-------------|----------|
679
+ | `always` | No approval needed | Tool executes immediately |
680
+ | `session` | Ask once per session | After approval, tool runs freely |
681
+ | `once` | Ask every time | User must approve each execution |
682
+ | `deny` | Always blocked | Tool cannot execute |
683
+
684
+ ### Wildcard Patterns
685
+
686
+ Permission rules support wildcards for flexible matching:
687
+
688
+ ```typescript
689
+ // Match all tools starting with "delete_"
690
+ { toolName: 'delete_*', level: 'deny' }
691
+
692
+ // Match all tools ending with "_file"
693
+ { toolName: '*_file', level: 'session' }
694
+
695
+ // Match tools containing "dangerous"
696
+ { toolName: '*dangerous*', level: 'once' }
697
+ ```
698
+
699
+ ### Standalone PermissionManager
700
+
701
+ ```typescript
702
+ import { PermissionManager } from '@compilr-dev/agents';
703
+
704
+ const permissions = new PermissionManager({
705
+ enabled: true,
706
+ defaultLevel: 'always',
707
+ onPermissionRequest: async (request) => {
708
+ return await promptUser(request.preview);
709
+ },
710
+ });
711
+
712
+ // Add rules dynamically
713
+ permissions.addRule({
714
+ toolName: 'bash',
715
+ level: 'once',
716
+ description: 'Shell commands',
717
+ tags: ['shell', 'dangerous'],
718
+ });
719
+
720
+ // Check permission before execution
721
+ const result = await permissions.check('bash', { command: 'rm -rf /tmp/test' });
722
+ if (result.allowed) {
723
+ // Proceed with execution
724
+ } else {
725
+ console.log(`Denied: ${result.reason}`);
726
+ }
727
+
728
+ // Grant session-level permission programmatically
729
+ permissions.grantSession('write_file');
730
+
731
+ // Check if tool has session grant
732
+ if (permissions.hasSessionGrant('write_file')) {
733
+ console.log('write_file approved for this session');
734
+ }
735
+ ```
736
+
737
+ ### Permission Events
738
+
739
+ Monitor permission activity:
740
+
741
+ ```typescript
742
+ permissions.onEvent((event) => {
743
+ switch (event.type) {
744
+ case 'permission:granted':
745
+ console.log(`${event.toolName} allowed`);
746
+ break;
747
+ case 'permission:denied':
748
+ console.log(`${event.toolName} denied`);
749
+ break;
750
+ case 'permission:asked':
751
+ console.log(`Asking about ${event.toolName}`);
752
+ break;
753
+ case 'permission:session_granted':
754
+ console.log(`${event.toolName} approved for session`);
755
+ break;
756
+ }
757
+ });
758
+ ```
759
+
760
+ ### Permissions vs Guardrails
761
+
762
+ Both systems provide safety, but serve different purposes:
763
+
764
+ | Aspect | Permissions | Guardrails |
765
+ |--------|-------------|------------|
766
+ | **Purpose** | Access control | Content safety |
767
+ | **Scope** | Tool-level | Input patterns |
768
+ | **Timing** | Before tool call | Before execution |
769
+ | **Typical Use** | "Can this tool run?" | "Is this input safe?" |
770
+ | **User Interaction** | Session/once approval | Confirm dangerous ops |
771
+
772
+ Use them together for comprehensive safety:
773
+ - Permissions control *which* tools can be used
774
+ - Guardrails check *what* inputs are safe
775
+
776
+ ## Project Memory (CLAUDE.md, GEMINI.md, etc.)
777
+
778
+ Project Memory automatically discovers and loads project-specific instructions from markdown files. It supports various LLM-specific naming conventions:
779
+
780
+ | Provider | Files Searched |
781
+ |----------|----------------|
782
+ | Claude | `CLAUDE.md`, `.claude.md`, `.claude/instructions.md` |
783
+ | Gemini | `GEMINI.md`, `.gemini.md`, `.gemini/instructions.md` |
784
+ | OpenAI/GPT | `OPENAI.md`, `GPT.md`, `CHATGPT.md` |
785
+ | Copilot | `COPILOT.md`, `.github/copilot-instructions.md` |
786
+ | Cursor | `CURSOR.md`, `.cursorrules`, `.cursor/rules` |
787
+ | Generic | `PROJECT.md`, `INSTRUCTIONS.md`, `AI.md`, `CONTEXT.md` |
788
+
789
+ ### Using with Agent
790
+
791
+ ```typescript
792
+ import { Agent, ClaudeProvider } from '@compilr-dev/agents';
793
+
794
+ // Option 1: Factory method (recommended)
795
+ const agent = await Agent.createWithMemory(
796
+ {
797
+ provider: new ClaudeProvider({ apiKey: process.env.ANTHROPIC_API_KEY }),
798
+ systemPrompt: 'You are a helpful assistant.',
799
+ },
800
+ { providers: 'claude', includeGeneric: true },
801
+ '/path/to/project' // defaults to cwd
802
+ );
803
+
804
+ // Access loaded memory
805
+ const memory = agent.getProjectMemory();
806
+ console.log(`Loaded ${memory?.files.length} instruction files`);
807
+
808
+ // Option 2: Pre-load memory manually
809
+ import { ProjectMemoryLoader } from '@compilr-dev/agents';
810
+
811
+ const loader = new ProjectMemoryLoader({
812
+ providers: ['claude', 'gemini'],
813
+ includeGeneric: true,
814
+ });
815
+ const memory = await loader.load('/path/to/project');
816
+
817
+ const agent = new Agent({
818
+ provider,
819
+ systemPrompt: 'You are a helpful assistant.',
820
+ projectMemory: memory,
821
+ });
822
+ ```
823
+
824
+ ### Multiple Providers
825
+
826
+ Search for instructions from multiple LLM providers:
827
+
828
+ ```typescript
829
+ const agent = await Agent.createWithMemory(
830
+ { provider },
831
+ {
832
+ providers: ['claude', 'gemini', 'openai'],
833
+ includeGeneric: true, // Also search PROJECT.md, AI.md, etc.
834
+ combineStrategy: 'concat', // Combine all found files
835
+ }
836
+ );
837
+ ```
838
+
839
+ ### ProjectMemoryLoader Options
840
+
841
+ ```typescript
842
+ const loader = new ProjectMemoryLoader({
843
+ // Provider(s) to search for
844
+ providers: 'claude', // or ['claude', 'gemini']
845
+
846
+ // Include generic patterns (PROJECT.md, AI.md, etc.)
847
+ includeGeneric: true,
848
+
849
+ // Search parent directories up to git root
850
+ searchParents: true,
851
+ stopAtGitRoot: true,
852
+ maxParentDepth: 10,
853
+
854
+ // How to combine multiple files
855
+ combineStrategy: 'concat', // 'concat' | 'priority' | 'dedupe'
856
+
857
+ // Content limits
858
+ maxContentSize: 100000, // 100KB max
859
+
860
+ // Headers in combined output
861
+ includeHeaders: true,
862
+ headerFormat: '# From: {relativePath}\n\n',
863
+ });
864
+ ```
865
+
866
+ ### Combine Strategies
867
+
868
+ | Strategy | Description |
869
+ |----------|-------------|
870
+ | `concat` | Concatenate all files with separators (default) |
871
+ | `priority` | Use only the highest priority file |
872
+ | `dedupe` | Concatenate but remove duplicate content |
873
+
874
+ ### Custom Patterns
875
+
876
+ Add custom file patterns for your own naming conventions:
877
+
878
+ ```typescript
879
+ const loader = new ProjectMemoryLoader({
880
+ providers: 'claude',
881
+ customPatterns: [
882
+ { pattern: 'TEAM-RULES.md', priority: 0, description: 'Team rules' },
883
+ { pattern: '.ai-config.md', priority: 1, description: 'AI config' },
884
+ ],
885
+ });
886
+ ```
887
+
888
+ ### Standalone Usage
889
+
890
+ Use the loader without an Agent:
891
+
892
+ ```typescript
893
+ import {
894
+ loadProjectMemory,
895
+ hasProjectMemory,
896
+ getSupportedProviders,
897
+ getProviderPatterns,
898
+ } from '@compilr-dev/agents';
899
+
900
+ // Quick check if memory files exist
901
+ if (await hasProjectMemory('/path/to/project', { providers: 'claude' })) {
902
+ console.log('Found project instructions!');
903
+ }
904
+
905
+ // Load memory directly
906
+ const memory = await loadProjectMemory('/path/to/project', {
907
+ providers: ['claude', 'gemini'],
908
+ });
909
+
910
+ console.log(`Loaded ${memory.files.length} files`);
911
+ console.log(`Estimated tokens: ${memory.estimatedTokens}`);
912
+
913
+ // Get patterns for a provider
914
+ const patterns = getProviderPatterns('cursor');
915
+ // Returns: [{ pattern: 'CURSOR.md', ... }, { pattern: '.cursorrules', ... }]
916
+
917
+ // List all supported providers
918
+ const providers = getSupportedProviders();
919
+ // Returns: ['claude', 'anthropic', 'gemini', 'openai', 'gpt', 'copilot', 'cursor', 'codeium']
920
+ ```
921
+
922
+ ## Rate Limiting
923
+
924
+ Protect against API rate limits with automatic retry and backoff:
925
+
926
+ ```typescript
927
+ import { Agent, ClaudeProvider, createRateLimitedProvider } from '@compilr-dev/agents';
928
+
929
+ // Wrap any provider with rate limiting
930
+ const provider = createRateLimitedProvider(
931
+ new ClaudeProvider({ apiKey: process.env.ANTHROPIC_API_KEY }),
932
+ {
933
+ maxRequestsPerMinute: 50,
934
+ maxTokensPerMinute: 100000,
935
+ maxRetries: 3,
936
+ initialBackoffMs: 1000,
937
+ maxBackoffMs: 60000,
938
+ backoffMultiplier: 2,
939
+ onRateLimited: (info) => {
940
+ console.log(`Rate limited, waiting ${info.waitMs}ms`);
941
+ },
942
+ }
943
+ );
944
+
945
+ const agent = new Agent({ provider });
946
+ ```
947
+
948
+ ### Standalone Rate Limiter
949
+
950
+ ```typescript
951
+ import { RateLimiter } from '@compilr-dev/agents';
952
+
953
+ const limiter = new RateLimiter({
954
+ maxRequestsPerMinute: 60,
955
+ maxTokensPerMinute: 100000,
956
+ });
957
+
958
+ // Check before making requests
959
+ await limiter.waitForCapacity();
960
+
961
+ // Record usage after requests
962
+ limiter.recordRequest(1500); // tokens used
963
+
964
+ // Check current state
965
+ console.log(`Requests remaining: ${limiter.getAvailableRequests()}`);
966
+ console.log(`Tokens remaining: ${limiter.getAvailableTokens()}`);
967
+ ```
968
+
969
+ ## Usage Tracking
970
+
971
+ Track token usage across agent sessions:
972
+
973
+ ```typescript
974
+ import { Agent, ClaudeProvider } from '@compilr-dev/agents';
975
+
976
+ const agent = new Agent({
977
+ provider: new ClaudeProvider({ apiKey: process.env.ANTHROPIC_API_KEY }),
978
+ usage: {
979
+ enabled: true,
980
+ warnThresholds: {
981
+ inputTokens: 100000,
982
+ outputTokens: 50000,
983
+ },
984
+ onWarning: (warning) => {
985
+ console.log(`Usage warning: ${warning.metric} at ${warning.currentValue}`);
986
+ },
987
+ },
988
+ });
989
+
990
+ // After running the agent
991
+ const result = await agent.run('Hello!');
992
+
993
+ // Get usage stats
994
+ const usage = agent.getUsage();
995
+ console.log(`Input tokens: ${usage.inputTokens}`);
996
+ console.log(`Output tokens: ${usage.outputTokens}`);
997
+ console.log(`Total tokens: ${usage.totalTokens}`);
998
+ console.log(`Requests: ${usage.requests}`);
999
+ ```
1000
+
1001
+ ## Rehearsal System (Impact Analysis)
1002
+
1003
+ Rehearsal analyzes potentially destructive operations before execution, showing what files and git state would be affected:
1004
+
1005
+ ```typescript
1006
+ import { Agent, ClaudeProvider } from '@compilr-dev/agents';
1007
+
1008
+ const agent = new Agent({
1009
+ provider: new ClaudeProvider({ apiKey: process.env.ANTHROPIC_API_KEY }),
1010
+ rehearsal: {
1011
+ enabled: true,
1012
+ gitAnalysis: true, // Analyze git impact
1013
+ fileAnalysis: true, // Analyze file impact
1014
+ autoConfirm: false, // Require user confirmation
1015
+ workingDirectory: '/path/to/project',
1016
+ onRehearsalComplete: async (result) => {
1017
+ console.log('=== Rehearsal Report ===');
1018
+ console.log(`Files affected: ${result.files?.filesAffected || 0}`);
1019
+ console.log(`Git impact: ${result.git?.summary || 'None'}`);
1020
+
1021
+ // Return true to proceed, false to cancel
1022
+ return await askUserConfirmation('Proceed with these changes?');
1023
+ },
1024
+ },
1025
+ });
1026
+
1027
+ // Destructive operations trigger rehearsal automatically
1028
+ await agent.run('Delete all .log files and reset the git branch');
1029
+ ```
1030
+
1031
+ ### Rehearsal Report
1032
+
1033
+ The rehearsal system provides detailed impact analysis:
1034
+
1035
+ ```typescript
1036
+ interface RehearsalResult {
1037
+ files?: {
1038
+ filesAffected: number;
1039
+ deletions: string[];
1040
+ modifications: string[];
1041
+ creations: string[];
1042
+ totalSizeImpact: number;
1043
+ };
1044
+ git?: {
1045
+ hasUncommittedChanges: boolean;
1046
+ uncommittedFiles: string[];
1047
+ branchesAffected: string[];
1048
+ commitsAffected: number;
1049
+ summary: string;
1050
+ };
1051
+ riskLevel: 'low' | 'medium' | 'high' | 'critical';
1052
+ warnings: string[];
1053
+ }
1054
+ ```
1055
+
1056
+ ## Task Tool (Sub-Agents)
1057
+
1058
+ Spawn specialized sub-agents for complex tasks:
1059
+
1060
+ ```typescript
1061
+ import { Agent, ClaudeProvider, createTaskTool } from '@compilr-dev/agents';
1062
+
1063
+ const taskTool = createTaskTool({
1064
+ provider: new ClaudeProvider({ apiKey: process.env.ANTHROPIC_API_KEY }),
1065
+ agentTypes: {
1066
+ explore: {
1067
+ systemPrompt: 'You are a code exploration expert.',
1068
+ tools: ['read_file', 'glob', 'grep'],
1069
+ contextMode: 'full', // Inherit full conversation context
1070
+ },
1071
+ 'code-review': {
1072
+ systemPrompt: 'You are a code reviewer.',
1073
+ tools: ['read_file', 'grep'],
1074
+ contextMode: 'summary', // Get summarized context
1075
+ },
1076
+ refactor: {
1077
+ systemPrompt: 'You are a refactoring expert.',
1078
+ tools: ['read_file', 'write_file', 'edit'],
1079
+ contextMode: 'none', // No inherited context
1080
+ },
1081
+ },
1082
+ defaultThoroughness: 'medium', // 'quick' | 'medium' | 'thorough'
1083
+ maxConcurrentTasks: 3,
1084
+ });
1085
+
1086
+ agent.registerTool(taskTool);
1087
+
1088
+ // The LLM can now spawn sub-agents:
1089
+ // task({ agentType: 'explore', prompt: 'Find all React components' })
1090
+ ```
1091
+
1092
+ ### Built-in Agent Types
1093
+
1094
+ | Type | Purpose | Default Tools |
1095
+ |------|---------|---------------|
1096
+ | `explore` | Codebase exploration | glob, grep, read_file |
1097
+ | `code-review` | Code quality review | read_file, grep |
1098
+ | `refactor` | Code refactoring | read_file, write_file, edit |
1099
+ | `test-runner` | Running tests | bash, read_file |
1100
+ | `doc-lookup` | Documentation search | read_file, grep, web_fetch |
1101
+ | `debug` | Debugging assistance | read_file, grep, bash |
1102
+ | `security-audit` | Security analysis | read_file, grep |
1103
+ | `plan` | Task planning | read_file, glob |
1104
+ | `general` | General purpose | All tools |
1105
+
1106
+ ## Hooks System
1107
+
1108
+ Extend agent behavior with lifecycle hooks:
1109
+
1110
+ ```typescript
1111
+ import { Agent, ClaudeProvider, HooksManager } from '@compilr-dev/agents';
1112
+
1113
+ const hooks = new HooksManager();
1114
+
1115
+ // Before each LLM call
1116
+ hooks.register('beforeChat', async (context) => {
1117
+ console.log(`Sending ${context.messages.length} messages`);
1118
+ // Modify messages if needed
1119
+ return { messages: context.messages };
1120
+ });
1121
+
1122
+ // After each LLM response
1123
+ hooks.register('afterChat', async (context) => {
1124
+ console.log(`Received: ${context.response.text?.slice(0, 50)}...`);
1125
+ });
1126
+
1127
+ // Before tool execution
1128
+ hooks.register('beforeToolCall', async (context) => {
1129
+ console.log(`Calling ${context.toolName} with`, context.input);
1130
+ // Return { skip: true } to skip execution
1131
+ });
1132
+
1133
+ // After tool execution
1134
+ hooks.register('afterToolCall', async (context) => {
1135
+ console.log(`${context.toolName} returned:`, context.result);
1136
+ // Modify result if needed
1137
+ return { result: context.result };
1138
+ });
1139
+
1140
+ const agent = new Agent({
1141
+ provider: new ClaudeProvider({ apiKey: process.env.ANTHROPIC_API_KEY }),
1142
+ hooks,
1143
+ });
1144
+ ```
1145
+
1146
+ ## Skills
1147
+
1148
+ Skills are reusable prompt templates that enhance agent capabilities:
1149
+
1150
+ ```typescript
1151
+ import { Agent, ClaudeProvider, SkillsManager, BUILTIN_SKILLS } from '@compilr-dev/agents';
1152
+
1153
+ // Use built-in skills
1154
+ const skills = new SkillsManager({
1155
+ skills: BUILTIN_SKILLS, // code-review, debug, explain, refactor, planning, security-review
1156
+ });
1157
+
1158
+ const agent = new Agent({
1159
+ provider: new ClaudeProvider({ apiKey: process.env.ANTHROPIC_API_KEY }),
1160
+ skills,
1161
+ });
1162
+
1163
+ // Invoke a skill
1164
+ const result = await agent.run('/skill code-review src/auth.ts');
1165
+ ```
1166
+
1167
+ ### Custom Skills
1168
+
1169
+ ```typescript
1170
+ const customSkills = new SkillsManager({
1171
+ skills: [
1172
+ {
1173
+ name: 'optimize',
1174
+ description: 'Optimize code for performance',
1175
+ prompt: `Analyze the following code and suggest performance optimizations:
1176
+ - Identify bottlenecks
1177
+ - Suggest algorithmic improvements
1178
+ - Recommend caching strategies
1179
+ - Consider memory usage`,
1180
+ tags: ['performance', 'optimization'],
1181
+ },
1182
+ ],
1183
+ });
1184
+ ```
1185
+
1186
+ ### Built-in Skills
1187
+
1188
+ | Skill | Description |
1189
+ |-------|-------------|
1190
+ | `code-review` | Comprehensive code review with quality, security, and style feedback |
1191
+ | `debug` | Step-by-step debugging assistance |
1192
+ | `explain` | Clear explanations of code functionality |
1193
+ | `refactor` | Refactoring suggestions with clean code principles |
1194
+ | `planning` | Task breakdown and implementation planning |
1195
+ | `security-review` | Security vulnerability analysis |
1196
+
1197
+ ## Tracing & Logging
1198
+
1199
+ Monitor agent execution with structured logging:
1200
+
1201
+ ```typescript
1202
+ import { Agent, ClaudeProvider, TracingManager } from '@compilr-dev/agents';
1203
+
1204
+ const tracing = new TracingManager({
1205
+ enabled: true,
1206
+ logLevel: 'info', // 'debug' | 'info' | 'warn' | 'error'
1207
+ destination: 'console', // or 'file' or custom function
1208
+ filePath: './agent-logs.jsonl',
1209
+ includeTimestamps: true,
1210
+ redactPatterns: [/api[_-]?key/i, /password/i], // Redact sensitive data
1211
+ });
1212
+
1213
+ const agent = new Agent({
1214
+ provider: new ClaudeProvider({ apiKey: process.env.ANTHROPIC_API_KEY }),
1215
+ tracing,
1216
+ });
1217
+
1218
+ // Logs include:
1219
+ // - LLM requests/responses
1220
+ // - Tool calls and results
1221
+ // - Errors and warnings
1222
+ // - Timing information
1223
+ ```
1224
+
1225
+ ### OpenTelemetry Integration
1226
+
1227
+ ```typescript
1228
+ import { createOtelTracing } from '@compilr-dev/agents';
1229
+
1230
+ // Export traces to your observability platform
1231
+ const tracing = createOtelTracing({
1232
+ serviceName: 'my-agent',
1233
+ endpoint: 'http://localhost:4318/v1/traces',
1234
+ });
1235
+
1236
+ const agent = new Agent({ provider, tracing });
1237
+ ```
1238
+
1239
+ ## Examples
1240
+
1241
+ See the `examples/` directory for runnable demos:
1242
+
1243
+ ```bash
1244
+ # Basic agent usage
1245
+ npx tsx examples/basic-agent.ts
1246
+
1247
+ # Agent with custom tools
1248
+ npx tsx examples/agent-with-tools.ts
1249
+
1250
+ # Streaming events
1251
+ npx tsx examples/streaming-events.ts
1252
+ ```
1253
+
1254
+ ## Testing
1255
+
1256
+ ```bash
1257
+ # Run tests
1258
+ npm test
1259
+
1260
+ # Run with coverage
1261
+ npm run test:coverage
1262
+
1263
+ # Watch mode
1264
+ npm run test:watch
1265
+ ```
1266
+
1267
+ ## Design Philosophy
1268
+
1269
+ 1. **Minimal dependencies**: Only `@anthropic-ai/sdk` as optional peer dep
1270
+ 2. **Type safety**: Full TypeScript support with strict mode
1271
+ 3. **Extensibility**: Easy to add new providers and tools
1272
+ 4. **Testability**: MockProvider for easy unit testing
1273
+ 5. **Real-time feedback**: Event system for CLI applications
1274
+
1275
+ ## License
1276
+
1277
+ MIT