Files
opencode-multi-model/AGENTS.md
T

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 format to format files

TypeScript Conventions

  • Use interface for object shapes; avoid type aliases unless needed
  • Use explicit return types on exported functions
  • Avoid any when possible
  • Use noUncheckedIndexedAccess: true and noImplicitOverride: true in 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 type for 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 @returns descriptions
  • Add inline comments for hard-to-understand code

Error Handling

  • Return result objects (e.g., MultiModelResult, CommandResult) with success: boolean
  • Include descriptive error messages prefixed with Error:
  • Provide actionable error messages (e.g., suggest valid models on failure)
  • Use chalk for 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:test framework
  • Mock Bun.$ using the mock() function from bun:test
  • Use spyOn() for fs/os module mocking
  • Group tests with describe() blocks
  • Test file naming: *.test.ts in tests/ 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