opencode-agent-modes 0.1.2 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -147,7 +147,38 @@ To add a custom preset (e.g., "premium"):
147
147
 
148
148
  3. Restart opencode to apply changes.
149
149
 
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
151
153
 
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
+ ```
@@ -1,10 +1,46 @@
1
1
  import type { ModeSwitcherConfig } from './types.ts';
2
2
  /**
3
- * Initialize the plugin configuration if it doesn't exist
4
- * @returns The configuration (existing or newly created)
3
+ * Initializes the plugin configuration if it doesn't exist.
4
+ *
5
+ * This function performs the following steps:
6
+ * 1. Checks if a configuration file already exists
7
+ * 2. If exists, loads and returns it
8
+ * 3. If not, creates a new configuration by:
9
+ * - Building a performance preset from current settings
10
+ * - Building an economy preset with free models
11
+ * - Setting default mode to "performance"
12
+ * - Saving the configuration to disk
13
+ *
14
+ * This is called on plugin startup to ensure a valid configuration
15
+ * is always available.
16
+ *
17
+ * @returns Promise resolving to the configuration (existing or newly created)
18
+ * @throws {Error} If configuration creation or file I/O fails
19
+ * @example
20
+ * ```typescript
21
+ * const config = await initializeConfig();
22
+ * console.log(config.currentMode); // "performance"
23
+ * ```
5
24
  */
6
25
  export declare function initializeConfig(): Promise<ModeSwitcherConfig>;
7
26
  /**
8
- * Ensure configuration is valid and has required presets
27
+ * Validates that a configuration object is well-formed and has required presets.
28
+ *
29
+ * This function performs the following checks:
30
+ * - `currentMode` field is present and non-empty
31
+ * - `presets` object exists and contains at least one preset
32
+ * - A preset exists for the current mode
33
+ *
34
+ * @param config - The configuration object to validate
35
+ * @returns True if configuration is valid, false otherwise
36
+ * @example
37
+ * ```typescript
38
+ * const config = await loadPluginConfig();
39
+ * if (validateConfig(config)) {
40
+ * console.log('Configuration is valid');
41
+ * } else {
42
+ * console.error('Invalid configuration detected');
43
+ * }
44
+ * ```
9
45
  */
10
46
  export declare function validateConfig(config: ModeSwitcherConfig): boolean;
@@ -1,4 +1,4 @@
1
- import type { ModeSwitcherConfig, OpencodeConfig, OhMyOpencodeConfig } from './types.ts';
1
+ import type { ModeSwitcherConfig, OhMyOpencodeConfig, OpencodeConfig } from './types.ts';
2
2
  /**
3
3
  * Expands tilde (~) notation to the user's home directory path.
4
4
  *
package/dist/index.d.ts CHANGED
@@ -1,9 +1,34 @@
1
- import type { Plugin } from "@opencode-ai/plugin";
2
1
  /**
3
- * OpenCode Agent Mode Switcher Plugin
2
+ * @fileoverview OpenCode Agent Mode Switcher Plugin.
4
3
  *
5
- * Allows switching between different agent mode presets (e.g., performance vs economy)
6
- * that configure which AI models are used for each agent type.
4
+ * This plugin provides tools for managing agent mode presets in OpenCode.
5
+ * It allows users to switch between different configurations (e.g., performance
6
+ * vs economy modes) that determine which AI models are used for each agent type.
7
+ *
8
+ * @module index
9
+ */
10
+ import type { Plugin } from '@opencode-ai/plugin';
11
+ /**
12
+ * OpenCode Agent Mode Switcher Plugin.
13
+ *
14
+ * Provides tools for switching between agent mode presets (e.g., performance
15
+ * vs economy) that configure which AI models are used for each agent type.
16
+ * The plugin initializes on startup by loading configurations and copying
17
+ * slash command files to the OpenCode command directory.
18
+ *
19
+ * @param params - Plugin initialization parameters
20
+ * @param params.client - OpenCode client for SDK interactions
21
+ * @returns Plugin object containing mode management tools
22
+ *
23
+ * @example
24
+ * ```typescript
25
+ * // Plugin is automatically loaded by OpenCode
26
+ * // Users can then use slash commands:
27
+ * // /mode-performance
28
+ * // /mode-economy
29
+ * // /mode-status
30
+ * // /mode-list
31
+ * ```
7
32
  */
8
33
  declare const modeSwitcherPlugin: Plugin;
9
34
  export default modeSwitcherPlugin;
package/dist/index.js CHANGED
@@ -12330,6 +12330,8 @@ function tool(input) {
12330
12330
  return input;
12331
12331
  }
12332
12332
  tool.schema = exports_external;
12333
+ // src/config/types.ts
12334
+ var DEFAULT_ECONOMY_MODEL = "opencode/glm-4.7-free";
12333
12335
  // src/config/loader.ts
12334
12336
  import { homedir } from "os";
12335
12337
  import { join } from "path";
@@ -13790,13 +13792,8 @@ async function saveOhMyOpencodeConfig(config2) {
13790
13792
  await saveJsonFile(getOhMyOpencodeConfigPath(), config2);
13791
13793
  }
13792
13794
  async function pluginConfigExists() {
13793
- const file2 = Bun.file(getPluginConfigPath());
13794
- return await file2.exists();
13795
+ return Bun.file(getPluginConfigPath()).exists();
13795
13796
  }
13796
-
13797
- // src/config/types.ts
13798
- var DEFAULT_ECONOMY_MODEL = "opencode/glm-4.7-free";
13799
-
13800
13797
  // src/config/initializer.ts
13801
13798
  var OPENCODE_AGENTS = [
13802
13799
  "build",
@@ -13882,7 +13879,37 @@ async function initializeConfig() {
13882
13879
  await savePluginConfig(config2);
13883
13880
  return config2;
13884
13881
  }
13885
-
13882
+ // src/config/command-installer.ts
13883
+ import { copyFileSync, existsSync, mkdirSync, readdirSync } from "fs";
13884
+ import { homedir as homedir2 } from "os";
13885
+ import { dirname, join as join2 } from "path";
13886
+ import { fileURLToPath } from "url";
13887
+ var COMMANDS_DEST = join2(homedir2(), ".config", "opencode", "command");
13888
+ function findCommandsDir() {
13889
+ const __dirname2 = dirname(fileURLToPath(import.meta.url));
13890
+ const candidates = [
13891
+ join2(__dirname2, "..", "commands"),
13892
+ join2(__dirname2, "..", "..", "commands")
13893
+ ];
13894
+ return candidates.find(existsSync) ?? null;
13895
+ }
13896
+ function copyCommandFiles() {
13897
+ const commandsSrc = findCommandsDir();
13898
+ if (!commandsSrc) {
13899
+ return -1;
13900
+ }
13901
+ try {
13902
+ mkdirSync(COMMANDS_DEST, { recursive: true });
13903
+ const files = readdirSync(commandsSrc).filter((f) => f.endsWith(".md"));
13904
+ for (const file2 of files) {
13905
+ copyFileSync(join2(commandsSrc, file2), join2(COMMANDS_DEST, file2));
13906
+ }
13907
+ return files.length;
13908
+ } catch (error45) {
13909
+ console.warn("[agent-mode-switcher] Warning: Could not copy command files:", error45 instanceof Error ? error45.message : String(error45));
13910
+ return -1;
13911
+ }
13912
+ }
13886
13913
  // src/modes/manager.ts
13887
13914
  class ModeManager {
13888
13915
  client;
@@ -13892,6 +13919,7 @@ class ModeManager {
13892
13919
  }
13893
13920
  async initialize() {
13894
13921
  this.config = await initializeConfig();
13922
+ await this.applyCurrentModeIfNeeded();
13895
13923
  }
13896
13924
  async ensureConfig() {
13897
13925
  if (!this.config) {
@@ -13899,6 +13927,55 @@ class ModeManager {
13899
13927
  }
13900
13928
  return this.config;
13901
13929
  }
13930
+ async applyCurrentModeIfNeeded() {
13931
+ if (!this.config) {
13932
+ return;
13933
+ }
13934
+ const preset = this.config.presets[this.config.currentMode];
13935
+ if (!preset) {
13936
+ return;
13937
+ }
13938
+ const drifted = await this.hasConfigDrift(preset);
13939
+ if (!drifted) {
13940
+ return;
13941
+ }
13942
+ await this.updateOpencodeConfig(preset.model, preset.opencode);
13943
+ await this.updateOhMyOpencodeConfig(preset["oh-my-opencode"]);
13944
+ this.client.tui.showToast({
13945
+ body: {
13946
+ title: "Mode Applied",
13947
+ message: `Applied "${this.config.currentMode}" mode. Restart opencode to take effect.`,
13948
+ variant: "warning",
13949
+ duration: 5000
13950
+ }
13951
+ }).catch(() => {});
13952
+ }
13953
+ async hasConfigDrift(preset) {
13954
+ const opencodeConfig = await loadOpencodeConfig();
13955
+ const ohMyConfig = await loadOhMyOpencodeConfig();
13956
+ if (preset.model && opencodeConfig) {
13957
+ if (opencodeConfig.model !== preset.model) {
13958
+ return true;
13959
+ }
13960
+ }
13961
+ if (opencodeConfig?.agent) {
13962
+ for (const [agentName, agentPreset] of Object.entries(preset.opencode)) {
13963
+ const actual = opencodeConfig.agent[agentName];
13964
+ if (actual?.model !== agentPreset.model) {
13965
+ return true;
13966
+ }
13967
+ }
13968
+ }
13969
+ if (ohMyConfig?.agents) {
13970
+ for (const [agentName, agentPreset] of Object.entries(preset["oh-my-opencode"])) {
13971
+ const actual = ohMyConfig.agents[agentName];
13972
+ if (actual?.model !== agentPreset.model) {
13973
+ return true;
13974
+ }
13975
+ }
13976
+ }
13977
+ return false;
13978
+ }
13902
13979
  async getCurrentMode() {
13903
13980
  const config2 = await this.ensureConfig();
13904
13981
  return config2.currentMode;
@@ -13989,14 +14066,12 @@ ${modes}`;
13989
14066
  if (globalModel) {
13990
14067
  opencodeConfig.model = globalModel;
13991
14068
  }
13992
- if (Object.keys(agentPresets).length > 0) {
13993
- opencodeConfig.agent = opencodeConfig.agent || {};
13994
- for (const [agentName, preset] of Object.entries(agentPresets)) {
13995
- opencodeConfig.agent[agentName] = {
13996
- ...opencodeConfig.agent[agentName],
13997
- model: preset.model
13998
- };
13999
- }
14069
+ opencodeConfig.agent = opencodeConfig.agent || {};
14070
+ for (const [agentName, preset] of Object.entries(agentPresets)) {
14071
+ opencodeConfig.agent[agentName] = {
14072
+ ...opencodeConfig.agent[agentName],
14073
+ model: preset.model
14074
+ };
14000
14075
  }
14001
14076
  await saveOpencodeConfig(opencodeConfig);
14002
14077
  return "updated";
@@ -14027,37 +14102,6 @@ ${modes}`;
14027
14102
  return config2.showToastOnStartup;
14028
14103
  }
14029
14104
  }
14030
- // src/config/command-installer.ts
14031
- import { copyFileSync, mkdirSync, readdirSync, existsSync } from "fs";
14032
- import { homedir as homedir2 } from "os";
14033
- import { dirname, join as join2 } from "path";
14034
- import { fileURLToPath } from "url";
14035
- var COMMANDS_DEST = join2(homedir2(), ".config", "opencode", "command");
14036
- function findCommandsDir() {
14037
- const __dirname2 = dirname(fileURLToPath(import.meta.url));
14038
- const candidates = [
14039
- join2(__dirname2, "..", "commands"),
14040
- join2(__dirname2, "..", "..", "commands")
14041
- ];
14042
- return candidates.find(existsSync) ?? null;
14043
- }
14044
- function copyCommandFiles() {
14045
- const commandsSrc = findCommandsDir();
14046
- if (!commandsSrc) {
14047
- return -1;
14048
- }
14049
- try {
14050
- mkdirSync(COMMANDS_DEST, { recursive: true });
14051
- const files = readdirSync(commandsSrc).filter((f) => f.endsWith(".md"));
14052
- for (const file2 of files) {
14053
- copyFileSync(join2(commandsSrc, file2), join2(COMMANDS_DEST, file2));
14054
- }
14055
- return files.length;
14056
- } catch (error45) {
14057
- console.warn("[agent-mode-switcher] Warning: Could not copy command files:", error45 instanceof Error ? error45.message : String(error45));
14058
- return -1;
14059
- }
14060
- }
14061
14105
  // src/index.ts
14062
14106
  var modeSwitcherPlugin = async ({ client }) => {
14063
14107
  const modeManager = new ModeManager(client);
@@ -1,54 +1,233 @@
1
1
  import type { OpencodeClient } from '@opencode-ai/sdk';
2
2
  import type { ModePreset } from '../config/types.ts';
3
3
  /**
4
- * Manages agent mode switching between different presets
4
+ * Manages agent mode switching between different presets.
5
+ *
6
+ * This class provides the core functionality for switching between
7
+ * performance and economy modes (or custom presets). It handles:
8
+ * - Loading and managing plugin configuration
9
+ * - Switching between different model presets
10
+ * - Updating OpenCode configuration files
11
+ * - Providing status and listing available modes
12
+ *
13
+ * The manager updates three configuration files when switching modes:
14
+ * - `~/.config/opencode/agent-mode-switcher.json` (plugin state)
15
+ * - `~/.config/opencode/opencode.json` (OpenCode agents)
16
+ * - `~/.config/opencode/oh-my-opencode.json` (oh-my-opencode agents)
17
+ *
18
+ * @example
19
+ * ```typescript
20
+ * const manager = new ModeManager(client);
21
+ * await manager.initialize();
22
+ *
23
+ * // Switch to economy mode
24
+ * const result = await manager.switchMode('economy');
25
+ * console.log(result);
26
+ *
27
+ * // Get current status
28
+ * const status = await manager.getStatus();
29
+ * console.log(status);
30
+ * ```
5
31
  */
6
32
  export declare class ModeManager {
7
33
  private readonly client;
8
34
  private config;
9
35
  constructor(client: OpencodeClient);
10
36
  /**
11
- * Initialize the mode manager and load configuration
37
+ * Initializes the mode manager and loads configuration.
38
+ *
39
+ * This method should be called before using any other manager methods.
40
+ * It loads or creates the plugin configuration file, ensuring all
41
+ * required presets are available.
42
+ *
43
+ * @throws {Error} If configuration initialization fails
44
+ * @example
45
+ * ```typescript
46
+ * const manager = new ModeManager(client);
47
+ * await manager.initialize();
48
+ * ```
12
49
  */
13
50
  initialize(): Promise<void>;
14
51
  /**
15
- * Ensure configuration is loaded
52
+ * Ensures configuration is loaded before any operation.
53
+ *
54
+ * This internal method is called by all public methods to lazily
55
+ * initialize the configuration if it hasn't been loaded yet.
56
+ *
57
+ * @returns Promise resolving to the loaded configuration
58
+ * @throws {Error} If configuration loading fails
59
+ * @private
16
60
  */
17
61
  private ensureConfig;
18
62
  /**
19
- * Get the current mode name
63
+ * Checks if actual config files have drifted from the current
64
+ * mode preset and applies the preset if needed.
65
+ *
66
+ * This handles the case where a user manually edits
67
+ * `agent-mode-switcher.json` to change `currentMode` while
68
+ * OpenCode is not running. On next startup, the actual config
69
+ * files are updated to match the expected preset values,
70
+ * and a toast notification prompts the user to restart.
71
+ *
72
+ * @private
73
+ */
74
+ private applyCurrentModeIfNeeded;
75
+ /**
76
+ * Compares a mode preset against the actual opencode.json and
77
+ * oh-my-opencode.json files to detect configuration drift.
78
+ *
79
+ * Checks global model and per-agent model values. Returns true
80
+ * if any expected value differs from the actual file content.
81
+ *
82
+ * @param preset - The mode preset to compare against
83
+ * @returns True if actual configs differ from the preset
84
+ * @private
85
+ */
86
+ private hasConfigDrift;
87
+ /**
88
+ * Gets the name of the currently active mode.
89
+ *
90
+ * @returns Promise resolving to the current mode name (e.g., "performance", "economy")
91
+ * @example
92
+ * ```typescript
93
+ * const currentMode = await manager.getCurrentMode();
94
+ * console.log(`Current mode: ${currentMode}`);
95
+ * ```
20
96
  */
21
97
  getCurrentMode(): Promise<string>;
22
98
  /**
23
- * Get a specific preset by name
99
+ * Gets a specific mode preset by name.
100
+ *
101
+ * @param modeName - The name of the mode to retrieve (e.g., "performance", "economy")
102
+ * @returns Promise resolving to the preset configuration, or undefined if not found
103
+ * @example
104
+ * ```typescript
105
+ * const preset = await manager.getPreset('economy');
106
+ * if (preset) {
107
+ * console.log(preset.description);
108
+ * console.log(preset.model);
109
+ * }
110
+ * ```
24
111
  */
25
112
  getPreset(modeName: string): Promise<ModePreset | undefined>;
26
113
  /**
27
- * Get all available mode names
114
+ * Gets a formatted list of all available modes.
115
+ *
116
+ * Returns a multi-line string listing each mode with its description,
117
+ * marking the currently active mode with "(current)".
118
+ *
119
+ * @returns Promise resolving to formatted string listing all available modes
120
+ * @example
121
+ * ```typescript
122
+ * const list = await manager.listModes();
123
+ * console.log(list);
124
+ * // Output:
125
+ * // Available modes:
126
+ * // - performance (current): High-performance models for complex tasks
127
+ * // - economy: Cost-efficient free model for routine tasks
128
+ * ```
28
129
  */
29
130
  listModes(): Promise<string>;
30
131
  /**
31
- * Get current status including mode and agent configurations
132
+ * Gets detailed status information for the current mode.
133
+ *
134
+ * Returns a formatted multi-line string showing:
135
+ * - Current mode name and description
136
+ * - Global model setting (if configured)
137
+ * - All OpenCode agents and their assigned models
138
+ * - All oh-my-opencode agents and their assigned models
139
+ *
140
+ * @returns Promise resolving to formatted status string
141
+ * @example
142
+ * ```typescript
143
+ * const status = await manager.getStatus();
144
+ * console.log(status);
145
+ * // Output:
146
+ * // Current mode: performance
147
+ * // Description: High-performance models for complex tasks
148
+ * // Global model: (not set)
149
+ * //
150
+ * // OpenCode agents:
151
+ * // - build: anthropic/claude-sonnet-4
152
+ * // - plan: anthropic/claude-sonnet-4
153
+ * // ...
154
+ * ```
32
155
  */
33
156
  getStatus(): Promise<string>;
34
157
  /**
35
- * Switch to a different mode
158
+ * Switches to a different mode by updating all configuration files.
159
+ *
160
+ * This method performs the following operations:
161
+ * 1. Validates that the requested mode exists
162
+ * 2. Updates `opencode.json` with new global model and agent settings
163
+ * 3. Updates `oh-my-opencode.json` with new agent settings
164
+ * 4. Updates `agent-mode-switcher.json` with the new current mode
165
+ * 5. Shows a toast notification (if available)
166
+ *
167
+ * Configuration files that don't exist are skipped with a warning.
168
+ * Changes take effect after restarting OpenCode.
169
+ *
170
+ * @param modeName - The name of the mode to switch to
171
+ * @returns Promise resolving to a formatted result message with status of each config update
172
+ * @example
173
+ * ```typescript
174
+ * const result = await manager.switchMode('economy');
175
+ * console.log(result);
176
+ * // Output:
177
+ * // Switched to economy mode
178
+ * // Cost-efficient free model for routine tasks
179
+ * //
180
+ * // Results:
181
+ * // - opencode.json: updated
182
+ * // - oh-my-opencode.json: updated
183
+ * // - agent-mode-switcher.json: updated
184
+ * //
185
+ * // Note: Restart opencode to apply changes.
186
+ * ```
36
187
  */
37
188
  switchMode(modeName: string): Promise<string>;
38
189
  /**
39
- * Update opencode.json with global model and agent section
40
- * @param globalModel - Global model setting (optional)
41
- * @param agentPresets - Agent-specific model settings
42
- * @returns Result status: "updated", "skipped (not found)", or "error: ..."
190
+ * Updates opencode.json with global model and agent section.
191
+ *
192
+ * This internal method modifies the OpenCode configuration file to apply
193
+ * the new preset's settings. It preserves other configuration properties
194
+ * and only updates model-related fields.
195
+ *
196
+ * @param globalModel - Global model setting (optional). If provided, sets the top-level "model" field
197
+ * @param agentPresets - Agent-specific model settings. Keys are agent names, values contain model strings
198
+ * @returns Promise resolving to result status: "updated", "skipped (not found)", or "error: ..."
199
+ * @private
43
200
  */
44
201
  private updateOpencodeConfig;
45
202
  /**
46
- * Update oh-my-opencode.json agents section with preset values
47
- * @returns Result status: "updated", "skipped (not found)", or "error: ..."
203
+ * Updates oh-my-opencode.json agents section with preset values.
204
+ *
205
+ * This internal method modifies the oh-my-opencode configuration file
206
+ * to apply the new preset's agent settings. Unlike opencode.json, this
207
+ * only updates the agents section and doesn't set a global model.
208
+ *
209
+ * @param agentPresets - Agent-specific model settings. Keys are agent names, values contain model strings
210
+ * @returns Promise resolving to result status: "updated", "skipped (not found)", or "error: ..."
211
+ * @private
48
212
  */
49
213
  private updateOhMyOpencodeConfig;
50
214
  /**
51
- * Check if toast should be shown on startup
215
+ * Checks if a toast notification should be shown on plugin startup.
216
+ *
217
+ * This is controlled by the `showToastOnStartup` configuration flag,
218
+ * which can be useful for reminding users of the current mode when
219
+ * OpenCode starts.
220
+ *
221
+ * @returns Promise resolving to true if toast should be shown, false otherwise
222
+ * @example
223
+ * ```typescript
224
+ * if (await manager.shouldShowToastOnStartup()) {
225
+ * const mode = await manager.getCurrentMode();
226
+ * await client.tui.showToast({
227
+ * body: { message: `Current mode: ${mode}` }
228
+ * });
229
+ * }
230
+ * ```
52
231
  */
53
232
  shouldShowToastOnStartup(): Promise<boolean>;
54
233
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-agent-modes",
3
- "version": "0.1.2",
3
+ "version": "0.2.0",
4
4
  "description": "OpenCode plugin to switch agent modes between performance and economy presets",
5
5
  "module": "src/index.ts",
6
6
  "main": "dist/index.js",
@@ -25,29 +25,23 @@
25
25
  "scripts": {
26
26
  "typecheck": "tsc --noEmit",
27
27
  "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 .",
31
31
  "test": "bun test",
32
32
  "test:watch": "bun test --watch",
33
33
  "test:coverage": "bun test --coverage",
34
34
  "prepublishOnly": "bun run build"
35
35
  },
36
- "keywords": [
37
- "opencode",
38
- "plugin",
39
- "agent",
40
- "mode",
41
- "switcher"
42
- ],
36
+ "keywords": ["opencode", "plugin", "agent", "mode", "switcher"],
43
37
  "author": "j4rviscmd",
44
38
  "license": "MIT",
45
39
  "engines": {
46
40
  "node": ">=18"
47
41
  },
48
42
  "devDependencies": {
49
- "@types/bun": "latest",
50
- "prettier": "^3.8.0"
43
+ "@biomejs/biome": "^1.9.4",
44
+ "@types/bun": "latest"
51
45
  },
52
46
  "peerDependencies": {
53
47
  "typescript": "^5"