33The Claude Code SDK now includes a powerful fluent API that makes it easier to build and execute queries with a chainable interface.
44
55## Table of Contents
6+
67- [ Getting Started] ( #getting-started )
78- [ Query Builder] ( #query-builder )
89- [ Response Parser] ( #response-parser )
@@ -18,11 +19,7 @@ The fluent API provides a more intuitive way to interact with Claude Code:
1819import { claude } from ' @instantlyeasy/claude-code-sdk-ts' ;
1920
2021// Simple example
21- const response = await claude ()
22- .withModel (' sonnet' )
23- .skipPermissions ()
24- .query (' Hello, Claude!' )
25- .asText ();
22+ const response = await claude ().withModel (' sonnet' ).skipPermissions ().query (' Hello, Claude!' ).asText ();
2623```
2724
2825## Query Builder
@@ -33,44 +30,54 @@ The `QueryBuilder` class provides chainable methods for configuring your query:
3330
3431``` typescript
3532claude ()
36- .withModel (' opus' ) // or 'sonnet', 'haiku'
37- .withTimeout (60000 ) // 60 seconds
38- .debug (true ) // Enable debug mode
33+ .withModel (' opus' ) // or 'sonnet', 'haiku'
34+ .withTimeout (60000 ) // 60 seconds
35+ .debug (true ); // Enable debug mode
3936```
4037
4138### Tool Management
4239
4340``` typescript
4441claude ()
45- .allowTools (' Read' , ' Write' , ' Edit' ) // Explicitly allow tools
46- .denyTools (' Bash' , ' WebSearch' ) // Explicitly deny tools
42+ .allowTools (' Read' , ' Write' , ' Edit' ) // Explicitly allow tools
43+ .denyTools (' Bash' , ' WebSearch' ); // Explicitly deny tools
4744```
4845
4946### Permissions
5047
5148``` typescript
5249claude ()
53- .skipPermissions () // Bypass all permission prompts
54- .acceptEdits () // Auto-accept file edits
55- .withPermissions (' default' ) // Use default permission handling
50+ .skipPermissions () // Bypass all permission prompts
51+ .acceptEdits () // Auto-accept file edits
52+ .withPermissions (' default' ); // Use default permission handling
5653```
5754
5855### Environment Configuration
5956
57+ ``` typescript
58+ claude ().inDirectory (' /path/to/project' ).withEnv ({ NODE_ENV: ' production' });
59+ ```
60+
61+ ### Directory Context
62+
6063``` typescript
6164claude ()
62- .inDirectory (' /path/to/project' )
63- .withEnv ({ NODE_ENV: ' production' })
65+ .addDirectory (' /path/to/dir' ) // Add single directory
66+ .addDirectory ([' ../apps' , ' ../lib' ]) // Add multiple directories
67+ .addDirectory (' /another/dir' ); // Accumulate with multiple calls
6468```
6569
70+ The ` addDirectory ` method allows you to add additional working directories for Claude to access (validates each path exists as a directory).
71+
72+ - ** Single directory** : Pass a string path
73+ - ** Multiple directories** : Pass an array of string paths
74+ - ** Accumulative** : Multiple calls to ` addDirectory ` will accumulate all directories
75+ - ** CLI mapping** : Generates ` --add-dir ` flag with space-separated paths
76+
6677### MCP Servers
6778
6879``` typescript
69- claude ()
70- .withMCP (
71- { command: ' mcp-server-filesystem' , args: [' --readonly' ] },
72- { command: ' mcp-server-git' }
73- )
80+ claude ().withMCP ({ command: ' mcp-server-filesystem' , args: [' --readonly' ] }, { command: ' mcp-server-git' });
7481```
7582
7683### Event Handlers
@@ -79,7 +86,7 @@ claude()
7986claude ()
8087 .onMessage (msg => console .log (' Message:' , msg .type ))
8188 .onAssistant (content => console .log (' Assistant says...' ))
82- .onToolUse (tool => console .log (` Using ${tool .name } ` ))
89+ .onToolUse (tool => console .log (` Using ${tool .name } ` ));
8390```
8491
8592## Response Parser
@@ -126,7 +133,7 @@ console.log(`Cost: $${usage.totalCost}`);
126133### Streaming
127134
128135``` typescript
129- await parser .stream (async ( message ) => {
136+ await parser .stream (async message => {
130137 if (message .type === ' assistant' ) {
131138 // Handle streaming content
132139 }
@@ -165,9 +172,7 @@ const logger = new ConsoleLogger(LogLevel.DEBUG, '[MyApp]');
165172const jsonLogger = new JSONLogger (LogLevel .INFO );
166173
167174// Use with QueryBuilder
168- claude ()
169- .withLogger (logger )
170- .query (' ...' );
175+ claude ().withLogger (logger ).query (' ...' );
171176```
172177
173178### Custom Logger Implementation
@@ -188,9 +193,14 @@ class CustomLogger implements Logger {
188193
189194 // Implement convenience methods
190195 error(message : string , context ? : Record <string , any >): void {
191- this .log ({ level: LogLevel .ERROR , message , timestamp: new Date (), context });
196+ this .log ({
197+ level: LogLevel .ERROR ,
198+ message ,
199+ timestamp: new Date (),
200+ context
201+ });
192202 }
193-
203+
194204 // ... implement warn, info, debug, trace
195205}
196206```
@@ -214,10 +224,7 @@ const multiLogger = new MultiLogger([
214224async function queryWithRetry(prompt : string , maxRetries = 3 ) {
215225 for (let i = 0 ; i < maxRetries ; i ++ ) {
216226 try {
217- return await claude ()
218- .withTimeout (30000 )
219- .query (prompt )
220- .asText ();
227+ return await claude ().withTimeout (30000 ).query (prompt ).asText ();
221228 } catch (error ) {
222229 if (i === maxRetries - 1 ) throw error ;
223230 await new Promise (resolve => setTimeout (resolve , 1000 * Math .pow (2 , i )));
@@ -231,13 +238,13 @@ async function queryWithRetry(prompt: string, maxRetries = 3) {
231238``` typescript
232239function createQuery(options : { readonly? : boolean }) {
233240 const builder = claude ();
234-
241+
235242 if (options .readonly ) {
236243 builder .allowTools (' Read' , ' Grep' , ' Glob' ).denyTools (' Write' , ' Edit' );
237244 } else {
238245 builder .allowTools (' Read' , ' Write' , ' Edit' );
239246 }
240-
247+
241248 return builder ;
242249}
243250```
@@ -248,16 +255,14 @@ function createQuery(options: { readonly?: boolean }) {
248255const cache = new Map ();
249256
250257async function cachedQuery(prompt : string ) {
251- const cacheKey = ` ${prompt }:${Date .now () / 60000 | 0 } ` ; // 1-minute cache
252-
258+ const cacheKey = ` ${prompt }:${( Date .now () / 60000 ) | 0 } ` ; // 1-minute cache
259+
253260 if (cache .has (cacheKey )) {
254261 return cache .get (cacheKey );
255262 }
256-
257- const result = await claude ()
258- .query (prompt )
259- .asText ();
260-
263+
264+ const result = await claude ().query (prompt ).asText ();
265+
261266 cache .set (cacheKey , result );
262267 return result ;
263268}
@@ -283,14 +288,15 @@ import { claude } from '@instantlyeasy/claude-code-sdk-ts';
283288await claude ()
284289 .withModel (' sonnet' )
285290 .query (' Hello' )
286- .stream (async ( message ) => {
291+ .stream (async message => {
287292 // Process messages
288293 });
289294```
290295
291296### Common Migration Patterns
292297
2932981 . ** Simple text extraction** :
299+
294300``` typescript
295301// Before
296302let text = ' ' ;
@@ -305,12 +311,11 @@ for await (const message of query('Generate text')) {
305311}
306312
307313// After
308- const text = await claude ()
309- .query (' Generate text' )
310- .asText ();
314+ const text = await claude ().query (' Generate text' ).asText ();
311315```
312316
3133172 . ** Tool result extraction** :
318+
314319``` typescript
315320// Before
316321const results = [];
@@ -325,13 +330,11 @@ for await (const message of query('Read files', { allowedTools: ['Read'] })) {
325330}
326331
327332// After
328- const results = await claude ()
329- .allowTools (' Read' )
330- .query (' Read files' )
331- .findToolResults (' Read' );
333+ const results = await claude ().allowTools (' Read' ).query (' Read files' ).findToolResults (' Read' );
332334```
333335
3343363 . ** Error handling** :
337+
335338``` typescript
336339// Before
337340try {
@@ -351,4 +354,4 @@ if (!success) {
351354}
352355```
353356
354- The fluent API is designed to reduce boilerplate while maintaining the full power of the original API. You can mix and match approaches as needed for your use case.
357+ The fluent API is designed to reduce boilerplate while maintaining the full power of the original API. You can mix and match approaches as needed for your use case.
0 commit comments