oh-my-opencode-serverlocal 0.1.2 → 0.1.3

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.
@@ -1,7 +1,6 @@
1
1
  export { createAcpRunTool } from './acp-run';
2
2
  export { ast_grep_replace, ast_grep_search } from './ast-grep';
3
3
  export { createCancelTaskTool } from './cancel-task';
4
- export { createCouncilTool } from './council';
5
4
  export type { PresetManager } from './preset-manager';
6
5
  export { createPresetManager } from './preset-manager';
7
6
  export { createWebfetchTool } from './smartfetch';
package/dist/tui.js CHANGED
@@ -110,12 +110,10 @@ var SUBAGENT_NAMES = [
110
110
  "oracle",
111
111
  "designer",
112
112
  "fixer",
113
- "observer",
114
- "council",
115
- "councillor"
113
+ "observer"
116
114
  ];
117
115
  var ALL_AGENT_NAMES = ["orchestrator", ...SUBAGENT_NAMES];
118
- var PROTECTED_AGENTS = new Set(["orchestrator", "councillor"]);
116
+ var PROTECTED_AGENTS = new Set(["orchestrator"]);
119
117
  var DEFAULT_MODELS = {
120
118
  orchestrator: undefined,
121
119
  oracle: undefined,
@@ -123,9 +121,7 @@ var DEFAULT_MODELS = {
123
121
  explorer: undefined,
124
122
  designer: undefined,
125
123
  fixer: undefined,
126
- observer: undefined,
127
- council: undefined,
128
- councillor: undefined
124
+ observer: undefined
129
125
  };
130
126
  var POLL_INTERVAL_BACKGROUND_MS = 2000;
131
127
  var MAX_POLL_TIME_MS = 5 * 60 * 1000;
@@ -148,12 +144,6 @@ var READONLY_FILE_OPERATIONS_RULES = `**File Operations Rules**:
148
144
  - Prefer dedicated file tools for codebase inspection: glob/grep/ast_grep_search for discovery and read for file contents.
149
145
  - Bash is allowed for non-mutating diagnostics and shell-native inspection when it is the clearest tool, but not for modifying files.
150
146
  - Do not use cat/head/tail/sed/awk only to read code into context; use read/grep unless a shell pipeline is genuinely the better diagnostic.`;
151
- var NO_SHELL_READONLY_FILE_OPERATIONS_RULES = `**File Operations Rules**:
152
- - READ-ONLY: inspect and report; do not modify files.
153
- - Use glob/grep/ast_grep_search for discovery and read for file contents.
154
- - Do not use bash or shell commands.`;
155
- var TMUX_SPAWN_DELAY_MS = 500;
156
- var COUNCILLOR_STAGGER_MS = 250;
157
147
  var DEFAULT_DISABLED_AGENTS = ["observer"];
158
148
  var DEFAULT_MAX_SESSIONS_PER_AGENT = 2;
159
149
  var DEFAULT_READ_CONTEXT_MIN_LINES = 10;
@@ -198,96 +188,10 @@ function getOpenCodeConfigPaths() {
198
188
  const configDir = getConfigDir();
199
189
  return [join(configDir, "opencode.json"), join(configDir, "opencode.jsonc")];
200
190
  }
201
- // src/config/council-schema.ts
202
- import { z } from "zod";
203
-
204
- // src/utils/councillor-models.ts
205
- function normalizeCouncillorModels(model, fallbackVariant) {
206
- const raw = Array.isArray(model) ? model : [model];
207
- return raw.map((entry) => typeof entry === "string" ? { id: entry, variant: fallbackVariant } : { id: entry.id, variant: entry.variant ?? fallbackVariant });
208
- }
209
-
210
- // src/config/council-schema.ts
211
- var ModelIdSchema = z.string().regex(/^[^/\s]+\/[^\s]+$/, 'Expected provider/model format (e.g. "openai/gpt-5.6-luna")');
212
- var CouncillorModelEntrySchema = z.object({
213
- id: ModelIdSchema,
214
- variant: z.string().optional()
215
- });
216
- var CouncillorModelSchema = z.union([
217
- ModelIdSchema,
218
- z.array(z.union([ModelIdSchema, CouncillorModelEntrySchema])).min(1)
219
- ]).describe('Model ID in provider/model format (e.g. "openai/gpt-5.6-luna"), or an ' + "ordered fallback chain (array of model IDs or { id, variant } entries) " + "tried in order until one responds.");
220
- var CouncillorConfigSchema = z.object({
221
- model: CouncillorModelSchema,
222
- variant: z.string().optional(),
223
- prompt: z.string().optional().describe("Optional role/guidance injected into the councillor user prompt")
224
- }).transform((c) => {
225
- const models = normalizeCouncillorModels(c.model, c.variant);
226
- return {
227
- model: models[0].id,
228
- variant: c.variant,
229
- prompt: c.prompt,
230
- models
231
- };
232
- });
233
- var CouncilPresetSchema = z.record(z.string(), z.record(z.string(), z.unknown())).transform((entries, ctx) => {
234
- const councillors = {};
235
- for (const [key, raw] of Object.entries(entries)) {
236
- if (key === "master")
237
- continue;
238
- if (key === "councillors" && typeof raw === "object" && raw !== null) {
239
- for (const [innerKey, innerRaw] of Object.entries(raw)) {
240
- const innerParsed = CouncillorConfigSchema.safeParse(innerRaw);
241
- if (!innerParsed.success) {
242
- ctx.addIssue({
243
- code: z.ZodIssueCode.custom,
244
- message: `Invalid councillor "${innerKey}" (nested under legacy "councillors" key): ${innerParsed.error.issues.map((i) => i.message).join(", ")}`
245
- });
246
- return z.NEVER;
247
- }
248
- councillors[innerKey] = innerParsed.data;
249
- }
250
- continue;
251
- }
252
- const parsed = CouncillorConfigSchema.safeParse(raw);
253
- if (!parsed.success) {
254
- ctx.addIssue({
255
- code: z.ZodIssueCode.custom,
256
- message: `Invalid councillor "${key}": ${parsed.error.issues.map((i) => i.message).join(", ")}`
257
- });
258
- return z.NEVER;
259
- }
260
- councillors[key] = parsed.data;
261
- }
262
- return councillors;
263
- });
264
- var CouncillorExecutionModeSchema = z.enum(["parallel", "serial"]).default("parallel").describe('Execution mode for councillors. Use "serial" for single-model systems to avoid conflicts. ' + 'Use "parallel" for multi-model systems for faster execution.');
265
- var CouncilConfigSchema = z.object({
266
- presets: z.record(z.string(), CouncilPresetSchema),
267
- timeout: z.number().min(0).default(180000),
268
- default_preset: z.string().default("default"),
269
- councillor_execution_mode: CouncillorExecutionModeSchema.describe('Execution mode for councillors. "serial" runs them one at a time (required for single-model systems). "parallel" runs them concurrently (default, faster for multi-model systems).'),
270
- councillor_retries: z.number().int().min(0).max(5).default(3).describe("Number of retry attempts for councillors that return empty responses " + "(e.g. due to provider rate limiting). Default: 3 retries."),
271
- master: z.unknown().optional().describe("DEPRECATED - ignored. Council agent synthesizes directly.")
272
- }).transform((data) => {
273
- const deprecated = [];
274
- if (data.master !== undefined)
275
- deprecated.push("master");
276
- const legacyMasterModel = typeof data.master === "object" && data.master !== null && "model" in data.master && typeof data.master.model === "string" ? data.master.model : undefined;
277
- return {
278
- presets: data.presets,
279
- timeout: data.timeout,
280
- default_preset: data.default_preset,
281
- councillor_execution_mode: data.councillor_execution_mode,
282
- councillor_retries: data.councillor_retries,
283
- _deprecated: deprecated.length > 0 ? deprecated : undefined,
284
- _legacyMasterModel: legacyMasterModel
285
- };
286
- });
287
191
  // src/config/schema.ts
288
- import { z as z2 } from "zod";
289
- var ProviderModelIdSchema = z2.string().regex(/^[^/\s]+\/[^\s]+$/, "Expected provider/model format (provider/.../model)");
290
- var ManualAgentPlanSchema = z2.object({
192
+ import { z } from "zod";
193
+ var ProviderModelIdSchema = z.string().regex(/^[^/\s]+\/[^\s]+$/, "Expected provider/model format (provider/.../model)");
194
+ var ManualAgentPlanSchema = z.object({
291
195
  primary: ProviderModelIdSchema,
292
196
  fallback1: ProviderModelIdSchema,
293
197
  fallback2: ProviderModelIdSchema,
@@ -301,12 +205,12 @@ var ManualAgentPlanSchema = z2.object({
301
205
  ]);
302
206
  if (unique.size !== 4) {
303
207
  ctx.addIssue({
304
- code: z2.ZodIssueCode.custom,
208
+ code: z.ZodIssueCode.custom,
305
209
  message: "primary and fallbacks must be unique per agent"
306
210
  });
307
211
  }
308
212
  });
309
- var ManualPlanSchema = z2.object({
213
+ var ManualPlanSchema = z.object({
310
214
  orchestrator: ManualAgentPlanSchema,
311
215
  oracle: ManualAgentPlanSchema,
312
216
  designer: ManualAgentPlanSchema,
@@ -314,12 +218,12 @@ var ManualPlanSchema = z2.object({
314
218
  librarian: ManualAgentPlanSchema,
315
219
  fixer: ManualAgentPlanSchema
316
220
  }).strict();
317
- var PermissionActionSchema = z2.enum(["ask", "allow", "deny"]);
318
- var PermissionRuleSchema = z2.union([
221
+ var PermissionActionSchema = z.enum(["ask", "allow", "deny"]);
222
+ var PermissionRuleSchema = z.union([
319
223
  PermissionActionSchema,
320
- z2.record(z2.string(), PermissionActionSchema)
224
+ z.record(z.string(), PermissionActionSchema)
321
225
  ]);
322
- var PermissionObjectSchema = z2.object({
226
+ var PermissionObjectSchema = z.object({
323
227
  read: PermissionRuleSchema.optional(),
324
228
  edit: PermissionRuleSchema.optional(),
325
229
  glob: PermissionRuleSchema.optional(),
@@ -337,32 +241,32 @@ var PermissionObjectSchema = z2.object({
337
241
  codesearch: PermissionActionSchema.optional(),
338
242
  doom_loop: PermissionActionSchema.optional()
339
243
  }).catchall(PermissionRuleSchema);
340
- var PermissionConfigSchema = z2.union([
244
+ var PermissionConfigSchema = z.union([
341
245
  PermissionActionSchema,
342
246
  PermissionObjectSchema
343
247
  ]);
344
- var AgentOverrideConfigSchema = z2.object({
345
- model: z2.union([
346
- z2.string(),
347
- z2.array(z2.union([
348
- z2.string(),
349
- z2.object({
350
- id: z2.string(),
351
- variant: z2.string().optional()
248
+ var AgentOverrideConfigSchema = z.object({
249
+ model: z.union([
250
+ z.string(),
251
+ z.array(z.union([
252
+ z.string(),
253
+ z.object({
254
+ id: z.string(),
255
+ variant: z.string().optional()
352
256
  })
353
257
  ])).min(1)
354
258
  ]).optional(),
355
- temperature: z2.number().min(0).max(2).optional(),
356
- variant: z2.string().optional().catch(undefined),
357
- skills: z2.array(z2.string()).optional(),
358
- mcps: z2.array(z2.string()).optional(),
359
- prompt: z2.string().min(1).optional(),
360
- orchestratorPrompt: z2.string().min(1).optional(),
361
- options: z2.record(z2.string(), z2.unknown()).optional(),
362
- displayName: z2.string().min(1).optional(),
259
+ temperature: z.number().min(0).max(2).optional(),
260
+ variant: z.string().optional().catch(undefined),
261
+ skills: z.array(z.string()).optional(),
262
+ mcps: z.array(z.string()).optional(),
263
+ prompt: z.string().min(1).optional(),
264
+ orchestratorPrompt: z.string().min(1).optional(),
265
+ options: z.record(z.string(), z.unknown()).optional(),
266
+ displayName: z.string().min(1).optional(),
363
267
  permission: PermissionConfigSchema.optional()
364
268
  }).strict();
365
- var MultiplexerTypeSchema = z2.enum([
269
+ var MultiplexerTypeSchema = z.enum([
366
270
  "auto",
367
271
  "tmux",
368
272
  "zellij",
@@ -370,107 +274,106 @@ var MultiplexerTypeSchema = z2.enum([
370
274
  "cmux",
371
275
  "none"
372
276
  ]);
373
- var MultiplexerLayoutSchema = z2.enum([
277
+ var MultiplexerLayoutSchema = z.enum([
374
278
  "main-horizontal",
375
279
  "main-vertical",
376
280
  "tiled",
377
281
  "even-horizontal",
378
282
  "even-vertical"
379
283
  ]);
380
- var ZellijPaneModeSchema = z2.enum(["agent-tab", "current-tab"]);
284
+ var ZellijPaneModeSchema = z.enum(["agent-tab", "current-tab"]);
381
285
  var TmuxLayoutSchema = MultiplexerLayoutSchema;
382
- var MultiplexerConfigSchema = z2.object({
286
+ var MultiplexerConfigSchema = z.object({
383
287
  type: MultiplexerTypeSchema.default("none"),
384
288
  layout: MultiplexerLayoutSchema.default("main-vertical"),
385
- main_pane_size: z2.number().min(20).max(80).default(60),
289
+ main_pane_size: z.number().min(20).max(80).default(60),
386
290
  zellij_pane_mode: ZellijPaneModeSchema.default("agent-tab")
387
291
  });
388
- var TmuxConfigSchema = z2.object({
389
- enabled: z2.boolean().default(false),
292
+ var TmuxConfigSchema = z.object({
293
+ enabled: z.boolean().default(false),
390
294
  layout: TmuxLayoutSchema.default("main-vertical"),
391
- main_pane_size: z2.number().min(20).max(80).default(60)
295
+ main_pane_size: z.number().min(20).max(80).default(60)
392
296
  });
393
- var PresetSchema = z2.record(z2.string(), AgentOverrideConfigSchema);
394
- var WebsearchConfigSchema = z2.object({
395
- provider: z2.enum(["exa", "tavily"]).default("exa")
297
+ var PresetSchema = z.record(z.string(), AgentOverrideConfigSchema);
298
+ var WebsearchConfigSchema = z.object({
299
+ provider: z.enum(["exa", "tavily"]).default("exa")
396
300
  });
397
- var McpNameSchema = z2.enum(["websearch", "context7", "gh_grep"]);
398
- var InterviewConfigSchema = z2.object({
399
- maxQuestions: z2.number().int().min(1).max(10).default(2),
400
- outputFolder: z2.string().min(1).default("interview"),
401
- autoOpenBrowser: z2.boolean().default(true).describe("Automatically open the interview UI in your default browser during interactive runs. Disabled automatically in tests and CI."),
402
- port: z2.number().int().min(0).max(65535).default(0),
403
- dashboard: z2.boolean().default(false)
301
+ var McpNameSchema = z.enum(["websearch", "context7", "gh_grep"]);
302
+ var InterviewConfigSchema = z.object({
303
+ maxQuestions: z.number().int().min(1).max(10).default(2),
304
+ outputFolder: z.string().min(1).default("interview"),
305
+ autoOpenBrowser: z.boolean().default(true).describe("Automatically open the interview UI in your default browser during interactive runs. Disabled automatically in tests and CI."),
306
+ port: z.number().int().min(0).max(65535).default(0),
307
+ dashboard: z.boolean().default(false)
404
308
  });
405
- var BackgroundJobsConfigSchema = z2.object({
406
- maxSessionsPerAgent: z2.number().int().min(1).max(10).default(2),
407
- readContextMinLines: z2.number().int().min(0).max(1000).default(10),
408
- readContextMaxFiles: z2.number().int().min(0).max(50).default(8)
309
+ var BackgroundJobsConfigSchema = z.object({
310
+ maxSessionsPerAgent: z.number().int().min(1).max(10).default(2),
311
+ readContextMinLines: z.number().int().min(0).max(1000).default(10),
312
+ readContextMaxFiles: z.number().int().min(0).max(50).default(8)
409
313
  });
410
- var FailoverConfigSchema = z2.object({
411
- enabled: z2.boolean().default(true),
412
- timeoutMs: z2.number().min(0).default(15000),
413
- retryDelayMs: z2.number().min(0).default(500),
414
- maxRetries: z2.number().int().min(0).default(3).describe("Number of consecutive 429/rate-limit responses tolerated on the " + "same model before aborting (or swapping to the next fallback " + "model when a chain is configured)."),
415
- retry_on_empty: z2.boolean().default(true).describe("When true (default), empty provider responses are treated as failures, " + "triggering fallback/retry. Set to false to treat them as successes."),
416
- runtimeOverride: z2.boolean().optional().describe("DEPRECATED: no longer used. Previously controlled whether out-of-chain " + "runtime model picks triggered fallback. Fallback is now always " + "disabled when a user explicitly selects a model via /model.")
314
+ var FailoverConfigSchema = z.object({
315
+ enabled: z.boolean().default(true),
316
+ timeoutMs: z.number().min(0).default(15000),
317
+ retryDelayMs: z.number().min(0).default(500),
318
+ maxRetries: z.number().int().min(0).default(3).describe("Number of consecutive 429/rate-limit responses tolerated on the " + "same model before aborting (or swapping to the next fallback " + "model when a chain is configured)."),
319
+ retry_on_empty: z.boolean().default(true).describe("When true (default), empty provider responses are treated as failures, " + "triggering fallback/retry. Set to false to treat them as successes."),
320
+ runtimeOverride: z.boolean().optional().describe("DEPRECATED: no longer used. Previously controlled whether out-of-chain " + "runtime model picks triggered fallback. Fallback is now always " + "disabled when a user explicitly selects a model via /model.")
417
321
  }).strict();
418
- var CompanionConfigSchema = z2.object({
419
- enabled: z2.boolean().optional(),
420
- binaryPath: z2.string().min(1).optional().describe("Path to a custom companion binary to launch."),
421
- position: z2.enum(["bottom-right", "bottom-left", "top-right", "top-left"]).optional(),
422
- size: z2.enum(["small", "medium", "large"]).optional(),
423
- gifPack: z2.enum(["default"]).optional().describe("Bundled companion animation pack to use."),
424
- loopStyle: z2.enum(["classic", "smooth"]).optional().describe("Companion animation playback style: classic loops or smooth ping-pong playback."),
425
- speed: z2.number().min(0.25).max(4).optional().describe("Companion animation playback speed multiplier. Defaults to 1."),
426
- debug: z2.boolean().optional().describe("Enable verbose native companion debug logs.")
322
+ var CompanionConfigSchema = z.object({
323
+ enabled: z.boolean().optional(),
324
+ binaryPath: z.string().min(1).optional().describe("Path to a custom companion binary to launch."),
325
+ position: z.enum(["bottom-right", "bottom-left", "top-right", "top-left"]).optional(),
326
+ size: z.enum(["small", "medium", "large"]).optional(),
327
+ gifPack: z.enum(["default"]).optional().describe("Bundled companion animation pack to use."),
328
+ loopStyle: z.enum(["classic", "smooth"]).optional().describe("Companion animation playback style: classic loops or smooth ping-pong playback."),
329
+ speed: z.number().min(0.25).max(4).optional().describe("Companion animation playback speed multiplier. Defaults to 1."),
330
+ debug: z.boolean().optional().describe("Enable verbose native companion debug logs.")
427
331
  });
428
- var AcpAgentPermissionModeSchema = z2.enum(["ask", "allow", "reject"]);
332
+ var AcpAgentPermissionModeSchema = z.enum(["ask", "allow", "reject"]);
429
333
  var MAX_ACP_TIMEOUT_MS = 2147483647;
430
- var AcpAgentConfigSchema = z2.object({
431
- command: z2.string().min(1),
432
- args: z2.array(z2.string()).default([]),
433
- env: z2.record(z2.string(), z2.string()).default({}),
434
- cwd: z2.string().min(1).optional(),
435
- description: z2.string().min(1).optional(),
436
- prompt: z2.string().min(1).optional(),
437
- orchestratorPrompt: z2.string().min(1).optional(),
334
+ var AcpAgentConfigSchema = z.object({
335
+ command: z.string().min(1),
336
+ args: z.array(z.string()).default([]),
337
+ env: z.record(z.string(), z.string()).default({}),
338
+ cwd: z.string().min(1).optional(),
339
+ description: z.string().min(1).optional(),
340
+ prompt: z.string().min(1).optional(),
341
+ orchestratorPrompt: z.string().min(1).optional(),
438
342
  wrapperModel: ProviderModelIdSchema.optional(),
439
- timeoutMs: z2.number().int().min(0).max(MAX_ACP_TIMEOUT_MS).default(0).describe("Timeout for a single ACP run in milliseconds. Set to 0 to disable the timeout."),
343
+ timeoutMs: z.number().int().min(0).max(MAX_ACP_TIMEOUT_MS).default(0).describe("Timeout for a single ACP run in milliseconds. Set to 0 to disable the timeout."),
440
344
  permissionMode: AcpAgentPermissionModeSchema.default("ask")
441
345
  }).strict();
442
- var AcpAgentsConfigSchema = z2.record(z2.string(), AcpAgentConfigSchema);
346
+ var AcpAgentsConfigSchema = z.record(z.string(), AcpAgentConfigSchema);
443
347
  function rejectOrchestratorPromptOnOrchestrator(overrides, ctx, pathPrefix) {
444
348
  for (const [name, override] of Object.entries(overrides)) {
445
349
  if (name === "orchestrator" && override.orchestratorPrompt !== undefined) {
446
350
  ctx.addIssue({
447
- code: z2.ZodIssueCode.custom,
351
+ code: z.ZodIssueCode.custom,
448
352
  path: [...pathPrefix, name, "orchestratorPrompt"],
449
353
  message: "orchestratorPrompt is not supported for the orchestrator agent"
450
354
  });
451
355
  }
452
356
  }
453
357
  }
454
- var PluginConfigSchema = z2.object({
455
- preset: z2.string().optional(),
456
- setDefaultAgent: z2.boolean().optional(),
457
- compactSidebar: z2.boolean().optional().describe("Use the compact TUI sidebar layout. Defaults to true; set false to use the expanded layout."),
458
- stripOrchestratorModel: z2.boolean().optional().describe("When true, omit orchestrator.model and orchestrator.variant from the SDK config so OpenCode uses the session model selected with /model after subagent dispatch. An explicitly selected preset that sets orchestrator.model is preserved. Defaults to false."),
459
- autoUpdate: z2.boolean().optional().describe("Disable automatic installation of plugin updates when false. Defaults to true."),
460
- presets: z2.record(z2.string(), PresetSchema).optional(),
461
- agents: z2.record(z2.string(), AgentOverrideConfigSchema).optional(),
462
- disabled_agents: z2.array(z2.string()).optional().describe("Agent names to disable completely. " + "Disabled agents are not instantiated and cannot be delegated to. " + "Orchestrator and council internal agents (councillor) cannot be disabled. " + "By default, 'observer' is disabled. Remove it from this list and configure a vision-capable model to enable."),
463
- image_routing: z2.enum(["auto", "direct"]).optional().describe("How image attachments are handled. " + "When omitted, preserves legacy conditional behavior: intercept " + 'attachments only when observer is enabled. "auto": requires ' + "observer to be enabled and saves attachments to disk before " + 'nudging delegation to @observer. "direct": always passes ' + "attachments to the orchestrator untouched."),
464
- disabled_mcps: z2.array(z2.string()).optional().describe("MCP server names to disable completely. Disabled servers are not " + "started and cannot be used by agents."),
465
- disabled_tools: z2.array(z2.string()).optional().describe("Tool names to disable completely. Disabled tools are not registered with OpenCode and cannot be used by agents."),
466
- disabled_skills: z2.array(z2.string()).optional().describe("Skill names to disable completely. Disabled skills are not granted to agents, even when referenced by presets or agent overrides."),
358
+ var PluginConfigSchema = z.object({
359
+ preset: z.string().optional(),
360
+ setDefaultAgent: z.boolean().optional(),
361
+ compactSidebar: z.boolean().optional().describe("Use the compact TUI sidebar layout. Defaults to true; set false to use the expanded layout."),
362
+ stripOrchestratorModel: z.boolean().optional().describe("When true, omit orchestrator.model and orchestrator.variant from the SDK config so OpenCode uses the session model selected with /model after subagent dispatch. An explicitly selected preset that sets orchestrator.model is preserved. Defaults to false."),
363
+ autoUpdate: z.boolean().optional().describe("Disable automatic installation of plugin updates when false. Defaults to true."),
364
+ presets: z.record(z.string(), PresetSchema).optional(),
365
+ agents: z.record(z.string(), AgentOverrideConfigSchema).optional(),
366
+ disabled_agents: z.array(z.string()).optional().describe("Agent names to disable completely. " + "Disabled agents are not instantiated and cannot be delegated to. " + "Orchestrator cannot be disabled. " + "By default, 'observer' is disabled. Remove it from this list and configure a vision-capable model to enable."),
367
+ image_routing: z.enum(["auto", "direct"]).optional().describe("How image attachments are handled. " + "When omitted, preserves legacy conditional behavior: intercept " + 'attachments only when observer is enabled. "auto": requires ' + "observer to be enabled and saves attachments to disk before " + 'nudging delegation to @observer. "direct": always passes ' + "attachments to the orchestrator untouched."),
368
+ disabled_mcps: z.array(z.string()).optional().describe("MCP server names to disable completely. Disabled servers are not " + "started and cannot be used by agents."),
369
+ disabled_tools: z.array(z.string()).optional().describe("Tool names to disable completely. Disabled tools are not registered with OpenCode and cannot be used by agents."),
370
+ disabled_skills: z.array(z.string()).optional().describe("Skill names to disable completely. Disabled skills are not granted to agents, even when referenced by presets or agent overrides."),
467
371
  multiplexer: MultiplexerConfigSchema.optional(),
468
372
  tmux: TmuxConfigSchema.optional(),
469
373
  websearch: WebsearchConfigSchema.optional(),
470
374
  interview: InterviewConfigSchema.optional(),
471
375
  backgroundJobs: BackgroundJobsConfigSchema.optional(),
472
376
  fallback: FailoverConfigSchema.optional(),
473
- council: CouncilConfigSchema.optional(),
474
377
  companion: CompanionConfigSchema.optional(),
475
378
  acpAgents: AcpAgentsConfigSchema.optional()
476
379
  }).superRefine((value, ctx) => {
@@ -511,9 +414,7 @@ var DEFAULT_AGENT_MCPS = {
511
414
  librarian: ["websearch", "context7", "gh_grep"],
512
415
  explorer: [],
513
416
  fixer: [],
514
- observer: [],
515
- council: [],
516
- councillor: []
417
+ observer: []
517
418
  };
518
419
  function parseList(items, allAvailable) {
519
420
  if (!items || items.length === 0) {
@@ -702,7 +603,6 @@ function mergePluginConfigs(base, override) {
702
603
  interview: deepMerge(base.interview, override.interview),
703
604
  backgroundJobs: deepMerge(base.backgroundJobs, override.backgroundJobs),
704
605
  fallback: deepMerge(base.fallback, override.fallback),
705
- council: deepMerge(base.council, override.council),
706
606
  acpAgents: deepMerge(base.acpAgents, override.acpAgents),
707
607
  companion: deepMerge(base.companion, override.companion)
708
608
  };
@@ -926,7 +826,7 @@ function isPluginDisabledByEnv(env = process.env) {
926
826
  // src/tui.ts
927
827
  var PLUGIN_NAME = "oh-my-opencode-serverlocal";
928
828
  var CONFIG_WARNING_COLOR = "orange";
929
- var FALLBACK_SIDEBAR_AGENTS = SUBAGENT_NAMES.filter((agent) => agent !== "councillor" && agent !== "council" && !DEFAULT_DISABLED_AGENTS.includes(agent));
829
+ var FALLBACK_SIDEBAR_AGENTS = SUBAGENT_NAMES.filter((agent) => !DEFAULT_DISABLED_AGENTS.includes(agent));
930
830
  var BORDER = { type: "single" };
931
831
  async function readPackageVersion() {
932
832
  try {
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Shared session utilities for council and background managers.
2
+ * Shared session utilities for background managers.
3
3
  */
4
4
  import type { PluginInput } from '@opencode-ai/plugin';
5
5
  type OpencodeClient = PluginInput['client'];
@@ -2,8 +2,8 @@
2
2
  * Tracks subagent spawn depth to prevent excessive nesting.
3
3
  *
4
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)
5
+ * Depth 1 = agent spawned by root (e.g., explorer, librarian)
6
+ * Depth 2 = agent spawned by depth-1 agent (e.g., explorer spawning another subagent)
7
7
  * Depth 3 = agent spawned by depth-2 agent (max depth by default)
8
8
  *
9
9
  * When max depth is exceeded, the spawn is blocked.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oh-my-opencode-serverlocal",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "Custom serverlocal fork of oh-my-opencode-slim — fully owned, custom prompts + commands, dist synced via opencode-dotfiles",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -1,27 +0,0 @@
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
- * Format councillor results for the council agent to synthesize.
15
- *
16
- * Formats councillor results as structured data that the council agent
17
- * (which called the tool) will receive as the tool response. The council
18
- * agent's system prompt contains synthesis instructions.
19
- * Returns a special message when all councillors failed to produce output.
20
- */
21
- export declare function formatCouncillorResults(originalPrompt: string, councillorResults: Array<{
22
- name: string;
23
- model: string;
24
- status: string;
25
- result?: string;
26
- error?: string;
27
- }>): string;
@@ -1,2 +0,0 @@
1
- import { type AgentDefinition } from './orchestrator';
2
- export declare function createCouncillorAgent(model: string, customPrompt?: string, customAppendPrompt?: string): AgentDefinition;
@@ -1,137 +0,0 @@
1
- import { z } from 'zod';
2
- import { type CouncillorModelEntry } from '../utils/councillor-models';
3
- export type { CouncillorModelEntry };
4
- /**
5
- * Configuration for a single councillor within a preset.
6
- * Each councillor is an independent LLM that processes the same prompt.
7
- *
8
- * Councillors run as agent sessions with read-only codebase access
9
- * (read, glob, grep, lsp, list). They can examine the codebase but
10
- * cannot modify files or spawn subagents.
11
- *
12
- * `model` accepts a single ID or an ordered fallback chain. The parsed config
13
- * exposes `models` (the normalized chain) plus `model` (the primary, for
14
- * backward compatibility).
15
- */
16
- export declare const CouncillorConfigSchema: z.ZodPipe<z.ZodObject<{
17
- model: z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
18
- id: z.ZodString;
19
- variant: z.ZodOptional<z.ZodString>;
20
- }, z.core.$strip>]>>]>;
21
- variant: z.ZodOptional<z.ZodString>;
22
- prompt: z.ZodOptional<z.ZodString>;
23
- }, z.core.$strip>, z.ZodTransform<{
24
- model: string;
25
- variant: string | undefined;
26
- prompt: string | undefined;
27
- models: CouncillorModelEntry[];
28
- }, {
29
- model: string | (string | {
30
- id: string;
31
- variant?: string | undefined;
32
- })[];
33
- variant?: string | undefined;
34
- prompt?: string | undefined;
35
- }>>;
36
- export type CouncillorConfig = z.infer<typeof CouncillorConfigSchema>;
37
- /**
38
- * A named preset grouping several councillors.
39
- *
40
- * All keys are treated as councillor names mapping to councillor configs.
41
- * The reserved key `"master"` is silently ignored (legacy from when
42
- * council-master was a separate agent).
43
- */
44
- export declare const CouncilPresetSchema: z.ZodPipe<z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodUnknown>>, z.ZodTransform<Record<string, {
45
- model: string;
46
- variant: string | undefined;
47
- prompt: string | undefined;
48
- models: CouncillorModelEntry[];
49
- }>, Record<string, Record<string, unknown>>>>;
50
- export type CouncilPreset = z.infer<typeof CouncilPresetSchema>;
51
- /**
52
- * Execution mode for councillors.
53
- * - parallel: Run all councillors concurrently (default, fastest for multi-model systems)
54
- * - serial: Run councillors one at a time (required for single-model systems to avoid conflicts)
55
- */
56
- export declare const CouncillorExecutionModeSchema: z.ZodDefault<z.ZodEnum<{
57
- parallel: "parallel";
58
- serial: "serial";
59
- }>>;
60
- /**
61
- * Top-level council configuration.
62
- *
63
- * Example JSONC:
64
- * ```jsonc
65
- * {
66
- * "council": {
67
- * "presets": {
68
- * "default": {
69
- * "alpha": { "model": "openai/gpt-5.6-luna" },
70
- * "beta": { "model": "openai/gpt-5.3-codex" },
71
- * "gamma": { "model": "google/gemini-3-pro" }
72
- * }
73
- * },
74
- * "timeout": 180000,
75
- * "councillor_execution_mode": "serial"
76
- * }
77
- * }
78
- * ```
79
- */
80
- export declare const CouncilConfigSchema: z.ZodPipe<z.ZodObject<{
81
- presets: z.ZodRecord<z.ZodString, z.ZodPipe<z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodUnknown>>, z.ZodTransform<Record<string, {
82
- model: string;
83
- variant: string | undefined;
84
- prompt: string | undefined;
85
- models: CouncillorModelEntry[];
86
- }>, Record<string, Record<string, unknown>>>>>;
87
- timeout: z.ZodDefault<z.ZodNumber>;
88
- default_preset: z.ZodDefault<z.ZodString>;
89
- councillor_execution_mode: z.ZodDefault<z.ZodEnum<{
90
- parallel: "parallel";
91
- serial: "serial";
92
- }>>;
93
- councillor_retries: z.ZodDefault<z.ZodNumber>;
94
- master: z.ZodOptional<z.ZodUnknown>;
95
- }, z.core.$strip>, z.ZodTransform<{
96
- presets: Record<string, Record<string, {
97
- model: string;
98
- variant: string | undefined;
99
- prompt: string | undefined;
100
- models: CouncillorModelEntry[];
101
- }>>;
102
- timeout: number;
103
- default_preset: string;
104
- councillor_execution_mode: "parallel" | "serial";
105
- councillor_retries: number;
106
- _deprecated: string[] | undefined;
107
- _legacyMasterModel: string | undefined;
108
- }, {
109
- presets: Record<string, Record<string, {
110
- model: string;
111
- variant: string | undefined;
112
- prompt: string | undefined;
113
- models: CouncillorModelEntry[];
114
- }>>;
115
- timeout: number;
116
- default_preset: string;
117
- councillor_execution_mode: "parallel" | "serial";
118
- councillor_retries: number;
119
- master?: unknown;
120
- }>>;
121
- export type CouncilConfig = z.infer<typeof CouncilConfigSchema>;
122
- export type CouncillorExecutionMode = z.infer<typeof CouncillorExecutionModeSchema>;
123
- /**
124
- * Result of a council session.
125
- */
126
- export interface CouncilResult {
127
- success: boolean;
128
- result?: string;
129
- error?: string;
130
- councillorResults: Array<{
131
- name: string;
132
- model: string;
133
- status: 'completed' | 'failed' | 'timed_out';
134
- result?: string;
135
- error?: string;
136
- }>;
137
- }