opencode-conductor-cdd-plugin 1.0.0-beta.19 → 1.0.0-beta.20
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
|
@@ -92,18 +92,31 @@ We highly recommend pinning the `@cdd` agent to a "flash" model for optimal perf
|
|
|
92
92
|
|
|
93
93
|
### oh-my-opencode-slim Config
|
|
94
94
|
**File:** `~/.config/opencode/oh-my-opencode-slim.json`
|
|
95
|
+
|
|
96
|
+
**⚠️ Important**: For synergy to activate with oh-my-opencode-slim, you **must** configure a `cdd` agent in the config file. The presence of the file alone is not sufficient.
|
|
97
|
+
|
|
95
98
|
```json
|
|
96
99
|
{
|
|
97
100
|
"agents": {
|
|
98
101
|
"cdd": {
|
|
99
102
|
"model": "anthropic/claude-3-5-sonnet"
|
|
103
|
+
},
|
|
104
|
+
"designer": {
|
|
105
|
+
"model": "google/gemini-flash-1.5"
|
|
106
|
+
},
|
|
107
|
+
"explorer": {
|
|
108
|
+
"model": "google/gemini-flash-1.5"
|
|
100
109
|
}
|
|
101
110
|
}
|
|
102
111
|
}
|
|
103
112
|
```
|
|
104
113
|
|
|
105
114
|
**Framework Detection Priority:**
|
|
106
|
-
When multiple synergy frameworks are detected, Conductor CDD prioritizes oh-my-opencode-slim over oh-my-opencode.
|
|
115
|
+
When multiple synergy frameworks are detected, Conductor CDD prioritizes oh-my-opencode-slim over oh-my-opencode. However, synergy will **only activate** if the selected framework has a `cdd` agent explicitly configured:
|
|
116
|
+
|
|
117
|
+
1. **Check slim**: If `~/.config/opencode/oh-my-opencode-slim.json` exists **and** has `agents.cdd` → use slim (highest priority)
|
|
118
|
+
2. **Check OMO**: If `~/.config/opencode/oh-my-opencode.json` exists **and** has `agents.cdd` → use OMO (fallback)
|
|
119
|
+
3. **No synergy**: If neither config has a `cdd` agent → Conductor operates in manual mode
|
|
107
120
|
|
|
108
121
|
**Agent Mappings for oh-my-opencode-slim:**
|
|
109
122
|
Conductor CDD automatically maps generic agent names to slim-specific agent names:
|
|
@@ -140,9 +153,12 @@ When using **OhMyOpenCode**, `@cdd` acts as your Technical Lead. While **Sisyphu
|
|
|
140
153
|
### oh-my-opencode-slim Integration
|
|
141
154
|
When using **oh-my-opencode-slim**, `@cdd` integrates with the lightweight agent framework, automatically mapping to slim-specific agents like `explorer`, `designer`, and `librarian` for specialized tasks.
|
|
142
155
|
|
|
156
|
+
**Requirements**: You **must** configure a `cdd` agent in your `oh-my-opencode-slim.json` for synergy to activate. Simply having the file present is not sufficient.
|
|
157
|
+
|
|
143
158
|
### Key Features
|
|
144
|
-
- **Automatic Detection**: Conductor CDD automatically detects which framework you're using
|
|
145
|
-
- **
|
|
159
|
+
- **Automatic Detection**: Conductor CDD automatically detects which framework you're using based on the presence of a `cdd` agent in the config
|
|
160
|
+
- **Strict CDD Requirement**: Synergy only activates if the framework config explicitly includes a `cdd` agent (file presence alone is insufficient)
|
|
161
|
+
- **Priority Resolution**: When both frameworks have a `cdd` agent configured, oh-my-opencode-slim takes priority
|
|
146
162
|
- **Agent Mapping**: Generic agent names are automatically mapped to framework-specific names
|
|
147
163
|
- **Graceful Fallback**: If a requested agent is unavailable or disabled, tasks fall back to `@cdd`
|
|
148
164
|
- **Loop Protection**: Built-in safeguards ensure no conflicts with framework continuation enforcers during interactive Q&A
|
|
@@ -1,10 +1,22 @@
|
|
|
1
1
|
export type SynergyFramework = 'none' | 'oh-my-opencode' | 'oh-my-opencode-slim';
|
|
2
|
+
/**
|
|
3
|
+
* Result of CDD configuration detection across multiple config files.
|
|
4
|
+
* Checks ~/.config/opencode/{opencode.json, oh-my-opencode.json, oh-my-opencode-slim.json}
|
|
5
|
+
*/
|
|
2
6
|
export interface ConfigDetectionResult {
|
|
7
|
+
/** Whether CDD agent is configured in opencode.json */
|
|
3
8
|
hasCDDInOpenCode: boolean;
|
|
9
|
+
/** Whether CDD agent is configured in oh-my-opencode.json */
|
|
4
10
|
hasCDDInOMO: boolean;
|
|
11
|
+
/** Whether CDD agent is configured in oh-my-opencode-slim.json */
|
|
12
|
+
hasCDDInSlim: boolean;
|
|
13
|
+
/** Whether synergy mode should be activated (true if any synergy framework detected) */
|
|
5
14
|
synergyActive: boolean;
|
|
15
|
+
/** The CDD model string extracted from configs (priority: slim > OMO > opencode) */
|
|
6
16
|
cddModel?: string;
|
|
17
|
+
/** Which synergy framework to use (priority: slim > OMO > none) */
|
|
7
18
|
synergyFramework: SynergyFramework;
|
|
19
|
+
/** Available agents from slim config (filtered by disabled_agents) */
|
|
8
20
|
slimAgents?: string[];
|
|
9
21
|
}
|
|
10
22
|
export declare function detectCDDConfig(): ConfigDetectionResult;
|
|
@@ -8,6 +8,7 @@ export function detectCDDConfig() {
|
|
|
8
8
|
const slimJsonPath = join(opencodeConfigDir, "oh-my-opencode-slim.json");
|
|
9
9
|
let hasCDDInOpenCode = false;
|
|
10
10
|
let hasCDDInOMO = false;
|
|
11
|
+
let hasCDDInSlim = false;
|
|
11
12
|
let cddModel;
|
|
12
13
|
let synergyFramework = 'none';
|
|
13
14
|
let slimAgents;
|
|
@@ -17,8 +18,16 @@ export function detectCDDConfig() {
|
|
|
17
18
|
const config = JSON.parse(readFileSync(slimJsonPath, "utf-8"));
|
|
18
19
|
// Check if config is not empty and has actual content
|
|
19
20
|
if (config && Object.keys(config).length > 0) {
|
|
20
|
-
|
|
21
|
-
|
|
21
|
+
// Check for CDD agent in slim config (strict detection)
|
|
22
|
+
if (config.agents && config.agents.cdd) {
|
|
23
|
+
hasCDDInSlim = true;
|
|
24
|
+
synergyFramework = 'oh-my-opencode-slim';
|
|
25
|
+
// Extract model from slim config (priority over OMO and opencode.json)
|
|
26
|
+
if (config.agents.cdd.model) {
|
|
27
|
+
cddModel = config.agents.cdd.model;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
// Extract available agents (filter out disabled ones) regardless of CDD presence
|
|
22
31
|
const coreAgents = ['explorer', 'librarian', 'oracle', 'designer'];
|
|
23
32
|
const disabledAgents = new Set(config.disabled_agents ?? []);
|
|
24
33
|
slimAgents = coreAgents.filter(agent => !disabledAgents.has(agent));
|
|
@@ -28,15 +37,19 @@ export function detectCDDConfig() {
|
|
|
28
37
|
// Silently fail on parse errors
|
|
29
38
|
}
|
|
30
39
|
}
|
|
31
|
-
// Check oh-my-opencode.json (only if slim
|
|
32
|
-
|
|
40
|
+
// Check oh-my-opencode.json (only if slim doesn't have CDD)
|
|
41
|
+
// NOTE: We still check OMO to set hasCDDInOMO flag even if slim has priority
|
|
42
|
+
if (existsSync(omoJsonPath)) {
|
|
33
43
|
try {
|
|
34
44
|
const config = JSON.parse(readFileSync(omoJsonPath, "utf-8"));
|
|
35
45
|
if (config.agents && config.agents.cdd) {
|
|
36
46
|
hasCDDInOMO = true;
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
47
|
+
// Only activate OMO synergy if slim doesn't have CDD (slim takes priority)
|
|
48
|
+
if (synergyFramework === 'none') {
|
|
49
|
+
synergyFramework = 'oh-my-opencode';
|
|
50
|
+
}
|
|
51
|
+
// Extract model from oh-my-opencode.json (only if not already set by slim)
|
|
52
|
+
if (!cddModel && config.agents.cdd.model) {
|
|
40
53
|
cddModel = config.agents.cdd.model;
|
|
41
54
|
}
|
|
42
55
|
}
|
|
@@ -45,13 +58,13 @@ export function detectCDDConfig() {
|
|
|
45
58
|
// Silently fail on parse errors
|
|
46
59
|
}
|
|
47
60
|
}
|
|
48
|
-
// Check opencode.json (fallback if model not found in OMO)
|
|
61
|
+
// Check opencode.json (fallback if model not found in slim or OMO)
|
|
49
62
|
if (existsSync(opencodeJsonPath)) {
|
|
50
63
|
try {
|
|
51
64
|
const config = JSON.parse(readFileSync(opencodeJsonPath, "utf-8"));
|
|
52
65
|
if (config.agent && config.agent.cdd) {
|
|
53
66
|
hasCDDInOpenCode = true;
|
|
54
|
-
// Only use this model if we didn't find one in oh-my-opencode.json
|
|
67
|
+
// Only use this model if we didn't find one in slim or oh-my-opencode.json
|
|
55
68
|
if (!cddModel && config.agent.cdd.model) {
|
|
56
69
|
cddModel = config.agent.cdd.model;
|
|
57
70
|
}
|
|
@@ -64,6 +77,7 @@ export function detectCDDConfig() {
|
|
|
64
77
|
return {
|
|
65
78
|
hasCDDInOpenCode,
|
|
66
79
|
hasCDDInOMO,
|
|
80
|
+
hasCDDInSlim,
|
|
67
81
|
synergyActive: synergyFramework !== 'none',
|
|
68
82
|
cddModel,
|
|
69
83
|
synergyFramework,
|
|
@@ -119,7 +119,7 @@ describe("configDetection", () => {
|
|
|
119
119
|
});
|
|
120
120
|
// New tests for oh-my-opencode-slim detection
|
|
121
121
|
describe("oh-my-opencode-slim detection", () => {
|
|
122
|
-
it("should detect
|
|
122
|
+
it("should NOT detect synergy when slim config has no cdd agent", () => {
|
|
123
123
|
vi.mocked(existsSync).mockImplementation((path) => path === slimJsonPath);
|
|
124
124
|
vi.mocked(readFileSync).mockImplementation((path) => {
|
|
125
125
|
if (path === slimJsonPath) {
|
|
@@ -130,11 +130,11 @@ describe("configDetection", () => {
|
|
|
130
130
|
return "";
|
|
131
131
|
});
|
|
132
132
|
const result = detectCDDConfig();
|
|
133
|
-
expect(result.synergyActive).toBe(
|
|
134
|
-
expect(result.synergyFramework).toBe('
|
|
133
|
+
expect(result.synergyActive).toBe(false);
|
|
134
|
+
expect(result.synergyFramework).toBe('none');
|
|
135
135
|
expect(result.slimAgents).toEqual(['explorer', 'librarian', 'oracle', 'designer']);
|
|
136
136
|
});
|
|
137
|
-
it("should prioritize oh-my-opencode
|
|
137
|
+
it("should prioritize oh-my-opencode over slim when slim has no cdd agent", () => {
|
|
138
138
|
vi.mocked(existsSync).mockReturnValue(true);
|
|
139
139
|
vi.mocked(readFileSync).mockImplementation((path) => {
|
|
140
140
|
if (path === slimJsonPath) {
|
|
@@ -146,10 +146,11 @@ describe("configDetection", () => {
|
|
|
146
146
|
return "";
|
|
147
147
|
});
|
|
148
148
|
const result = detectCDDConfig();
|
|
149
|
-
expect(result.synergyFramework).toBe('oh-my-opencode
|
|
149
|
+
expect(result.synergyFramework).toBe('oh-my-opencode');
|
|
150
150
|
expect(result.synergyActive).toBe(true);
|
|
151
|
+
expect(result.cddModel).toBe('model-from-omo');
|
|
151
152
|
});
|
|
152
|
-
it("should filter out disabled agents from slim config", () => {
|
|
153
|
+
it("should filter out disabled agents from slim config (but require cdd for synergy)", () => {
|
|
153
154
|
vi.mocked(existsSync).mockImplementation((path) => path === slimJsonPath);
|
|
154
155
|
vi.mocked(readFileSync).mockImplementation((path) => {
|
|
155
156
|
if (path === slimJsonPath) {
|
|
@@ -160,7 +161,8 @@ describe("configDetection", () => {
|
|
|
160
161
|
return "";
|
|
161
162
|
});
|
|
162
163
|
const result = detectCDDConfig();
|
|
163
|
-
expect(result.synergyFramework).toBe('
|
|
164
|
+
expect(result.synergyFramework).toBe('none');
|
|
165
|
+
expect(result.synergyActive).toBe(false);
|
|
164
166
|
expect(result.slimAgents).toEqual(['explorer', 'librarian']);
|
|
165
167
|
});
|
|
166
168
|
it("should handle empty oh-my-opencode-slim config", () => {
|
|
@@ -203,4 +205,199 @@ describe("configDetection", () => {
|
|
|
203
205
|
expect(result.synergyActive).toBe(false);
|
|
204
206
|
});
|
|
205
207
|
});
|
|
208
|
+
// New tests for CDD agent detection in oh-my-opencode-slim
|
|
209
|
+
describe("CDD agent detection in oh-my-opencode-slim", () => {
|
|
210
|
+
it("should detect cdd agent in slim config and activate synergy", () => {
|
|
211
|
+
vi.mocked(existsSync).mockImplementation((path) => path === slimJsonPath);
|
|
212
|
+
vi.mocked(readFileSync).mockImplementation((path) => {
|
|
213
|
+
if (path === slimJsonPath) {
|
|
214
|
+
return JSON.stringify({
|
|
215
|
+
agents: {
|
|
216
|
+
cdd: { model: "anthropic/claude-3-5-sonnet" },
|
|
217
|
+
designer: { model: "google/gemini-3-flash" }
|
|
218
|
+
}
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
return "";
|
|
222
|
+
});
|
|
223
|
+
const result = detectCDDConfig();
|
|
224
|
+
expect(result.hasCDDInSlim).toBe(true);
|
|
225
|
+
expect(result.synergyFramework).toBe('oh-my-opencode-slim');
|
|
226
|
+
expect(result.synergyActive).toBe(true);
|
|
227
|
+
expect(result.cddModel).toBe("anthropic/claude-3-5-sonnet");
|
|
228
|
+
});
|
|
229
|
+
it("should not activate synergy when slim config exists but no cdd agent", () => {
|
|
230
|
+
vi.mocked(existsSync).mockImplementation((path) => path === slimJsonPath);
|
|
231
|
+
vi.mocked(readFileSync).mockImplementation((path) => {
|
|
232
|
+
if (path === slimJsonPath) {
|
|
233
|
+
return JSON.stringify({
|
|
234
|
+
agents: {
|
|
235
|
+
designer: { model: "google/gemini-3-flash" }
|
|
236
|
+
}
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
return "";
|
|
240
|
+
});
|
|
241
|
+
const result = detectCDDConfig();
|
|
242
|
+
expect(result.hasCDDInSlim).toBe(false);
|
|
243
|
+
expect(result.synergyFramework).toBe('none');
|
|
244
|
+
expect(result.synergyActive).toBe(false);
|
|
245
|
+
});
|
|
246
|
+
it("should not activate synergy when slim config has empty agents object", () => {
|
|
247
|
+
vi.mocked(existsSync).mockImplementation((path) => path === slimJsonPath);
|
|
248
|
+
vi.mocked(readFileSync).mockImplementation((path) => {
|
|
249
|
+
if (path === slimJsonPath) {
|
|
250
|
+
return JSON.stringify({ agents: {} });
|
|
251
|
+
}
|
|
252
|
+
return "";
|
|
253
|
+
});
|
|
254
|
+
const result = detectCDDConfig();
|
|
255
|
+
expect(result.hasCDDInSlim).toBe(false);
|
|
256
|
+
expect(result.synergyFramework).toBe('none');
|
|
257
|
+
expect(result.synergyActive).toBe(false);
|
|
258
|
+
});
|
|
259
|
+
it("should handle malformed slim config gracefully with hasCDDInSlim false", () => {
|
|
260
|
+
vi.mocked(existsSync).mockImplementation((path) => path === slimJsonPath);
|
|
261
|
+
vi.mocked(readFileSync).mockImplementation((path) => {
|
|
262
|
+
if (path === slimJsonPath) {
|
|
263
|
+
return "invalid json";
|
|
264
|
+
}
|
|
265
|
+
return "";
|
|
266
|
+
});
|
|
267
|
+
const result = detectCDDConfig();
|
|
268
|
+
expect(result.hasCDDInSlim).toBe(false);
|
|
269
|
+
expect(result.synergyFramework).toBe('none');
|
|
270
|
+
expect(result.synergyActive).toBe(false);
|
|
271
|
+
});
|
|
272
|
+
it("should extract cdd model from slim config when present", () => {
|
|
273
|
+
vi.mocked(existsSync).mockImplementation((path) => path === slimJsonPath);
|
|
274
|
+
vi.mocked(readFileSync).mockImplementation((path) => {
|
|
275
|
+
if (path === slimJsonPath) {
|
|
276
|
+
return JSON.stringify({
|
|
277
|
+
agents: {
|
|
278
|
+
cdd: { model: "anthropic/claude-3-5-haiku" }
|
|
279
|
+
}
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
return "";
|
|
283
|
+
});
|
|
284
|
+
const result = detectCDDConfig();
|
|
285
|
+
expect(result.cddModel).toBe("anthropic/claude-3-5-haiku");
|
|
286
|
+
expect(result.hasCDDInSlim).toBe(true);
|
|
287
|
+
});
|
|
288
|
+
it("should handle cdd agent without model field in slim", () => {
|
|
289
|
+
vi.mocked(existsSync).mockImplementation((path) => path === slimJsonPath);
|
|
290
|
+
vi.mocked(readFileSync).mockImplementation((path) => {
|
|
291
|
+
if (path === slimJsonPath) {
|
|
292
|
+
return JSON.stringify({
|
|
293
|
+
agents: {
|
|
294
|
+
cdd: {}
|
|
295
|
+
}
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
return "";
|
|
299
|
+
});
|
|
300
|
+
const result = detectCDDConfig();
|
|
301
|
+
expect(result.hasCDDInSlim).toBe(true);
|
|
302
|
+
expect(result.cddModel).toBeUndefined();
|
|
303
|
+
});
|
|
304
|
+
it("should prioritize slim model over oh-my-opencode model when both have cdd", () => {
|
|
305
|
+
vi.mocked(existsSync).mockReturnValue(true);
|
|
306
|
+
vi.mocked(readFileSync).mockImplementation((path) => {
|
|
307
|
+
if (path === slimJsonPath) {
|
|
308
|
+
return JSON.stringify({
|
|
309
|
+
agents: {
|
|
310
|
+
cdd: { model: "model-from-slim" }
|
|
311
|
+
}
|
|
312
|
+
});
|
|
313
|
+
}
|
|
314
|
+
if (path === omoJsonPath) {
|
|
315
|
+
return JSON.stringify({
|
|
316
|
+
agents: {
|
|
317
|
+
cdd: { model: "model-from-omo" }
|
|
318
|
+
}
|
|
319
|
+
});
|
|
320
|
+
}
|
|
321
|
+
return "";
|
|
322
|
+
});
|
|
323
|
+
const result = detectCDDConfig();
|
|
324
|
+
expect(result.cddModel).toBe("model-from-slim");
|
|
325
|
+
expect(result.synergyFramework).toBe('oh-my-opencode-slim');
|
|
326
|
+
expect(result.hasCDDInSlim).toBe(true);
|
|
327
|
+
expect(result.hasCDDInOMO).toBe(true);
|
|
328
|
+
});
|
|
329
|
+
it("should select oh-my-opencode when only OMO has cdd", () => {
|
|
330
|
+
vi.mocked(existsSync).mockReturnValue(true);
|
|
331
|
+
vi.mocked(readFileSync).mockImplementation((path) => {
|
|
332
|
+
if (path === slimJsonPath) {
|
|
333
|
+
return JSON.stringify({
|
|
334
|
+
agents: {
|
|
335
|
+
designer: { model: "google/gemini-3-flash" }
|
|
336
|
+
}
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
if (path === omoJsonPath) {
|
|
340
|
+
return JSON.stringify({
|
|
341
|
+
agents: {
|
|
342
|
+
cdd: { model: "model-from-omo" }
|
|
343
|
+
}
|
|
344
|
+
});
|
|
345
|
+
}
|
|
346
|
+
return "";
|
|
347
|
+
});
|
|
348
|
+
const result = detectCDDConfig();
|
|
349
|
+
expect(result.hasCDDInSlim).toBe(false);
|
|
350
|
+
expect(result.hasCDDInOMO).toBe(true);
|
|
351
|
+
expect(result.synergyFramework).toBe('oh-my-opencode');
|
|
352
|
+
});
|
|
353
|
+
it("should select slim when only slim has cdd", () => {
|
|
354
|
+
vi.mocked(existsSync).mockReturnValue(true);
|
|
355
|
+
vi.mocked(readFileSync).mockImplementation((path) => {
|
|
356
|
+
if (path === slimJsonPath) {
|
|
357
|
+
return JSON.stringify({
|
|
358
|
+
agents: {
|
|
359
|
+
cdd: { model: "model-from-slim" }
|
|
360
|
+
}
|
|
361
|
+
});
|
|
362
|
+
}
|
|
363
|
+
if (path === omoJsonPath) {
|
|
364
|
+
return JSON.stringify({
|
|
365
|
+
agents: {
|
|
366
|
+
sisyphus: { model: "google/gemini-3-flash" }
|
|
367
|
+
}
|
|
368
|
+
});
|
|
369
|
+
}
|
|
370
|
+
return "";
|
|
371
|
+
});
|
|
372
|
+
const result = detectCDDConfig();
|
|
373
|
+
expect(result.hasCDDInSlim).toBe(true);
|
|
374
|
+
expect(result.hasCDDInOMO).toBe(false);
|
|
375
|
+
expect(result.synergyFramework).toBe('oh-my-opencode-slim');
|
|
376
|
+
});
|
|
377
|
+
it("should not activate synergy when neither framework has cdd", () => {
|
|
378
|
+
vi.mocked(existsSync).mockReturnValue(true);
|
|
379
|
+
vi.mocked(readFileSync).mockImplementation((path) => {
|
|
380
|
+
if (path === slimJsonPath) {
|
|
381
|
+
return JSON.stringify({
|
|
382
|
+
agents: {
|
|
383
|
+
designer: { model: "google/gemini-3-flash" }
|
|
384
|
+
}
|
|
385
|
+
});
|
|
386
|
+
}
|
|
387
|
+
if (path === omoJsonPath) {
|
|
388
|
+
return JSON.stringify({
|
|
389
|
+
agents: {
|
|
390
|
+
sisyphus: { model: "google/gemini-3-flash" }
|
|
391
|
+
}
|
|
392
|
+
});
|
|
393
|
+
}
|
|
394
|
+
return "";
|
|
395
|
+
});
|
|
396
|
+
const result = detectCDDConfig();
|
|
397
|
+
expect(result.hasCDDInSlim).toBe(false);
|
|
398
|
+
expect(result.hasCDDInOMO).toBe(false);
|
|
399
|
+
expect(result.synergyFramework).toBe('none');
|
|
400
|
+
expect(result.synergyActive).toBe(false);
|
|
401
|
+
});
|
|
402
|
+
});
|
|
206
403
|
});
|
|
@@ -15,6 +15,7 @@ describe("synergyState", () => {
|
|
|
15
15
|
vi.mocked(detectCDDConfig).mockReturnValue({
|
|
16
16
|
hasCDDInOpenCode: false,
|
|
17
17
|
hasCDDInOMO: false,
|
|
18
|
+
hasCDDInSlim: true,
|
|
18
19
|
synergyActive: true,
|
|
19
20
|
synergyFramework: 'oh-my-opencode-slim',
|
|
20
21
|
slimAgents: ['explorer', 'librarian', 'oracle', 'designer'],
|
|
@@ -28,6 +29,7 @@ describe("synergyState", () => {
|
|
|
28
29
|
vi.mocked(detectCDDConfig).mockReturnValue({
|
|
29
30
|
hasCDDInOpenCode: false,
|
|
30
31
|
hasCDDInOMO: false,
|
|
32
|
+
hasCDDInSlim: true,
|
|
31
33
|
synergyActive: true,
|
|
32
34
|
synergyFramework: 'oh-my-opencode-slim',
|
|
33
35
|
slimAgents: ['explorer', 'librarian'],
|
|
@@ -42,6 +44,7 @@ describe("synergyState", () => {
|
|
|
42
44
|
.mockReturnValueOnce({
|
|
43
45
|
hasCDDInOpenCode: false,
|
|
44
46
|
hasCDDInOMO: false,
|
|
47
|
+
hasCDDInSlim: true,
|
|
45
48
|
synergyActive: true,
|
|
46
49
|
synergyFramework: 'oh-my-opencode-slim',
|
|
47
50
|
slimAgents: ['explorer'],
|
|
@@ -49,6 +52,7 @@ describe("synergyState", () => {
|
|
|
49
52
|
.mockReturnValueOnce({
|
|
50
53
|
hasCDDInOpenCode: false,
|
|
51
54
|
hasCDDInOMO: true,
|
|
55
|
+
hasCDDInSlim: false,
|
|
52
56
|
synergyActive: true,
|
|
53
57
|
synergyFramework: 'oh-my-opencode',
|
|
54
58
|
cddModel: 'model-1',
|
|
@@ -64,13 +68,15 @@ describe("synergyState", () => {
|
|
|
64
68
|
.mockReturnValueOnce({
|
|
65
69
|
hasCDDInOpenCode: false,
|
|
66
70
|
hasCDDInOMO: false,
|
|
71
|
+
hasCDDInSlim: true,
|
|
67
72
|
synergyActive: true,
|
|
68
73
|
synergyFramework: 'oh-my-opencode-slim',
|
|
69
74
|
slimAgents: ['explorer'],
|
|
70
75
|
})
|
|
71
76
|
.mockReturnValueOnce({
|
|
72
77
|
hasCDDInOpenCode: false,
|
|
73
|
-
hasCDDInOMO:
|
|
78
|
+
hasCDDInOMO: true,
|
|
79
|
+
hasCDDInSlim: false,
|
|
74
80
|
synergyActive: true,
|
|
75
81
|
synergyFramework: 'oh-my-opencode',
|
|
76
82
|
cddModel: 'model-changed',
|
|
@@ -85,6 +91,7 @@ describe("synergyState", () => {
|
|
|
85
91
|
vi.mocked(detectCDDConfig).mockReturnValue({
|
|
86
92
|
hasCDDInOpenCode: true,
|
|
87
93
|
hasCDDInOMO: false,
|
|
94
|
+
hasCDDInSlim: false,
|
|
88
95
|
synergyActive: false,
|
|
89
96
|
synergyFramework: 'none',
|
|
90
97
|
cddModel: 'model-1',
|
|
@@ -99,13 +106,15 @@ describe("synergyState", () => {
|
|
|
99
106
|
.mockReturnValueOnce({
|
|
100
107
|
hasCDDInOpenCode: false,
|
|
101
108
|
hasCDDInOMO: false,
|
|
109
|
+
hasCDDInSlim: true,
|
|
102
110
|
synergyActive: true,
|
|
103
111
|
synergyFramework: 'oh-my-opencode-slim',
|
|
104
112
|
slimAgents: ['explorer'],
|
|
105
113
|
})
|
|
106
114
|
.mockReturnValueOnce({
|
|
107
115
|
hasCDDInOpenCode: false,
|
|
108
|
-
hasCDDInOMO:
|
|
116
|
+
hasCDDInOMO: true,
|
|
117
|
+
hasCDDInSlim: false,
|
|
109
118
|
synergyActive: true,
|
|
110
119
|
synergyFramework: 'oh-my-opencode',
|
|
111
120
|
cddModel: 'model-1',
|
|
@@ -124,6 +133,7 @@ describe("synergyState", () => {
|
|
|
124
133
|
vi.mocked(detectCDDConfig).mockReturnValue({
|
|
125
134
|
hasCDDInOpenCode: false,
|
|
126
135
|
hasCDDInOMO: false,
|
|
136
|
+
hasCDDInSlim: false,
|
|
127
137
|
synergyActive: false,
|
|
128
138
|
synergyFramework: 'none',
|
|
129
139
|
});
|
|
@@ -136,6 +146,7 @@ describe("synergyState", () => {
|
|
|
136
146
|
vi.mocked(detectCDDConfig).mockReturnValue({
|
|
137
147
|
hasCDDInOpenCode: false,
|
|
138
148
|
hasCDDInOMO: false,
|
|
149
|
+
hasCDDInSlim: true,
|
|
139
150
|
synergyActive: true,
|
|
140
151
|
synergyFramework: 'oh-my-opencode-slim',
|
|
141
152
|
slimAgents: ['explorer', 'oracle'],
|
|
@@ -147,6 +158,7 @@ describe("synergyState", () => {
|
|
|
147
158
|
vi.mocked(detectCDDConfig).mockReturnValue({
|
|
148
159
|
hasCDDInOpenCode: false,
|
|
149
160
|
hasCDDInOMO: true,
|
|
161
|
+
hasCDDInSlim: false,
|
|
150
162
|
synergyActive: true,
|
|
151
163
|
synergyFramework: 'oh-my-opencode',
|
|
152
164
|
cddModel: 'model-1',
|
|
@@ -163,13 +175,15 @@ describe("synergyState", () => {
|
|
|
163
175
|
.mockReturnValueOnce({
|
|
164
176
|
hasCDDInOpenCode: false,
|
|
165
177
|
hasCDDInOMO: false,
|
|
178
|
+
hasCDDInSlim: true,
|
|
166
179
|
synergyActive: true,
|
|
167
180
|
synergyFramework: 'oh-my-opencode-slim',
|
|
168
181
|
slimAgents: ['explorer'],
|
|
169
182
|
})
|
|
170
183
|
.mockReturnValueOnce({
|
|
171
184
|
hasCDDInOpenCode: false,
|
|
172
|
-
hasCDDInOMO:
|
|
185
|
+
hasCDDInOMO: true,
|
|
186
|
+
hasCDDInSlim: false,
|
|
173
187
|
synergyActive: true,
|
|
174
188
|
synergyFramework: 'oh-my-opencode',
|
|
175
189
|
cddModel: 'changed',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencode-conductor-cdd-plugin",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.20",
|
|
4
4
|
"description": "Context-Driven Development (CDD) plugin for OpenCode - Transform your AI coding workflow with structured specifications, plans, and implementation tracking",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
@@ -53,6 +53,7 @@
|
|
|
53
53
|
"@semantic-release/npm": "^12.0.1",
|
|
54
54
|
"@semantic-release/release-notes-generator": "^14.0.0",
|
|
55
55
|
"@types/node": "^20.0.0",
|
|
56
|
+
"@vitest/coverage-v8": "^4.0.17",
|
|
56
57
|
"semantic-release": "^24.2.1",
|
|
57
58
|
"typescript": "^5.0.0",
|
|
58
59
|
"vitest": "^4.0.16"
|