oh-my-opencode-slim 0.8.4 → 0.8.6

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
@@ -1,6 +1,6 @@
1
1
  <div align="center">
2
- <img src="img/team.png" alt="Pantheon agents" width="420">
3
- <p><i>Six divine beings emerged from the dawn of code, each an immortal master of their craft await your command to forge order from chaos and build what was once thought impossible.</i></p>
2
+ <img src="img/team.png" alt="Pantheon agents" style="border-radius: 10px;" width="620">
3
+ <p><i>Seven divine beings emerged from the dawn of code, each an immortal master of their craft await your command to forge order from chaos and build what was once thought impossible.</i></p>
4
4
  <p><b>Open Multi Agent Suite</b> · Mix any models · Auto delegate tasks</p>
5
5
  <p><a href="https://moltfounders.com/jobs/09d1c6e7-9e0e-4683-8d78-e2376aaa2333"><img src="https://moltfounders.com/badges/4.png" alt="MoltFounders" height="30"></a></p>
6
6
  </div>
@@ -56,10 +56,6 @@ https://raw.githubusercontent.com/alvinunreal/oh-my-opencode-slim/refs/heads/mas
56
56
 
57
57
  **Detailed installation guide:** [docs/installation.md](docs/installation.md)
58
58
 
59
- **Additional guides:**
60
- - **[Provider Configurations](docs/provider-configurations.md)** - Config examples for all supported providers
61
- - **[Tmux Integration](docs/tmux-integration.md)** - Real-time agent monitoring with tmux
62
-
63
59
  ### ✅ Verify Your Setup
64
60
 
65
61
  After installation and authentication, verify all agents are configured and responding:
@@ -114,7 +110,7 @@ If any agent fails to respond, check your provider authentication and config fil
114
110
  </tr>
115
111
  <tr>
116
112
  <td colspan="2">
117
- <b>Recommended Models:</b> <code>openai/gpt-5.4</code> <code>kimi-for-coding/k2p5</code>
113
+ <b>Recommended Models:</b> <code>openai/gpt-5.4</code> <code>anthropic/claude-opus-4.6</code>
118
114
  </td>
119
115
  </tr>
120
116
  </table>
@@ -150,7 +146,7 @@ If any agent fails to respond, check your provider authentication and config fil
150
146
  </tr>
151
147
  <tr>
152
148
  <td colspan="2">
153
- <b>Recommended Models:</b> <code>cerebras/zai-glm-4.7</code> <code>google/gemini-3.1-pro-preview</code> <code>openai/gpt-5.4-mini</code>
149
+ <b>Recommended Models:</b> <code>cerebras/zai-glm-4.7</code> <code>fireworks-ai/accounts/fireworks/routers/kimi-k2p5-turbo</code> <code>openai/gpt-5.4-mini</code>
154
150
  </td>
155
151
  </tr>
156
152
  </table>
@@ -181,12 +177,53 @@ If any agent fails to respond, check your provider authentication and config fil
181
177
  </tr>
182
178
  <tr>
183
179
  <td colspan="2">
184
- <b>Default Model:</b> <code>openai/gpt-5.4</code>
180
+ <b>Default Model:</b> <code>openai/gpt-5.4 (high)</code>
181
+ </td>
182
+ </tr>
183
+ <tr>
184
+ <td colspan="2">
185
+ <b>Recommended Models:</b> <code>openai/gpt-5.4 (high)</code> <code>google/gemini-3.1-pro-preview (high)</code>
186
+ </td>
187
+ </tr>
188
+ </table>
189
+
190
+ ---
191
+
192
+ ### Council: The Chorus of Minds
193
+
194
+ <table>
195
+ <tr>
196
+ <td width="30%" align="center" valign="top">
197
+ <img src="img/council.png" width="240" style="border-radius: 10px;">
198
+ <br><sub><i>Many minds, one verdict.</i></sub>
199
+ </td>
200
+ <td width="70%" valign="top">
201
+ The Council is not a lone being but a chamber of minds summoned when one answer is not enough. It sends your question to multiple models in parallel, gathers their competing judgments, and places them before a master who distills the strongest ideas into a single verdict. Where a solitary agent may miss a path, the Council cross-examines possibility itself.
202
+ </td>
203
+ </tr>
204
+ <tr>
205
+ <td colspan="2">
206
+ <b>Role:</b> <code>Multi-LLM consensus and synthesis</code>
207
+ </td>
208
+ </tr>
209
+ <tr>
210
+ <td colspan="2">
211
+ <b>Prompt:</b> <a href="src/agents/council.ts"><code>council.ts</code></a>
185
212
  </td>
186
213
  </tr>
187
214
  <tr>
188
215
  <td colspan="2">
189
- <b>Recommended Models:</b> <code>openai/gpt-5.4</code> <code>kimi-for-coding/k2p5</code>
216
+ <b>Guide:</b> <a href="docs/council.md"><code>docs/council.md</code></a>
217
+ </td>
218
+ </tr>
219
+ <tr>
220
+ <td colspan="2">
221
+ <b>Default Setup:</b> <code>Config-driven</code> — council master + councillors are chosen from your configured preset
222
+ </td>
223
+ </tr>
224
+ <tr>
225
+ <td colspan="2">
226
+ <b>Recommended Setup:</b> <code>Strong master</code> + <code>diverse councillors</code> across providers
190
227
  </td>
191
228
  </tr>
192
229
  </table>
@@ -222,7 +259,7 @@ If any agent fails to respond, check your provider authentication and config fil
222
259
  </tr>
223
260
  <tr>
224
261
  <td colspan="2">
225
- <b>Recommended Models:</b> <code>google/gemini-3.1-pro-preview</code> <code>openai/gpt-5.4-mini</code>
262
+ <b>Recommended Models:</b> <code>cerebras/zai-glm-4.7</code> <code>fireworks-ai/accounts/fireworks/routers/kimi-k2p5-turbo</code> <code>openai/gpt-5.4-mini</code>
226
263
  </td>
227
264
  </tr>
228
265
  </table>
@@ -253,12 +290,12 @@ If any agent fails to respond, check your provider authentication and config fil
253
290
  </tr>
254
291
  <tr>
255
292
  <td colspan="2">
256
- <b>Default Model:</b> <code>kimi-for-coding/k2p5</code>
293
+ <b>Default Model:</b> <code>openai/gpt-5.4-mini</code>
257
294
  </td>
258
295
  </tr>
259
296
  <tr>
260
297
  <td colspan="2">
261
- <b>Recommended Models:</b> <code>google/gemini-3.1-pro-preview</code>
298
+ <b>Recommended Models:</b> <code>google/gemini-3.1-pro-preview</code> <code>kimi-for-coding/k2p5</code>
262
299
  </td>
263
300
  </tr>
264
301
  </table>
@@ -294,7 +331,7 @@ If any agent fails to respond, check your provider authentication and config fil
294
331
  </tr>
295
332
  <tr>
296
333
  <td colspan="2">
297
- <b>Recommended Models:</b> <code>cerebras/zai-glm-4.7</code> <code>google/gemini-3.1-pro-preview</code> <code>openai/gpt-5.4-mini</code>
334
+ <b>Recommended Models:</b> <code>cerebras/zai-glm-4.7</code> <code>fireworks-ai/accounts/fireworks/routers/kimi-k2p5-turbo</code> <code>openai/gpt-5.4-mini</code>
298
335
  </td>
299
336
  </tr>
300
337
  </table>
@@ -303,11 +340,35 @@ If any agent fails to respond, check your provider authentication and config fil
303
340
 
304
341
  ## 📚 Documentation
305
342
 
306
- - **[Quick Reference](docs/quick-reference.md)** - Skills, MCPs, Tools, Configuration
307
- - **[Provider Configurations](docs/provider-configurations.md)** - Config examples for OpenAI, Kimi, Copilot, ZAI
308
- - **[Installation Guide](docs/installation.md)** - Detailed installation and troubleshooting
309
- - **[Cartography Skill](docs/cartography.md)** - Custom skill for repository mapping + codemap generation
310
- - **[Tmux Integration](docs/tmux-integration.md)** - Real-time agent monitoring with tmux
343
+ ### 🚀 Getting Started
344
+
345
+ | Doc | Contents |
346
+ |-----|----------|
347
+ | **[Installation Guide](docs/installation.md)** | CLI flags, `--reset`, auth, troubleshooting |
348
+ | **[Provider Configurations](docs/provider-configurations.md)** | OpenAI, Kimi, Copilot, ZAI, Fireworks AI — mixing providers, fallback chains |
349
+
350
+ ### ✨ Features
351
+
352
+ | Feature | Doc | What it does |
353
+ |---------|-----|--------------|
354
+ | **Council** | [council.md](docs/council.md) | Run N models in parallel, synthesize one answer (`@council`) |
355
+ | **Tmux Integration** | [tmux-integration.md](docs/tmux-integration.md) | Watch agents work in real-time with auto-spawned panes |
356
+ | **Cartography Skill** | [cartography.md](docs/cartography.md) | Auto-generate hierarchical codemaps for any codebase |
357
+
358
+ ### ⚙️ Config & Reference
359
+
360
+ | Doc | Contents |
361
+ |-----|----------|
362
+ | **[Skills](docs/skills.md)** | `simplify`, `agent-browser`, `cartography` — assignment syntax |
363
+ | **[MCPs](docs/mcps.md)** | `websearch`, `context7`, `grep_app` — permissions per agent |
364
+ | **[Tools](docs/tools.md)** | Background tasks, LSP, code search, formatters |
365
+ | **[Configuration](docs/configuration.md)** | Config files, prompt overriding, JSONC, full option reference |
366
+
367
+ ### 💡 Author's Setup
368
+
369
+ | Doc | Contents |
370
+ |-----|----------|
371
+ | **[Author's Preset](docs/authors-preset.md)** | The exact config the author runs daily — OpenAI + Fireworks AI + GitHub Copilot |
311
372
 
312
373
  ---
313
374
 
@@ -0,0 +1,2 @@
1
+ import { type AgentDefinition } from './orchestrator';
2
+ export declare function createCouncilMasterAgent(model: string, customPrompt?: string, customAppendPrompt?: string): AgentDefinition;
@@ -0,0 +1,28 @@
1
+ import { type AgentDefinition } from './orchestrator';
2
+ export declare function createCouncilAgent(model: string, customPrompt?: string, customAppendPrompt?: string): AgentDefinition;
3
+ /**
4
+ * Build the prompt for a specific councillor session.
5
+ *
6
+ * Returns the raw user prompt — the agent factory (councillor.ts) provides
7
+ * the system prompt with tool-aware instructions. No duplication.
8
+ *
9
+ * If a per-councillor prompt override is provided, it is prepended as
10
+ * role/guidance context before the user's question.
11
+ */
12
+ export declare function formatCouncillorPrompt(userPrompt: string, councillorPrompt?: string): string;
13
+ /**
14
+ * Build the synthesis prompt for the council master.
15
+ *
16
+ * Formats councillor results as structured data — the agent factory
17
+ * (council-master.ts) provides the system prompt with synthesis instructions.
18
+ * Returns a special prompt when all councillors failed to produce output.
19
+ *
20
+ * @param masterPrompt - Optional per-master guidance appended to the synthesis.
21
+ */
22
+ export declare function formatMasterSynthesisPrompt(originalPrompt: string, councillorResults: Array<{
23
+ name: string;
24
+ model: string;
25
+ status: string;
26
+ result?: string;
27
+ error?: string;
28
+ }>, masterPrompt?: string): string;
@@ -0,0 +1,2 @@
1
+ import { type AgentDefinition } from './orchestrator';
2
+ export declare function createCouncillorAgent(model: string, customPrompt?: string, customAppendPrompt?: string): AgentDefinition;
@@ -9,6 +9,12 @@ export interface AgentDefinition {
9
9
  variant?: string;
10
10
  }>;
11
11
  }
12
+ /**
13
+ * Resolve agent prompt from base/custom/append inputs.
14
+ * If customPrompt is provided, it replaces the base entirely.
15
+ * Otherwise, customAppendPrompt is appended to the base.
16
+ */
17
+ export declare function resolvePrompt(base: string, customPrompt?: string, customAppendPrompt?: string): string;
12
18
  export declare function createOrchestratorAgent(model?: string | Array<string | {
13
19
  id: string;
14
20
  variant?: string;
@@ -15,6 +15,7 @@
15
15
  import type { PluginInput } from '@opencode-ai/plugin';
16
16
  import type { BackgroundTaskConfig, PluginConfig } from '../config';
17
17
  import type { TmuxConfig } from '../config/schema';
18
+ import { SubagentDepthTracker } from './subagent-depth';
18
19
  /**
19
20
  * Represents a background task running in an isolated session.
20
21
  * Tasks are tracked from creation through completion or failure.
@@ -46,6 +47,7 @@ export declare class BackgroundTaskManager {
46
47
  private tasks;
47
48
  private tasksBySessionId;
48
49
  private agentBySessionId;
50
+ private depthTracker;
49
51
  private client;
50
52
  private directory;
51
53
  private tmuxEnabled;
@@ -94,7 +96,6 @@ export declare class BackgroundTaskManager {
94
96
  */
95
97
  private processQueue;
96
98
  private resolveFallbackChain;
97
- private promptWithTimeout;
98
99
  /**
99
100
  * Calculate tool permissions for a spawned agent based on its own delegation rules.
100
101
  * Agents that cannot delegate (leaf nodes) get delegation tools disabled entirely,
@@ -172,4 +173,8 @@ export declare class BackgroundTaskManager {
172
173
  * Clean up all tasks.
173
174
  */
174
175
  cleanup(): void;
176
+ /**
177
+ * Get the depth tracker instance for use by other managers.
178
+ */
179
+ getDepthTracker(): SubagentDepthTracker;
175
180
  }
@@ -1,2 +1,3 @@
1
1
  export { type BackgroundTask, BackgroundTaskManager, type LaunchOptions, } from './background-manager';
2
+ export { SubagentDepthTracker } from './subagent-depth';
2
3
  export { TmuxSessionManager } from './tmux-session-manager';
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Tracks subagent spawn depth to prevent excessive nesting.
3
+ *
4
+ * Depth 0 = root session (user's main conversation)
5
+ * Depth 1 = agent spawned by root (e.g., explorer, council)
6
+ * Depth 2 = agent spawned by depth-1 agent (e.g., councillor spawned by council)
7
+ * Depth 3 = agent spawned by depth-2 agent (max depth by default)
8
+ *
9
+ * When max depth is exceeded, the spawn is blocked.
10
+ */
11
+ export declare class SubagentDepthTracker {
12
+ private depthBySession;
13
+ private readonly _maxDepth;
14
+ constructor(maxDepth?: number);
15
+ /** Maximum allowed depth. */
16
+ get maxDepth(): number;
17
+ /**
18
+ * Get the current depth of a session.
19
+ * Root sessions (not tracked) have depth 0.
20
+ */
21
+ getDepth(sessionId: string): number;
22
+ /**
23
+ * Register a child session and check if the spawn is allowed.
24
+ * @returns true if allowed, false if max depth exceeded
25
+ */
26
+ registerChild(parentSessionId: string, childSessionId: string): boolean;
27
+ /**
28
+ * Clean up session tracking when a session is deleted.
29
+ */
30
+ cleanup(sessionId: string): void;
31
+ /**
32
+ * Clean up all tracking data.
33
+ */
34
+ cleanupAll(): void;
35
+ }
package/dist/cli/index.js CHANGED
@@ -96,7 +96,10 @@ var SUBAGENT_NAMES = [
96
96
  "librarian",
97
97
  "oracle",
98
98
  "designer",
99
- "fixer"
99
+ "fixer",
100
+ "council",
101
+ "councillor",
102
+ "council-master"
100
103
  ];
101
104
  var ORCHESTRATOR_NAME = "orchestrator";
102
105
  var ALL_AGENT_NAMES = [ORCHESTRATOR_NAME, ...SUBAGENT_NAMES];
@@ -13634,6 +13637,61 @@ function date4(params) {
13634
13637
 
13635
13638
  // node_modules/zod/v4/classic/external.js
13636
13639
  config(en_default());
13640
+ // src/config/council-schema.ts
13641
+ var ModelIdSchema = exports_external.string().regex(/^[^/\s]+\/[^\s]+$/, 'Expected provider/model format (e.g. "openai/gpt-5.4-mini")');
13642
+ var CouncillorConfigSchema = exports_external.object({
13643
+ model: ModelIdSchema.describe('Model ID in provider/model format (e.g. "openai/gpt-5.4-mini")'),
13644
+ variant: exports_external.string().optional(),
13645
+ prompt: exports_external.string().optional().describe("Optional role/guidance injected into the councillor user prompt")
13646
+ });
13647
+ var PresetMasterOverrideSchema = exports_external.object({
13648
+ model: ModelIdSchema.optional().describe("Override the master model for this preset"),
13649
+ variant: exports_external.string().optional().describe("Override the master variant for this preset"),
13650
+ prompt: exports_external.string().optional().describe("Override the master synthesis guidance for this preset")
13651
+ });
13652
+ var CouncilPresetSchema = exports_external.record(exports_external.string(), exports_external.record(exports_external.string(), exports_external.unknown())).transform((entries, ctx) => {
13653
+ const councillors = {};
13654
+ let masterOverride;
13655
+ for (const [key, raw] of Object.entries(entries)) {
13656
+ if (key === "master") {
13657
+ const parsed = PresetMasterOverrideSchema.safeParse(raw);
13658
+ if (!parsed.success) {
13659
+ ctx.addIssue(`Invalid master override in preset: ${parsed.error.issues.map((i) => i.message).join(", ")}`);
13660
+ return exports_external.NEVER;
13661
+ }
13662
+ masterOverride = parsed.data;
13663
+ } else {
13664
+ const parsed = CouncillorConfigSchema.safeParse(raw);
13665
+ if (!parsed.success) {
13666
+ ctx.addIssue(`Invalid councillor "${key}": ${parsed.error.issues.map((i) => i.message).join(", ")}`);
13667
+ return exports_external.NEVER;
13668
+ }
13669
+ councillors[key] = parsed.data;
13670
+ }
13671
+ }
13672
+ return { councillors, master: masterOverride };
13673
+ });
13674
+ var CouncilMasterConfigSchema = exports_external.object({
13675
+ model: ModelIdSchema.describe('Model ID for the council master (e.g. "anthropic/claude-opus-4-6")'),
13676
+ variant: exports_external.string().optional(),
13677
+ prompt: exports_external.string().optional().describe("Optional role/guidance injected into the master synthesis prompt")
13678
+ });
13679
+ var CouncilConfigSchema = exports_external.object({
13680
+ master: CouncilMasterConfigSchema,
13681
+ presets: exports_external.record(exports_external.string(), CouncilPresetSchema),
13682
+ master_timeout: exports_external.number().min(0).default(300000),
13683
+ councillors_timeout: exports_external.number().min(0).default(180000),
13684
+ default_preset: exports_external.string().default("default"),
13685
+ master_fallback: exports_external.array(ModelIdSchema).optional().transform((val) => {
13686
+ if (!val)
13687
+ return val;
13688
+ const unique = [...new Set(val)];
13689
+ if (unique.length !== val.length) {
13690
+ return unique;
13691
+ }
13692
+ return val;
13693
+ }).describe("Fallback models for the council master. Tried in order if the primary model fails. " + 'Example: ["anthropic/claude-sonnet-4-6", "openai/gpt-5.4"]')
13694
+ });
13637
13695
  // src/config/schema.ts
13638
13696
  var ProviderModelIdSchema = exports_external.string().regex(/^[^/\s]+\/[^\s]+$/, "Expected provider/model format (provider/.../model)");
13639
13697
  var ManualAgentPlanSchema = exports_external.object({
@@ -13722,7 +13780,8 @@ var PluginConfigSchema = exports_external.object({
13722
13780
  disabled_mcps: exports_external.array(exports_external.string()).optional(),
13723
13781
  tmux: TmuxConfigSchema.optional(),
13724
13782
  background: BackgroundTaskConfigSchema.optional(),
13725
- fallback: FailoverConfigSchema.optional()
13783
+ fallback: FailoverConfigSchema.optional(),
13784
+ council: CouncilConfigSchema.optional()
13726
13785
  });
13727
13786
  // src/config/agent-mcps.ts
13728
13787
  var DEFAULT_AGENT_MCPS = {
@@ -13731,7 +13790,10 @@ var DEFAULT_AGENT_MCPS = {
13731
13790
  oracle: [],
13732
13791
  librarian: ["websearch", "context7", "grep_app"],
13733
13792
  explorer: [],
13734
- fixer: []
13793
+ fixer: [],
13794
+ council: [],
13795
+ councillor: [],
13796
+ "council-master": []
13735
13797
  };
13736
13798
 
13737
13799
  // src/cli/skills.ts
@@ -7,6 +7,16 @@
7
7
  * 3. ~/.config/opencode
8
8
  */
9
9
  export declare function getConfigDir(): string;
10
+ /**
11
+ * Get OpenCode config directories in read/search order.
12
+ *
13
+ * Resolution order:
14
+ * 1. OPENCODE_CONFIG_DIR (if set)
15
+ * 2. XDG_CONFIG_HOME/opencode or ~/.config/opencode
16
+ *
17
+ * Duplicate entries are removed.
18
+ */
19
+ export declare function getConfigSearchDirs(): string[];
10
20
  export declare function getOpenCodeConfigPaths(): string[];
11
21
  export declare function getConfigJson(): string;
12
22
  export declare function getConfigJsonc(): string;
@@ -1,8 +1,9 @@
1
1
  export declare const AGENT_ALIASES: Record<string, string>;
2
- export declare const SUBAGENT_NAMES: readonly ["explorer", "librarian", "oracle", "designer", "fixer"];
2
+ export declare const SUBAGENT_NAMES: readonly ["explorer", "librarian", "oracle", "designer", "fixer", "council", "councillor", "council-master"];
3
3
  export declare const ORCHESTRATOR_NAME: "orchestrator";
4
- export declare const ALL_AGENT_NAMES: readonly ["orchestrator", "explorer", "librarian", "oracle", "designer", "fixer"];
4
+ export declare const ALL_AGENT_NAMES: readonly ["orchestrator", "explorer", "librarian", "oracle", "designer", "fixer", "council", "councillor", "council-master"];
5
5
  export type AgentName = (typeof ALL_AGENT_NAMES)[number];
6
+ export declare const ORCHESTRATABLE_AGENTS: readonly ["explorer", "librarian", "oracle", "designer", "fixer", "council"];
6
7
  export declare const SUBAGENT_DELEGATION_RULES: Record<AgentName, readonly string[]>;
7
8
  export declare const DEFAULT_MODELS: Record<AgentName, string | undefined>;
8
9
  export declare const POLL_INTERVAL_MS = 500;
@@ -11,4 +12,8 @@ export declare const POLL_INTERVAL_BACKGROUND_MS = 2000;
11
12
  export declare const DEFAULT_TIMEOUT_MS: number;
12
13
  export declare const MAX_POLL_TIME_MS: number;
13
14
  export declare const FALLBACK_FAILOVER_TIMEOUT_MS = 15000;
15
+ export declare const DEFAULT_MAX_SUBAGENT_DEPTH = 3;
16
+ export declare const PHASE_REMINDER_TEXT = "Recall Workflow Rules:\nUnderstand \u2192 build the best path (delegated based on Agent rules, split and parallelized as much as possible) \u2192 execute \u2192 verify.\nIf delegating, launch the specialist in the same turn you mention it.";
17
+ export declare const TMUX_SPAWN_DELAY_MS = 500;
18
+ export declare const COUNCILLOR_STAGGER_MS = 250;
14
19
  export declare const STABLE_POLLS_THRESHOLD = 3;
@@ -0,0 +1,134 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * Configuration for a single councillor within a preset.
4
+ * Each councillor is an independent LLM that processes the same prompt.
5
+ *
6
+ * Councillors run as agent sessions with read-only codebase access
7
+ * (read, glob, grep, lsp, list). They can examine the codebase but
8
+ * cannot modify files or spawn subagents.
9
+ */
10
+ export declare const CouncillorConfigSchema: z.ZodObject<{
11
+ model: z.ZodString;
12
+ variant: z.ZodOptional<z.ZodString>;
13
+ prompt: z.ZodOptional<z.ZodString>;
14
+ }, z.core.$strip>;
15
+ export type CouncillorConfig = z.infer<typeof CouncillorConfigSchema>;
16
+ /**
17
+ * Per-preset master override. All fields are optional — any field
18
+ * provided here overrides the global `council.master` for this preset.
19
+ * Fields not provided fall back to the global master config.
20
+ */
21
+ export declare const PresetMasterOverrideSchema: z.ZodObject<{
22
+ model: z.ZodOptional<z.ZodString>;
23
+ variant: z.ZodOptional<z.ZodString>;
24
+ prompt: z.ZodOptional<z.ZodString>;
25
+ }, z.core.$strip>;
26
+ export type PresetMasterOverride = z.infer<typeof PresetMasterOverrideSchema>;
27
+ /**
28
+ * A named preset grouping several councillors with an optional master override.
29
+ *
30
+ * The reserved key `"master"` provides per-preset overrides for the council
31
+ * master (model, variant, prompt). All other keys are treated as councillor
32
+ * names mapping to councillor configs.
33
+ *
34
+ * After parsing, the preset resolves to:
35
+ * `{ councillors: Record<string, CouncillorConfig>, master?: PresetMasterOverride }`
36
+ */
37
+ export declare const CouncilPresetSchema: z.ZodPipe<z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodUnknown>>, z.ZodTransform<{
38
+ councillors: Record<string, {
39
+ model: string;
40
+ variant?: string | undefined;
41
+ prompt?: string | undefined;
42
+ }>;
43
+ master: {
44
+ model?: string | undefined;
45
+ variant?: string | undefined;
46
+ prompt?: string | undefined;
47
+ } | undefined;
48
+ }, Record<string, Record<string, unknown>>>>;
49
+ export type CouncilPreset = z.infer<typeof CouncilPresetSchema>;
50
+ /**
51
+ * Council Master configuration.
52
+ * The master receives all councillor responses and produces the final synthesis.
53
+ *
54
+ * Note: The master runs as a council-master agent session with zero
55
+ * permissions (deny all). Synthesis is a text-in/text-out operation —
56
+ * no tools or MCPs are needed.
57
+ */
58
+ export declare const CouncilMasterConfigSchema: z.ZodObject<{
59
+ model: z.ZodString;
60
+ variant: z.ZodOptional<z.ZodString>;
61
+ prompt: z.ZodOptional<z.ZodString>;
62
+ }, z.core.$strip>;
63
+ export type CouncilMasterConfig = z.infer<typeof CouncilMasterConfigSchema>;
64
+ /**
65
+ * Top-level council configuration.
66
+ *
67
+ * Example JSONC:
68
+ * ```jsonc
69
+ * {
70
+ * "council": {
71
+ * "master": { "model": "anthropic/claude-opus-4-6" },
72
+ * "presets": {
73
+ * "default": {
74
+ * "alpha": { "model": "openai/gpt-5.4-mini" },
75
+ * "beta": { "model": "openai/gpt-5.3-codex" },
76
+ * "gamma": { "model": "google/gemini-3-pro" }
77
+ * }
78
+ * },
79
+ * "master_timeout": 300000,
80
+ * "councillors_timeout": 180000
81
+ * }
82
+ * }
83
+ * ```
84
+ */
85
+ export declare const CouncilConfigSchema: z.ZodObject<{
86
+ master: z.ZodObject<{
87
+ model: z.ZodString;
88
+ variant: z.ZodOptional<z.ZodString>;
89
+ prompt: z.ZodOptional<z.ZodString>;
90
+ }, z.core.$strip>;
91
+ presets: z.ZodRecord<z.ZodString, z.ZodPipe<z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodUnknown>>, z.ZodTransform<{
92
+ councillors: Record<string, {
93
+ model: string;
94
+ variant?: string | undefined;
95
+ prompt?: string | undefined;
96
+ }>;
97
+ master: {
98
+ model?: string | undefined;
99
+ variant?: string | undefined;
100
+ prompt?: string | undefined;
101
+ } | undefined;
102
+ }, Record<string, Record<string, unknown>>>>>;
103
+ master_timeout: z.ZodDefault<z.ZodNumber>;
104
+ councillors_timeout: z.ZodDefault<z.ZodNumber>;
105
+ default_preset: z.ZodDefault<z.ZodString>;
106
+ master_fallback: z.ZodPipe<z.ZodOptional<z.ZodArray<z.ZodString>>, z.ZodTransform<string[] | undefined, string[] | undefined>>;
107
+ }, z.core.$strip>;
108
+ export type CouncilConfig = z.infer<typeof CouncilConfigSchema>;
109
+ /**
110
+ * A sensible default council configuration that users can copy into their
111
+ * opencode.jsonc. Provides a 3-councillor preset using common models.
112
+ *
113
+ * Users should replace models with ones they have access to.
114
+ *
115
+ * ```jsonc
116
+ * "council": DEFAULT_COUNCIL_CONFIG
117
+ * ```
118
+ */
119
+ export declare const DEFAULT_COUNCIL_CONFIG: z.input<typeof CouncilConfigSchema>;
120
+ /**
121
+ * Result of a council session.
122
+ */
123
+ export interface CouncilResult {
124
+ success: boolean;
125
+ result?: string;
126
+ error?: string;
127
+ councillorResults: Array<{
128
+ name: string;
129
+ model: string;
130
+ status: 'completed' | 'failed' | 'timed_out';
131
+ result?: string;
132
+ error?: string;
133
+ }>;
134
+ }
@@ -1,4 +1,5 @@
1
1
  export * from './constants';
2
+ export * from './council-schema';
2
3
  export { loadAgentPrompt, loadPluginConfig } from './loader';
3
4
  export * from './schema';
4
5
  export { getAgentOverride } from './utils';
@@ -1,6 +1,7 @@
1
1
  import { z } from 'zod';
2
2
  declare const FALLBACK_AGENT_NAMES: readonly ["orchestrator", "oracle", "designer", "explorer", "librarian", "fixer"];
3
3
  declare const MANUAL_AGENT_NAMES: readonly ["orchestrator", "oracle", "designer", "explorer", "librarian", "fixer"];
4
+ export declare const ProviderModelIdSchema: z.ZodString;
4
5
  export declare const ManualAgentPlanSchema: z.ZodObject<{
5
6
  primary: z.ZodString;
6
7
  fallback1: z.ZodString;
@@ -215,6 +216,29 @@ export declare const PluginConfigSchema: z.ZodObject<{
215
216
  fixer: z.ZodOptional<z.ZodArray<z.ZodString>>;
216
217
  }, z.core.$catchall<z.ZodArray<z.ZodString>>>>;
217
218
  }, z.core.$strip>>;
219
+ council: z.ZodOptional<z.ZodObject<{
220
+ master: z.ZodObject<{
221
+ model: z.ZodString;
222
+ variant: z.ZodOptional<z.ZodString>;
223
+ prompt: z.ZodOptional<z.ZodString>;
224
+ }, z.core.$strip>;
225
+ presets: z.ZodRecord<z.ZodString, z.ZodPipe<z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodUnknown>>, z.ZodTransform<{
226
+ councillors: Record<string, {
227
+ model: string;
228
+ variant?: string | undefined;
229
+ prompt?: string | undefined;
230
+ }>;
231
+ master: {
232
+ model?: string | undefined;
233
+ variant?: string | undefined;
234
+ prompt?: string | undefined;
235
+ } | undefined;
236
+ }, Record<string, Record<string, unknown>>>>>;
237
+ master_timeout: z.ZodDefault<z.ZodNumber>;
238
+ councillors_timeout: z.ZodDefault<z.ZodNumber>;
239
+ default_preset: z.ZodDefault<z.ZodString>;
240
+ master_fallback: z.ZodPipe<z.ZodOptional<z.ZodArray<z.ZodString>>, z.ZodTransform<string[] | undefined, string[] | undefined>>;
241
+ }, z.core.$strip>>;
218
242
  }, z.core.$strip>;
219
243
  export type PluginConfig = z.infer<typeof PluginConfigSchema>;
220
244
  export type { AgentName } from './constants';
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Council Manager
3
+ *
4
+ * Orchestrates multi-LLM council sessions: launches councillors in
5
+ * parallel, collects results, then runs the council master for synthesis.
6
+ */
7
+ import type { PluginInput } from '@opencode-ai/plugin';
8
+ import type { SubagentDepthTracker } from '../background/subagent-depth';
9
+ import type { PluginConfig } from '../config';
10
+ import type { CouncilResult } from '../config/council-schema';
11
+ export declare class CouncilManager {
12
+ private client;
13
+ private directory;
14
+ private config?;
15
+ private depthTracker?;
16
+ private tmuxEnabled;
17
+ constructor(ctx: PluginInput, config?: PluginConfig, depthTracker?: SubagentDepthTracker, tmuxEnabled?: boolean);
18
+ /**
19
+ * Run a full council session.
20
+ *
21
+ * 1. Look up the preset
22
+ * 2. Launch all councillors in parallel
23
+ * 3. Collect results (respecting timeout)
24
+ * 4. Run master synthesis
25
+ * 5. Return combined result
26
+ */
27
+ runCouncil(prompt: string, presetName: string | undefined, parentSessionId: string): Promise<CouncilResult>;
28
+ /**
29
+ * Inject a start notification into the parent session so the user
30
+ * sees immediate feedback while councillors are spinning up.
31
+ */
32
+ private sendStartNotification;
33
+ /**
34
+ * Run a single agent session: create → register → prompt → extract → cleanup.
35
+ * Both councillors and the master follow this identical lifecycle.
36
+ */
37
+ private runAgentSession;
38
+ private runCouncillors;
39
+ private runMaster;
40
+ }
@@ -0,0 +1 @@
1
+ export { CouncilManager } from './council-manager';
@@ -2,7 +2,7 @@ export type { AutoUpdateCheckerOptions } from './auto-update-checker';
2
2
  export { createAutoUpdateCheckerHook } from './auto-update-checker';
3
3
  export { createChatHeadersHook } from './chat-headers';
4
4
  export { createDelegateTaskRetryHook } from './delegate-task-retry';
5
- export { ForegroundFallbackManager, isRateLimitError } from './foreground-fallback';
5
+ export { ForegroundFallbackManager, isRateLimitError, } from './foreground-fallback';
6
6
  export { createJsonErrorRecoveryHook } from './json-error-recovery';
7
7
  export { createPhaseReminderHook } from './phase-reminder';
8
- export { createPostReadNudgeHook } from './post-read-nudge';
8
+ export { createPostFileToolNudgeHook } from './post-file-tool-nudge';