Skip to main content

@tokenring-ai/codebase

The Codebase plugin provides codebase context to AI agents by managing multiple types of resources that deliver file structures, symbol information, and complete file contents. It allows selective inclusion of project files and directories, enabling AI agents to reason about and interact with the codebase effectively.

The plugin serves as a context provider that injects relevant codebase information into chat sessions through a context handler. It supports three resource types: file trees (directory structure), repo maps (symbol information), and whole files (complete file contents). Users can manage which resources are enabled through interactive commands or programmatic configuration.

Key Features

  • Multiple Resource Types: Supports file trees, repo maps, and whole files
  • Interactive Resource Selection: Tree-based interactive selection via /codebase select
  • Wildcard Pattern Support: Enable resources using wildcard patterns (e.g., src/*)
  • Agent-Specific Configuration: Each agent can have different enabled resources
  • State Persistence: Enabled resources persist across agent sessions
  • Repository Map Generation: Automatically generates symbol-based code maps using code-chopper
  • Context Injection: Automatically injects codebase context into chat sessions
  • Multi-language Support: Supports TypeScript, JavaScript, Python, C, C++, Rust, Go, Java, Ruby, and Bash

Core Components

CodeBaseService

The main service class that implements TokenRingService. It manages a registry of FileMatchResource instances and provides methods for resource management and repository map generation.

Service Properties:

  • name: Service identifier ("CodeBaseService")
  • description: Service description
  • resourceRegistry: KeyedRegistry<FileMatchResource> - Registry managing all resource instances
  • options: Service configuration options

Resource Management Methods:

registerResource(
name: string,
resource: FileMatchResource
): void

getAvailableResources(): string[]

getEnabledResources(
agent: Agent
): FileMatchResource[]

getEnabledResourceNames(
agent: Agent
): Set<string>

setEnabledResources(
resourceNames: string[],
agent: Agent
): Set<string>

enableResources(
resourceNames: string[],
agent: Agent
): Set<string>

disableResources(
resourceNames: string[],
agent: Agent
): Set<string>

Repository Mapping Methods:

async generateRepoMap(
files: Set<string>,
fileSystem: FileSystemService,
agent: Agent
): Promise<string | null>

getLanguageFromExtension(
ext: string
): LanguageEnum | null

formatFileOutput(
filePath: string,
chunks: any[]
): string | null

Method Descriptions:

  • registerResource(name, resource): Registers a new resource with the service, making it available for use
  • getAvailableResources(): Returns all registered resource names as an array of strings
  • getEnabledResources(agent): Returns an array of enabled FileMatchResource instances for the specified agent
  • getEnabledResourceNames(agent): Returns a Set of enabled resource names
  • setEnabledResources(resourceNames, agent): Sets the enabled resources to the provided list, replacing any existing resources
  • enableResources(resourceNames, agent): Adds the specified resources to the enabled set
  • disableResources(resourceNames, agent): Removes the specified resources from the enabled set
  • generateRepoMap(files, fileSystem, agent): Generates a repository map showing symbol snippets from the specified files
  • getLanguageFromExtension(ext): Maps file extensions to language types (typescript, javascript, python, c, cpp, rust, go, java, ruby, bash)
  • formatFileOutput(filePath, chunks): Formats file output for repository maps, showing the first line of each symbol

FileTreeResource

Represents directory structure of the codebase. Extends FileMatchResource from @tokenring-ai/filesystem. Provides file trees showing the directory hierarchy of the codebase without including file contents.

Class Definition:

import {FileMatchResource} from "@tokenring-ai/filesystem";

export default class FileTreeResource extends FileMatchResource {
readonly name = "FileTreeService";
description = "Provides FileTree functionality";
}

Usage:

codebaseService.registerResource("src", new FileTreeResource({
// FileMatchResource configuration options
}));

RepoMapResource

Generates symbol-based repository maps showing function and class signatures. Uses code-chopper to parse code and extract symbols, providing the AI with a high-level view of the codebase structure.

Class Definition:

import {FileMatchResource} from "@tokenring-ai/filesystem";

export default class RepoMapResource extends FileMatchResource {
readonly name = "RepoMapResource";
description = "Provides RepoMap functionality";
}

Usage:

codebaseService.registerResource("api", new RepoMapResource({
// FileMatchResource configuration options
}));

WholeFileResource

Includes the full contents of specified files. Useful for configuration files, small utilities, or files that need complete context.

Class Definition:

import {FileMatchResource} from "@tokenring-ai/filesystem";

export default class WholeFileResource extends FileMatchResource {
readonly name = "WholeFileResource";
description = "Provides whole files to include in the chat context";
}

Usage:

codebaseService.registerResource("config", new WholeFileResource({
// FileMatchResource configuration options
}));

Services

CodeBaseService

The main service that implements TokenRingService and manages codebase resources.

Service Interface:

interface TokenRingService {
name: string;
description: string;
readonly options: z.output<typeof CodeBaseServiceConfigSchema>;

attach(agent: Agent): void;
}

Service Registration:

The service is automatically registered during plugin installation:

const codebaseService = new CodeBaseService(config.codebase);
app.addServices(codebaseService);

Attach Method:

When an agent attaches to the service, it initializes state with merged configuration:

attach(agent: Agent): void {
const { enabledResources } = deepMerge(
this.options.agentDefaults,
agent.getAgentConfigSlice('codebase', CodeBaseAgentConfigSchema)
);

agent.initializeState(CodeBaseState, {
enabledResources: enabledResources.map(resourceName =>
this.resourceRegistry.ensureItemNamesLike(resourceName)
).flat()
});
}

Providers

This package does not use provider registration patterns. Resources are registered directly with the CodeBaseService using the registerResource method.

RPC Endpoints

This package does not define any RPC endpoints.

Chat Commands

The plugin registers the following agent commands through AgentCommandService:

/codebase select

Interactive tree-based resource selection. Opens a tree view allowing users to browse and select codebase resources.

Command Definition:

{
name: "codebase select",
description: "/codebase select - Interactive resource selection",
help: `# /codebase select

Open an interactive tree view to browse and select codebase resources. Recommended when unsure of exact resource names.

## Example

/codebase select`,
execute: async (remainder: string, agent: Agent): Promise<string> => {
const codebaseService = agent.requireServiceByType(CodeBaseService);
const sortedResources = codebaseService.getAvailableResources().sort((a, b) => a.localeCompare(b));

const selection = await agent.askQuestion({
message: `Select resources to include in your chat context`,
question: {
type: 'treeSelect',
label: "Codebase Resource Selection",
key: "result",
defaultValue: Array.from(codebaseService.getEnabledResourceNames(agent)),
minimumSelections: 0,
tree: buildResourceTree(sortedResources),
}
});

if (selection) {
const enabled = codebaseService.setEnabledResources(selection, agent);
return `Currently enabled codebase resources: ${Array.from(enabled).join(", ")}`;
}
return "Resource selection cancelled.";
}
}

/codebase enable

Enable one or more codebase resources by name. Supports wildcard patterns.

Command Definition:

{
name: "codebase enable",
description: "/codebase enable - Enable codebase resources",
help: `# /codebase enable <resource...>

Enable one or more codebase resources by name.

## Example

/codebase enable src/utils
/codebase enable api docs`,
execute: async (remainder: string, agent: Agent): Promise<string> => {
const enabled = agent.requireServiceByType(CodeBaseService)
.enableResources(remainder.split(/\s+/).filter(Boolean), agent);
return `Currently enabled codebase resources: ${Array.from(enabled).join(", ")}`;
}
}

/codebase disable

Disable one or more codebase resources by name.

Command Definition:

{
name: "codebase disable",
description: "/codebase disable - Disable codebase resources",
help: `# /codebase disable <resource...>

Disable one or more codebase resources by name.

## Example

/codebase disable src/utils
/codebase disable src/utils src/types`,
execute: async (remainder: string, agent: Agent): Promise<string> => {
const enabled = agent.requireServiceByType(CodeBaseService)
.disableResources(remainder.split(/\s+/).filter(Boolean), agent);
return `Currently enabled codebase resources: ${Array.from(enabled).join(", ")}`;
}
}

/codebase set

Set the enabled codebase resources, replacing the current selection.

Command Definition:

{
name: "codebase set",
description: "/codebase set - Set enabled codebase resources",
help: `# /codebase set <resource...>

Set the enabled codebase resources, replacing the current selection.

## Example

/codebase set src/utils
/codebase set src/utils src/types`,
execute: async (remainder: string, agent: Agent): Promise<string> => {
const enabled = agent.requireServiceByType(CodeBaseService)
.setEnabledResources(remainder.split(/\s+/).filter(Boolean), agent);
return `Currently enabled codebase resources: ${Array.from(enabled).join(", ")}`;
}
}

/codebase reset

Reset the enabled codebase resources to the initial configuration defined in agentDefaults.

Command Definition:

{
name: "codebase reset",
description: "/codebase reset - Reset enabled codebase resources",
help: `# /codebase reset

Reset the enabled codebase resources to the initial configuration.

## Example

/codebase reset`,
execute: async (remainder: string, agent: Agent): Promise<string> => {
const enabled = agent.mutateState(CodeBaseState, state => {
state.reset();
return state.enabledResources;
})
return `Currently enabled codebase resources: ${Array.from(enabled).join(", ")}`;
}
}

/codebase list

List all currently enabled codebase resources.

Command Definition:

{
name: "codebase list",
description: "/codebase list - List enabled codebase resources",
help: `# /codebase list

List all currently enabled codebase resources.

## Example

/codebase list`,
execute: async (_remainder: string, agent: Agent): Promise<string> => {
const active = Array.from(
agent.requireServiceByType(CodeBaseService).getEnabledResourceNames(agent)
);
if (active.length === 0) return "No codebase resources are currently enabled.";
return `Enabled codebase resources:\n${numberedList(active)}`;
}
}

/codebase show repo

Display the currently enabled repository map and structure. Requires RepoMap resources to be enabled first.

Command Definition:

{
name: "codebase show repo",
description: "/codebase show repo - Display the repository map",
help: `# /codebase show repo

Display the currently enabled repository map and structure. Requires RepoMap resources to be enabled first.

## Example

/codebase show repo`,
execute: async (_remainder: string, agent: Agent): Promise<string> => {
const codebaseService = agent.requireServiceByType(CodeBaseService);
const repoMaps = Object.values(codebaseService.getEnabledResources(agent))
.filter(r => r instanceof RepoMapResource);

if (repoMaps.length === 0) return "No RepoMap resources are currently enabled. Enable a RepoMap resource first.";

const repoMapFiles = new Set<string>();
for (const resource of repoMaps) {
await resource.addFilesToSet(repoMapFiles, agent);
}

if (repoMapFiles.size > 0) {
const repoMap = await codebaseService.generateRepoMap(repoMapFiles, agent.requireServiceByType(FileSystemService), agent);
if (repoMap) return `Repository map:\n${repoMap}`;
}

return "No repository map found. Ensure RepoMap resources are configured and enabled.";
}
}

Configuration

The plugin is configured through the codebase section in the plugin configuration. It accepts a CodeBaseServiceConfigSchema which defines available resources and default agent settings.

Configuration Schema

import { z } from "zod";

const CodeBaseServiceConfigSchema = z.object({
resources: z.record(z.string(), z.any()),
agentDefaults: z.object({
enabledResources: z.array(z.string()).default([])
}).default({ enabledResources: [] })
});

const CodeBaseAgentConfigSchema = z
.object({
enabledResources: z.array(z.string()).optional()
}).default({});

Configuration Example

const pluginConfig = {
codebase: {
resources: {
"src": {
type: "fileTree"
},
"api": {
type: "repoMap"
},
"config": {
type: "wholeFile"
},
"docs": {
type: "fileTree"
}
},
agentDefaults: {
enabledResources: []
}
}
};

Plugin Registration

import codeBasePlugin from "@tokenring-ai/codebase";
import TokenRingApp from "@tokenring-ai/app";

const app = new TokenRingApp();

app.install(codeBasePlugin, {
codebase: {
resources: {
"src": {
type: "fileTree"
},
"api": {
type: "repoMap"
},
"config": {
type: "wholeFile"
}
},
agentDefaults: {
enabledResources: []
}
}
});

Agent Configuration

The CodeBaseService provides agent-level configuration through the attach method, which merges service defaults with agent-specific settings. This allows different agents to have different resource enablement preferences while maintaining consistent resource availability.

Agent Configuration Schema

import { z } from "zod";

const CodeBaseAgentConfigSchema = z.object({
enabledResources: z.array(z.string()).optional()
}).default({});

Agent Configuration Example

import { Agent } from "@tokenring-ai/agent";

const agent = new Agent({
config: {
codebase: {
enabledResources: ["src/components", "src/utils"]
}
}
});

// CodeBaseService.attach() merges service defaults with agent config
// resulting in the union of both enabled resource sets

Configuration Merging

When an agent attaches to the CodeBaseService:

  1. Service defaults from agentDefaults are merged with
  2. Agent-specific configuration from agent.getAgentConfigSlice('codebase')
  3. The result determines which resources are enabled for that agent

During configuration merging, the service uses ensureItemNamesLike to handle wildcard patterns in resource names, mapping them to actual tool names.

State Management

CodeBaseState

The CodeBaseState class implements AgentStateSlice and manages the enabled resources state for agents.

State Interface:

interface AgentStateSlice {
name: string;
enabledResources: Set<string>;

transferStateFromParent(parent: Agent): void;
reset(): void;
serialize(): object;
deserialize(data: any): void;
show(): string[];
}

State Properties:

  • name: State slice identifier ("CodeBaseState")
  • enabledResources: A Set<string> containing the names of currently enabled resources
  • serializationSchema: Zod schema for serialization

State Methods:

constructor(
initialConfig: z.output<typeof CodeBaseServiceConfigSchema>["agentDefaults"]
)

transferStateFromParent(parent: Agent): void

reset(): void

serialize(): z.output<typeof serializationSchema>

deserialize(data: z.output<typeof serializationSchema>): void

show(): string[]

State Behavior:

  • transferStateFromParent: Copies enabled resources from parent agent state
  • reset: Resets enabled resources to the initial configuration from agentDefaults
  • serialize: Returns an object with enabledResources as an array
  • deserialize: Restores enabled resources from serialized data
  • show: Returns a formatted string showing enabled resources

State Persistence:

Enabled resources persist across agent sessions through the state serialization/deserialization mechanism. When an agent is created, it inherits the enabled resources from its parent agent via the transferStateFromParent method.

Serialization Schema:

const serializationSchema = z.object({
enabledResources: z.array(z.string()).default([])
}).prefault({});

Context Handlers

The plugin provides a context handler that injects relevant codebase information into chat sessions when files are being processed or when the agent needs code context.

codebase-context Handler

The context handler generates three types of context items in the following order:

  1. File Tree Context: Directory structure of the codebase for files that are not whole files or repo maps
  2. Repo Map Context: Symbol information showing function and class signatures from repo map resources
  3. Whole File Context: Complete contents of files from whole file resources

Context Handler Function:

async function* getContextItems({agent}: ContextHandlerOptions): AsyncGenerator<ContextItem>

Context Generation Flow:

// 1. Generate file tree context for non-whole-file and non-repo-map resources
const fileTreeFiles = new Set<string>();
for (const name in resources) {
const resource = resources[name];
if (
!(resource instanceof WholeFileResource) &&
!(resource instanceof RepoMapResource)
) {
await resource.addFilesToSet(fileTreeFiles, agent);
}
}

if (fileTreeFiles.size > 0) {
yield {
role: "user",
content: `// Directory Tree of project files:\n${Array.from(fileTreeFiles)
.sort()
.join("\n")}`
};
}

// 2. Generate repo map context for repo map resources
const repoMapFiles = new Set<string>();
for (const name in resources) {
const resource = resources[name];
if (resource instanceof RepoMapResource) {
await resource.addFilesToSet(repoMapFiles, agent);
}
}

if (repoMapFiles.size > 0) {
const repoMap = await codebaseService.generateRepoMap(
repoMapFiles,
fileSystem,
agent
);
if (repoMap) {
yield {
role: "user",
content: repoMap
};
}
}

// 3. Generate whole file context for whole file resources
const wholeFiles = new Set<string>();
for (const name in resources) {
const resource = resources[name];
if (resource instanceof WholeFileResource) {
await resource.addFilesToSet(wholeFiles, agent);
}
}

for await (const file of wholeFiles) {
const content = await fileSystem.readTextFile(file, agent);
yield {
role: "user",
content: `// Complete contents of file: ${file}\n${content}`
};
}

Context Handler Registration:

The context handler is automatically registered during plugin installation:

app.waitForService(ChatService, chatService => {
chatService.registerContextHandlers(contextHandlers);
});

Integration

FileSystemService

The CodeBaseService uses FileSystemService to retrieve file contents for generating repository maps and providing whole file context.

import { FileSystemService } from "@tokenring-ai/filesystem";

const fileSystem = agent.requireServiceByType(FileSystemService);

// Read file content
const content = await fileSystem.readTextFile(filePath, agent);

// Get file metadata
const metadata = await fileSystem.getFileMetadata(filePath, agent);

Agent

The plugin integrates with the agent system through several mechanisms:

Chat Commands:

Commands are registered through the plugin's install method:

app.waitForService(AgentCommandService, agentCommandService =>
agentCommandService.addAgentCommands(agentCommands)
);

Context Handlers:

Context handlers are registered through the plugin's install method:

app.waitForService(ChatService, chatService => {
chatService.registerContextHandlers(contextHandlers);
});

State Initialization:

State is initialized when the agent attaches to the service:

attach(agent: Agent): void {
const { enabledResources } = deepMerge(
this.options.agentDefaults,
agent.getAgentConfigSlice('codebase', CodeBaseAgentConfigSchema)
);

agent.initializeState(CodeBaseState, {
enabledResources: enabledResources.map(resourceName =>
this.resourceRegistry.ensureItemNamesLike(resourceName)
).flat()
});
}

Plugin Installation

The plugin is installed during application initialization:

import codeBasePlugin from "@tokenring-ai/codebase";
import TokenRingApp from "@tokenring-ai/app";

const app = new TokenRingApp();

app.install(codeBasePlugin, {
codebase: {
resources: {
"src": {
type: "fileTree"
},
"api": {
type: "repoMap"
},
"config": {
type: "wholeFile"
}
},
agentDefaults: {
enabledResources: []
}
}
});

Usage Examples

Basic Setup

import codeBasePlugin from "@tokenring-ai/codebase";
import TokenRingApp from "@tokenring-ai/app";

const app = new TokenRingApp();

app.install(codeBasePlugin, {
codebase: {
resources: {
"src": {
type: "fileTree"
},
"api": {
type: "repoMap"
},
"config": {
type: "wholeFile"
}
},
agentDefaults: {
enabledResources: []
}
}
});

Interactive Resource Selection

# Start a chat session
/codebase select

# The agent will display an interactive tree view of available resources
# Use arrow keys to navigate, space to select, and enter to confirm

# After selection, the enabled resources are updated automatically
# The agent will receive the selected resources in subsequent context

Programmatic Resource Management

import { Agent } from "@tokenring-ai/agent";
import { CodeBaseService } from "@tokenring-ai/codebase";

// Create an agent with codebase configuration
const agent = new Agent({
config: {
codebase: {
enabledResources: ["src/components", "src/utils"]
}
}
});

// Get the CodeBaseService
const codebaseService = agent.requireServiceByType(CodeBaseService);

// Enable additional resources
codebaseService.enableResources(["src/types"], agent);

// List all enabled resources
const enabled = codebaseService.getEnabledResourceNames(agent);
console.log("Enabled resources:", Array.from(enabled));

// Disable specific resources
codebaseService.disableResources(["test/*"], agent);

// Set specific resources (replaces existing)
codebaseService.setEnabledResources(["src/api"], agent);

// Reset to initial configuration
codebaseService.mutateState(CodeBaseState, state => {
state.reset();
});

Generating Repository Map

import { Agent } from "@tokenring-ai/agent";
import { CodeBaseService } from "@tokenring-ai/codebase";
import { FileSystemService } from "@tokenring-ai/filesystem";

const agent = new Agent();
const codebaseService = agent.requireServiceByType(CodeBaseService);
const fileSystem = agent.requireServiceByType(FileSystemService);

// Get repo map resources
const repoMapResources = codebaseService.getEnabledResources(agent)
.filter(resource => resource instanceof RepoMapResource);

// Collect files from all repo map resources
const repoMapFiles = new Set<string>();
for (const resource of repoMapResources) {
await resource.addFilesToSet(repoMapFiles, agent);
}

// Generate repository map
const repoMap = await codebaseService.generateRepoMap(
repoMapFiles,
fileSystem,
agent
);

if (repoMap) {
console.log("Repository map:");
console.log(repoMap);
}

Multi-language Repository Mapping

The service automatically detects file types and generates appropriate repository maps:

// Language mappings supported by getLanguageFromExtension
const languageMap = {
".js": "javascript",
".jsx": "javascript",
".ts": "typescript",
".tsx": "typescript",
".py": "python",
".h": "c",
".c": "c",
".hxx": "cpp",
".cxx": "cpp",
".hpp": "cpp",
".cpp": "cpp",
".rs": "rust",
".go": "go",
".java": "java",
".rb": "ruby",
".sh": "bash",
".bash": "bash"
};

// Unsupported extensions return null and are skipped during repo map generation

Context Injection in Chat

The context handler automatically injects codebase information when the agent needs it:

// When the agent starts a chat session, the context handler generates:
// 1. File tree for non-whole-file, non-repo-map resources
// 2. Repo map for repo map resources
// 3. Whole file contents for whole file resources

// These context items are added to the chat as user messages:
// - Directory structure of project files
// - Symbol snippets from code files
// - Complete contents of specific files

Best Practices

Resource Selection Strategies

  • Use /codebase select for interactive exploration when unsure of exact resource names
  • Start with file trees for large codebases to provide directory structure
  • Add repo maps for specific areas of interest (e.g., api, components)
  • Use whole files only for small, critical files (e.g., config, README)
  • Enable resources incrementally and test the context quality

Performance Considerations

  • Large codebases: Use file trees and repo maps instead of whole files to reduce context size
  • Multiple agents: Configure different enabledResources for different agent types
  • Wildcard patterns: Use wildcards (src/*) for enabling multiple resources efficiently
  • Lazy evaluation: Resources are only loaded when needed during context generation

Wildcard Pattern Matching

  • Wildcard patterns in resource names are resolved using ensureItemNamesLike
  • Patterns like src/* match all resources under src/ directory
  • Partial matches work (e.g., src matches src/components, src/utils)
  • Multiple patterns on a single line are supported (e.g., /codebase enable src/* utils/*)

State Management

  • Resources persist across agent sessions through state serialization
  • Use transferStateFromParent to inherit resources from parent agents
  • Reset resources when needed using the /codebase reset command

Error Handling

  • Errors during file processing are logged but don't stop context generation
  • Unsupported file types are skipped during repo map generation
  • Empty resource sets are handled gracefully

Agent Configuration

  • Service defaults provide a baseline for all agents
  • Agent-specific overrides allow customization per agent
  • Use getAgentConfigSlice('codebase') to retrieve agent-specific configuration

Testing and Development

Running Tests

bun test

Test Configuration

// vitest.config.ts
import { defineConfig } from "vitest/config";

export default defineConfig({
test: {
include: ["**/*.test.ts"],
environment: "node",
globals: true,
isolate: true,
coverage: {
provider: "v8",
reporter: ["text", "json", "html"]
}
},
});

Test Coverage

bun test --coverage

Package Structure

pkg/codebase/
├── CodeBaseService.ts # Main service class
├── FileTreeResource.ts # File tree resource implementation
├── RepoMapResource.ts # Repository map resource implementation
├── WholeFileResource.ts # Whole file resource implementation
├── commands.ts # Command exports
├── contextHandlers.ts # Context handler exports
├── schema.ts # Configuration schemas
├── state/
│ └── codeBaseState.ts # State management implementation
├── commands/
│ └── codebase/
│ ├── buildResourceTree.ts
│ ├── disable.ts
│ ├── enable.ts
│ ├── list.ts
│ ├── reset.ts
│ ├── select.ts
│ ├── set.ts
│ └── showRepo.ts
├── contextHandlers/
│ └── codebaseContext.ts # Context handler implementation
├── plugin.ts # Plugin registration
├── package.json # Package metadata
└── index.ts # Public exports

Build Instructions

bun run build

Dependencies

  • @tokenring-ai/agent - Central orchestration system (0.2.0)
  • @tokenring-ai/app - Base application framework and plugin system (0.2.0)
  • @tokenring-ai/chat - Chat service and context handling (0.2.0)
  • @tokenring-ai/filesystem - File system operations and resources (0.2.0)
  • @tokenring-ai/utility - Shared utilities including deepMerge and KeyedRegistry (0.2.0)
  • code-chopper - Code parsing and symbol extraction (^0.1.8)
  • zod - Runtime type validation and schema definition (^4.3.6)

Dev Dependencies

  • vitest - Testing framework (^4.1.0)
  • typescript - TypeScript compiler (^5.9.3)
  • FileMatchResource: Base class for all file-based resources from @tokenring-ai/filesystem
  • Chat Commands: /codebase select, /codebase enable, /codebase disable, /codebase set, /codebase reset, /codebase list, /codebase show repo
  • Context Handlers: codebase-context - Automatic codebase context injection
  • Agent State: CodeBaseState - Resource enablement state management
  • KeyedRegistry: Resource registry pattern from @tokenring-ai/utility

License

MIT License - see LICENSE file for details.