Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

elwood

image

Programmatically import and instrument the locally installed Claude Code CLI via Babel AST. Drop-in replacement for @anthropic-ai/claude-agent-sdk that runs in-process -- zero subprocess spawning.

How it works

Instead of spawning claude -p as a subprocess (like the official SDK), elwood:

  1. Locates the installed Claude Code CLI (cli.js)
  2. Parses the 13MB bundle with Babel AST
  3. Fingerprints internal functions via evidence-based pattern matching
  4. Injects instrumentation hooks
  5. Calls agentLoop() directly in-process

This gives you the same API as @anthropic-ai/claude-agent-sdk with lower latency and direct access to internals.

Install

npm install @secemp/elwood

Requires Claude Code to be installed:

npm install -g @anthropic-ai/claude-code

Quick start

import { query } from '@secemp/elwood';

for await (const message of query({
  prompt: 'What files are in this directory?',
  options: { maxTurns: 3 },
})) {
  if (message.type === 'result') {
    console.log(message.result);
  }
}

No API key needed if logged in via claude login (Pro/Max subscription).

API

query({ prompt, options })

Returns an async generator yielding messages. Options include:

  • model -- model to use
  • systemPrompt -- string or {type: 'preset', append: '...'}
  • maxTurns -- maximum conversation turns
  • allowedTools -- auto-approve these tools
  • hooks -- {PreToolUse: [...], PostToolUse: [...], ...}
  • mcpServers -- MCP server configs
  • permissionMode -- 'default' | 'acceptEdits' | 'bypassPermissions'
  • continue / resume / resumeSessionAt / forkSession -- session management
  • env / stderr -- environment and output control
  • ...and all other official SDK options

Query control methods

const conversation = query({ prompt: '...' });
conversation.interrupt();          // soft interrupt
conversation.setModel('...');      // change model mid-conversation
conversation.setPermissionMode('acceptEdits');
await conversation.supportedModels();
await conversation.supportedCommands();
conversation.close();              // cleanup

tool(name, description, schema, handler)

import { tool, createSdkMcpServer, query } from '@secemp/elwood';

const weather = tool('get_weather', 'Get weather',
  { type: 'object', properties: { city: { type: 'string' } } },
  ({ city }) => `72F in ${city}`
);

const server = await createSdkMcpServer({ tools: [weather] });

for await (const msg of query({
  prompt: 'Weather in NYC?',
  options: { mcpServers: [server] },
})) { /* ... */ }

Session utilities

import { listSessions, getSessionMessages, getSessionInfo } from '@secemp/elwood';

const sessions = await listSessions();
const messages = await getSessionMessages(sessions[0].id);

V2 Session API

import { unstable_v2_createSession, unstable_v2_prompt } from '@secemp/elwood';

const result = await unstable_v2_prompt('Explain recursion');

Low-level AST access

import { locate, load, instrument, parseBundle } from '@secemp/elwood';

const { cliPath, version } = await locate();
const ast = parseBundle(cliPath);

Auth

Works with all Claude Code auth methods:

  • Claude Pro/Max subscription (claude login)
  • ANTHROPIC_API_KEY environment variable
  • OAuth tokens
  • Bedrock/Vertex/Foundry

Examples

See the examples/ directory for 24 working examples covering queries, hooks, MCP, custom tools, sessions, and more.

License

MIT

About

Programmatically import and instrument the locally installed Claude Code CLI via Babel AST -- drop-in replacement for @anthropic-ai/claude-agent-sdk

Topics

Resources

Stars

7 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages