mirror of
https://github.com/bendtherules/opencode-multi-model.git
synced 2026-08-18 13:42:21 +00:00
4.5 KiB
4.5 KiB
AGENTS.md
Project Overview
opencode-multi-model is a Bun/TypeScript project that provides multi-model tmux session management for AI coding assistants. Works as an OpenCode plugin, standalone CLI, and project tool.
Key features:
- Launch multiple AI models in isolated tmux sessions
- Git worktree management for each model session
- Archive tag creation for session state preservation
- Supports both OpenCode and Kilo binaries
- Available as CLI tool, OpenCode plugin, or project-level import
Build, Lint, and Test Commands
# Install dependencies
bun install
# Build for production
bun run build
# Run tests with coverage (HTML report in ./coverage)
bun run coverage
# Run a specific test by name
bun test --test-name-pattern "fails if session name is empty"
# TypeScript type checking
bun run typecheck
# Lint with Biome
bun run lint
# Auto-fix lint issues
bun run lint:fix
# Format code with Biome
bun run format
# Full quality check
bun run typecheck && bun run lint
Code Style Guidelines
General
- Use TypeScript with strict mode
- Use Bun as the runtime and package manager
- Use ESM modules (
"type": "module"in package.json) - Use
node:prefix for Node.js built-ins
Formatting (Biome)
- Indent: 2 spaces (not tabs)
- Quote style: Double quotes for JS strings
- Semicolons: Required
- Run
bun run formatto format files
TypeScript Conventions
- Use
interfacefor object shapes; avoidtypealiases unless needed - Use explicit return types on exported functions
- Avoid
anywhen possible - Use
noUncheckedIndexedAccess: trueandnoImplicitOverride: truein tsconfig - All types/interfaces go in
src/types.ts
Naming Conventions
- Files: kebab-case (
multi-model-open.ts) - Functions: camelCase (
openMultiModel) - Types/Interfaces: PascalCase (
MultiModelOptions) - Constants: UPPER_SNAKE_CASE (e.g.,
MAX_SUGGESTIONS)
Imports
- Use
import typefor type-only imports - Group imports: external packages, internal modules, types
- Example:
import * as fs from "node:fs"; import chalk from "chalk"; import type { MultiModelOptions } from "../types"; import { runCommand } from "./utils";
JSDoc Comments
- Use JSDoc for all exported functions
- Include
@example,@param, and@returnsdescriptions - Add inline comments for hard-to-understand code
Error Handling
- Return result objects (e.g.,
MultiModelResult,CommandResult) withsuccess: boolean - Include descriptive error messages prefixed with
Error: - Provide actionable error messages (e.g., suggest valid models on failure)
- Use
chalkfor colored terminal output (red for errors, dim for secondary info, bold for primary info)
Shell Commands
- Use
Bun.$template tag for shell commands - Always use
quiet().nothrow()to capture output - Wrap command execution in
runCommand()utility - Never use single-character variable names
Testing
- Use
bun:testframework - Mock
Bun.$using themock()function frombun:test - Use
spyOn()for fs/os module mocking - Group tests with
describe()blocks - Test file naming:
*.test.tsintests/directory
Project Structure
src/
├── index.ts # Plugin entry point (default export)
├── cli.ts # CLI entry point
├── types.ts # All TypeScript interfaces/types
├── core/
│ ├── index.ts # Core exports
│ ├── open.ts # Session launch logic
│ ├── close.ts # Session close logic
│ ├── cleanup.ts # Archive tag cleanup logic
│ └── utils.ts # Shared utilities
└── tools/
├── open.ts # OpenCode tool definition
├── close.ts # CloseCode tool definition
└── cleanup.ts # Cleanup tool definition
tests/
├── open.test.ts
├── close.test.ts
├── cleanup.test.ts
├── open_error.test.ts
├── close_error.test.ts
└── utils.test.ts
Git Branch and Tag Naming
- Session branches:
opencode/<session-name>/<window-name> - Archive tags:
archive/<branch-name>-<timestamp>(created by close command) - Worktrees:
~/.local/share/opencode/multi-model/<session>/<window>/
Common Pitfalls
- Tmux session names use raw input; git branches/paths use sanitized names
- Window names must be unique; collisions get numeric suffixes (e.g.,
gpt-5-2,gpt-5-2-2) - Window names are truncated to 24 characters to fit tmux limits
- Worktree paths are checked for existence before creation to avoid conflicts