opencode-agent-modes 0.2.0 → 0.3.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 +4 -0
- package/dist/config/guards.d.ts +14 -0
- package/dist/config/index.d.ts +1 -0
- package/dist/config/types.d.ts +36 -8
- package/dist/index.js +115 -89
- package/dist/modes/manager.d.ts +14 -12
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -150,6 +150,10 @@ To add a custom preset (e.g., "premium"):
|
|
|
150
150
|
> [!INFO]
|
|
151
151
|
> - Changes require an opencode restart to take effect
|
|
152
152
|
> - Custom mode presets can be added by editing the configuration file
|
|
153
|
+
> - Built-in command files (`mode-performance.md`, `mode-economy.md`, etc.)
|
|
154
|
+
> are overwritten on every plugin startup. Do not modify them directly.
|
|
155
|
+
> - Custom command files (e.g., `mode-premium.md`) are not affected by
|
|
156
|
+
> this overwrite and will persist across restarts.
|
|
153
157
|
|
|
154
158
|
## Development
|
|
155
159
|
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type guard utilities for configuration processing.
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Checks if a value is a plain object (not null, not array).
|
|
6
|
+
*
|
|
7
|
+
* This is used throughout the codebase to distinguish between
|
|
8
|
+
* hierarchical structures and leaf values when processing
|
|
9
|
+
* configurations.
|
|
10
|
+
*
|
|
11
|
+
* @param obj - Value to check
|
|
12
|
+
* @returns True if the value is a plain object
|
|
13
|
+
*/
|
|
14
|
+
export declare function isObject(obj: unknown): obj is Record<string, unknown>;
|
package/dist/config/index.d.ts
CHANGED
package/dist/config/types.d.ts
CHANGED
|
@@ -1,17 +1,38 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Generic model configuration for any agent.
|
|
3
|
+
*
|
|
4
|
+
* This interface is intentionally flexible to support arbitrary
|
|
5
|
+
* properties beyond just `model` and `variant`.
|
|
3
6
|
*/
|
|
4
|
-
export interface
|
|
5
|
-
model
|
|
7
|
+
export interface ModelConfig {
|
|
8
|
+
model?: string;
|
|
9
|
+
variant?: string;
|
|
10
|
+
[key: string]: unknown;
|
|
6
11
|
}
|
|
7
12
|
/**
|
|
8
|
-
*
|
|
13
|
+
* Hierarchical preset structure supporting arbitrary nesting.
|
|
14
|
+
*
|
|
15
|
+
* This type recursively represents the configuration structure for
|
|
16
|
+
* both opencode and oh-my-opencode, supporting any level of nesting
|
|
17
|
+
* (e.g., agents/categories, future sections).
|
|
18
|
+
*
|
|
19
|
+
* Note: This type alias has a circular reference by design to support
|
|
20
|
+
* recursive structures. The TypeScript compiler warning about this
|
|
21
|
+
* can be safely ignored.
|
|
22
|
+
*/
|
|
23
|
+
export type HierarchicalPreset = Record<string, ModelConfig | HierarchicalPreset>;
|
|
24
|
+
/**
|
|
25
|
+
* Mode preset containing configurations for both opencode and oh-my-opencode agents.
|
|
26
|
+
*
|
|
27
|
+
* Both opencode and oh-my-opencode use the same HierarchicalPreset type,
|
|
28
|
+
* allowing them to have arbitrary nested structures that are handled
|
|
29
|
+
* uniformly by recursive merge functions.
|
|
9
30
|
*/
|
|
10
31
|
export interface ModePreset {
|
|
11
32
|
description: string;
|
|
12
33
|
model?: string;
|
|
13
|
-
opencode:
|
|
14
|
-
'oh-my-opencode':
|
|
34
|
+
opencode: HierarchicalPreset;
|
|
35
|
+
'oh-my-opencode': HierarchicalPreset;
|
|
15
36
|
}
|
|
16
37
|
/**
|
|
17
38
|
* Main configuration for the mode switcher plugin
|
|
@@ -23,6 +44,9 @@ export interface ModeSwitcherConfig {
|
|
|
23
44
|
}
|
|
24
45
|
/**
|
|
25
46
|
* OpenCode agent configuration structure in opencode.json
|
|
47
|
+
*
|
|
48
|
+
* @deprecated This type is kept for backward compatibility but may not
|
|
49
|
+
* accurately represent the actual structure. Use ModelConfig directly.
|
|
26
50
|
*/
|
|
27
51
|
export interface OpencodeAgentConfig {
|
|
28
52
|
model?: string;
|
|
@@ -31,17 +55,21 @@ export interface OpencodeAgentConfig {
|
|
|
31
55
|
}
|
|
32
56
|
/**
|
|
33
57
|
* OpenCode configuration file structure
|
|
58
|
+
*
|
|
59
|
+
* Supports arbitrary properties beyond the documented ones.
|
|
34
60
|
*/
|
|
35
61
|
export interface OpencodeConfig {
|
|
36
62
|
model?: string;
|
|
37
|
-
agent?:
|
|
63
|
+
agent?: HierarchicalPreset;
|
|
38
64
|
[key: string]: unknown;
|
|
39
65
|
}
|
|
40
66
|
/**
|
|
41
67
|
* Oh-my-opencode configuration file structure
|
|
68
|
+
*
|
|
69
|
+
* Supports arbitrary properties and nested structures like
|
|
70
|
+
* agents, categories, and any future sections.
|
|
42
71
|
*/
|
|
43
72
|
export interface OhMyOpencodeConfig {
|
|
44
|
-
agents?: Record<string, AgentPreset>;
|
|
45
73
|
[key: string]: unknown;
|
|
46
74
|
}
|
|
47
75
|
/**
|
package/dist/index.js
CHANGED
|
@@ -12332,6 +12332,10 @@ function tool(input) {
|
|
|
12332
12332
|
tool.schema = exports_external;
|
|
12333
12333
|
// src/config/types.ts
|
|
12334
12334
|
var DEFAULT_ECONOMY_MODEL = "opencode/glm-4.7-free";
|
|
12335
|
+
// src/config/guards.ts
|
|
12336
|
+
function isObject2(obj) {
|
|
12337
|
+
return typeof obj === "object" && obj !== null && !Array.isArray(obj);
|
|
12338
|
+
}
|
|
12335
12339
|
// src/config/loader.ts
|
|
12336
12340
|
import { homedir } from "os";
|
|
12337
12341
|
import { join } from "path";
|
|
@@ -13795,35 +13799,29 @@ async function pluginConfigExists() {
|
|
|
13795
13799
|
return Bun.file(getPluginConfigPath()).exists();
|
|
13796
13800
|
}
|
|
13797
13801
|
// src/config/initializer.ts
|
|
13798
|
-
|
|
13799
|
-
|
|
13800
|
-
|
|
13801
|
-
|
|
13802
|
-
|
|
13803
|
-
|
|
13804
|
-
|
|
13805
|
-
|
|
13806
|
-
|
|
13807
|
-
|
|
13808
|
-
|
|
13809
|
-
const ohMyOpencodeConfig = await loadOhMyOpencodeConfig();
|
|
13810
|
-
const opencodePreset = {};
|
|
13811
|
-
const ohMyOpencodePreset = {};
|
|
13812
|
-
if (opencodeConfig?.agent) {
|
|
13813
|
-
for (const agentName of OPENCODE_AGENTS) {
|
|
13814
|
-
const agentConfig = opencodeConfig.agent[agentName];
|
|
13815
|
-
if (agentConfig?.model) {
|
|
13816
|
-
opencodePreset[agentName] = { model: agentConfig.model };
|
|
13817
|
-
}
|
|
13818
|
-
}
|
|
13819
|
-
}
|
|
13820
|
-
if (ohMyOpencodeConfig?.agents) {
|
|
13821
|
-
for (const [agentName, agentConfig] of Object.entries(ohMyOpencodeConfig.agents)) {
|
|
13822
|
-
if (agentConfig?.model) {
|
|
13823
|
-
ohMyOpencodePreset[agentName] = { model: agentConfig.model };
|
|
13802
|
+
function applyEconomyModel(config2, economyModel) {
|
|
13803
|
+
const result = {};
|
|
13804
|
+
for (const [key, value] of Object.entries(config2)) {
|
|
13805
|
+
if (isObject2(value)) {
|
|
13806
|
+
if ("model" in value) {
|
|
13807
|
+
result[key] = {
|
|
13808
|
+
...value,
|
|
13809
|
+
model: economyModel
|
|
13810
|
+
};
|
|
13811
|
+
} else {
|
|
13812
|
+
result[key] = applyEconomyModel(value, economyModel);
|
|
13824
13813
|
}
|
|
13814
|
+
} else {
|
|
13815
|
+
result[key] = value;
|
|
13825
13816
|
}
|
|
13826
13817
|
}
|
|
13818
|
+
return result;
|
|
13819
|
+
}
|
|
13820
|
+
async function buildPerformancePreset() {
|
|
13821
|
+
const opencodeConfig = await loadOpencodeConfig();
|
|
13822
|
+
const ohMyOpencodeConfig = await loadOhMyOpencodeConfig();
|
|
13823
|
+
const opencodePreset = opencodeConfig?.agent || {};
|
|
13824
|
+
const ohMyOpencodePreset = ohMyOpencodeConfig || {};
|
|
13827
13825
|
const globalModel = opencodeConfig?.model;
|
|
13828
13826
|
return {
|
|
13829
13827
|
description: "High-performance models for complex tasks",
|
|
@@ -13835,22 +13833,8 @@ async function buildPerformancePreset() {
|
|
|
13835
13833
|
async function buildEconomyPreset() {
|
|
13836
13834
|
const opencodeConfig = await loadOpencodeConfig();
|
|
13837
13835
|
const ohMyOpencodeConfig = await loadOhMyOpencodeConfig();
|
|
13838
|
-
const opencodePreset = {};
|
|
13839
|
-
const ohMyOpencodePreset = {};
|
|
13840
|
-
if (opencodeConfig?.agent) {
|
|
13841
|
-
for (const agentName of Object.keys(opencodeConfig.agent)) {
|
|
13842
|
-
opencodePreset[agentName] = { model: DEFAULT_ECONOMY_MODEL };
|
|
13843
|
-
}
|
|
13844
|
-
} else {
|
|
13845
|
-
for (const agentName of OPENCODE_AGENTS) {
|
|
13846
|
-
opencodePreset[agentName] = { model: DEFAULT_ECONOMY_MODEL };
|
|
13847
|
-
}
|
|
13848
|
-
}
|
|
13849
|
-
if (ohMyOpencodeConfig?.agents) {
|
|
13850
|
-
for (const agentName of Object.keys(ohMyOpencodeConfig.agents)) {
|
|
13851
|
-
ohMyOpencodePreset[agentName] = { model: DEFAULT_ECONOMY_MODEL };
|
|
13852
|
-
}
|
|
13853
|
-
}
|
|
13836
|
+
const opencodePreset = applyEconomyModel(opencodeConfig?.agent || {}, DEFAULT_ECONOMY_MODEL);
|
|
13837
|
+
const ohMyOpencodePreset = applyEconomyModel(ohMyOpencodeConfig || {}, DEFAULT_ECONOMY_MODEL);
|
|
13854
13838
|
return {
|
|
13855
13839
|
description: "Cost-efficient free model for routine tasks",
|
|
13856
13840
|
model: DEFAULT_ECONOMY_MODEL,
|
|
@@ -13911,6 +13895,69 @@ function copyCommandFiles() {
|
|
|
13911
13895
|
}
|
|
13912
13896
|
}
|
|
13913
13897
|
// src/modes/manager.ts
|
|
13898
|
+
function isLeafNode(value) {
|
|
13899
|
+
return "model" in value && typeof value.model === "string";
|
|
13900
|
+
}
|
|
13901
|
+
function deepMergeModel(target, preset) {
|
|
13902
|
+
for (const [key, value] of Object.entries(preset)) {
|
|
13903
|
+
if (!isObject2(value))
|
|
13904
|
+
continue;
|
|
13905
|
+
const actualValue = target[key];
|
|
13906
|
+
if (isLeafNode(value)) {
|
|
13907
|
+
const valueRecord = value;
|
|
13908
|
+
const existing = actualValue ?? {};
|
|
13909
|
+
const merged = {
|
|
13910
|
+
...existing,
|
|
13911
|
+
...valueRecord
|
|
13912
|
+
};
|
|
13913
|
+
target[key] = merged;
|
|
13914
|
+
} else {
|
|
13915
|
+
const childTarget = actualValue ?? {};
|
|
13916
|
+
target[key] = childTarget;
|
|
13917
|
+
deepMergeModel(childTarget, value);
|
|
13918
|
+
}
|
|
13919
|
+
}
|
|
13920
|
+
}
|
|
13921
|
+
function hasDriftRecursive(actual, expected) {
|
|
13922
|
+
for (const [key, expectedValue] of Object.entries(expected)) {
|
|
13923
|
+
if (!isObject2(expectedValue))
|
|
13924
|
+
continue;
|
|
13925
|
+
const actualValue = actual[key];
|
|
13926
|
+
if (isLeafNode(expectedValue)) {
|
|
13927
|
+
const actualObj = actualValue;
|
|
13928
|
+
if (!actualObj) {
|
|
13929
|
+
return true;
|
|
13930
|
+
}
|
|
13931
|
+
for (const [propKey, expectedPropValue] of Object.entries(expectedValue)) {
|
|
13932
|
+
if (actualObj[propKey] !== expectedPropValue) {
|
|
13933
|
+
return true;
|
|
13934
|
+
}
|
|
13935
|
+
}
|
|
13936
|
+
} else if (hasDriftRecursive(actualValue || {}, expectedValue)) {
|
|
13937
|
+
return true;
|
|
13938
|
+
}
|
|
13939
|
+
}
|
|
13940
|
+
return false;
|
|
13941
|
+
}
|
|
13942
|
+
function formatHierarchicalTree(preset, indent = " ") {
|
|
13943
|
+
const lines = [];
|
|
13944
|
+
for (const [key, value] of Object.entries(preset)) {
|
|
13945
|
+
if (!isObject2(value))
|
|
13946
|
+
continue;
|
|
13947
|
+
if (isLeafNode(value)) {
|
|
13948
|
+
const variant = value.variant ? ` (${value.variant})` : "";
|
|
13949
|
+
const otherProps = Object.keys(value).filter((k) => k !== "model" && k !== "variant").map((k) => `${k}: ${JSON.stringify(value[k])}`).join(", ");
|
|
13950
|
+
const extra = otherProps ? ` [${otherProps}]` : "";
|
|
13951
|
+
lines.push(`${indent}${key}: ${value.model}${variant}${extra}`);
|
|
13952
|
+
} else {
|
|
13953
|
+
lines.push(`${indent}${key}:`);
|
|
13954
|
+
lines.push(formatHierarchicalTree(value, `${indent} `));
|
|
13955
|
+
}
|
|
13956
|
+
}
|
|
13957
|
+
return lines.join(`
|
|
13958
|
+
`);
|
|
13959
|
+
}
|
|
13960
|
+
|
|
13914
13961
|
class ModeManager {
|
|
13915
13962
|
client;
|
|
13916
13963
|
config = null;
|
|
@@ -13953,26 +14000,17 @@ class ModeManager {
|
|
|
13953
14000
|
async hasConfigDrift(preset) {
|
|
13954
14001
|
const opencodeConfig = await loadOpencodeConfig();
|
|
13955
14002
|
const ohMyConfig = await loadOhMyOpencodeConfig();
|
|
13956
|
-
if (
|
|
13957
|
-
|
|
13958
|
-
return true;
|
|
13959
|
-
}
|
|
14003
|
+
if (!opencodeConfig && !ohMyConfig) {
|
|
14004
|
+
return false;
|
|
13960
14005
|
}
|
|
13961
|
-
if (opencodeConfig?.
|
|
13962
|
-
|
|
13963
|
-
const actual = opencodeConfig.agent[agentName];
|
|
13964
|
-
if (actual?.model !== agentPreset.model) {
|
|
13965
|
-
return true;
|
|
13966
|
-
}
|
|
13967
|
-
}
|
|
14006
|
+
if (preset.model && opencodeConfig?.model !== preset.model) {
|
|
14007
|
+
return true;
|
|
13968
14008
|
}
|
|
13969
|
-
if (
|
|
13970
|
-
|
|
13971
|
-
|
|
13972
|
-
|
|
13973
|
-
|
|
13974
|
-
}
|
|
13975
|
-
}
|
|
14009
|
+
if (opencodeConfig?.agent && hasDriftRecursive(opencodeConfig.agent, preset.opencode)) {
|
|
14010
|
+
return true;
|
|
14011
|
+
}
|
|
14012
|
+
if (ohMyConfig && hasDriftRecursive(ohMyConfig, preset["oh-my-opencode"])) {
|
|
14013
|
+
return true;
|
|
13976
14014
|
}
|
|
13977
14015
|
return false;
|
|
13978
14016
|
}
|
|
@@ -14003,20 +14041,18 @@ ${modes}`;
|
|
|
14003
14041
|
return `Current mode: ${currentMode} (preset not found)`;
|
|
14004
14042
|
}
|
|
14005
14043
|
const globalModel = preset.model ? `Global model: ${preset.model}` : "Global model: (not set)";
|
|
14006
|
-
const
|
|
14007
|
-
|
|
14008
|
-
const ohMyOpencodeAgents = Object.entries(preset["oh-my-opencode"]).map(([name, cfg]) => ` - ${name}: ${cfg.model}`).join(`
|
|
14009
|
-
`);
|
|
14044
|
+
const opencodeTree = formatHierarchicalTree(preset.opencode);
|
|
14045
|
+
const ohMyOpencodeTree = formatHierarchicalTree(preset["oh-my-opencode"]);
|
|
14010
14046
|
return [
|
|
14011
14047
|
`Current mode: ${currentMode}`,
|
|
14012
14048
|
`Description: ${preset.description}`,
|
|
14013
14049
|
globalModel,
|
|
14014
14050
|
"",
|
|
14015
|
-
"OpenCode
|
|
14016
|
-
|
|
14051
|
+
"OpenCode config:",
|
|
14052
|
+
opencodeTree || " (none configured)",
|
|
14017
14053
|
"",
|
|
14018
|
-
"Oh-my-opencode
|
|
14019
|
-
|
|
14054
|
+
"Oh-my-opencode config:",
|
|
14055
|
+
ohMyOpencodeTree || " (none configured)"
|
|
14020
14056
|
].join(`
|
|
14021
14057
|
`);
|
|
14022
14058
|
}
|
|
@@ -14036,16 +14072,14 @@ ${modes}`;
|
|
|
14036
14072
|
this.config = config2;
|
|
14037
14073
|
await savePluginConfig(config2);
|
|
14038
14074
|
results.push("agent-mode-switcher.json: updated");
|
|
14039
|
-
|
|
14040
|
-
|
|
14041
|
-
|
|
14042
|
-
|
|
14043
|
-
|
|
14044
|
-
|
|
14045
|
-
|
|
14046
|
-
|
|
14047
|
-
});
|
|
14048
|
-
} catch {}
|
|
14075
|
+
this.client.tui.showToast({
|
|
14076
|
+
body: {
|
|
14077
|
+
title: "Mode Switched",
|
|
14078
|
+
message: `Switched to "${modeName}". Restart opencode to apply.`,
|
|
14079
|
+
variant: "warning",
|
|
14080
|
+
duration: 5000
|
|
14081
|
+
}
|
|
14082
|
+
}).catch(() => {});
|
|
14049
14083
|
return [
|
|
14050
14084
|
`Switched to ${modeName} mode`,
|
|
14051
14085
|
preset.description,
|
|
@@ -14067,12 +14101,7 @@ ${modes}`;
|
|
|
14067
14101
|
opencodeConfig.model = globalModel;
|
|
14068
14102
|
}
|
|
14069
14103
|
opencodeConfig.agent = opencodeConfig.agent || {};
|
|
14070
|
-
|
|
14071
|
-
opencodeConfig.agent[agentName] = {
|
|
14072
|
-
...opencodeConfig.agent[agentName],
|
|
14073
|
-
model: preset.model
|
|
14074
|
-
};
|
|
14075
|
-
}
|
|
14104
|
+
deepMergeModel(opencodeConfig.agent, agentPresets);
|
|
14076
14105
|
await saveOpencodeConfig(opencodeConfig);
|
|
14077
14106
|
return "updated";
|
|
14078
14107
|
} catch (error45) {
|
|
@@ -14080,16 +14109,13 @@ ${modes}`;
|
|
|
14080
14109
|
return `error: ${message}`;
|
|
14081
14110
|
}
|
|
14082
14111
|
}
|
|
14083
|
-
async updateOhMyOpencodeConfig(
|
|
14112
|
+
async updateOhMyOpencodeConfig(preset) {
|
|
14084
14113
|
try {
|
|
14085
14114
|
const ohMyConfig = await loadOhMyOpencodeConfig();
|
|
14086
14115
|
if (!ohMyConfig) {
|
|
14087
14116
|
return "skipped (not found)";
|
|
14088
14117
|
}
|
|
14089
|
-
ohMyConfig
|
|
14090
|
-
for (const [agentName, preset] of Object.entries(agentPresets)) {
|
|
14091
|
-
ohMyConfig.agents[agentName] = { model: preset.model };
|
|
14092
|
-
}
|
|
14118
|
+
deepMergeModel(ohMyConfig, preset);
|
|
14093
14119
|
await saveOhMyOpencodeConfig(ohMyConfig);
|
|
14094
14120
|
return "updated";
|
|
14095
14121
|
} catch (error45) {
|
package/dist/modes/manager.d.ts
CHANGED
|
@@ -76,7 +76,7 @@ export declare class ModeManager {
|
|
|
76
76
|
* Compares a mode preset against the actual opencode.json and
|
|
77
77
|
* oh-my-opencode.json files to detect configuration drift.
|
|
78
78
|
*
|
|
79
|
-
* Checks global model and per-agent model values. Returns true
|
|
79
|
+
* Checks global model and per-agent model values recursively. Returns true
|
|
80
80
|
* if any expected value differs from the actual file content.
|
|
81
81
|
*
|
|
82
82
|
* @param preset - The mode preset to compare against
|
|
@@ -134,8 +134,8 @@ export declare class ModeManager {
|
|
|
134
134
|
* Returns a formatted multi-line string showing:
|
|
135
135
|
* - Current mode name and description
|
|
136
136
|
* - Global model setting (if configured)
|
|
137
|
-
* -
|
|
138
|
-
* -
|
|
137
|
+
* - Hierarchical tree of OpenCode configuration
|
|
138
|
+
* - Hierarchical tree of oh-my-opencode configuration
|
|
139
139
|
*
|
|
140
140
|
* @returns Promise resolving to formatted status string
|
|
141
141
|
* @example
|
|
@@ -147,9 +147,10 @@ export declare class ModeManager {
|
|
|
147
147
|
* // Description: High-performance models for complex tasks
|
|
148
148
|
* // Global model: (not set)
|
|
149
149
|
* //
|
|
150
|
-
* // OpenCode
|
|
151
|
-
* //
|
|
152
|
-
* //
|
|
150
|
+
* // OpenCode config:
|
|
151
|
+
* // agent:
|
|
152
|
+
* // build: anthropic/claude-sonnet-4
|
|
153
|
+
* // plan: anthropic/claude-sonnet-4
|
|
153
154
|
* // ...
|
|
154
155
|
* ```
|
|
155
156
|
*/
|
|
@@ -191,22 +192,23 @@ export declare class ModeManager {
|
|
|
191
192
|
*
|
|
192
193
|
* This internal method modifies the OpenCode configuration file to apply
|
|
193
194
|
* the new preset's settings. It preserves other configuration properties
|
|
194
|
-
* and only updates model-related fields.
|
|
195
|
+
* and only updates model-related fields using recursive merge.
|
|
195
196
|
*
|
|
196
197
|
* @param globalModel - Global model setting (optional). If provided, sets the top-level "model" field
|
|
197
|
-
* @param agentPresets -
|
|
198
|
+
* @param agentPresets - Hierarchical preset structure for agent configuration
|
|
198
199
|
* @returns Promise resolving to result status: "updated", "skipped (not found)", or "error: ..."
|
|
199
200
|
* @private
|
|
200
201
|
*/
|
|
201
202
|
private updateOpencodeConfig;
|
|
202
203
|
/**
|
|
203
|
-
* Updates oh-my-opencode.json
|
|
204
|
+
* Updates oh-my-opencode.json with preset values.
|
|
204
205
|
*
|
|
205
206
|
* This internal method modifies the oh-my-opencode configuration file
|
|
206
|
-
* to apply the new preset's
|
|
207
|
-
*
|
|
207
|
+
* to apply the new preset's settings using recursive merge. The entire
|
|
208
|
+
* structure (agents, categories, etc.) is updated while preserving
|
|
209
|
+
* other properties.
|
|
208
210
|
*
|
|
209
|
-
* @param
|
|
211
|
+
* @param preset - Hierarchical preset structure for oh-my-opencode configuration
|
|
210
212
|
* @returns Promise resolving to result status: "updated", "skipped (not found)", or "error: ..."
|
|
211
213
|
* @private
|
|
212
214
|
*/
|