@tudeorangbiasa/sdd-multiagent-opencode 0.3.1 → 0.4.1
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/.opencode/commands/sdd-construct.md +8 -16
- package/.opencode/plugins/sdd-auto-reasoning.js +16 -20
- package/.opencode/plugins/sdd-model-router.js +72 -33
- package/.opencode/plugins/sdd-register.js +31 -52
- package/GUIDE.md +1 -1
- package/README.md +55 -30
- package/bin/sdd-opencode.js +87 -39
- package/package.json +2 -1
- package/sdd-multiagent-opencode.json +50 -0
- package/vendor/opencode-agent-rules/opencode-agent-rules.json +8 -0
- package/vendor/opencode-agent-rules/opencode.json +1 -7
- package/.sdd/templates/model-profile-template.json +0 -31
- package/.sdd/templates/reasoning-profile-template.json +0 -23
|
@@ -177,10 +177,10 @@ Ask:
|
|
|
177
177
|
|
|
178
178
|
> Explainer: SDD routes different agents to different models. Paid models get planning and orchestration roles. Free models get implementation and exploration roles. This section configures that routing.
|
|
179
179
|
|
|
180
|
-
|
|
180
|
+
Read `~/.config/opencode/sdd-multiagent-opencode.json` and summarize the current global routing. If the file is missing or still uses defaults, ask:
|
|
181
181
|
1. **Do you have a paid model subscription?** (OpenAI Plus, OpenCode Go, OpenCode Zen, or direct API keys)
|
|
182
182
|
2. **If yes, which provider?** This determines which agents get routed to paid models.
|
|
183
|
-
3. **If no,
|
|
183
|
+
3. **If no, keep the free-model defaults.** Implementation will still work but planning may be slower.
|
|
184
184
|
|
|
185
185
|
### Section D — Issue Tracker (ALL types)
|
|
186
186
|
|
|
@@ -293,18 +293,13 @@ If Phase 1 used the sniff test (no subagent spawned), write the stack profile no
|
|
|
293
293
|
|
|
294
294
|
This ensures `.sdd/stack-profile.json` always exists after `/sdd-construct`, regardless of whether a subagent was used.
|
|
295
295
|
|
|
296
|
-
### 3.2
|
|
296
|
+
### 3.2 Global SDD config
|
|
297
297
|
|
|
298
|
-
|
|
299
|
-
- If user has paid subscription → route orchestrator and planner to paid model
|
|
300
|
-
- If user has no paid subscription → use free model defaults
|
|
301
|
-
- Keep explorer, implementer, verifier, reviewer on free models
|
|
298
|
+
Do not create per-project model or reasoning profiles. SDD runtime configuration lives in `~/.config/opencode/sdd-multiagent-opencode.json`.
|
|
302
299
|
|
|
303
|
-
|
|
300
|
+
If the global config is missing, report it and suggest creating it. Do not write outside the project unless the user explicitly asks.
|
|
304
301
|
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
### 3.4 `CONTEXT.md` (at repo root)
|
|
302
|
+
### 3.3 `CONTEXT.md` (at repo root)
|
|
308
303
|
|
|
309
304
|
Create the domain glossary. Format:
|
|
310
305
|
|
|
@@ -627,8 +622,7 @@ Before reporting completion, verify:
|
|
|
627
622
|
### Universal checks (ALL project types):
|
|
628
623
|
- [ ] `.sdd/stack-profile.json` exists (written by explorer or by planner after sniff test)
|
|
629
624
|
- [ ] `.sdd/project-profile.json` exists and has non-null values for detected stack
|
|
630
|
-
- [ ]
|
|
631
|
-
- [ ] `.sdd/reasoning-profile.json` exists
|
|
625
|
+
- [ ] `~/.config/opencode/sdd-multiagent-opencode.json` exists or missing global config was reported
|
|
632
626
|
- [ ] `CONTEXT.md` exists at repo root (even if empty tables)
|
|
633
627
|
- [ ] `docs/adr/0001-project-initialization.md` exists
|
|
634
628
|
- [ ] `AGENTS.md` or `CLAUDE.md` has `## Agent skills` block
|
|
@@ -657,7 +651,7 @@ Before final output, verify:
|
|
|
657
651
|
- [ ] Grilling questions were asked one at a time (not dumped all at once)
|
|
658
652
|
- [ ] CONTEXT.md contains domain terms from the grilling session, not generic placeholders
|
|
659
653
|
- [ ] ADR documents actual decisions made during the session
|
|
660
|
-
- [ ]
|
|
654
|
+
- [ ] Global model routing reflects user's subscription status, or missing global config was reported
|
|
661
655
|
- [ ] No file paths or code snippets in CONTEXT.md
|
|
662
656
|
- [ ] Type-specific guardrails match classified project type
|
|
663
657
|
- [ ] No DESIGN.md generated for non-UI projects (backend, library, cli)
|
|
@@ -675,8 +669,6 @@ changed: SDD project initialized
|
|
|
675
669
|
Artifacts created:
|
|
676
670
|
- `.sdd/stack-profile.json` — raw stack detection results (from explorer or sniff test)
|
|
677
671
|
- `.sdd/project-profile.json` — stack detection results
|
|
678
|
-
- `.sdd/model-profile.json` — model routing configuration
|
|
679
|
-
- `.sdd/reasoning-profile.json` — reasoning effort per agent
|
|
680
672
|
- `CONTEXT.md` — domain glossary
|
|
681
673
|
- `docs/adr/0001-project-initialization.md` — initialization decisions
|
|
682
674
|
- `docs/agents/issue-tracker.md` — issue tracker configuration
|
|
@@ -1,11 +1,23 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
|
-
import { fileURLToPath } from "node:url";
|
|
4
3
|
|
|
5
|
-
const pluginDir = path.dirname(fileURLToPath(import.meta.url));
|
|
6
4
|
const LEVELS = new Set(["low", "medium", "high"]);
|
|
7
5
|
const pendingOverrides = new Map();
|
|
8
6
|
const recentCommands = new Map();
|
|
7
|
+
const globalConfigPath = path.join(
|
|
8
|
+
process.env.HOME || process.env.USERPROFILE || "",
|
|
9
|
+
".config",
|
|
10
|
+
"opencode",
|
|
11
|
+
"sdd-multiagent-opencode.json"
|
|
12
|
+
);
|
|
13
|
+
|
|
14
|
+
const DEFAULT_REASONING = {
|
|
15
|
+
default: "low",
|
|
16
|
+
applyProviderOptions: true,
|
|
17
|
+
resetToolOverrideAfterNextRequest: true,
|
|
18
|
+
agents: {},
|
|
19
|
+
commands: {},
|
|
20
|
+
};
|
|
9
21
|
|
|
10
22
|
function readJson(filePath) {
|
|
11
23
|
if (!fs.existsSync(filePath)) return null;
|
|
@@ -18,24 +30,8 @@ function readJson(filePath) {
|
|
|
18
30
|
}
|
|
19
31
|
|
|
20
32
|
function readProfile() {
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
path.join(pluginDir, "..", "..", ".sdd", "reasoning-profile.json"),
|
|
24
|
-
path.join(pluginDir, "..", ".sdd", "reasoning-profile.json"),
|
|
25
|
-
];
|
|
26
|
-
|
|
27
|
-
for (const candidate of candidates) {
|
|
28
|
-
const profile = readJson(candidate);
|
|
29
|
-
if (profile) return profile;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
return {
|
|
33
|
-
default: "low",
|
|
34
|
-
applyProviderOptions: true,
|
|
35
|
-
resetToolOverrideAfterNextRequest: true,
|
|
36
|
-
agents: {},
|
|
37
|
-
commands: {},
|
|
38
|
-
};
|
|
33
|
+
const pluginConfig = readJson(globalConfigPath);
|
|
34
|
+
return pluginConfig?.reasoning ?? DEFAULT_REASONING;
|
|
39
35
|
}
|
|
40
36
|
|
|
41
37
|
function normalizeLevel(level, fallback = "low") {
|
|
@@ -1,57 +1,96 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
3
|
+
|
|
4
|
+
const globalConfigPath = path.join(
|
|
5
|
+
process.env.HOME || process.env.USERPROFILE || "",
|
|
6
|
+
".config",
|
|
7
|
+
"opencode",
|
|
8
|
+
"sdd-multiagent-opencode.json"
|
|
9
|
+
);
|
|
10
|
+
const DEFAULT_PLUGIN_CONFIG = {
|
|
11
|
+
model: "openai/gpt-5.5",
|
|
12
|
+
small_model: "opencode/deepseek-v4-flash-free",
|
|
13
|
+
agent: {
|
|
14
|
+
"sdd-orchestrator": { model: "openai/gpt-5.5" },
|
|
15
|
+
"sdd-planner": { model: "openai/gpt-5.5" },
|
|
16
|
+
"sdd-explorer": { model: "opencode/deepseek-v4-flash-free" },
|
|
17
|
+
"sdd-implementer": { model: "opencode/deepseek-v4-flash-free" },
|
|
18
|
+
"sdd-verifier": { model: "opencode/qwen3.6-plus-free" },
|
|
19
|
+
"sdd-reviewer": { model: "opencode/minimax-m2.5-free" },
|
|
20
|
+
"sdd-quick": { model: "opencode/qwen3.6-plus-free" },
|
|
21
|
+
},
|
|
22
|
+
reasoning: {
|
|
23
|
+
default: "low",
|
|
24
|
+
applyProviderOptions: true,
|
|
25
|
+
resetToolOverrideAfterNextRequest: true,
|
|
26
|
+
agents: {
|
|
27
|
+
general: "medium",
|
|
28
|
+
plan: "high",
|
|
29
|
+
"sdd-orchestrator": "high",
|
|
30
|
+
"sdd-planner": "high",
|
|
31
|
+
"sdd-explorer": "low",
|
|
32
|
+
"sdd-implementer": "medium",
|
|
33
|
+
"sdd-verifier": "medium",
|
|
34
|
+
"sdd-reviewer": "medium",
|
|
35
|
+
"sdd-quick": "low",
|
|
36
|
+
},
|
|
37
|
+
commands: {
|
|
38
|
+
"sdd-explore": "medium",
|
|
39
|
+
"sdd-propose": "high",
|
|
40
|
+
"sdd-apply": "medium",
|
|
41
|
+
"sdd-ship": "medium",
|
|
42
|
+
"sdd-quick": "low",
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
function ensureConfigFile() {
|
|
48
|
+
if (fs.existsSync(globalConfigPath)) return;
|
|
49
|
+
|
|
50
|
+
try {
|
|
51
|
+
fs.mkdirSync(path.dirname(globalConfigPath), { recursive: true });
|
|
52
|
+
fs.writeFileSync(globalConfigPath, `${JSON.stringify(DEFAULT_PLUGIN_CONFIG, null, 2)}\n`);
|
|
53
|
+
} catch {
|
|
54
|
+
// If the global config cannot be seeded, continue with OpenCode's existing config.
|
|
24
55
|
}
|
|
56
|
+
}
|
|
25
57
|
|
|
26
|
-
|
|
58
|
+
function readConfig() {
|
|
59
|
+
ensureConfigFile();
|
|
60
|
+
if (!fs.existsSync(globalConfigPath)) return null;
|
|
61
|
+
|
|
62
|
+
try {
|
|
63
|
+
return JSON.parse(fs.readFileSync(globalConfigPath, "utf-8"));
|
|
64
|
+
} catch {
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
27
67
|
}
|
|
28
68
|
|
|
29
69
|
export default async () => {
|
|
30
70
|
return {
|
|
31
71
|
config: (cfg) => {
|
|
32
|
-
const
|
|
33
|
-
if (!
|
|
72
|
+
const pluginConfig = readConfig();
|
|
73
|
+
if (!pluginConfig) {
|
|
34
74
|
return;
|
|
35
75
|
}
|
|
36
76
|
|
|
37
|
-
if (
|
|
38
|
-
cfg.model =
|
|
77
|
+
if (pluginConfig.model) {
|
|
78
|
+
cfg.model = pluginConfig.model;
|
|
39
79
|
}
|
|
40
80
|
|
|
41
|
-
if (
|
|
42
|
-
cfg.small_model =
|
|
81
|
+
if (pluginConfig.small_model) {
|
|
82
|
+
cfg.small_model = pluginConfig.small_model;
|
|
43
83
|
}
|
|
44
84
|
|
|
45
85
|
if (!cfg.agent) {
|
|
46
86
|
cfg.agent = {};
|
|
47
87
|
}
|
|
48
88
|
|
|
49
|
-
for (const [agentName,
|
|
50
|
-
if (!
|
|
51
|
-
|
|
52
|
-
}
|
|
89
|
+
for (const [agentName, agentConfig] of Object.entries(pluginConfig.agent ?? {})) {
|
|
90
|
+
if (!agentConfig?.model) continue;
|
|
91
|
+
if (!cfg.agent[agentName]) continue;
|
|
53
92
|
|
|
54
|
-
cfg.agent[agentName].model = model;
|
|
93
|
+
cfg.agent[agentName].model = agentConfig.model;
|
|
55
94
|
}
|
|
56
95
|
},
|
|
57
96
|
};
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { fileURLToPath } from "node:url";
|
|
4
|
+
import sddAutoReasoning from "./sdd-auto-reasoning.js";
|
|
5
|
+
import sddModelRouter from "./sdd-model-router.js";
|
|
4
6
|
|
|
5
7
|
const __filename = fileURLToPath(import.meta.url);
|
|
6
8
|
const __dirname = path.dirname(__filename);
|
|
@@ -71,7 +73,9 @@ removeOldSymlinks();
|
|
|
71
73
|
|
|
72
74
|
const AGENTS = {
|
|
73
75
|
"sdd-orchestrator": {
|
|
76
|
+
description: "Internal coordination agent for complex SDD changes. Used by SDD commands when work needs multi-agent scheduling.",
|
|
74
77
|
mode: "subagent",
|
|
78
|
+
hidden: true,
|
|
75
79
|
temperature: 0.3,
|
|
76
80
|
permission: {
|
|
77
81
|
edit: "allow",
|
|
@@ -113,7 +117,9 @@ Return a concise coordination summary with completed work, blocked work, file co
|
|
|
113
117
|
},
|
|
114
118
|
|
|
115
119
|
"sdd-planner": {
|
|
120
|
+
description: "Creates compact SDD proposal, spec, design, and task artifacts for /sdd-propose and /sdd-construct.",
|
|
116
121
|
mode: "subagent",
|
|
122
|
+
hidden: true,
|
|
117
123
|
temperature: 0.3,
|
|
118
124
|
permission: {
|
|
119
125
|
edit: "allow",
|
|
@@ -171,7 +177,9 @@ For heavy apps (monorepo, microservices, multi-team): Include optional sections:
|
|
|
171
177
|
},
|
|
172
178
|
|
|
173
179
|
"sdd-explorer": {
|
|
180
|
+
description: "Readonly codebase exploration for /sdd-explore and uncertain SDD planning requests.",
|
|
174
181
|
mode: "subagent",
|
|
182
|
+
hidden: true,
|
|
175
183
|
temperature: 0.1,
|
|
176
184
|
permission: {
|
|
177
185
|
edit: "deny",
|
|
@@ -232,7 +240,9 @@ Return findings as:
|
|
|
232
240
|
},
|
|
233
241
|
|
|
234
242
|
"sdd-implementer": {
|
|
243
|
+
description: "Systematic implementation agent for approved /sdd-apply changes and /sdd-quick edits.",
|
|
235
244
|
mode: "subagent",
|
|
245
|
+
hidden: true,
|
|
236
246
|
temperature: 0.3,
|
|
237
247
|
permission: {
|
|
238
248
|
edit: "allow",
|
|
@@ -281,7 +291,9 @@ Use the question tool for ambiguous requirements or missing information.
|
|
|
281
291
|
},
|
|
282
292
|
|
|
283
293
|
"sdd-verifier": {
|
|
294
|
+
description: "Independent SDD validation agent for implementation completeness, tests, and UI/browser checks.",
|
|
284
295
|
mode: "subagent",
|
|
296
|
+
hidden: true,
|
|
285
297
|
temperature: 0.1,
|
|
286
298
|
permission: {
|
|
287
299
|
edit: "deny",
|
|
@@ -339,7 +351,9 @@ For each acceptance criterion, find implementing code and verify it meets the cr
|
|
|
339
351
|
},
|
|
340
352
|
|
|
341
353
|
"sdd-reviewer": {
|
|
354
|
+
description: "Final SDD review agent for /sdd-ship readiness, security, performance, and spec compliance.",
|
|
342
355
|
mode: "subagent",
|
|
356
|
+
hidden: true,
|
|
343
357
|
temperature: 0.2,
|
|
344
358
|
permission: {
|
|
345
359
|
edit: "deny",
|
|
@@ -478,7 +492,7 @@ After presenting findings, walk the user through decisions one at a time. Do not
|
|
|
478
492
|
3. Team size: solo, small team (2-5), or large team (5+)?
|
|
479
493
|
|
|
480
494
|
### Section C — Model Budget (ALL types)
|
|
481
|
-
|
|
495
|
+
Explain that SDD model and reasoning routing are configured globally in ~/.config/opencode/sdd-multiagent-opencode.json. Ask about paid model subscriptions only if the global config is missing or obviously still using defaults.
|
|
482
496
|
|
|
483
497
|
### Section D — Issue Tracker (ALL types)
|
|
484
498
|
Options: GitHub, GitLab, Local markdown, Other.
|
|
@@ -495,7 +509,7 @@ Options: GitHub, GitLab, Local markdown, Other.
|
|
|
495
509
|
|
|
496
510
|
## Phase 3: Scaffold Artifacts
|
|
497
511
|
|
|
498
|
-
Generate: .sdd/project-profile.json, .sdd/stack-profile.json,
|
|
512
|
+
Generate: .sdd/project-profile.json, .sdd/stack-profile.json, CONTEXT.md, docs/adr/0001-project-initialization.md, type-specific artifacts, docs/agents/issue-tracker.md, and update AGENTS.md with agent skills block. Do not create per-project model or reasoning profiles.
|
|
499
513
|
|
|
500
514
|
## Phase 4: Verification
|
|
501
515
|
|
|
@@ -511,7 +525,7 @@ End with:
|
|
|
511
525
|
changed: SDD project initialized
|
|
512
526
|
|
|
513
527
|
Artifacts created:
|
|
514
|
-
- .sdd/stack-profile.json, .sdd/project-profile.json
|
|
528
|
+
- .sdd/stack-profile.json, .sdd/project-profile.json
|
|
515
529
|
- CONTEXT.md, docs/adr/0001-project-initialization.md, docs/agents/issue-tracker.md
|
|
516
530
|
- AGENTS.md (agent skills block)
|
|
517
531
|
- <type-specific artifacts>
|
|
@@ -802,10 +816,22 @@ suggestion: Run /sdd-propose "<request>" for full workflow.`,
|
|
|
802
816
|
// ─── Plugin Export ───────────────────────────────────────────────────────────
|
|
803
817
|
|
|
804
818
|
export default async ({ client, project, directory, $ }) => {
|
|
819
|
+
const modelRouterHooks = await sddModelRouter({ client, project, directory, $ });
|
|
820
|
+
const autoReasoningHooks = await sddAutoReasoning({ client, project, directory, $ });
|
|
821
|
+
|
|
805
822
|
return {
|
|
806
|
-
|
|
823
|
+
...autoReasoningHooks,
|
|
807
824
|
|
|
808
825
|
config(cfg) {
|
|
826
|
+
// Register SDD agents through config; OpenCode 1.15 ignores top-level plugin `agent` hooks.
|
|
827
|
+
cfg.agent = cfg.agent || {};
|
|
828
|
+
for (const [name, agent] of Object.entries(AGENTS)) {
|
|
829
|
+
cfg.agent[name] = {
|
|
830
|
+
...(cfg.agent[name] ?? {}),
|
|
831
|
+
...agent,
|
|
832
|
+
};
|
|
833
|
+
}
|
|
834
|
+
|
|
809
835
|
// Register SDD skills path
|
|
810
836
|
const skillsDir = path.join(packageRoot, ".opencode", "skills");
|
|
811
837
|
if (fs.existsSync(skillsDir)) {
|
|
@@ -835,54 +861,7 @@ export default async ({ client, project, directory, $ }) => {
|
|
|
835
861
|
cfg.permission.skill["sdd-*"] = "allow";
|
|
836
862
|
}
|
|
837
863
|
|
|
838
|
-
|
|
839
|
-
// Load sdd-model-router
|
|
840
|
-
try {
|
|
841
|
-
const modelRouterPath = path.join(__dirname, "sdd-model-router.js");
|
|
842
|
-
if (fs.existsSync(modelRouterPath)) {
|
|
843
|
-
import(modelRouterPath).then(async (mod) => {
|
|
844
|
-
const pluginFn = mod.default;
|
|
845
|
-
if (pluginFn) {
|
|
846
|
-
const result = await pluginFn({ client, project, directory, $ });
|
|
847
|
-
if (result.config) {
|
|
848
|
-
result.config(cfg);
|
|
849
|
-
}
|
|
850
|
-
}
|
|
851
|
-
});
|
|
852
|
-
}
|
|
853
|
-
} catch {
|
|
854
|
-
// sdd-model-router not available, skip
|
|
855
|
-
}
|
|
856
|
-
|
|
857
|
-
// Load sdd-auto-reasoning
|
|
858
|
-
try {
|
|
859
|
-
const reasoningPath = path.join(__dirname, "sdd-auto-reasoning.js");
|
|
860
|
-
if (fs.existsSync(reasoningPath)) {
|
|
861
|
-
import(reasoningPath).then(async (mod) => {
|
|
862
|
-
const pluginFn = mod.default;
|
|
863
|
-
if (pluginFn) {
|
|
864
|
-
const result = await pluginFn({ client, project, directory, $ });
|
|
865
|
-
// Merge all hooks from auto-reasoning
|
|
866
|
-
for (const [hookName, hookFn] of Object.entries(result)) {
|
|
867
|
-
if (hookName !== "config" && typeof hookFn === "function") {
|
|
868
|
-
// Chain hook — call existing then new
|
|
869
|
-
const existing = cfg[hookName];
|
|
870
|
-
if (typeof existing === "function") {
|
|
871
|
-
cfg[hookName] = async (...args) => {
|
|
872
|
-
await existing(...args);
|
|
873
|
-
await hookFn(...args);
|
|
874
|
-
};
|
|
875
|
-
} else {
|
|
876
|
-
cfg[hookName] = hookFn;
|
|
877
|
-
}
|
|
878
|
-
}
|
|
879
|
-
}
|
|
880
|
-
}
|
|
881
|
-
});
|
|
882
|
-
}
|
|
883
|
-
} catch {
|
|
884
|
-
// sdd-auto-reasoning not available, skip
|
|
885
|
-
}
|
|
864
|
+
modelRouterHooks.config?.(cfg);
|
|
886
865
|
},
|
|
887
866
|
};
|
|
888
867
|
};
|
package/GUIDE.md
CHANGED
|
@@ -48,7 +48,7 @@ Run this once at the start of a project to set up the "spine" — stack detectio
|
|
|
48
48
|
- Section F: Type-specific guardrails (conditional)
|
|
49
49
|
|
|
50
50
|
3. **Phase 3: Scaffold Artifacts**
|
|
51
|
-
- `.sdd/project-profile.json`,
|
|
51
|
+
- `.sdd/project-profile.json`, plus global runtime config in `~/.config/opencode/sdd-multiagent-opencode.json`
|
|
52
52
|
- `CONTEXT.md` (domain glossary)
|
|
53
53
|
- `docs/adr/0001-project-initialization.md`
|
|
54
54
|
- Type-specific artifacts (conditional):
|
package/README.md
CHANGED
|
@@ -41,7 +41,7 @@ external UI skills # impeccable, taste, nothing-design, etc.
|
|
|
41
41
|
| **sdd-reviewer** | configurable | Code review (security, performance, spec compliance) |
|
|
42
42
|
| **sdd-quick** | configurable | Small cosmetic/config edits (~200 tokens via CLI wrapper) |
|
|
43
43
|
|
|
44
|
-
**All models are configurable** via
|
|
44
|
+
**All models are configurable** via `~/.config/opencode/sdd-multiagent-opencode.json`. Edit this file to change which model each agent uses. See [Model Settings](#model-settings) below.
|
|
45
45
|
|
|
46
46
|
## Quick Start
|
|
47
47
|
|
|
@@ -64,7 +64,7 @@ To pin a specific version:
|
|
|
64
64
|
```json
|
|
65
65
|
{
|
|
66
66
|
"plugin": [
|
|
67
|
-
"@tudeorangbiasa/sdd-multiagent-opencode@0.
|
|
67
|
+
"@tudeorangbiasa/sdd-multiagent-opencode@0.4.1"
|
|
68
68
|
]
|
|
69
69
|
}
|
|
70
70
|
```
|
|
@@ -116,7 +116,11 @@ Most work starts with `/sdd-propose`, then `/sdd-apply`, then `/sdd-ship`. Use `
|
|
|
116
116
|
|
|
117
117
|
## Model Settings
|
|
118
118
|
|
|
119
|
-
|
|
119
|
+
SDD model and reasoning routing are configured in one global plugin config:
|
|
120
|
+
|
|
121
|
+
`~/.config/opencode/sdd-multiagent-opencode.json`
|
|
122
|
+
|
|
123
|
+
Edit this file to change which model each SDD agent uses. This package does not read per-project model or reasoning profile files at runtime.
|
|
120
124
|
|
|
121
125
|
**⚠️ Requirement:** SDD works best with at least **ONE paid/subscription model** for orchestrator and planner. These roles need strong reasoning + multimodal capabilities that free models lack.
|
|
122
126
|
|
|
@@ -223,22 +227,43 @@ Models available at no cost via OpenCode Zen. Run `opencode models opencode | gr
|
|
|
223
227
|
- `groq/llama-3.3-70b-versatile` — Llama 3.3 70B via Groq
|
|
224
228
|
- `openrouter/deepseek-r1-free` — DeepSeek R1 via OpenRouter (free)
|
|
225
229
|
|
|
226
|
-
### Default
|
|
230
|
+
### Default Config
|
|
227
231
|
|
|
228
232
|
Recommended starting configuration (orchestrator/planner use OpenAI GPT 5.5, others use free):
|
|
229
233
|
|
|
230
234
|
```json
|
|
231
235
|
{
|
|
232
|
-
"
|
|
233
|
-
"
|
|
234
|
-
"
|
|
235
|
-
"sdd-orchestrator": "openai/gpt-5.5",
|
|
236
|
-
"sdd-planner": "openai/gpt-5.5",
|
|
237
|
-
"sdd-explorer": "opencode/deepseek-v4-flash-free",
|
|
238
|
-
"sdd-implementer": "opencode/deepseek-v4-flash-free",
|
|
239
|
-
"sdd-verifier": "opencode/qwen3.6-plus-free",
|
|
240
|
-
"sdd-reviewer": "opencode/minimax-m2.5-free",
|
|
241
|
-
"sdd-quick": "opencode/qwen3.6-plus-free"
|
|
236
|
+
"model": "openai/gpt-5.5",
|
|
237
|
+
"small_model": "opencode/deepseek-v4-flash-free",
|
|
238
|
+
"agent": {
|
|
239
|
+
"sdd-orchestrator": { "model": "openai/gpt-5.5" },
|
|
240
|
+
"sdd-planner": { "model": "openai/gpt-5.5" },
|
|
241
|
+
"sdd-explorer": { "model": "opencode/deepseek-v4-flash-free" },
|
|
242
|
+
"sdd-implementer": { "model": "opencode/deepseek-v4-flash-free" },
|
|
243
|
+
"sdd-verifier": { "model": "opencode/qwen3.6-plus-free" },
|
|
244
|
+
"sdd-reviewer": { "model": "opencode/minimax-m2.5-free" },
|
|
245
|
+
"sdd-quick": { "model": "opencode/qwen3.6-plus-free" }
|
|
246
|
+
},
|
|
247
|
+
"reasoning": {
|
|
248
|
+
"default": "low",
|
|
249
|
+
"applyProviderOptions": true,
|
|
250
|
+
"resetToolOverrideAfterNextRequest": true,
|
|
251
|
+
"agents": {
|
|
252
|
+
"sdd-orchestrator": "high",
|
|
253
|
+
"sdd-planner": "high",
|
|
254
|
+
"sdd-explorer": "low",
|
|
255
|
+
"sdd-implementer": "medium",
|
|
256
|
+
"sdd-verifier": "medium",
|
|
257
|
+
"sdd-reviewer": "medium",
|
|
258
|
+
"sdd-quick": "low"
|
|
259
|
+
},
|
|
260
|
+
"commands": {
|
|
261
|
+
"sdd-explore": "medium",
|
|
262
|
+
"sdd-propose": "high",
|
|
263
|
+
"sdd-apply": "medium",
|
|
264
|
+
"sdd-ship": "medium",
|
|
265
|
+
"sdd-quick": "low"
|
|
266
|
+
}
|
|
242
267
|
}
|
|
243
268
|
}
|
|
244
269
|
```
|
|
@@ -247,16 +272,16 @@ Recommended starting configuration (orchestrator/planner use OpenAI GPT 5.5, oth
|
|
|
247
272
|
|
|
248
273
|
```json
|
|
249
274
|
{
|
|
250
|
-
"
|
|
251
|
-
"
|
|
252
|
-
"
|
|
253
|
-
"sdd-orchestrator": "opencode-go/deepseek-v4-pro",
|
|
254
|
-
"sdd-planner": "opencode-go/deepseek-v4-pro",
|
|
255
|
-
"sdd-explorer": "opencode/deepseek-v4-flash-free",
|
|
256
|
-
"sdd-implementer": "opencode/deepseek-v4-flash-free",
|
|
257
|
-
"sdd-verifier": "opencode-go/kimi-k2.6",
|
|
258
|
-
"sdd-reviewer": "opencode/minimax-m2.5-free",
|
|
259
|
-
"sdd-quick": "opencode-go/qwen3.6-plus"
|
|
275
|
+
"model": "opencode-go/deepseek-v4-pro",
|
|
276
|
+
"small_model": "opencode/deepseek-v4-flash-free",
|
|
277
|
+
"agent": {
|
|
278
|
+
"sdd-orchestrator": { "model": "opencode-go/deepseek-v4-pro" },
|
|
279
|
+
"sdd-planner": { "model": "opencode-go/deepseek-v4-pro" },
|
|
280
|
+
"sdd-explorer": { "model": "opencode/deepseek-v4-flash-free" },
|
|
281
|
+
"sdd-implementer": { "model": "opencode/deepseek-v4-flash-free" },
|
|
282
|
+
"sdd-verifier": { "model": "opencode-go/kimi-k2.6" },
|
|
283
|
+
"sdd-reviewer": { "model": "opencode/minimax-m2.5-free" },
|
|
284
|
+
"sdd-quick": { "model": "opencode-go/qwen3.6-plus" }
|
|
260
285
|
}
|
|
261
286
|
}
|
|
262
287
|
```
|
|
@@ -270,13 +295,13 @@ Recommended starting configuration (orchestrator/planner use OpenAI GPT 5.5, oth
|
|
|
270
295
|
- **Reviewer** → MiniMax M2.5 free: structured code review output
|
|
271
296
|
- **Quick** → Qwen3.6 Plus free: minimal prompt for small cosmetic/config edits (~200 tokens)
|
|
272
297
|
|
|
273
|
-
`.opencode/plugins/sdd-model-router.js` reads
|
|
298
|
+
`.opencode/plugins/sdd-model-router.js` reads `~/.config/opencode/sdd-multiagent-opencode.json` at OpenCode startup and applies the model settings. **Restart OpenCode after editing it.**
|
|
274
299
|
|
|
275
|
-
**Important:** Do NOT set models in `opencode.json
|
|
300
|
+
**Important:** Do NOT set SDD agent models in `opencode.json`. All SDD model routing goes through `~/.config/opencode/sdd-multiagent-opencode.json`.
|
|
276
301
|
|
|
277
302
|
### Auto Reasoning
|
|
278
303
|
|
|
279
|
-
The
|
|
304
|
+
The plugin installs `.opencode/plugins/sdd-auto-reasoning.js` and reads the `reasoning` section from `~/.config/opencode/sdd-multiagent-opencode.json`.
|
|
280
305
|
|
|
281
306
|
The plugin reverse-engineers the behavior of `@howaboua/pi-auto-reasoning-tool` for OpenCode:
|
|
282
307
|
- sets reasoning effort automatically per agent and command
|
|
@@ -298,7 +323,7 @@ Default routing:
|
|
|
298
323
|
}
|
|
299
324
|
```
|
|
300
325
|
|
|
301
|
-
Restart OpenCode after editing
|
|
326
|
+
Restart OpenCode after editing `~/.config/opencode/sdd-multiagent-opencode.json`.
|
|
302
327
|
|
|
303
328
|
### Manual Install
|
|
304
329
|
|
|
@@ -380,8 +405,6 @@ For small cosmetic fixes:
|
|
|
380
405
|
.sdd/
|
|
381
406
|
├── config.json # Project configuration
|
|
382
407
|
├── project-profile.json # Stack and skill routing config
|
|
383
|
-
├── model-profile.json # Model routing per agent
|
|
384
|
-
├── reasoning-profile.json # Reasoning effort per agent/command
|
|
385
408
|
└── templates/ # Document templates
|
|
386
409
|
├── proposal-template.md
|
|
387
410
|
├── spec-template.md
|
|
@@ -407,6 +430,8 @@ specs/
|
|
|
407
430
|
└── QUICKFIX_LOG_ARCHIVE.md # Archived ledger entries
|
|
408
431
|
```
|
|
409
432
|
|
|
433
|
+
Global runtime config lives at `~/.config/opencode/sdd-multiagent-opencode.json`.
|
|
434
|
+
|
|
410
435
|
## Workflows
|
|
411
436
|
|
|
412
437
|
### New Project Setup
|
package/bin/sdd-opencode.js
CHANGED
|
@@ -122,6 +122,64 @@ function parseJsonc(filePath) {
|
|
|
122
122
|
return JSON.parse(stripped);
|
|
123
123
|
}
|
|
124
124
|
|
|
125
|
+
function readJsonSafe(filePath) {
|
|
126
|
+
if (!fs.existsSync(filePath)) return null;
|
|
127
|
+
|
|
128
|
+
try {
|
|
129
|
+
return JSON.parse(fs.readFileSync(filePath, "utf-8"));
|
|
130
|
+
} catch {
|
|
131
|
+
return null;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function getNativeAuthPath() {
|
|
136
|
+
const home = process.env.HOME || process.env.USERPROFILE || "";
|
|
137
|
+
const xdgDataHome = process.env.XDG_DATA_HOME || path.join(home, ".local", "share");
|
|
138
|
+
return path.join(xdgDataHome, "opencode", "auth.json");
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function getProviderId(model) {
|
|
142
|
+
if (typeof model !== "string") return null;
|
|
143
|
+
const separator = model.indexOf("/");
|
|
144
|
+
if (separator <= 0) return null;
|
|
145
|
+
return model.slice(0, separator);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
function getProviderEnvNames(providerId) {
|
|
149
|
+
const explicit = {
|
|
150
|
+
openai: ["OPENAI_API_KEY"],
|
|
151
|
+
anthropic: ["ANTHROPIC_API_KEY"],
|
|
152
|
+
google: ["GOOGLE_API_KEY", "GEMINI_API_KEY"],
|
|
153
|
+
opencode: ["OPENCODE_API_KEY", "OPENCODE_ZEN_API_KEY"],
|
|
154
|
+
openrouter: ["OPENROUTER_API_KEY"],
|
|
155
|
+
groq: ["GROQ_API_KEY"],
|
|
156
|
+
deepseek: ["DEEPSEEK_API_KEY"],
|
|
157
|
+
minimax: ["MINIMAX_API_KEY"],
|
|
158
|
+
moonshot: ["MOONSHOT_API_KEY"],
|
|
159
|
+
zai: ["ZAI_API_KEY"],
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
if (explicit[providerId]) return explicit[providerId];
|
|
163
|
+
|
|
164
|
+
return [`${providerId.toUpperCase().replace(/[^A-Z0-9]/g, "_")}_API_KEY`];
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
function describeProviderConfig(providerId, opencodeConfig, nativeAuth) {
|
|
168
|
+
const auth = nativeAuth?.[providerId];
|
|
169
|
+
if (auth?.type === "oauth") return "configured via OpenCode native oauth";
|
|
170
|
+
if (auth?.type === "api") return "configured via OpenCode native api auth";
|
|
171
|
+
if (auth) return "configured via OpenCode native auth";
|
|
172
|
+
|
|
173
|
+
const providerConfig = opencodeConfig?.provider?.[providerId];
|
|
174
|
+
if (providerConfig?.options?.apiKey) return "configured via opencode.json provider apiKey";
|
|
175
|
+
if (providerConfig) return "configured via opencode.json provider";
|
|
176
|
+
|
|
177
|
+
const envName = getProviderEnvNames(providerId).find((name) => !!process.env[name]);
|
|
178
|
+
if (envName) return `configured via ${envName}`;
|
|
179
|
+
|
|
180
|
+
return null;
|
|
181
|
+
}
|
|
182
|
+
|
|
125
183
|
// ─── Backup ──────────────────────────────────────────────────────────────────
|
|
126
184
|
|
|
127
185
|
function createBackup(filePath) {
|
|
@@ -177,7 +235,7 @@ function parseArgs(argv) {
|
|
|
177
235
|
// ─── Usage ───────────────────────────────────────────────────────────────────
|
|
178
236
|
|
|
179
237
|
function usage() {
|
|
180
|
-
console.log(`SDD Multi-Agent OpenCode Installer v0.
|
|
238
|
+
console.log(`SDD Multi-Agent OpenCode Installer v0.4.1
|
|
181
239
|
|
|
182
240
|
Usage:
|
|
183
241
|
sdd-opencode init [flags] Install SDD workflow into current project
|
|
@@ -331,8 +389,6 @@ function installSdd(ctx) {
|
|
|
331
389
|
|
|
332
390
|
const profileTemplates = [
|
|
333
391
|
{ dest: "project-profile.json", template: "project-profile-template.json", populate: true },
|
|
334
|
-
{ dest: "model-profile.json", template: "model-profile-template.json", populate: false },
|
|
335
|
-
{ dest: "reasoning-profile.json", template: "reasoning-profile-template.json", populate: false },
|
|
336
392
|
];
|
|
337
393
|
|
|
338
394
|
for (const { dest, template, populate } of profileTemplates) {
|
|
@@ -392,16 +448,6 @@ function patchOpencodeJson(ctx) {
|
|
|
392
448
|
|
|
393
449
|
if (!targetConfig.agent) targetConfig.agent = {};
|
|
394
450
|
|
|
395
|
-
// Patch compaction from vendor rules
|
|
396
|
-
const vendorRulesJson = path.join(packageRoot, "vendor/opencode-agent-rules/opencode.json");
|
|
397
|
-
if (fs.existsSync(vendorRulesJson)) {
|
|
398
|
-
const rulesConfig = JSON.parse(fs.readFileSync(vendorRulesJson, "utf-8"));
|
|
399
|
-
if (rulesConfig.agent?.compaction && !targetConfig.agent.compaction) {
|
|
400
|
-
targetConfig.agent.compaction = rulesConfig.agent.compaction;
|
|
401
|
-
ctx.installed.push("opencode.json (compaction patch)");
|
|
402
|
-
}
|
|
403
|
-
}
|
|
404
|
-
|
|
405
451
|
// Patch plugins
|
|
406
452
|
const pkgJsonPath = path.join(packageRoot, "opencode.json");
|
|
407
453
|
if (fs.existsSync(pkgJsonPath)) {
|
|
@@ -467,7 +513,7 @@ async function runInit(args) {
|
|
|
467
513
|
dryRunFiles: [],
|
|
468
514
|
};
|
|
469
515
|
|
|
470
|
-
console.log("\nSDD Multi-Agent OpenCode Installer v0.
|
|
516
|
+
console.log("\nSDD Multi-Agent OpenCode Installer v0.4.1\n");
|
|
471
517
|
console.log(`Target: ${targetRoot}`);
|
|
472
518
|
if (ctx.dryRun) console.log("Mode: DRY RUN (no files will be written)\n");
|
|
473
519
|
|
|
@@ -503,8 +549,8 @@ async function runInit(args) {
|
|
|
503
549
|
|
|
504
550
|
console.log("\nNext steps:");
|
|
505
551
|
console.log(" 1. Edit .sdd/project-profile.json with your stack");
|
|
506
|
-
console.log(" 2.
|
|
507
|
-
console.log(" 3.
|
|
552
|
+
console.log(" 2. Configure models in ~/.config/opencode/sdd-multiagent-opencode.json");
|
|
553
|
+
console.log(" 3. Run: /sdd-propose \"your first feature\"");
|
|
508
554
|
}
|
|
509
555
|
}
|
|
510
556
|
|
|
@@ -605,42 +651,44 @@ async function runDoctor(args) {
|
|
|
605
651
|
const cmdCount = fs.existsSync(commandsDir) ? fs.readdirSync(commandsDir).filter((f) => f.endsWith(".md")).length : 0;
|
|
606
652
|
report("L1", "commands available", cmdCount >= expectedCommands ? "pass" : "warn", `${cmdCount}/${expectedCommands} command files`);
|
|
607
653
|
|
|
608
|
-
// L2:
|
|
609
|
-
console.log("\nL2:
|
|
654
|
+
// L2: OpenCode provider configuration
|
|
655
|
+
console.log("\nL2: OpenCode Providers");
|
|
610
656
|
|
|
611
|
-
const
|
|
612
|
-
const
|
|
657
|
+
const sddConfigPath = path.join(globalConfigDir, "sdd-multiagent-opencode.json");
|
|
658
|
+
const sddConfig = readJsonSafe(sddConfigPath);
|
|
659
|
+
const globalOpencodeConfig = parseJsonc(path.join(globalConfigDir, "opencode.json"));
|
|
660
|
+
const nativeAuth = readJsonSafe(getNativeAuthPath());
|
|
613
661
|
|
|
614
|
-
if (
|
|
662
|
+
if (sddConfig) {
|
|
615
663
|
const models = new Set();
|
|
616
|
-
if (
|
|
617
|
-
if (
|
|
618
|
-
|
|
664
|
+
if (sddConfig.model) models.add(sddConfig.model);
|
|
665
|
+
if (sddConfig.small_model) models.add(sddConfig.small_model);
|
|
666
|
+
if (sddConfig.agent) {
|
|
667
|
+
for (const agentConfig of Object.values(sddConfig.agent)) {
|
|
668
|
+
if (agentConfig?.model) models.add(agentConfig.model);
|
|
669
|
+
}
|
|
619
670
|
}
|
|
620
671
|
|
|
621
|
-
const
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
const hasKey = !!process.env[name];
|
|
632
|
-
report("L2", `${name}`, hasKey ? "pass" : "warn", hasKey ? "set" : "not set — models requiring this provider were detected");
|
|
633
|
-
}
|
|
672
|
+
const providerIds = new Set([...models].map(getProviderId).filter(Boolean));
|
|
673
|
+
|
|
674
|
+
for (const providerId of providerIds) {
|
|
675
|
+
const configuredBy = describeProviderConfig(providerId, globalOpencodeConfig, nativeAuth);
|
|
676
|
+
report(
|
|
677
|
+
"L2",
|
|
678
|
+
`provider ${providerId}`,
|
|
679
|
+
configuredBy ? "pass" : "warn",
|
|
680
|
+
configuredBy ?? "model uses this provider but no native auth, opencode.json provider, or env key was found"
|
|
681
|
+
);
|
|
634
682
|
}
|
|
635
683
|
} else {
|
|
636
|
-
report("L2", "
|
|
684
|
+
report("L2", "sdd-multiagent-opencode.json", "warn", "not found in ~/.config/opencode — using built-in defaults");
|
|
637
685
|
}
|
|
638
686
|
|
|
639
687
|
// L3: Liveness probe (--deep only)
|
|
640
688
|
if (args.flags.deep) {
|
|
641
689
|
console.log("\nL3: Liveness Probe");
|
|
642
690
|
|
|
643
|
-
const primaryModel =
|
|
691
|
+
const primaryModel = sddConfig?.model || process.env.DEFAULT_MODEL || "unknown";
|
|
644
692
|
report("L3", "model endpoint", "warn", `would probe ${primaryModel} — liveness requires valid API credentials and network access`);
|
|
645
693
|
report("L3", "note", "warn", "full liveness probe requires HTTP client — run manually with curl or your provider's dashboard");
|
|
646
694
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tudeorangbiasa/sdd-multiagent-opencode",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.1",
|
|
4
4
|
"description": "Spec-Driven Development workflow kit for OpenCode with 5 core commands, multi-agent support, CLI wrappers, and configurable model routing",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": ".opencode/plugins/sdd-register.js",
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
"vendor",
|
|
16
16
|
"README.md",
|
|
17
17
|
"GUIDE.md",
|
|
18
|
+
"sdd-multiagent-opencode.json",
|
|
18
19
|
"opencode.json"
|
|
19
20
|
],
|
|
20
21
|
"scripts": {
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"model": "openai/gpt-5.5",
|
|
3
|
+
"small_model": "opencode/deepseek-v4-flash-free",
|
|
4
|
+
"agent": {
|
|
5
|
+
"sdd-orchestrator": {
|
|
6
|
+
"model": "openai/gpt-5.5"
|
|
7
|
+
},
|
|
8
|
+
"sdd-planner": {
|
|
9
|
+
"model": "openai/gpt-5.5"
|
|
10
|
+
},
|
|
11
|
+
"sdd-explorer": {
|
|
12
|
+
"model": "opencode/deepseek-v4-flash-free"
|
|
13
|
+
},
|
|
14
|
+
"sdd-implementer": {
|
|
15
|
+
"model": "opencode/deepseek-v4-flash-free"
|
|
16
|
+
},
|
|
17
|
+
"sdd-verifier": {
|
|
18
|
+
"model": "opencode/qwen3.6-plus-free"
|
|
19
|
+
},
|
|
20
|
+
"sdd-reviewer": {
|
|
21
|
+
"model": "opencode/minimax-m2.5-free"
|
|
22
|
+
},
|
|
23
|
+
"sdd-quick": {
|
|
24
|
+
"model": "opencode/qwen3.6-plus-free"
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
"reasoning": {
|
|
28
|
+
"default": "low",
|
|
29
|
+
"applyProviderOptions": true,
|
|
30
|
+
"resetToolOverrideAfterNextRequest": true,
|
|
31
|
+
"agents": {
|
|
32
|
+
"general": "medium",
|
|
33
|
+
"plan": "high",
|
|
34
|
+
"sdd-orchestrator": "high",
|
|
35
|
+
"sdd-planner": "high",
|
|
36
|
+
"sdd-explorer": "low",
|
|
37
|
+
"sdd-implementer": "medium",
|
|
38
|
+
"sdd-verifier": "medium",
|
|
39
|
+
"sdd-reviewer": "medium",
|
|
40
|
+
"sdd-quick": "low"
|
|
41
|
+
},
|
|
42
|
+
"commands": {
|
|
43
|
+
"sdd-explore": "medium",
|
|
44
|
+
"sdd-propose": "high",
|
|
45
|
+
"sdd-apply": "medium",
|
|
46
|
+
"sdd-ship": "medium",
|
|
47
|
+
"sdd-quick": "low"
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"_info": {
|
|
3
|
-
"description": "Model routing configuration. Edit this file to change which model each agent uses. Restart OpenCode after editing.",
|
|
4
|
-
"requirement": "SDD requires at least ONE paid/subscription model for orchestrator and planner. These roles need strong reasoning that free models cannot provide.",
|
|
5
|
-
"subscription_options": {
|
|
6
|
-
"openai_plus": "GPT 5.5 with reasoning and multimodal",
|
|
7
|
-
"opencode_go": "$10/month — includes DeepSeek V4 Pro, GLM 5.1, Kimi K2.6, MiniMax M2.7",
|
|
8
|
-
"opencode_zen": "Pay-per-token, zero markup — access to Claude Opus 4.7, GPT 5.5, Gemini 3.1 Pro"
|
|
9
|
-
},
|
|
10
|
-
"recommendations": {
|
|
11
|
-
"orchestrator": "PAID: GPT 5.5 (OpenAI) or DeepSeek V4 Pro (Go) — needs strong reasoning for DAG coordination",
|
|
12
|
-
"planner": "PAID: GPT 5.5 (OpenAI), Claude Opus 4.7, or DeepSeek V4 Pro (Go) — needs maximum reasoning for architecture",
|
|
13
|
-
"explorer": "FREE: DeepSeek v4 Flash — fast readonly exploration, token-efficient",
|
|
14
|
-
"implementer": "FREE: DeepSeek v4 Flash — code generation, high token usage",
|
|
15
|
-
"verifier": "FREE: Qwen3.6 Plus — multimodal for Chrome DevTools screenshots",
|
|
16
|
-
"reviewer": "FREE: MiniMax M2.5 — structured code review output",
|
|
17
|
-
"quick": "FREE: Qwen3.6 Plus or DeepSeek v4 Flash — minimal prompt for small edits"
|
|
18
|
-
}
|
|
19
|
-
},
|
|
20
|
-
"defaultPrimary": "openai/gpt-5.5",
|
|
21
|
-
"small": "opencode/deepseek-v4-flash-free",
|
|
22
|
-
"agents": {
|
|
23
|
-
"sdd-orchestrator": "openai/gpt-5.5",
|
|
24
|
-
"sdd-planner": "openai/gpt-5.5",
|
|
25
|
-
"sdd-explorer": "opencode/deepseek-v4-flash-free",
|
|
26
|
-
"sdd-implementer": "opencode/deepseek-v4-flash-free",
|
|
27
|
-
"sdd-verifier": "opencode/qwen3.6-plus-free",
|
|
28
|
-
"sdd-reviewer": "opencode/minimax-m2.5-free",
|
|
29
|
-
"sdd-quick": "opencode/qwen3.6-plus-free"
|
|
30
|
-
}
|
|
31
|
-
}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"default": "low",
|
|
3
|
-
"applyProviderOptions": true,
|
|
4
|
-
"resetToolOverrideAfterNextRequest": true,
|
|
5
|
-
"agents": {
|
|
6
|
-
"general": "medium",
|
|
7
|
-
"plan": "high",
|
|
8
|
-
"sdd-orchestrator": "high",
|
|
9
|
-
"sdd-planner": "high",
|
|
10
|
-
"sdd-explorer": "low",
|
|
11
|
-
"sdd-implementer": "medium",
|
|
12
|
-
"sdd-verifier": "medium",
|
|
13
|
-
"sdd-reviewer": "medium",
|
|
14
|
-
"sdd-quick": "low"
|
|
15
|
-
},
|
|
16
|
-
"commands": {
|
|
17
|
-
"sdd-explore": "medium",
|
|
18
|
-
"sdd-propose": "high",
|
|
19
|
-
"sdd-apply": "medium",
|
|
20
|
-
"sdd-ship": "medium",
|
|
21
|
-
"sdd-quick": "low"
|
|
22
|
-
}
|
|
23
|
-
}
|