Skip to content

Commit 7d3b901

Browse files
j4rviscmdclaude
andcommitted
fix: resolve Biome lint errors for CI
- Sort import statements (organizeImports) - Fix noUselessConstructor in MockModeManager - Fix noNonNullAssertion by adding explicit null check - Simplify return statements in initializer.ts and loader.ts - Add comprehensive JSDoc documentation Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent a7e7855 commit 7d3b901

8 files changed

Lines changed: 283 additions & 57 deletions

File tree

src/config/command-installer.ts

Lines changed: 1 addition & 1 deletion
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'

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', () => {

src/config/loader.ts

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
import { homedir } from 'node:os'
22
import { join } from 'node:path'
33
import {
4-
parse as parseJsonc,
5-
modify,
6-
applyEdits,
74
type ModificationOptions,
5+
applyEdits,
6+
modify,
7+
parse as parseJsonc,
88
} from 'jsonc-parser'
99
import type {
1010
ModeSwitcherConfig,
11-
OpencodeConfig,
1211
OhMyOpencodeConfig,
12+
OpencodeConfig,
1313
} from './types.ts'
1414

1515
/**
@@ -344,8 +344,7 @@ export async function saveOhMyOpencodeConfig(
344344
* @returns True if agent-mode-switcher.json exists, false otherwise
345345
*/
346346
export async function pluginConfigExists(): Promise<boolean> {
347-
const file = Bun.file(getPluginConfigPath())
348-
return await file.exists()
347+
return Bun.file(getPluginConfigPath()).exists()
349348
}
350349

351350
/**

src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010

1111
import { tool } from '@opencode-ai/plugin'
1212
import type { Plugin } from '@opencode-ai/plugin'
13-
import { ModeManager } from './modes/index.ts'
1413
import { copyCommandFiles } from './config/index.ts'
14+
import { ModeManager } from './modes/index.ts'
1515

1616
/**
1717
* OpenCode Agent Mode Switcher Plugin.

src/modes/manager.test.ts

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,24 @@ import type {
88
import { createMockOpencodeClient, sampleConfigs } from '../test-utils/mocks.ts'
99

1010
/**
11-
* Create a mock ModeManager for testing
12-
* This avoids the complexity of mocking file system operations
11+
* Mock implementation of ModeManager for testing purposes.
12+
*
13+
* This test double avoids the complexity of mocking file system operations
14+
* by storing configuration in memory. It implements the same public API
15+
* as the real ModeManager but uses in-memory state instead of reading/writing
16+
* JSON files.
17+
*
18+
* @internal
1319
*/
1420
class MockModeManager {
1521
private config: ModeSwitcherConfig | null = null
1622
private opencodeConfig: OpencodeConfig | null = null
1723
private ohMyConfig: OhMyOpencodeConfig | null = null
24+
private client: OpencodeClient
1825

19-
constructor(_client: OpencodeClient) {}
26+
constructor(client: OpencodeClient) {
27+
this.client = client
28+
}
2029

2130
setConfig(config: ModeSwitcherConfig): void {
2231
this.config = config
@@ -43,7 +52,10 @@ class MockModeManager {
4352
if (!this.config) {
4453
await this.initialize()
4554
}
46-
return this.config!
55+
if (!this.config) {
56+
throw new Error('Config not initialized')
57+
}
58+
return this.config
4759
}
4860

4961
async getCurrentMode(): Promise<string> {

0 commit comments

Comments
 (0)