Skip to content

Commit 1e1c988

Browse files
authored
Merge pull request #4 from j4rviscmd/chore/migrate-prettier-to-biome
chore: migrate from Prettier to Biome for formatting
2 parents bde5527 + 7d3b901 commit 1e1c988

14 files changed

Lines changed: 443 additions & 120 deletions

File tree

.github/workflows/ci.yml

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,8 @@ jobs:
1919
- name: Install
2020
run: bun install --frozen-lockfile --ignore-scripts
2121

22-
- name: Lint
23-
run: bun run lint
24-
25-
- name: Format
26-
run: bun run format
27-
28-
- name: Format check
29-
run: bun run format:check
22+
- name: Lint & Format
23+
run: bun run lint && bun run format:check
3024

3125
- name: Type check
3226
run: bun run typecheck

.prettierrc

Lines changed: 0 additions & 7 deletions
This file was deleted.

README.md

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,38 @@ To add a custom preset (e.g., "premium"):
147147

148148
3. Restart opencode to apply changes.
149149

150-
## Notes
150+
> [!INFO]
151+
> - Changes require an opencode restart to take effect
152+
> - Custom mode presets can be added by editing the configuration file
151153
152-
- Changes require an opencode restart to take effect
153-
- Custom mode presets can be added by editing the configuration file
154+
## Development
155+
156+
This project uses [Bun](https://bun.sh/) as the runtime and package manager.
157+
158+
### Prerequisites
159+
160+
- [Bun](https://bun.sh/) v1.0 or later
161+
162+
### Setup
163+
164+
```bash
165+
# Clone the repository
166+
git clone https://github.com/j4rviscmd/opencode-agent-modes.git
167+
cd opencode-agent-modes
168+
169+
# Install dependencies
170+
bun install
171+
172+
# Run tests
173+
bun test
174+
175+
# Type check
176+
bun run typecheck
177+
178+
# Lint & format
179+
bun run lint
180+
bun run format
181+
182+
# Build
183+
bun run build
184+
```

biome.json

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{
2+
"$schema": "https://biomejs.dev/schemas/1.9.4/schema.json",
3+
"organizeImports": {
4+
"enabled": true
5+
},
6+
"formatter": {
7+
"enabled": true,
8+
"indentStyle": "space",
9+
"indentWidth": 2,
10+
"lineWidth": 80
11+
},
12+
"javascript": {
13+
"formatter": {
14+
"semicolons": "asNeeded",
15+
"quoteStyle": "single",
16+
"trailingCommas": "es5"
17+
}
18+
},
19+
"linter": {
20+
"enabled": true,
21+
"rules": {
22+
"recommended": true
23+
}
24+
},
25+
"files": {
26+
"include": ["src/**/*.ts", "*.json"]
27+
}
28+
}

bun.lock

Lines changed: 19 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,29 +25,23 @@
2525
"scripts": {
2626
"typecheck": "tsc --noEmit",
2727
"build": "bun build src/index.ts --outdir dist --format esm --target bun && tsc -p tsconfig.build.json",
28-
"lint": "bunx biome check src/",
29-
"format": "prettier --write 'src/**/*.ts'",
30-
"format:check": "prettier --check 'src/**/*.ts'",
28+
"lint": "bunx biome check .",
29+
"format": "bunx biome format --write .",
30+
"format:check": "bunx biome format .",
3131
"test": "bun test",
3232
"test:watch": "bun test --watch",
3333
"test:coverage": "bun test --coverage",
3434
"prepublishOnly": "bun run build"
3535
},
36-
"keywords": [
37-
"opencode",
38-
"plugin",
39-
"agent",
40-
"mode",
41-
"switcher"
42-
],
36+
"keywords": ["opencode", "plugin", "agent", "mode", "switcher"],
4337
"author": "j4rviscmd",
4438
"license": "MIT",
4539
"engines": {
4640
"node": ">=18"
4741
},
4842
"devDependencies": {
49-
"@types/bun": "latest",
50-
"prettier": "^3.8.0"
43+
"@biomejs/biome": "^1.9.4",
44+
"@types/bun": "latest"
5145
},
5246
"peerDependencies": {
5347
"typescript": "^5"

src/config/command-installer.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
* @module config/command-installer
1010
*/
1111

12-
import { copyFileSync, mkdirSync, readdirSync, existsSync } from 'node:fs'
12+
import { copyFileSync, existsSync, mkdirSync, readdirSync } from 'node:fs'
1313
import { homedir } from 'node:os'
1414
import { dirname, join } from 'node:path'
1515
import { fileURLToPath } from 'node:url'
@@ -53,7 +53,7 @@ function findCommandsDir(): string | null {
5353

5454
// Try multiple paths to support different build outputs
5555
const candidates = [
56-
join(__dirname, '..', 'commands'), // Production: dist/ -> commands/
56+
join(__dirname, '..', 'commands'), // Production: dist/ -> commands/
5757
join(__dirname, '..', '..', 'commands'), // Development: src/config/ -> commands/
5858
]
5959

@@ -92,13 +92,10 @@ export function copyCommandFiles(): number {
9292
}
9393

9494
try {
95-
// Create destination directory with parents if needed
9695
mkdirSync(COMMANDS_DEST, { recursive: true })
9796

98-
// Filter only markdown files
9997
const files = readdirSync(commandsSrc).filter((f) => f.endsWith('.md'))
10098

101-
// Copy each command file to the destination
10299
for (const file of files) {
103100
copyFileSync(join(commandsSrc, file), join(COMMANDS_DEST, file))
104101
}

src/config/initializer.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import { describe, test, expect, beforeEach, afterEach } from 'bun:test'
1+
import { afterEach, beforeEach, describe, expect, test } from 'bun:test'
2+
import { mkdirSync, rmSync } from 'node:fs'
23
import { join } from 'node:path'
3-
import { rmSync, mkdirSync } from 'node:fs'
44
import { validateConfig } from './initializer.ts'
5-
import type { ModeSwitcherConfig, ModePreset } from './types.ts'
5+
import type { ModePreset, ModeSwitcherConfig } from './types.ts'
66

77
describe('initializer', () => {
88
describe('validateConfig', () => {

src/config/initializer.ts

Lines changed: 75 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
1-
import type { ModeSwitcherConfig, ModePreset, AgentPreset } from './types.ts'
2-
import { DEFAULT_ECONOMY_MODEL } from './types.ts'
31
import {
4-
loadOpencodeConfig,
52
loadOhMyOpencodeConfig,
3+
loadOpencodeConfig,
64
loadPluginConfig,
7-
savePluginConfig,
85
pluginConfigExists,
6+
savePluginConfig,
97
} from './loader.ts'
8+
import type { AgentPreset, ModePreset, ModeSwitcherConfig } from './types.ts'
9+
import { DEFAULT_ECONOMY_MODEL } from './types.ts'
1010

1111
/**
12-
* Default opencode agent names
12+
* Default opencode agent names.
13+
*
14+
* These are the standard agents used by OpenCode for various tasks.
15+
*
16+
* @constant
1317
*/
1418
const OPENCODE_AGENTS = [
1519
'build',
@@ -22,7 +26,19 @@ const OPENCODE_AGENTS = [
2226
] as const
2327

2428
/**
25-
* Build a preset from existing configurations
29+
* Builds a performance preset from existing OpenCode configurations.
30+
*
31+
* This function scans the current `opencode.json` and `oh-my-opencode.json`
32+
* files to extract the currently configured models for each agent. These
33+
* models are saved as the "performance" preset, preserving the user's
34+
* high-performance model choices.
35+
*
36+
* @returns Promise resolving to a ModePreset with performance-oriented models
37+
* @example
38+
* ```typescript
39+
* const preset = await buildPerformancePreset();
40+
* console.log(preset.opencode.build.model); // "anthropic/claude-sonnet-4"
41+
* ```
2642
*/
2743
async function buildPerformancePreset(): Promise<ModePreset> {
2844
const opencodeConfig = await loadOpencodeConfig()
@@ -64,7 +80,19 @@ async function buildPerformancePreset(): Promise<ModePreset> {
6480
}
6581

6682
/**
67-
* Build economy preset with free model
83+
* Builds an economy preset using the default free model.
84+
*
85+
* This function creates a cost-efficient preset where all agents
86+
* (both OpenCode and oh-my-opencode) are configured to use the
87+
* `opencode/glm-4.7-free` model. This provides a budget-friendly
88+
* alternative to performance mode for routine tasks.
89+
*
90+
* @returns Promise resolving to a ModePreset with economy-oriented models
91+
* @example
92+
* ```typescript
93+
* const preset = await buildEconomyPreset();
94+
* console.log(preset.model); // "opencode/glm-4.7-free"
95+
* ```
6896
*/
6997
async function buildEconomyPreset(): Promise<ModePreset> {
7098
const opencodeConfig = await loadOpencodeConfig()
@@ -101,8 +129,27 @@ async function buildEconomyPreset(): Promise<ModePreset> {
101129
}
102130

103131
/**
104-
* Initialize the plugin configuration if it doesn't exist
105-
* @returns The configuration (existing or newly created)
132+
* Initializes the plugin configuration if it doesn't exist.
133+
*
134+
* This function performs the following steps:
135+
* 1. Checks if a configuration file already exists
136+
* 2. If exists, loads and returns it
137+
* 3. If not, creates a new configuration by:
138+
* - Building a performance preset from current settings
139+
* - Building an economy preset with free models
140+
* - Setting default mode to "performance"
141+
* - Saving the configuration to disk
142+
*
143+
* This is called on plugin startup to ensure a valid configuration
144+
* is always available.
145+
*
146+
* @returns Promise resolving to the configuration (existing or newly created)
147+
* @throws {Error} If configuration creation or file I/O fails
148+
* @example
149+
* ```typescript
150+
* const config = await initializeConfig();
151+
* console.log(config.currentMode); // "performance"
152+
* ```
106153
*/
107154
export async function initializeConfig(): Promise<ModeSwitcherConfig> {
108155
const exists = await pluginConfigExists()
@@ -134,7 +181,24 @@ export async function initializeConfig(): Promise<ModeSwitcherConfig> {
134181
}
135182

136183
/**
137-
* Ensure configuration is valid and has required presets
184+
* Validates that a configuration object is well-formed and has required presets.
185+
*
186+
* This function performs the following checks:
187+
* - `currentMode` field is present and non-empty
188+
* - `presets` object exists and contains at least one preset
189+
* - A preset exists for the current mode
190+
*
191+
* @param config - The configuration object to validate
192+
* @returns True if configuration is valid, false otherwise
193+
* @example
194+
* ```typescript
195+
* const config = await loadPluginConfig();
196+
* if (validateConfig(config)) {
197+
* console.log('Configuration is valid');
198+
* } else {
199+
* console.error('Invalid configuration detected');
200+
* }
201+
* ```
138202
*/
139203
export function validateConfig(config: ModeSwitcherConfig): boolean {
140204
if (!config.currentMode) {
@@ -143,8 +207,5 @@ export function validateConfig(config: ModeSwitcherConfig): boolean {
143207
if (!config.presets || Object.keys(config.presets).length === 0) {
144208
return false
145209
}
146-
if (!config.presets[config.currentMode]) {
147-
return false
148-
}
149-
return true
210+
return Boolean(config.presets[config.currentMode])
150211
}

src/config/loader.test.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
1-
import { describe, test, expect, beforeEach, afterEach } from 'bun:test'
2-
import { join } from 'node:path'
1+
import { afterEach, beforeEach, describe, expect, test } from 'bun:test'
2+
import { mkdirSync, rmSync } from 'node:fs'
33
import { homedir } from 'node:os'
4-
import { rmSync, mkdirSync } from 'node:fs'
4+
import { join } from 'node:path'
55
import { parse as parseJsonc } from 'jsonc-parser'
6+
import { type ModificationOptions, applyEdits, modify } from 'jsonc-parser'
67
import {
8+
clearContentCache,
79
expandPath,
8-
getPluginConfigPath,
9-
getOpencodeConfigPath,
1010
getOhMyOpencodeConfigPath,
11-
clearContentCache,
11+
getOpencodeConfigPath,
12+
getPluginConfigPath,
1213
setContentCache,
1314
} from './loader.ts'
14-
import { modify, applyEdits, type ModificationOptions } from 'jsonc-parser'
1515
import type {
1616
ModeSwitcherConfig,
17-
OpencodeConfig,
1817
OhMyOpencodeConfig,
18+
OpencodeConfig,
1919
} from './types.ts'
2020

2121
describe('loader', () => {

0 commit comments

Comments
 (0)