# AGENTS.md ## Project Overview opencode-multi-model is a Bun/TypeScript project that provides multi-model tmux session management for AI coding assistants. It allows running multiple AI models simultaneously in isolated tmux windows with separate git worktrees. Available as three integration modes: - **OpenCode Plugin**: Loaded via `opencode.json` plugin array - **Standalone CLI**: Install globally and run `opencode-multi-model open -m ` - **Project Tool**: Import core functions from `"opencode-multi-model/core"` for project-level commands (used during development). Requires: tmux, git, opencode or kilo binary, Bun runtime. ## Build, Lint, and Test Commands ```bash # Install dependencies bun install # Build for production bun run build # Run tests bun test # 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 - Biome automatically organizes imports ### Documentation - Use JSDoc for all exported functions - Include `@example`, `@param`, and `@returns` descriptions - Add inline comments for hard-to-understand code - Modify Readme.md, if implementation details have changed. ### Error Handling - Return result objects (e.g., `MultiModelResult`, `CloseSessionResult`, `CleanupResult`) with `success: boolean` - Include descriptive error messages prefixed with `Error:` - Provide actionable error messages (e.g., suggest valid models on invalid model name) - 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 without throwing - Wrap command execution in `runCommand()` utility from `core/utils.ts` - Use `shellQuote()` for user-provided values in shell commands ### 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 (commander setup) ├── 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 (runCommand, shellQuote, etc.) └── tools/ ├── open.ts # OpenCode tool definition ├── close.ts # CloseCode tool definition └── cleanup.ts # Cleanup tool definition tests/ ├── open.test.ts # Open command tests ├── close.test.ts # Close command tests ├── cleanup.test.ts # Cleanup command tests ├── open_error.test.ts # Open error handling tests ├── close_error.test.ts # Close error handling tests └── utils.test.ts # Utility function tests ``` ### Git Branch and Tag Naming - Session branches: `opencode//` - Archive tags: `archive/-` (created by close command) - Worktrees: `~/.local/share/opencode/multi-model///` ### 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 - Archive tags preserve branch state before deletion for recovery