Skip to content

@chamvi/coding ​

Coding tools for chamvi agents and the coding backend contract. The public API of packages/coding/src/index.ts.

bash
npm install @chamvi/coding @chamvi/sandbox @chamvi/core ai --save

@chamvi/core, @chamvi/sandbox and ai are peer dependencies. See Workspaces & Coding for the behaviour.

codingTools ​

ts
function codingTools(workspaces: CodingWorkspaces): ToolSet;

type CodingWorkspaces = Pick<IWorkspaceManager, 'get'>;

Throws InvalidAgentDefinitionError when workspaces has no get. Returns read_file, write_file, edit_file, grep, list_files, bash and git_diff, each a defineTool() tool that resolves its workspace through workspaces.get(context.run.runId, input.workspace).

ToolInputResult
read_filepath, offset? (1-based, default 1), limit? (default and maximum 2000)ReadFileResult
write_filepath, contentWriteFileResult
edit_filepath, oldString, newString, replaceAll?EditFileResult
greppattern (POSIX ERE), path?, ignoreCase?, limit? (default 100, at most 500)GrepResult
list_filespath?, limit? (default 1000, at most 5000)ListFilesResult
bashcommand, cwd?, timeoutMs? (default 300 000, at most 1 800 000)ExecResult from @chamvi/sandbox
git_diffstaged?, path?GitDiffResult

Every tool also takes workspace?, the id from create_workspace. A path is relative to the workspace root or starts with /workspace/. Input the model can correct (a bad path, an oldString that is missing or ambiguous) is a ValidationError tool error; a missing or oversized file and any other sandbox failure a SandboxError tool error.

ts
/*
 * Copyright (c) 2026.
 * Author Peter Placzek (tada5hi)
 * For the full copyright and license information,
 * view the LICENSE file that was distributed with this source code.
 */

import type { IWorkspaceManager } from '@chamvi/sandbox';

/** What the coding tools need of a workspace manager: the run's workspaces by id. */
export type CodingWorkspaces = Pick<IWorkspaceManager, 'get'>;

export type ReadFileResult = {
    /** Relative to `/workspace`. */
    path: string;
    content: string;
    /** 1-based, inclusive. */
    startLine: number;
    endLine: number;
    totalLines: number;
    /** True when `content` was cut at `READ_MAX_CHARS`. */
    truncated: boolean;
};

export type WriteFileResult = {
    path: string;
    bytes: number;
};

export type EditFileResult = {
    path: string;
    replacements: number;
};

export type GrepMatch = {
    path: string;
    line: number;
    text: string;
};

export type GrepResult = {
    matches: GrepMatch[];
    /** True when more matches exist than were returned. */
    truncated: boolean;
};

export type ListFilesResult = {
    files: string[];
    truncated: boolean;
};

export type GitDiffResult = {
    /** `git status --short`. */
    status: string;
    diff: string;
    truncated: boolean;
};
ts
const READ_MAX_LINES: 2_000;
const READ_MAX_CHARS: 65_536;
const SEARCH_MAX_RESULTS: 500;
const LIST_MAX_RESULTS: 5_000;
const LINE_MAX_CHARS: 500;

ICodingBackend ​

The contract for something that solves a coding task in a workspace with its own tool loop. Only the contract ships; backends (the own tools in a nested loop, Claude Code) are planned.

ts
/*
 * Copyright (c) 2026.
 * Author Peter Placzek (tada5hi)
 * For the full copyright and license information,
 * view the LICENSE file that was distributed with this source code.
 */

import type { IWorkspace } from '@chamvi/sandbox';

export type CodingBudget = {
    maxSteps?: number;
    maxTokens?: number;
    timeoutMs?: number;
};

export type CodingTask = {
    /** The workspace to work in; the backend never disposes it. */
    workspace: IWorkspace;
    /** What to do, in plain language. */
    task: string;
    budget?: CodingBudget;
    signal?: AbortSignal;
};

export type CodingResult = {
    /** `done` when the task is solved, `stuck` when the backend gave up. */
    status: 'done' | 'stuck';
    summary: string;
    /** The workspace's changes as a unified diff. */
    diff: string;
};

/**
 * Something that solves a coding task in a workspace with its own tool loop
 * (the own coding tools, Claude Code, ...).
 */
export interface ICodingBackend {
    code(task: CodingTask): Promise<CodingResult>;
}