npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@fatagnus/codebuff

v1.0.6

Published

Official SDK for Codebuff — AI coding agent & framework

Readme

@fatagnus/codebuff

Official SDK for Codebuff - AI coding agent and framework

Installation

npm install @fatagnus/codebuff

Prerequisites

Usage

Basic Example

import { CodebuffClient } from '@fatagnus/codebuff'

async function main() {
  const client = new CodebuffClient({
    // You need to pass in your own API key here.
    // Get one here: https://www.codebuff.com/api-keys
    apiKey: process.env.CODEBUFF_API_KEY,
    cwd: process.cwd(),
  })

  // First run
  const runState1 = await client.run({
    // The agent id. Any agent on the store (https://codebuff.com/store)
    agent: 'codebuff/[email protected]',
    prompt: 'Create a simple calculator class',
    handleEvent: (event) => {
      // All events that happen during the run: agent start/finish, tool calls/results, text responses, errors.
      console.log('Codebuff Event', JSON.stringify(event))
    },
  })

  // Continue the same session with a follow-up
  const runOrError2 = await client.run({
    agent: 'codebuff/[email protected]',
    prompt: 'Add unit tests for the calculator',
    previousRun: runState1, // <-- this is where your next run differs from the previous run
    handleEvent: (event) => {
      console.log('Codebuff Event', JSON.stringify(event))
    },
  })
}

main()

Example 2: Custom Agents and Tools

Here, we create a full agent and custom tools that can be reused between runs.

import { z } from 'zod/v4'

import { CodebuffClient, getCustomToolDefinition } from '@fatagnus/codebuff'

import type { AgentDefinition } from '@fatagnus/codebuff'

async function main() {
  const client = new CodebuffClient({
    // Note: You need to pass in your own API key.
    // Get it here: https://www.codebuff.com/profile?tab=api-keys
    apiKey: process.env.CODEBUFF_API_KEY,
    // Optional directory agent runs from (if applicable).
    cwd: process.cwd(),
  })

  // Define your own custom agents!
  const myCustomAgent: AgentDefinition = {
    id: 'my-custom-agent',
    model: 'x-ai/grok-4-fast',
    displayName: 'Sentiment analyzer',
    toolNames: ['fetch_api_data'], // Defined below!
    instructionsPrompt: `
1. Describe the different sentiments in the given prompt.
2. Score the prompt along the following 5 dimensions:
  happiness, sadness, anger, fear, and surprise.`,
    // ... other AgentDefinition properties
  }

  // And define your own custom tools!
  const myCustomTool = getCustomToolDefinition({
    toolName: 'fetch_api_data',
    description: 'Fetch data from an API endpoint',
    inputSchema: z.object({
      url: z.url(),
      method: z.enum(['GET', 'POST']).default('GET'),
      headers: z.record(z.string(), z.string()).optional(),
    }),
    exampleInputs: [{ url: 'https://api.example.com/data', method: 'GET' }],
    execute: async ({ url, method, headers }) => {
      const response = await fetch(url, { method, headers })
      const data = await response.text()
      return [
        {
          type: 'json' as const,
          value: {
            message: `API Response: ${data.slice(0, 5000)}...`,
          },
        },
      ]
    },
  })

  const { output } = await client.run({
    // Run a custom agent by id. Must match an id in the agentDefinitions field below.
    agent: 'my-custom-agent',
    prompt: "Today I'm feeling very happy!",

    // Provide custom agent and tool definitions:
    agentDefinitions: [myCustomAgent],
    customToolDefinitions: [myCustomTool],

    handleEvent: (event) => {
      // All events that happen during the run: agent start/finish, tool calls/results, text responses, errors.
      console.log('Codebuff Event', JSON.stringify(event))
    },
  })

  if (output.type === 'error') {
    console.error(`The run failed:\n${output.message}`)
  } else {
    console.log('The run succeeded with output:', output)
  }
}

main()

API Reference

File Filtering

The fileFilter option controls which files the agent can read:

const client = new CodebuffClient({
  apiKey: process.env.CODEBUFF_API_KEY,
  fileFilter: (filePath) => {
    if (filePath === '.env') return { status: 'blocked' }
    if (filePath.endsWith('.env.example')) return { status: 'allow-example' }
    return { status: 'allow' }
  },
})

Statuses: 'blocked' (returns [BLOCKED]), 'allow-example' (prefixes content with [TEMPLATE]), 'allow' (normal read).

Default behavior: When no fileFilter is provided, gitignore checking is applied automatically. When a fileFilter IS provided, the caller owns all filtering.

loadLocalAgents(options)

Loads agent definitions from .agents directories on disk.

import { loadLocalAgents, CodebuffClient } from '@fatagnus/codebuff'

// Load from default locations (.agents in cwd, parent, or home)
const agents = await loadLocalAgents({ verbose: true })

// Or load from a specific directory
// const agents = await loadLocalAgents({ agentsPath: './my-agents' })

// Or load and validate agents (invalid agents are filtered out)
// const agents = await loadLocalAgents({ validate: true, verbose: true })

// Access source file path for debugging
for (const agent of Object.values(agents)) {
  console.log(`${agent.id} loaded from ${agent._sourceFilePath}`)
}

// Use the loaded agents with client.run()
const client = new CodebuffClient({ apiKey: process.env.CODEBUFF_API_KEY })
const result = await client.run({
  agent: 'my-custom-agent',
  agentDefinitions: Object.values(agents),
  prompt: 'Hello',
})

Parameters

  • agentsPath (string, optional): Path to a specific agents directory. If omitted, searches in {cwd}/.agents, {cwd}/../.agents, and {homedir}/.agents.
  • verbose (boolean, optional): Whether to log errors during loading. Defaults to false.
  • validate (boolean, optional): Whether to validate agents after loading. Invalid agents are filtered out. Defaults to false.

Returns

Returns a Promise<LoadedAgents> - a Record<string, LoadedAgentDefinition> of agent definitions keyed by their ID.

Each LoadedAgentDefinition extends AgentDefinition with:

  • _sourceFilePath (string): The file path the agent was loaded from

Supported File Types

  • .ts, .tsx - TypeScript files (automatically transpiled)
  • .js, .mjs, .cjs - JavaScript files

Files ending in .d.ts or .test.ts are excluded.

client.run(options)

Runs a Codebuff agent with the specified options.

Parameters

  • agent (string, required): The agent to run. Use 'base' for the default agent, or specify a custom agent ID if you made your own agent definition (passed with the agentDefinitions param).

  • prompt (string, required): The user prompt describing what you want the agent to do.

  • params (object, optional): Additional parameters for the agent. Most agents don't use this, but some custom agents can take a JSON object as input in addition to the user prompt string.

  • handleEvent (function, optional): Callback function that receives every event during execution (assistant messages, tool calls, etc.). This allows you to stream the agent's progress in real-time. We will likely add a token-by-token streaming callback in the future.

  • previousRun (object, optional): JSON state returned from a previous run() call. Use this to continue a conversation or session with the agent, maintaining context from previous interactions.

  • projectFiles (object, optional): All the files in your project as a plain JavaScript object. Keys should be the full path from your current directory to each file, and values should be the string contents of the file. Example: { "src/index.ts": "console.log('hi')" }. This helps Codebuff pick good source files for context. Note: This parameter was previously named allFiles but has been renamed for clarity.

  • knowledgeFiles (object, optional): Knowledge files to inject into every run() call. Uses the same schema as projectFiles - keys are file paths and values are file contents. These files are added directly to the agent's context.

  • agentDefinitions (array, optional): Array of custom agent definitions. Each object should satisfy the AgentDefinition type.

  • customToolDefinitions (array, optional): Array of custom tool definitions that extend the agent's capabilities. Each tool definition includes a name, Zod schema for input validation, and a handler function. These tools can be called by the agent during execution.

  • maxAgentSteps (number, optional): Maximum number of steps the agent can take before stopping. Use this as a safety measure in case your agent starts going off the rails. A reasonable number is around 20.

Returns

Returns a Promise that resolves to either a "success" or a "failure" object.

  • The "success" object contains a RunState object which can be passed into subsequent runs via the previousRun parameter to resume the conversation.
  • The "failure" object contains an Error object with a name, message, and stack properties.

The RunState object contains:

  • sessionState: Internal state to be passed to the next run
  • output: The agent's output (text, error, or other types)

Convex Compatibility

This SDK includes a special entry point for running agents in Convex backend actions. Convex actions run in a sandboxed Node.js environment without access to the file system or child_process, so we provide a ConvexCodebuffClient that works within these constraints.

Installation for Convex

npm install @fatagnus/codebuff

Basic Convex Example

import { ConvexCodebuffClient } from '@fatagnus/codebuff/convex'

// In a Convex action
export async function analyzeCode(apiKey: string, codeToAnalyze: string) {
  const client = new ConvexCodebuffClient({
    apiKey,
    // In Convex, provide project files as a plain object since there's no file system
    projectFiles: {
      'code-to-analyze.ts': codeToAnalyze,
    },
  })

  const result = await client.run({
    agent: 'codebuff/[email protected]',
    prompt: 'Please analyze the code in code-to-analyze.ts and explain what it does.',
  })

  if (result.output.type === 'error') {
    throw new Error(`Agent error: ${result.output.message}`)
  }

  return result.output
}

Full Convex Action Example

import { action } from "./_generated/server"
import { v } from "convex/values"
import { ConvexCodebuffClient } from "@fatagnus/codebuff/convex"

export const analyzeCode = action({
  args: {
    code: v.string(),
  },
  handler: async (ctx, args) => {
    const apiKey = process.env.CODEBUFF_API_KEY
    if (!apiKey) throw new Error("CODEBUFF_API_KEY not configured")

    const client = new ConvexCodebuffClient({
      apiKey,
      projectFiles: { "input.ts": args.code },
      maxAgentSteps: 10, // Limit steps to stay within Convex's timeout
    })

    const result = await client.run({
      agent: "codebuff/[email protected]",
      prompt: "Analyze this code and suggest improvements.",
    })

    if (result.output.type === "error") {
      throw new Error(result.output.message)
    }

    return result.output
  },
})

Multi-turn Conversations in Convex

import { ConvexCodebuffClient } from '@fatagnus/codebuff/convex'

export async function multiTurnConversation(
  apiKey: string,
  projectFiles: Record<string, string>,
) {
  const client = new ConvexCodebuffClient({
    apiKey,
    projectFiles,
  })

  // First turn
  const run1 = await client.run({
    agent: 'codebuff/[email protected]',
    prompt: 'What files are in this project?',
  })

  // Second turn - continues the conversation
  const run2 = await client.run({
    agent: 'codebuff/[email protected]',
    prompt: 'Now explain the main entry point.',
    previousRun: run1, // Pass the previous run state to continue the conversation
  })

  return run2
}

Subagent Spawning in Convex

The Convex runtime supports spawning subagents using the spawn_agents tool. To use this feature:

  1. Define your agents with spawnableAgents arrays
  2. Include all agent definitions in agentDefinitions
import { ConvexCodebuffClient } from '@fatagnus/codebuff/convex'
import type { AgentDefinition } from '@fatagnus/codebuff/convex'

const helperAgent: AgentDefinition = {
  id: 'helper',
  displayName: 'Helper Agent',
  systemPrompt: 'You are a helpful assistant that answers questions.',
  toolNames: ['read_files', 'end_turn'],
}

const orchestratorAgent: AgentDefinition = {
  id: 'orchestrator',
  displayName: 'Orchestrator',
  systemPrompt: 'You coordinate tasks by spawning helper agents.',
  toolNames: ['spawn_agents', 'read_files', 'end_turn'],
  spawnableAgents: ['helper'], // Can spawn the helper agent
}

const client = new ConvexCodebuffClient({
  apiKey,
  projectFiles: myFiles,
  agentDefinitions: [helperAgent, orchestratorAgent],
})

const result = await client.run({
  agent: orchestratorAgent,
  prompt: 'Analyze this codebase by spawning helpers for each file.',
})

Subagent limitations in Convex:

  • Maximum nesting depth of 5 levels
  • Subagents can only be spawned from agentDefinitions (no database lookups)
  • Subagents run in parallel using Promise.allSettled

Convex Limitations

When running in Convex, the following tools are not available (they will throw ConvexUnsupportedToolError):

  • run_terminal_command - No child_process access
  • code_search - Requires ripgrep and file system
  • write_file / str_replace - No file system write access
  • list_directory / glob - No file system access

You can provide custom implementations via overrideTools if needed:

const client = new ConvexCodebuffClient({
  apiKey,
  projectFiles: myFiles,
  overrideTools: {
    read_files: async ({ filePaths }) => {
      // Custom implementation to fetch files from your database
      const result: Record<string, string | null> = {}
      for (const path of filePaths) {
        result[path] = await fetchFileFromDatabase(path)
      }
      return result
    },
  },
})

ConvexCodebuffClient API

Constructor Options

  • apiKey (string, required): Your Codebuff API key
  • projectFiles (object, optional): Files as { path: content } - required since there's no file system
  • knowledgeFiles (object, optional): Knowledge files to inject into context
  • agentDefinitions (array, optional): Custom agent definitions
  • maxAgentSteps (number, optional): Max steps before stopping (recommended: 10-20 for Convex timeout limits)
  • handleEvent (function, optional): Event callback for streaming
  • handleStreamChunk (function, optional): Chunk callback for real-time updates. Receives text chunks and subagent events (subagent_start, subagent_chunk, subagent_finish)
  • overrideTools (object, optional): Custom tool implementations
  • customToolDefinitions (array, optional): Custom tool definitions

Methods

  • run(options): Run an agent (same options as standard CodebuffClient.run())
  • checkConnection(): Check if the Codebuff backend is reachable

License

MIT