Skip to main content

@tokenring-ai/code-watch

The @tokenring-ai/code-watch package provides a file monitoring service for the Token Ring AI ecosystem. It watches configured filesystems for file changes, detects special AI comment patterns (like # AI! or // AI!), and automatically spawns agents to execute code modifications based on those instructions.

This service uses polling-based file system watching with configurable intervals and stability thresholds to debounce rapid file changes. When an AI comment with the AI! marker is detected, the service spawns a configured agent type in headless mode to execute the requested code modifications.

Overview

Code Watch provides real-time file system monitoring for detecting code changes and processing AI instructions embedded in comments. It integrates seamlessly with the Token Ring agent framework, providing background service functionality that operates without chat commands or tools.

Key Features

  • File System Monitoring: Watches multiple filesystems for file additions and changes using virtual filesystem providers
  • AI Comment Detection: Detects AI triggers in both Python/shell (#) and C-style (//) comments
  • Smart Change Handling: Uses stability thresholds to debounce rapid file changes
  • Concurrent Processing: Processes files concurrently with configurable worker queue via async.queue
  • Agent Integration: Automatically spawns appropriate agents to execute AI instructions in headless mode
  • Error Handling: Comprehensive error logging and graceful failure handling
  • Ignore Filtering: Respects ignore patterns from filesystem providers
  • Background Service: Runs as a background service without chat commands or tools

Core Components

CodeWatchService

The main service responsible for file monitoring and AI comment processing. Implements the TokenRingService interface.

Location: pkg/code-watch/CodeWatchService.ts

Interface: Implements TokenRingService from @tokenring-ai/app

Plugin

Coordinates service registration and configuration handling using the TokenRingPlugin interface.

Location: pkg/code-watch/plugin.ts

Exports: Default token ring plugin configuration

Services

CodeWatchService

The primary service implementation that provides file monitoring and AI comment processing capabilities.

Implements: TokenRingService

Constructor:

constructor(app: TokenRingApp, config: z.output<typeof CodeWatchConfigSchema>)

Parameters:

  • app: TokenRing application instance
  • config: Configuration object for service settings

Properties:

PropertyTypeDescription
name"CodeWatchService"Service name
descriptionstringService description: "Provides CodeWatch functionality that monitors files for AI comments"
appTokenRingAppTokenRing application instance
configCodeWatchConfigService configuration
workQueueAsync.Queue<{ filePath: string, fileSystemProviderName: string }>Async queue for concurrent file processing operations

Methods:

async run(signal: AbortSignal): Promise<void>

Starts the service and begins monitoring files for changes across all configured filesystems.

Parameters:

  • signal: AbortSignal to cancel the service

Returns: Promise<void> that resolves when all watchers are set up

Behavior:

  • Iterates through all configured filesystems
  • Calls watchFileSystem() for each filesystem
  • Returns after all watchers are set up
  • Handles graceful shutdown when signal is aborted

async watchFileSystem(fileSystemProviderName: string, filesystemConfig: FileSystemConfig, signal: AbortSignal): Promise<void>

Configures a new filesystem to watch.

Parameters:

  • fileSystemProviderName: Unique identifier for the filesystem provider
  • filesystemConfig: Configuration object including pollInterval, stabilityThreshold, and agentType
  • signal: AbortSignal to cancel the watcher

Returns: Promise<void> that resolves when the watcher is set up

Behavior:

  • Retrieves FileSystemService from the app
  • Gets the filesystem provider by name
  • Creates a file system watcher using the provider's watch() method
  • Sets up event handlers for add, change, and unlink events
  • Implements debouncing using stabilityThreshold to handle rapid changes
  • Processes files that pass the stability threshold via workQueue
  • Uses ignore patterns from the filesystem provider via createIgnoreFilter()
  • Returns after setting up the watcher and waiting for abort signal

Event Handling:

const onFileChanged = (eventType: string, filePath: string) => {
if (modifiedFiles.has(filePath)) {
clearTimeout(modifiedFiles.get(filePath));
modifiedFiles.delete(filePath);
}

if (eventType === "add" || eventType === "change") {
modifiedFiles.set(filePath, setTimeout(() => {
this.workQueue.push({filePath, fileSystemProviderName});
}));
}
};

async processFileForAIComments({filePath, fileSystemProviderName}: {filePath: string, fileSystemProviderName: string}): Promise<void>

Scans a file for AI comments and processes them.

Parameters:

  • filePath: Path to the file
  • fileSystemProviderName: Name of the filesystem provider

Returns: Promise<void> that resolves when processing is complete

Behavior:

  • Reads the file content from the filesystem provider
  • Splits content into lines
  • Checks each line for AI comment patterns:
    • Lines starting with # (Python/shell style)
    • Lines starting with // (C-style)
  • Calls checkAndTriggerAIAction() for each comment line

async checkAndTriggerAIAction(line: string, filePath: string, lineNumber: number, fileSystemProviderName: string): Promise<void>

Checks a comment line for AI triggers and initiates action.

Parameters:

  • line: The comment line content (trimmed)
  • filePath: Path of the file containing the comment
  • lineNumber: Line number in the file (1-indexed)
  • fileSystemProviderName: Name of the filesystem provider

Returns: Promise<void> that resolves when action is initiated

AI Trigger Patterns:

  • Lines starting with # AI or // AI
  • Lines ending with AI!

If either pattern matches, calls handleAIComment().

async handleAIComment(commentLine: string, filePath: string, lineNumber: number, fileSystemProviderName: string): Promise<void>

Handles processing of a specific AI comment.

Parameters:

  • commentLine: The comment line content
  • filePath: Path of the file
  • lineNumber: Line number in the file
  • fileSystemProviderName: Name of the filesystem provider

Returns: Promise<void> that resolves when handling is complete

Behavior:

  • Extracts the actual comment content (removes # or // markers)
  • Checks if comment contains AI! marker
  • Triggers code modification if AI! is present via triggerCodeModification()

Comment Content Extraction:

let content = commentLine.trim();
if (commentLine.startsWith("# ")) {
content = commentLine.substring(2);
} else if (commentLine.startsWith("// ")) {
content = commentLine.substring(3);
}

async triggerCodeModification(content: string, filePath: string, lineNumber: number, fileSystemProviderName: string): Promise<void>

Triggers code modification agent for an AI! comment.

Parameters:

  • content: The content of the comment
  • filePath: Path of the file
  • lineNumber: Line number in the file
  • fileSystemProviderName: Name of the filesystem provider

Returns: Promise<void> that resolves when code modification starts

Behavior:

  • Retrieves AgentManager and FileSystemService from the app
  • Gets the agent type from the filesystem configuration
  • Spawns agent of specified type in headless mode via agentManager.spawnAgent()
  • Sets active filesystem for the agent via fileSystemService.setActiveFileSystem()
  • Creates and executes modification prompt
  • Calls runCodeModification() to execute the agent
  • Agent is responsible for removing the AI! comment after completion

Prompt Template:

The service generates a prompt that instructs the agent to:

  1. Look for lines marked with AI! tag
  2. Complete the instructions in that line or nearby comments
  3. Update the file using the file_write tool
  4. Must remove any lines that end with AI!

async runCodeModification(prompt: string, filePath: string, agent: Agent): Promise<void>

Executes code modification agent.

Parameters:

  • prompt: The instruction prompt for the agent
  • filePath: Path of the file
  • agent: The Agent instance to execute commands on

Returns: Promise<void> that resolves when modification is complete

Behavior:

  • Adds file to agent's chat context via fileSystemService.addFileToChat()
  • Retrieves AgentCommandService from the agent
  • Executes /work command with the prompt via agentCommandService.executeAgentCommand()
  • Waits for agent to complete the task

Chat Commands

This package does not provide chat commands. It operates as a background service monitoring files for changes.

RPC Endpoints

This package does not define RPC endpoints.

Configuration

Configuration Schema

The plugin configuration is defined in plugin.ts:

import { TokenRingPlugin } from "@tokenring-ai/app";
import { z } from "zod";
import CodeWatchService from "./CodeWatchService.ts";
import { CodeWatchConfigSchema } from "./index.ts";
import packageJSON from './package.json' with {type: 'json'};

const packageConfigSchema = z.object({
codewatch: CodeWatchConfigSchema.optional(),
});

export default {
name: packageJSON.name,
version: packageJSON.version,
description: packageJSON.description,
install(app, config) {
if (config.codewatch) {
app.addServices(new CodeWatchService(app, config.codewatch));
}
},
config: packageConfigSchema
} satisfies TokenRingPlugin<typeof packageConfigSchema>;

The configuration schema is defined in index.ts:

import { z } from "zod";

export const CodeWatchConfigSchema = z.object({
filesystems: z.record(z.string(), z.object({
pollInterval: z.number().default(1000),
stabilityThreshold: z.number().default(2000),
agentType: z.string()
})),

concurrency: z.number().default(1),
});

Configuration Options

Top-Level Configuration

FieldTypeDefaultDescription
codewatchCodeWatchConfigoptionalMain configuration for CodeWatch service

CodeWatchConfig

FieldTypeDefaultDescription
filesystemsRecord<string, FileSystemConfig>requiredConfiguration for each filesystem to monitor
concurrencynumber1Maximum concurrent file processing operations

FileSystemConfig

FieldTypeDefaultDescription
pollIntervalnumber1000Polling interval in milliseconds for detecting file changes
stabilityThresholdnumber2000Time in milliseconds to wait after a change before processing
agentTypestringrequiredType of agent to spawn for code modifications

Configuration Example

{
codewatch: {
filesystems: {
local: {
pollInterval: 1000, // Check for changes every 1 second
stabilityThreshold: 2000, // Wait 2 seconds after last change before processing
agentType: 'code-modification-agent'
}
},
concurrency: 2 // Process up to 2 files concurrently
}
}

Integration

Plugin Registration

The package integrates with the TokenRing application through the plugin system:

import TokenRingApp from '@tokenring-ai/app';
import codeWatch from '@tokenring-ai/code-watch/plugin';

const app = new TokenRingApp();
app.install(codeWatch, {
codewatch: {
filesystems: {
local: {
pollInterval: 1000,
stabilityThreshold: 2000,
agentType: 'code-modification-agent'
}
},
concurrency: 2
}
});

Service Registration

When installed, the plugin automatically registers the CodeWatchService:

if (config.codewatch) {
app.addServices(new CodeWatchService(app, config.codewatch));
}

Required Services

The CodeWatchService requires the following services to be available:

  • FileSystemService: For file operations and watching
  • AgentManager: For spawning agents to execute AI instructions

Agent Workflow

When an AI! comment is detected in a file:

  1. The service spawns an agent of the specified type in headless mode
  2. The file is added to the agent's chat context using FileSystemService.addFileToChat()
  3. The agent executes the instruction from the AI! comment via /work command
  4. The agent uses available tools to complete the requested task
  5. The agent updates the file using the file write tool
  6. The agent removes the AI! comment from the file as a completion marker

Usage Examples

Basic Plugin Installation

import TokenRingApp from '@tokenring-ai/app';
import codeWatch from '@tokenring-ai/code-watch/plugin';

const app = new TokenRingApp();

app.install(codeWatch, {
codewatch: {
filesystems: {
local: {
pollInterval: 1000,
stabilityThreshold: 2000,
agentType: 'code-modification-agent'
}
},
concurrency: 2
}
});

// Start the application
await app.run();

Multiple Filesystem Configuration

import TokenRingApp from '@tokenring-ai/app';
import codeWatch from '@tokenring-ai/code-watch/plugin';

const app = new TokenRingApp();

app.install(codeWatch, {
codewatch: {
filesystems: {
local: {
pollInterval: 1000,
stabilityThreshold: 2000,
agentType: 'code-modification-agent'
},
project: {
pollInterval: 1500,
stabilityThreshold: 2500,
agentType: 'project-agent'
}
},
concurrency: 3
}
});

await app.run();

AI Comment Examples

Python/Shell Style Comments

# AI! Fix the off-by-one error in the loop below
for i in range(10):
print(i)

C-Style Comments

// AI! Refactor this function to use async/await
function fetchData() {
return fetch('/api/data').then(res => res.json());
}

Inline AI Instructions

const result = processData(data); // AI! Add error handling here

Comment Detection Patterns

The service detects AI comments using these patterns:

  1. Lines starting with # AI (Python/shell style)
  2. Lines starting with // AI (C-style)
  3. Lines ending with AI! (any style)

Important: Only comments containing AI! will trigger code modification. Comments that match the prefix patterns but don't contain AI! will be detected but won't trigger action.

Best Practices

Agent Selection

Choose appropriate agent types based on the complexity of tasks:

  • Use simpler agents for straightforward modifications
  • Use more capable agents for complex refactoring

Balancing Performance

  • Adjust pollInterval for responsiveness vs. system load
  • Set appropriate stabilityThreshold to avoid processing incomplete writes
  • Configure concurrency based on your system's capabilities
  • Stability thresholds handle file write completion detection

Error Monitoring

Implement monitoring for service errors to catch issues early:

  • File processing errors are logged via app.serviceError()
  • Agent execution errors are caught and logged
  • Watcher errors are caught and logged via event handlers

File Stability

Ensure files are fully written before triggering processing. The stabilityThreshold handles this by waiting for changes to settle through debouncing.

Provider Configuration

Configure appropriate filesystem providers before starting:

  • Each filesystem provider must support watch and readFile operations
  • Providers should have appropriate ignore patterns for non-code files
  • Polling intervals can vary by filesystem location

Testing and Development

Running Tests

bun test

Running Tests in Watch Mode

bun test:watch

Running Test Coverage

bun test:coverage

Build

bun build

Package Structure

pkg/code-watch/
├── index.ts # Configuration schema and exports
├── CodeWatchService.ts # Main service implementation
├── plugin.ts # Plugin definition and registration
├── package.json # Package metadata and dependencies
├── README.md # Package documentation
├── vitest.config.ts # Test configuration
└── BRAINSTORM.md # Feature brainstorming and roadmap

Test Configuration

Test files are configured in vitest.config.ts:

import {defineConfig} from "vitest/config";

export default defineConfig({
test: {
include: ["**/*.test.ts"],
environment: "node",
globals: true,
isolate: true,
},
});

Note: No test files currently exist in the package. Test infrastructure is configured but individual tests have not been implemented yet.

Dependencies

Production Dependencies

PackageVersionDescription
@tokenring-ai/app0.2.0Core application framework
@tokenring-ai/agent0.2.0Agent management and orchestration
@tokenring-ai/filesystem0.2.0File system abstraction and providers
@tokenring-ai/utility0.2.0Utility functions and helpers
@tokenring-ai/chat0.2.0Chat functionality
zod^4.3.6Schema validation
async^3.2.6Concurrent processing utilities
ignore^7.0.5Ignore pattern matching

Development Dependencies

PackageVersionDescription
vitest^4.1.0Testing framework
typescript^5.9.3TypeScript compiler
@types/async^3.2.25Async type definitions
  • @tokenring-ai/app: Core application framework

    • TokenRingPlugin: Plugin interface and TokenRingApp access
    • TokenRingService: Service interface and service registration
    • TokenRingApp: Main application class
  • @tokenring-ai/agent: Agent management and execution

    • Agent: Agent class for command execution
    • AgentManager: Agent spawning and management
    • AgentCommandService: Command execution interface
  • @tokenring-ai/filesystem: File system abstraction

    • FileSystemService: File system management
    • FileSystemProvider: File system provider interface
    • createIgnoreFilter: Ignore pattern filter utility
  • @tokenring-ai/utility: Utility functions

    • waitForAbort: Abort signal handler utility

License

MIT License - see LICENSE file for details.