Files
boocode/apps/coder/src/services/tools/adapter.ts
indifferentketchup ce31577d1e v2.0.0-beta: write tools, pending-changes queue, inference loop, API routes
Phase 2 of v2.0. BooCoder is now a functional write-capable chatbot.

Write-path guard: resolveWritePath() uses resolve() (no realpath — files may
not exist for creates) + prefix-check + secret-file deny list (.env, *.pem,
id_rsa*, etc.). 23 unit tests cover traversal attacks.

Pending-changes service: queueEdit/Create/Delete → applyOne/All →
rejectOne/All → rewindOne. Edit diffs stored as JSON {old, new}. All writes
queue before touching disk; apply re-validates the path guard.

5 write tools: edit_file, create_file, delete_file, apply_pending, rewind.
Registered alongside 25 read-only tools from BooChat (30 total, alpha-sorted).
Write tools use a module-level inference context for sql+sessionId injection.

Inference loop via workspace dependency: apps/coder imports
createInferenceRunner, createBroker, ALL_TOOLS from @boocode/server (dist/).
apps/server gains declaration: true + exports map with typed subpath entries.
No code duplication — one inference engine shared by both apps.

API routes: POST /api/sessions/:id/messages (user msg → inference), POST stop,
GET/POST pending-changes CRUD (5 endpoints), WebSocket session streaming.

Dockerfile updated to build apps/server first (coder depends on its .d.ts).
Health endpoint reports tool count: {"ok":true,"db":true,"tools":30}.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 01:53:38 +00:00

31 lines
1.2 KiB
TypeScript

/**
* Adapts BooCoder write tools (which take ToolContext) into BooChat's ToolDef
* interface (which takes `projectRoot, extraRoots?`).
*
* The adapter reads the module-level inference context at execute time, so the
* wrapping happens at boot (static) — no per-inference re-wrap needed.
*/
import type { ToolDef as ServerToolDef } from '@boocode/server/tools';
import type { ToolDef, ToolContext } from './types.js';
import { getInferenceContext } from './inference_context.js';
/**
* Wrap a BooCoder write tool (execute takes ToolContext) into a BooChat
* ToolDef (execute takes projectRoot + optional extraRoots). The adapter
* builds the ToolContext from the module-level inference context at call time.
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function adaptWriteTool(tool: ToolDef<any>): ServerToolDef<any> {
return {
name: tool.name,
description: tool.description,
inputSchema: tool.inputSchema,
jsonSchema: tool.jsonSchema,
async execute(input: unknown, projectRoot: string, _extraRoots?: readonly string[]): Promise<unknown> {
const ctx: ToolContext = getInferenceContext();
return tool.execute(input, projectRoot, ctx);
},
};
}