refactor: wave 2 - split atlas, auto-update-checker, session-recovery, todo-enforcer, background-task hooks
- Extract atlas/ into 15 focused modules (hook, event handler, tool policies, types, etc.) - Split auto-update-checker into checker/ and hook/ subdirectories with single-purpose files - Decompose session-recovery into separate recovery strategy files per error type - Extract todo-continuation-enforcer from monolith to directory with dedicated modules - Split background-task/tools.ts into individual tool creator files - Extract command-executor, tmux-utils into focused sub-modules - Split config/schema.ts into domain-specific schema files - Decompose cli/config-manager.ts into focused modules - Rollback skill-mcp-manager, model-availability, index.ts splits that broke tests - Fix all import path depths for moved files (../../ -> ../../../) - Add explicit type annotations to resolve TS7006 implicit any errors Typecheck: 0 errors Tests: 2359 pass, 5 fail (all pre-existing)
This commit is contained in:
+21
-462
@@ -1,464 +1,23 @@
|
||||
import { z } from "zod"
|
||||
import { AnyMcpNameSchema, McpNameSchema } from "../mcp/types"
|
||||
|
||||
const PermissionValue = z.enum(["ask", "allow", "deny"])
|
||||
|
||||
const BashPermission = z.union([
|
||||
PermissionValue,
|
||||
z.record(z.string(), PermissionValue),
|
||||
])
|
||||
|
||||
const AgentPermissionSchema = z.object({
|
||||
edit: PermissionValue.optional(),
|
||||
bash: BashPermission.optional(),
|
||||
webfetch: PermissionValue.optional(),
|
||||
task: PermissionValue.optional(),
|
||||
doom_loop: PermissionValue.optional(),
|
||||
external_directory: PermissionValue.optional(),
|
||||
})
|
||||
|
||||
export const BuiltinAgentNameSchema = z.enum([
|
||||
"sisyphus",
|
||||
"hephaestus",
|
||||
"prometheus",
|
||||
"oracle",
|
||||
"librarian",
|
||||
"explore",
|
||||
"multimodal-looker",
|
||||
"metis",
|
||||
"momus",
|
||||
"atlas",
|
||||
])
|
||||
|
||||
export const BuiltinSkillNameSchema = z.enum([
|
||||
"playwright",
|
||||
"agent-browser",
|
||||
"dev-browser",
|
||||
"frontend-ui-ux",
|
||||
"git-master",
|
||||
])
|
||||
|
||||
export const OverridableAgentNameSchema = z.enum([
|
||||
"build",
|
||||
"plan",
|
||||
"sisyphus",
|
||||
"hephaestus",
|
||||
"sisyphus-junior",
|
||||
"OpenCode-Builder",
|
||||
"prometheus",
|
||||
"metis",
|
||||
"momus",
|
||||
"oracle",
|
||||
"librarian",
|
||||
"explore",
|
||||
"multimodal-looker",
|
||||
"atlas",
|
||||
])
|
||||
|
||||
export const AgentNameSchema = BuiltinAgentNameSchema
|
||||
|
||||
export const HookNameSchema = z.enum([
|
||||
"todo-continuation-enforcer",
|
||||
"context-window-monitor",
|
||||
"session-recovery",
|
||||
"session-notification",
|
||||
"comment-checker",
|
||||
"grep-output-truncator",
|
||||
"tool-output-truncator",
|
||||
"question-label-truncator",
|
||||
"directory-agents-injector",
|
||||
"directory-readme-injector",
|
||||
"empty-task-response-detector",
|
||||
"think-mode",
|
||||
"subagent-question-blocker",
|
||||
"anthropic-context-window-limit-recovery",
|
||||
"preemptive-compaction",
|
||||
"rules-injector",
|
||||
"background-notification",
|
||||
"auto-update-checker",
|
||||
"startup-toast",
|
||||
"keyword-detector",
|
||||
"agent-usage-reminder",
|
||||
"non-interactive-env",
|
||||
"interactive-bash-session",
|
||||
|
||||
"thinking-block-validator",
|
||||
"ralph-loop",
|
||||
"category-skill-reminder",
|
||||
|
||||
"compaction-context-injector",
|
||||
"compaction-todo-preserver",
|
||||
"claude-code-hooks",
|
||||
"auto-slash-command",
|
||||
"edit-error-recovery",
|
||||
"delegate-task-retry",
|
||||
"prometheus-md-only",
|
||||
"sisyphus-junior-notepad",
|
||||
"start-work",
|
||||
"atlas",
|
||||
"unstable-agent-babysitter",
|
||||
"task-reminder",
|
||||
"task-resume-info",
|
||||
"stop-continuation-guard",
|
||||
"tasks-todowrite-disabler",
|
||||
"write-existing-file-guard",
|
||||
"anthropic-effort",
|
||||
])
|
||||
|
||||
export const BuiltinCommandNameSchema = z.enum([
|
||||
"init-deep",
|
||||
"ralph-loop",
|
||||
"ulw-loop",
|
||||
"cancel-ralph",
|
||||
"refactor",
|
||||
"start-work",
|
||||
"stop-continuation",
|
||||
])
|
||||
|
||||
export const AgentOverrideConfigSchema = z.object({
|
||||
/** @deprecated Use `category` instead. Model is inherited from category defaults. */
|
||||
model: z.string().optional(),
|
||||
variant: z.string().optional(),
|
||||
/** Category name to inherit model and other settings from CategoryConfig */
|
||||
category: z.string().optional(),
|
||||
/** Skill names to inject into agent prompt */
|
||||
skills: z.array(z.string()).optional(),
|
||||
temperature: z.number().min(0).max(2).optional(),
|
||||
top_p: z.number().min(0).max(1).optional(),
|
||||
prompt: z.string().optional(),
|
||||
prompt_append: z.string().optional(),
|
||||
tools: z.record(z.string(), z.boolean()).optional(),
|
||||
disable: z.boolean().optional(),
|
||||
description: z.string().optional(),
|
||||
mode: z.enum(["subagent", "primary", "all"]).optional(),
|
||||
color: z
|
||||
.string()
|
||||
.regex(/^#[0-9A-Fa-f]{6}$/)
|
||||
.optional(),
|
||||
permission: AgentPermissionSchema.optional(),
|
||||
/** Maximum tokens for response. Passed directly to OpenCode SDK. */
|
||||
maxTokens: z.number().optional(),
|
||||
/** Extended thinking configuration (Anthropic). Overrides category and default settings. */
|
||||
thinking: z.object({
|
||||
type: z.enum(["enabled", "disabled"]),
|
||||
budgetTokens: z.number().optional(),
|
||||
}).optional(),
|
||||
/** Reasoning effort level (OpenAI). Overrides category and default settings. */
|
||||
reasoningEffort: z.enum(["low", "medium", "high", "xhigh"]).optional(),
|
||||
/** Text verbosity level. */
|
||||
textVerbosity: z.enum(["low", "medium", "high"]).optional(),
|
||||
/** Provider-specific options. Passed directly to OpenCode SDK. */
|
||||
providerOptions: z.record(z.string(), z.unknown()).optional(),
|
||||
})
|
||||
|
||||
export const AgentOverridesSchema = z.object({
|
||||
build: AgentOverrideConfigSchema.optional(),
|
||||
plan: AgentOverrideConfigSchema.optional(),
|
||||
sisyphus: AgentOverrideConfigSchema.optional(),
|
||||
hephaestus: AgentOverrideConfigSchema.optional(),
|
||||
"sisyphus-junior": AgentOverrideConfigSchema.optional(),
|
||||
"OpenCode-Builder": AgentOverrideConfigSchema.optional(),
|
||||
prometheus: AgentOverrideConfigSchema.optional(),
|
||||
metis: AgentOverrideConfigSchema.optional(),
|
||||
momus: AgentOverrideConfigSchema.optional(),
|
||||
oracle: AgentOverrideConfigSchema.optional(),
|
||||
librarian: AgentOverrideConfigSchema.optional(),
|
||||
explore: AgentOverrideConfigSchema.optional(),
|
||||
"multimodal-looker": AgentOverrideConfigSchema.optional(),
|
||||
atlas: AgentOverrideConfigSchema.optional(),
|
||||
})
|
||||
|
||||
export const ClaudeCodeConfigSchema = z.object({
|
||||
mcp: z.boolean().optional(),
|
||||
commands: z.boolean().optional(),
|
||||
skills: z.boolean().optional(),
|
||||
agents: z.boolean().optional(),
|
||||
hooks: z.boolean().optional(),
|
||||
plugins: z.boolean().optional(),
|
||||
plugins_override: z.record(z.string(), z.boolean()).optional(),
|
||||
})
|
||||
|
||||
export const SisyphusAgentConfigSchema = z.object({
|
||||
disabled: z.boolean().optional(),
|
||||
default_builder_enabled: z.boolean().optional(),
|
||||
planner_enabled: z.boolean().optional(),
|
||||
replace_plan: z.boolean().optional(),
|
||||
})
|
||||
|
||||
export const CategoryConfigSchema = z.object({
|
||||
/** Human-readable description of the category's purpose. Shown in task prompt. */
|
||||
description: z.string().optional(),
|
||||
model: z.string().optional(),
|
||||
variant: z.string().optional(),
|
||||
temperature: z.number().min(0).max(2).optional(),
|
||||
top_p: z.number().min(0).max(1).optional(),
|
||||
maxTokens: z.number().optional(),
|
||||
thinking: z.object({
|
||||
type: z.enum(["enabled", "disabled"]),
|
||||
budgetTokens: z.number().optional(),
|
||||
}).optional(),
|
||||
reasoningEffort: z.enum(["low", "medium", "high", "xhigh"]).optional(),
|
||||
textVerbosity: z.enum(["low", "medium", "high"]).optional(),
|
||||
tools: z.record(z.string(), z.boolean()).optional(),
|
||||
prompt_append: z.string().optional(),
|
||||
/** Mark agent as unstable - forces background mode for monitoring. Auto-enabled for gemini/minimax models. */
|
||||
is_unstable_agent: z.boolean().optional(),
|
||||
})
|
||||
|
||||
export const BuiltinCategoryNameSchema = z.enum([
|
||||
"visual-engineering",
|
||||
"ultrabrain",
|
||||
"deep",
|
||||
"artistry",
|
||||
"quick",
|
||||
"unspecified-low",
|
||||
"unspecified-high",
|
||||
"writing",
|
||||
])
|
||||
|
||||
export const CategoriesConfigSchema = z.record(z.string(), CategoryConfigSchema)
|
||||
|
||||
export const CommentCheckerConfigSchema = z.object({
|
||||
/** Custom prompt to replace the default warning message. Use {{comments}} placeholder for detected comments XML. */
|
||||
custom_prompt: z.string().optional(),
|
||||
})
|
||||
|
||||
export const DynamicContextPruningConfigSchema = z.object({
|
||||
/** Enable dynamic context pruning (default: false) */
|
||||
enabled: z.boolean().default(false),
|
||||
/** Notification level: off, minimal, or detailed (default: detailed) */
|
||||
notification: z.enum(["off", "minimal", "detailed"]).default("detailed"),
|
||||
/** Turn protection - prevent pruning recent tool outputs */
|
||||
turn_protection: z.object({
|
||||
enabled: z.boolean().default(true),
|
||||
turns: z.number().min(1).max(10).default(3),
|
||||
}).optional(),
|
||||
/** Tools that should never be pruned */
|
||||
protected_tools: z.array(z.string()).default([
|
||||
"task", "todowrite", "todoread",
|
||||
"lsp_rename",
|
||||
"session_read", "session_write", "session_search",
|
||||
]),
|
||||
/** Pruning strategies configuration */
|
||||
strategies: z.object({
|
||||
/** Remove duplicate tool calls (same tool + same args) */
|
||||
deduplication: z.object({
|
||||
enabled: z.boolean().default(true),
|
||||
}).optional(),
|
||||
/** Prune write inputs when file subsequently read */
|
||||
supersede_writes: z.object({
|
||||
enabled: z.boolean().default(true),
|
||||
/** Aggressive mode: prune any write if ANY subsequent read */
|
||||
aggressive: z.boolean().default(false),
|
||||
}).optional(),
|
||||
/** Prune errored tool inputs after N turns */
|
||||
purge_errors: z.object({
|
||||
enabled: z.boolean().default(true),
|
||||
turns: z.number().min(1).max(20).default(5),
|
||||
}).optional(),
|
||||
}).optional(),
|
||||
})
|
||||
|
||||
export const ExperimentalConfigSchema = z.object({
|
||||
aggressive_truncation: z.boolean().optional(),
|
||||
auto_resume: z.boolean().optional(),
|
||||
preemptive_compaction: z.boolean().optional(),
|
||||
/** Truncate all tool outputs, not just whitelisted tools (default: false). Tool output truncator is enabled by default - disable via disabled_hooks. */
|
||||
truncate_all_tool_outputs: z.boolean().optional(),
|
||||
/** Dynamic context pruning configuration */
|
||||
dynamic_context_pruning: DynamicContextPruningConfigSchema.optional(),
|
||||
/** Enable experimental task system for Todowrite disabler hook */
|
||||
task_system: z.boolean().optional(),
|
||||
/** Timeout in ms for loadAllPluginComponents during config handler init (default: 10000, min: 1000) */
|
||||
plugin_load_timeout_ms: z.number().min(1000).optional(),
|
||||
/** Wrap hook creation in try/catch to prevent one failing hook from crashing the plugin (default: true at call site) */
|
||||
safe_hook_creation: z.boolean().optional(),
|
||||
})
|
||||
|
||||
export const SkillSourceSchema = z.union([
|
||||
z.string(),
|
||||
z.object({
|
||||
path: z.string(),
|
||||
recursive: z.boolean().optional(),
|
||||
glob: z.string().optional(),
|
||||
}),
|
||||
])
|
||||
|
||||
export const SkillDefinitionSchema = z.object({
|
||||
description: z.string().optional(),
|
||||
template: z.string().optional(),
|
||||
from: z.string().optional(),
|
||||
model: z.string().optional(),
|
||||
agent: z.string().optional(),
|
||||
subtask: z.boolean().optional(),
|
||||
"argument-hint": z.string().optional(),
|
||||
license: z.string().optional(),
|
||||
compatibility: z.string().optional(),
|
||||
metadata: z.record(z.string(), z.unknown()).optional(),
|
||||
"allowed-tools": z.array(z.string()).optional(),
|
||||
disable: z.boolean().optional(),
|
||||
})
|
||||
|
||||
export const SkillEntrySchema = z.union([
|
||||
z.boolean(),
|
||||
SkillDefinitionSchema,
|
||||
])
|
||||
|
||||
export const SkillsConfigSchema = z.union([
|
||||
z.array(z.string()),
|
||||
z.record(z.string(), SkillEntrySchema).and(z.object({
|
||||
sources: z.array(SkillSourceSchema).optional(),
|
||||
enable: z.array(z.string()).optional(),
|
||||
disable: z.array(z.string()).optional(),
|
||||
}).partial()),
|
||||
])
|
||||
|
||||
export const RalphLoopConfigSchema = z.object({
|
||||
/** Enable ralph loop functionality (default: false - opt-in feature) */
|
||||
enabled: z.boolean().default(false),
|
||||
/** Default max iterations if not specified in command (default: 100) */
|
||||
default_max_iterations: z.number().min(1).max(1000).default(100),
|
||||
/** Custom state file directory relative to project root (default: .opencode/) */
|
||||
state_dir: z.string().optional(),
|
||||
})
|
||||
|
||||
export const BackgroundTaskConfigSchema = z.object({
|
||||
defaultConcurrency: z.number().min(1).optional(),
|
||||
providerConcurrency: z.record(z.string(), z.number().min(0)).optional(),
|
||||
modelConcurrency: z.record(z.string(), z.number().min(0)).optional(),
|
||||
/** Stale timeout in milliseconds - interrupt tasks with no activity for this duration (default: 180000 = 3 minutes, minimum: 60000 = 1 minute) */
|
||||
staleTimeoutMs: z.number().min(60000).optional(),
|
||||
})
|
||||
|
||||
export const NotificationConfigSchema = z.object({
|
||||
/** Force enable session-notification even if external notification plugins are detected (default: false) */
|
||||
force_enable: z.boolean().optional(),
|
||||
})
|
||||
|
||||
export const BabysittingConfigSchema = z.object({
|
||||
timeout_ms: z.number().default(120000),
|
||||
})
|
||||
|
||||
export const GitMasterConfigSchema = z.object({
|
||||
/** Add "Ultraworked with Sisyphus" footer to commit messages (default: true). Can be boolean or custom string. */
|
||||
commit_footer: z.union([z.boolean(), z.string()]).default(true),
|
||||
/** Add "Co-authored-by: Sisyphus" trailer to commit messages (default: true) */
|
||||
include_co_authored_by: z.boolean().default(true),
|
||||
})
|
||||
|
||||
export const BrowserAutomationProviderSchema = z.enum(["playwright", "agent-browser", "dev-browser"])
|
||||
|
||||
export const BrowserAutomationConfigSchema = z.object({
|
||||
/**
|
||||
* Browser automation provider to use for the "playwright" skill.
|
||||
* - "playwright": Uses Playwright MCP server (@playwright/mcp) - default
|
||||
* - "agent-browser": Uses Vercel's agent-browser CLI (requires: bun add -g agent-browser)
|
||||
* - "dev-browser": Uses dev-browser skill with persistent browser state
|
||||
*/
|
||||
provider: BrowserAutomationProviderSchema.default("playwright"),
|
||||
})
|
||||
|
||||
export const WebsearchProviderSchema = z.enum(["exa", "tavily"])
|
||||
|
||||
export const WebsearchConfigSchema = z.object({
|
||||
/**
|
||||
* Websearch provider to use.
|
||||
* - "exa": Uses Exa websearch (default, works without API key)
|
||||
* - "tavily": Uses Tavily websearch (requires TAVILY_API_KEY)
|
||||
*/
|
||||
provider: WebsearchProviderSchema.optional(),
|
||||
})
|
||||
|
||||
export const TmuxLayoutSchema = z.enum([
|
||||
'main-horizontal', // main pane top, agent panes bottom stack
|
||||
'main-vertical', // main pane left, agent panes right stack (default)
|
||||
'tiled', // all panes same size grid
|
||||
'even-horizontal', // all panes horizontal row
|
||||
'even-vertical', // all panes vertical stack
|
||||
])
|
||||
|
||||
export const TmuxConfigSchema = z.object({
|
||||
enabled: z.boolean().default(false),
|
||||
layout: TmuxLayoutSchema.default('main-vertical'),
|
||||
main_pane_size: z.number().min(20).max(80).default(60),
|
||||
main_pane_min_width: z.number().min(40).default(120),
|
||||
agent_pane_min_width: z.number().min(20).default(40),
|
||||
})
|
||||
|
||||
export const SisyphusTasksConfigSchema = z.object({
|
||||
/** Absolute or relative storage path override. When set, bypasses global config dir. */
|
||||
storage_path: z.string().optional(),
|
||||
/** Force task list ID (alternative to env ULTRAWORK_TASK_LIST_ID) */
|
||||
task_list_id: z.string().optional(),
|
||||
/** Enable Claude Code path compatibility mode */
|
||||
claude_code_compat: z.boolean().default(false),
|
||||
})
|
||||
|
||||
export const SisyphusConfigSchema = z.object({
|
||||
tasks: SisyphusTasksConfigSchema.optional(),
|
||||
})
|
||||
export const OhMyOpenCodeConfigSchema = z.object({
|
||||
$schema: z.string().optional(),
|
||||
/** Enable new task system (default: false) */
|
||||
new_task_system_enabled: z.boolean().optional(),
|
||||
/** Default agent name for `oh-my-opencode run` (env: OPENCODE_DEFAULT_AGENT) */
|
||||
default_run_agent: z.string().optional(),
|
||||
disabled_mcps: z.array(AnyMcpNameSchema).optional(),
|
||||
disabled_agents: z.array(BuiltinAgentNameSchema).optional(),
|
||||
disabled_skills: z.array(BuiltinSkillNameSchema).optional(),
|
||||
disabled_hooks: z.array(HookNameSchema).optional(),
|
||||
disabled_commands: z.array(BuiltinCommandNameSchema).optional(),
|
||||
/** Disable specific tools by name (e.g., ["todowrite", "todoread"]) */
|
||||
disabled_tools: z.array(z.string()).optional(),
|
||||
agents: AgentOverridesSchema.optional(),
|
||||
categories: CategoriesConfigSchema.optional(),
|
||||
claude_code: ClaudeCodeConfigSchema.optional(),
|
||||
sisyphus_agent: SisyphusAgentConfigSchema.optional(),
|
||||
comment_checker: CommentCheckerConfigSchema.optional(),
|
||||
experimental: ExperimentalConfigSchema.optional(),
|
||||
auto_update: z.boolean().optional(),
|
||||
skills: SkillsConfigSchema.optional(),
|
||||
ralph_loop: RalphLoopConfigSchema.optional(),
|
||||
background_task: BackgroundTaskConfigSchema.optional(),
|
||||
notification: NotificationConfigSchema.optional(),
|
||||
babysitting: BabysittingConfigSchema.optional(),
|
||||
git_master: GitMasterConfigSchema.optional(),
|
||||
browser_automation_engine: BrowserAutomationConfigSchema.optional(),
|
||||
websearch: WebsearchConfigSchema.optional(),
|
||||
tmux: TmuxConfigSchema.optional(),
|
||||
sisyphus: SisyphusConfigSchema.optional(),
|
||||
/** Migration history to prevent re-applying migrations (e.g., model version upgrades) */
|
||||
_migrations: z.array(z.string()).optional(),
|
||||
})
|
||||
|
||||
export type OhMyOpenCodeConfig = z.infer<typeof OhMyOpenCodeConfigSchema>
|
||||
export type AgentOverrideConfig = z.infer<typeof AgentOverrideConfigSchema>
|
||||
export type AgentOverrides = z.infer<typeof AgentOverridesSchema>
|
||||
export type BackgroundTaskConfig = z.infer<typeof BackgroundTaskConfigSchema>
|
||||
export type AgentName = z.infer<typeof AgentNameSchema>
|
||||
export type HookName = z.infer<typeof HookNameSchema>
|
||||
export type BuiltinCommandName = z.infer<typeof BuiltinCommandNameSchema>
|
||||
export type BuiltinSkillName = z.infer<typeof BuiltinSkillNameSchema>
|
||||
export type SisyphusAgentConfig = z.infer<typeof SisyphusAgentConfigSchema>
|
||||
export type CommentCheckerConfig = z.infer<typeof CommentCheckerConfigSchema>
|
||||
export type ExperimentalConfig = z.infer<typeof ExperimentalConfigSchema>
|
||||
export type DynamicContextPruningConfig = z.infer<typeof DynamicContextPruningConfigSchema>
|
||||
export type SkillsConfig = z.infer<typeof SkillsConfigSchema>
|
||||
export type SkillDefinition = z.infer<typeof SkillDefinitionSchema>
|
||||
export type RalphLoopConfig = z.infer<typeof RalphLoopConfigSchema>
|
||||
export type NotificationConfig = z.infer<typeof NotificationConfigSchema>
|
||||
export type BabysittingConfig = z.infer<typeof BabysittingConfigSchema>
|
||||
export type CategoryConfig = z.infer<typeof CategoryConfigSchema>
|
||||
export type CategoriesConfig = z.infer<typeof CategoriesConfigSchema>
|
||||
export type BuiltinCategoryName = z.infer<typeof BuiltinCategoryNameSchema>
|
||||
export type GitMasterConfig = z.infer<typeof GitMasterConfigSchema>
|
||||
export type BrowserAutomationProvider = z.infer<typeof BrowserAutomationProviderSchema>
|
||||
export type BrowserAutomationConfig = z.infer<typeof BrowserAutomationConfigSchema>
|
||||
export type WebsearchProvider = z.infer<typeof WebsearchProviderSchema>
|
||||
export type WebsearchConfig = z.infer<typeof WebsearchConfigSchema>
|
||||
export type TmuxConfig = z.infer<typeof TmuxConfigSchema>
|
||||
export type TmuxLayout = z.infer<typeof TmuxLayoutSchema>
|
||||
export type SisyphusTasksConfig = z.infer<typeof SisyphusTasksConfigSchema>
|
||||
export type SisyphusConfig = z.infer<typeof SisyphusConfigSchema>
|
||||
export * from "./schema/agent-names"
|
||||
export * from "./schema/agent-overrides"
|
||||
export * from "./schema/babysitting"
|
||||
export * from "./schema/background-task"
|
||||
export * from "./schema/browser-automation"
|
||||
export * from "./schema/categories"
|
||||
export * from "./schema/claude-code"
|
||||
export * from "./schema/comment-checker"
|
||||
export * from "./schema/commands"
|
||||
export * from "./schema/dynamic-context-pruning"
|
||||
export * from "./schema/experimental"
|
||||
export * from "./schema/git-master"
|
||||
export * from "./schema/hooks"
|
||||
export * from "./schema/notification"
|
||||
export * from "./schema/oh-my-opencode-config"
|
||||
export * from "./schema/ralph-loop"
|
||||
export * from "./schema/skills"
|
||||
export * from "./schema/sisyphus"
|
||||
export * from "./schema/sisyphus-agent"
|
||||
export * from "./schema/tmux"
|
||||
export * from "./schema/websearch"
|
||||
|
||||
export { AnyMcpNameSchema, type AnyMcpName, McpNameSchema, type McpName } from "../mcp/types"
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
import { z } from "zod"
|
||||
|
||||
export const BuiltinAgentNameSchema = z.enum([
|
||||
"sisyphus",
|
||||
"hephaestus",
|
||||
"prometheus",
|
||||
"oracle",
|
||||
"librarian",
|
||||
"explore",
|
||||
"multimodal-looker",
|
||||
"metis",
|
||||
"momus",
|
||||
"atlas",
|
||||
])
|
||||
|
||||
export const BuiltinSkillNameSchema = z.enum([
|
||||
"playwright",
|
||||
"agent-browser",
|
||||
"dev-browser",
|
||||
"frontend-ui-ux",
|
||||
"git-master",
|
||||
])
|
||||
|
||||
export const OverridableAgentNameSchema = z.enum([
|
||||
"build",
|
||||
"plan",
|
||||
"sisyphus",
|
||||
"hephaestus",
|
||||
"sisyphus-junior",
|
||||
"OpenCode-Builder",
|
||||
"prometheus",
|
||||
"metis",
|
||||
"momus",
|
||||
"oracle",
|
||||
"librarian",
|
||||
"explore",
|
||||
"multimodal-looker",
|
||||
"atlas",
|
||||
])
|
||||
|
||||
export const AgentNameSchema = BuiltinAgentNameSchema
|
||||
export type AgentName = z.infer<typeof AgentNameSchema>
|
||||
|
||||
export type BuiltinSkillName = z.infer<typeof BuiltinSkillNameSchema>
|
||||
@@ -0,0 +1,60 @@
|
||||
import { z } from "zod"
|
||||
import { AgentPermissionSchema } from "./internal/permission"
|
||||
|
||||
export const AgentOverrideConfigSchema = z.object({
|
||||
/** @deprecated Use `category` instead. Model is inherited from category defaults. */
|
||||
model: z.string().optional(),
|
||||
variant: z.string().optional(),
|
||||
/** Category name to inherit model and other settings from CategoryConfig */
|
||||
category: z.string().optional(),
|
||||
/** Skill names to inject into agent prompt */
|
||||
skills: z.array(z.string()).optional(),
|
||||
temperature: z.number().min(0).max(2).optional(),
|
||||
top_p: z.number().min(0).max(1).optional(),
|
||||
prompt: z.string().optional(),
|
||||
prompt_append: z.string().optional(),
|
||||
tools: z.record(z.string(), z.boolean()).optional(),
|
||||
disable: z.boolean().optional(),
|
||||
description: z.string().optional(),
|
||||
mode: z.enum(["subagent", "primary", "all"]).optional(),
|
||||
color: z
|
||||
.string()
|
||||
.regex(/^#[0-9A-Fa-f]{6}$/)
|
||||
.optional(),
|
||||
permission: AgentPermissionSchema.optional(),
|
||||
/** Maximum tokens for response. Passed directly to OpenCode SDK. */
|
||||
maxTokens: z.number().optional(),
|
||||
/** Extended thinking configuration (Anthropic). Overrides category and default settings. */
|
||||
thinking: z
|
||||
.object({
|
||||
type: z.enum(["enabled", "disabled"]),
|
||||
budgetTokens: z.number().optional(),
|
||||
})
|
||||
.optional(),
|
||||
/** Reasoning effort level (OpenAI). Overrides category and default settings. */
|
||||
reasoningEffort: z.enum(["low", "medium", "high", "xhigh"]).optional(),
|
||||
/** Text verbosity level. */
|
||||
textVerbosity: z.enum(["low", "medium", "high"]).optional(),
|
||||
/** Provider-specific options. Passed directly to OpenCode SDK. */
|
||||
providerOptions: z.record(z.string(), z.unknown()).optional(),
|
||||
})
|
||||
|
||||
export const AgentOverridesSchema = z.object({
|
||||
build: AgentOverrideConfigSchema.optional(),
|
||||
plan: AgentOverrideConfigSchema.optional(),
|
||||
sisyphus: AgentOverrideConfigSchema.optional(),
|
||||
hephaestus: AgentOverrideConfigSchema.optional(),
|
||||
"sisyphus-junior": AgentOverrideConfigSchema.optional(),
|
||||
"OpenCode-Builder": AgentOverrideConfigSchema.optional(),
|
||||
prometheus: AgentOverrideConfigSchema.optional(),
|
||||
metis: AgentOverrideConfigSchema.optional(),
|
||||
momus: AgentOverrideConfigSchema.optional(),
|
||||
oracle: AgentOverrideConfigSchema.optional(),
|
||||
librarian: AgentOverrideConfigSchema.optional(),
|
||||
explore: AgentOverrideConfigSchema.optional(),
|
||||
"multimodal-looker": AgentOverrideConfigSchema.optional(),
|
||||
atlas: AgentOverrideConfigSchema.optional(),
|
||||
})
|
||||
|
||||
export type AgentOverrideConfig = z.infer<typeof AgentOverrideConfigSchema>
|
||||
export type AgentOverrides = z.infer<typeof AgentOverridesSchema>
|
||||
@@ -0,0 +1,7 @@
|
||||
import { z } from "zod"
|
||||
|
||||
export const BabysittingConfigSchema = z.object({
|
||||
timeout_ms: z.number().default(120000),
|
||||
})
|
||||
|
||||
export type BabysittingConfig = z.infer<typeof BabysittingConfigSchema>
|
||||
@@ -0,0 +1,11 @@
|
||||
import { z } from "zod"
|
||||
|
||||
export const BackgroundTaskConfigSchema = z.object({
|
||||
defaultConcurrency: z.number().min(1).optional(),
|
||||
providerConcurrency: z.record(z.string(), z.number().min(0)).optional(),
|
||||
modelConcurrency: z.record(z.string(), z.number().min(0)).optional(),
|
||||
/** Stale timeout in milliseconds - interrupt tasks with no activity for this duration (default: 180000 = 3 minutes, minimum: 60000 = 1 minute) */
|
||||
staleTimeoutMs: z.number().min(60000).optional(),
|
||||
})
|
||||
|
||||
export type BackgroundTaskConfig = z.infer<typeof BackgroundTaskConfigSchema>
|
||||
@@ -0,0 +1,22 @@
|
||||
import { z } from "zod"
|
||||
|
||||
export const BrowserAutomationProviderSchema = z.enum([
|
||||
"playwright",
|
||||
"agent-browser",
|
||||
"dev-browser",
|
||||
])
|
||||
|
||||
export const BrowserAutomationConfigSchema = z.object({
|
||||
/**
|
||||
* Browser automation provider to use for the "playwright" skill.
|
||||
* - "playwright": Uses Playwright MCP server (@playwright/mcp) - default
|
||||
* - "agent-browser": Uses Vercel's agent-browser CLI (requires: bun add -g agent-browser)
|
||||
* - "dev-browser": Uses dev-browser skill with persistent browser state
|
||||
*/
|
||||
provider: BrowserAutomationProviderSchema.default("playwright"),
|
||||
})
|
||||
|
||||
export type BrowserAutomationProvider = z.infer<
|
||||
typeof BrowserAutomationProviderSchema
|
||||
>
|
||||
export type BrowserAutomationConfig = z.infer<typeof BrowserAutomationConfigSchema>
|
||||
@@ -0,0 +1,40 @@
|
||||
import { z } from "zod"
|
||||
|
||||
export const CategoryConfigSchema = z.object({
|
||||
/** Human-readable description of the category's purpose. Shown in task prompt. */
|
||||
description: z.string().optional(),
|
||||
model: z.string().optional(),
|
||||
variant: z.string().optional(),
|
||||
temperature: z.number().min(0).max(2).optional(),
|
||||
top_p: z.number().min(0).max(1).optional(),
|
||||
maxTokens: z.number().optional(),
|
||||
thinking: z
|
||||
.object({
|
||||
type: z.enum(["enabled", "disabled"]),
|
||||
budgetTokens: z.number().optional(),
|
||||
})
|
||||
.optional(),
|
||||
reasoningEffort: z.enum(["low", "medium", "high", "xhigh"]).optional(),
|
||||
textVerbosity: z.enum(["low", "medium", "high"]).optional(),
|
||||
tools: z.record(z.string(), z.boolean()).optional(),
|
||||
prompt_append: z.string().optional(),
|
||||
/** Mark agent as unstable - forces background mode for monitoring. Auto-enabled for gemini/minimax models. */
|
||||
is_unstable_agent: z.boolean().optional(),
|
||||
})
|
||||
|
||||
export const BuiltinCategoryNameSchema = z.enum([
|
||||
"visual-engineering",
|
||||
"ultrabrain",
|
||||
"deep",
|
||||
"artistry",
|
||||
"quick",
|
||||
"unspecified-low",
|
||||
"unspecified-high",
|
||||
"writing",
|
||||
])
|
||||
|
||||
export const CategoriesConfigSchema = z.record(z.string(), CategoryConfigSchema)
|
||||
|
||||
export type CategoryConfig = z.infer<typeof CategoryConfigSchema>
|
||||
export type CategoriesConfig = z.infer<typeof CategoriesConfigSchema>
|
||||
export type BuiltinCategoryName = z.infer<typeof BuiltinCategoryNameSchema>
|
||||
@@ -0,0 +1,13 @@
|
||||
import { z } from "zod"
|
||||
|
||||
export const ClaudeCodeConfigSchema = z.object({
|
||||
mcp: z.boolean().optional(),
|
||||
commands: z.boolean().optional(),
|
||||
skills: z.boolean().optional(),
|
||||
agents: z.boolean().optional(),
|
||||
hooks: z.boolean().optional(),
|
||||
plugins: z.boolean().optional(),
|
||||
plugins_override: z.record(z.string(), z.boolean()).optional(),
|
||||
})
|
||||
|
||||
export type ClaudeCodeConfig = z.infer<typeof ClaudeCodeConfigSchema>
|
||||
@@ -0,0 +1,13 @@
|
||||
import { z } from "zod"
|
||||
|
||||
export const BuiltinCommandNameSchema = z.enum([
|
||||
"init-deep",
|
||||
"ralph-loop",
|
||||
"ulw-loop",
|
||||
"cancel-ralph",
|
||||
"refactor",
|
||||
"start-work",
|
||||
"stop-continuation",
|
||||
])
|
||||
|
||||
export type BuiltinCommandName = z.infer<typeof BuiltinCommandNameSchema>
|
||||
@@ -0,0 +1,8 @@
|
||||
import { z } from "zod"
|
||||
|
||||
export const CommentCheckerConfigSchema = z.object({
|
||||
/** Custom prompt to replace the default warning message. Use {{comments}} placeholder for detected comments XML. */
|
||||
custom_prompt: z.string().optional(),
|
||||
})
|
||||
|
||||
export type CommentCheckerConfig = z.infer<typeof CommentCheckerConfigSchema>
|
||||
@@ -0,0 +1,55 @@
|
||||
import { z } from "zod"
|
||||
|
||||
export const DynamicContextPruningConfigSchema = z.object({
|
||||
/** Enable dynamic context pruning (default: false) */
|
||||
enabled: z.boolean().default(false),
|
||||
/** Notification level: off, minimal, or detailed (default: detailed) */
|
||||
notification: z.enum(["off", "minimal", "detailed"]).default("detailed"),
|
||||
/** Turn protection - prevent pruning recent tool outputs */
|
||||
turn_protection: z
|
||||
.object({
|
||||
enabled: z.boolean().default(true),
|
||||
turns: z.number().min(1).max(10).default(3),
|
||||
})
|
||||
.optional(),
|
||||
/** Tools that should never be pruned */
|
||||
protected_tools: z.array(z.string()).default([
|
||||
"task",
|
||||
"todowrite",
|
||||
"todoread",
|
||||
"lsp_rename",
|
||||
"session_read",
|
||||
"session_write",
|
||||
"session_search",
|
||||
]),
|
||||
/** Pruning strategies configuration */
|
||||
strategies: z
|
||||
.object({
|
||||
/** Remove duplicate tool calls (same tool + same args) */
|
||||
deduplication: z
|
||||
.object({
|
||||
enabled: z.boolean().default(true),
|
||||
})
|
||||
.optional(),
|
||||
/** Prune write inputs when file subsequently read */
|
||||
supersede_writes: z
|
||||
.object({
|
||||
enabled: z.boolean().default(true),
|
||||
/** Aggressive mode: prune any write if ANY subsequent read */
|
||||
aggressive: z.boolean().default(false),
|
||||
})
|
||||
.optional(),
|
||||
/** Prune errored tool inputs after N turns */
|
||||
purge_errors: z
|
||||
.object({
|
||||
enabled: z.boolean().default(true),
|
||||
turns: z.number().min(1).max(20).default(5),
|
||||
})
|
||||
.optional(),
|
||||
})
|
||||
.optional(),
|
||||
})
|
||||
|
||||
export type DynamicContextPruningConfig = z.infer<
|
||||
typeof DynamicContextPruningConfigSchema
|
||||
>
|
||||
@@ -0,0 +1,20 @@
|
||||
import { z } from "zod"
|
||||
import { DynamicContextPruningConfigSchema } from "./dynamic-context-pruning"
|
||||
|
||||
export const ExperimentalConfigSchema = z.object({
|
||||
aggressive_truncation: z.boolean().optional(),
|
||||
auto_resume: z.boolean().optional(),
|
||||
preemptive_compaction: z.boolean().optional(),
|
||||
/** Truncate all tool outputs, not just whitelisted tools (default: false). Tool output truncator is enabled by default - disable via disabled_hooks. */
|
||||
truncate_all_tool_outputs: z.boolean().optional(),
|
||||
/** Dynamic context pruning configuration */
|
||||
dynamic_context_pruning: DynamicContextPruningConfigSchema.optional(),
|
||||
/** Enable experimental task system for Todowrite disabler hook */
|
||||
task_system: z.boolean().optional(),
|
||||
/** Timeout in ms for loadAllPluginComponents during config handler init (default: 10000, min: 1000) */
|
||||
plugin_load_timeout_ms: z.number().min(1000).optional(),
|
||||
/** Wrap hook creation in try/catch to prevent one failing hook from crashing the plugin (default: true at call site) */
|
||||
safe_hook_creation: z.boolean().optional(),
|
||||
})
|
||||
|
||||
export type ExperimentalConfig = z.infer<typeof ExperimentalConfigSchema>
|
||||
@@ -0,0 +1,10 @@
|
||||
import { z } from "zod"
|
||||
|
||||
export const GitMasterConfigSchema = z.object({
|
||||
/** Add "Ultraworked with Sisyphus" footer to commit messages (default: true). Can be boolean or custom string. */
|
||||
commit_footer: z.union([z.boolean(), z.string()]).default(true),
|
||||
/** Add "Co-authored-by: Sisyphus" trailer to commit messages (default: true) */
|
||||
include_co_authored_by: z.boolean().default(true),
|
||||
})
|
||||
|
||||
export type GitMasterConfig = z.infer<typeof GitMasterConfigSchema>
|
||||
@@ -0,0 +1,51 @@
|
||||
import { z } from "zod"
|
||||
|
||||
export const HookNameSchema = z.enum([
|
||||
"todo-continuation-enforcer",
|
||||
"context-window-monitor",
|
||||
"session-recovery",
|
||||
"session-notification",
|
||||
"comment-checker",
|
||||
"grep-output-truncator",
|
||||
"tool-output-truncator",
|
||||
"question-label-truncator",
|
||||
"directory-agents-injector",
|
||||
"directory-readme-injector",
|
||||
"empty-task-response-detector",
|
||||
"think-mode",
|
||||
"subagent-question-blocker",
|
||||
"anthropic-context-window-limit-recovery",
|
||||
"preemptive-compaction",
|
||||
"rules-injector",
|
||||
"background-notification",
|
||||
"auto-update-checker",
|
||||
"startup-toast",
|
||||
"keyword-detector",
|
||||
"agent-usage-reminder",
|
||||
"non-interactive-env",
|
||||
"interactive-bash-session",
|
||||
|
||||
"thinking-block-validator",
|
||||
"ralph-loop",
|
||||
"category-skill-reminder",
|
||||
|
||||
"compaction-context-injector",
|
||||
"compaction-todo-preserver",
|
||||
"claude-code-hooks",
|
||||
"auto-slash-command",
|
||||
"edit-error-recovery",
|
||||
"delegate-task-retry",
|
||||
"prometheus-md-only",
|
||||
"sisyphus-junior-notepad",
|
||||
"start-work",
|
||||
"atlas",
|
||||
"unstable-agent-babysitter",
|
||||
"task-reminder",
|
||||
"task-resume-info",
|
||||
"stop-continuation-guard",
|
||||
"tasks-todowrite-disabler",
|
||||
"write-existing-file-guard",
|
||||
"anthropic-effort",
|
||||
])
|
||||
|
||||
export type HookName = z.infer<typeof HookNameSchema>
|
||||
@@ -0,0 +1,20 @@
|
||||
import { z } from "zod"
|
||||
|
||||
export const PermissionValueSchema = z.enum(["ask", "allow", "deny"])
|
||||
export type PermissionValue = z.infer<typeof PermissionValueSchema>
|
||||
|
||||
const BashPermissionSchema = z.union([
|
||||
PermissionValueSchema,
|
||||
z.record(z.string(), PermissionValueSchema),
|
||||
])
|
||||
|
||||
export const AgentPermissionSchema = z.object({
|
||||
edit: PermissionValueSchema.optional(),
|
||||
bash: BashPermissionSchema.optional(),
|
||||
webfetch: PermissionValueSchema.optional(),
|
||||
task: PermissionValueSchema.optional(),
|
||||
doom_loop: PermissionValueSchema.optional(),
|
||||
external_directory: PermissionValueSchema.optional(),
|
||||
})
|
||||
|
||||
export type AgentPermission = z.infer<typeof AgentPermissionSchema>
|
||||
@@ -0,0 +1,8 @@
|
||||
import { z } from "zod"
|
||||
|
||||
export const NotificationConfigSchema = z.object({
|
||||
/** Force enable session-notification even if external notification plugins are detected (default: false) */
|
||||
force_enable: z.boolean().optional(),
|
||||
})
|
||||
|
||||
export type NotificationConfig = z.infer<typeof NotificationConfigSchema>
|
||||
@@ -0,0 +1,57 @@
|
||||
import { z } from "zod"
|
||||
import { AnyMcpNameSchema } from "../../mcp/types"
|
||||
import { BuiltinAgentNameSchema, BuiltinSkillNameSchema } from "./agent-names"
|
||||
import { AgentOverridesSchema } from "./agent-overrides"
|
||||
import { BabysittingConfigSchema } from "./babysitting"
|
||||
import { BackgroundTaskConfigSchema } from "./background-task"
|
||||
import { BrowserAutomationConfigSchema } from "./browser-automation"
|
||||
import { CategoriesConfigSchema } from "./categories"
|
||||
import { ClaudeCodeConfigSchema } from "./claude-code"
|
||||
import { CommentCheckerConfigSchema } from "./comment-checker"
|
||||
import { BuiltinCommandNameSchema } from "./commands"
|
||||
import { ExperimentalConfigSchema } from "./experimental"
|
||||
import { GitMasterConfigSchema } from "./git-master"
|
||||
import { HookNameSchema } from "./hooks"
|
||||
import { NotificationConfigSchema } from "./notification"
|
||||
import { RalphLoopConfigSchema } from "./ralph-loop"
|
||||
import { SkillsConfigSchema } from "./skills"
|
||||
import { SisyphusConfigSchema } from "./sisyphus"
|
||||
import { SisyphusAgentConfigSchema } from "./sisyphus-agent"
|
||||
import { TmuxConfigSchema } from "./tmux"
|
||||
import { WebsearchConfigSchema } from "./websearch"
|
||||
|
||||
export const OhMyOpenCodeConfigSchema = z.object({
|
||||
$schema: z.string().optional(),
|
||||
/** Enable new task system (default: false) */
|
||||
new_task_system_enabled: z.boolean().optional(),
|
||||
/** Default agent name for `oh-my-opencode run` (env: OPENCODE_DEFAULT_AGENT) */
|
||||
default_run_agent: z.string().optional(),
|
||||
disabled_mcps: z.array(AnyMcpNameSchema).optional(),
|
||||
disabled_agents: z.array(BuiltinAgentNameSchema).optional(),
|
||||
disabled_skills: z.array(BuiltinSkillNameSchema).optional(),
|
||||
disabled_hooks: z.array(HookNameSchema).optional(),
|
||||
disabled_commands: z.array(BuiltinCommandNameSchema).optional(),
|
||||
/** Disable specific tools by name (e.g., ["todowrite", "todoread"]) */
|
||||
disabled_tools: z.array(z.string()).optional(),
|
||||
agents: AgentOverridesSchema.optional(),
|
||||
categories: CategoriesConfigSchema.optional(),
|
||||
claude_code: ClaudeCodeConfigSchema.optional(),
|
||||
sisyphus_agent: SisyphusAgentConfigSchema.optional(),
|
||||
comment_checker: CommentCheckerConfigSchema.optional(),
|
||||
experimental: ExperimentalConfigSchema.optional(),
|
||||
auto_update: z.boolean().optional(),
|
||||
skills: SkillsConfigSchema.optional(),
|
||||
ralph_loop: RalphLoopConfigSchema.optional(),
|
||||
background_task: BackgroundTaskConfigSchema.optional(),
|
||||
notification: NotificationConfigSchema.optional(),
|
||||
babysitting: BabysittingConfigSchema.optional(),
|
||||
git_master: GitMasterConfigSchema.optional(),
|
||||
browser_automation_engine: BrowserAutomationConfigSchema.optional(),
|
||||
websearch: WebsearchConfigSchema.optional(),
|
||||
tmux: TmuxConfigSchema.optional(),
|
||||
sisyphus: SisyphusConfigSchema.optional(),
|
||||
/** Migration history to prevent re-applying migrations (e.g., model version upgrades) */
|
||||
_migrations: z.array(z.string()).optional(),
|
||||
})
|
||||
|
||||
export type OhMyOpenCodeConfig = z.infer<typeof OhMyOpenCodeConfigSchema>
|
||||
@@ -0,0 +1,12 @@
|
||||
import { z } from "zod"
|
||||
|
||||
export const RalphLoopConfigSchema = z.object({
|
||||
/** Enable ralph loop functionality (default: false - opt-in feature) */
|
||||
enabled: z.boolean().default(false),
|
||||
/** Default max iterations if not specified in command (default: 100) */
|
||||
default_max_iterations: z.number().min(1).max(1000).default(100),
|
||||
/** Custom state file directory relative to project root (default: .opencode/) */
|
||||
state_dir: z.string().optional(),
|
||||
})
|
||||
|
||||
export type RalphLoopConfig = z.infer<typeof RalphLoopConfigSchema>
|
||||
@@ -0,0 +1,10 @@
|
||||
import { z } from "zod"
|
||||
|
||||
export const SisyphusAgentConfigSchema = z.object({
|
||||
disabled: z.boolean().optional(),
|
||||
default_builder_enabled: z.boolean().optional(),
|
||||
planner_enabled: z.boolean().optional(),
|
||||
replace_plan: z.boolean().optional(),
|
||||
})
|
||||
|
||||
export type SisyphusAgentConfig = z.infer<typeof SisyphusAgentConfigSchema>
|
||||
@@ -0,0 +1,17 @@
|
||||
import { z } from "zod"
|
||||
|
||||
export const SisyphusTasksConfigSchema = z.object({
|
||||
/** Absolute or relative storage path override. When set, bypasses global config dir. */
|
||||
storage_path: z.string().optional(),
|
||||
/** Force task list ID (alternative to env ULTRAWORK_TASK_LIST_ID) */
|
||||
task_list_id: z.string().optional(),
|
||||
/** Enable Claude Code path compatibility mode */
|
||||
claude_code_compat: z.boolean().default(false),
|
||||
})
|
||||
|
||||
export const SisyphusConfigSchema = z.object({
|
||||
tasks: SisyphusTasksConfigSchema.optional(),
|
||||
})
|
||||
|
||||
export type SisyphusTasksConfig = z.infer<typeof SisyphusTasksConfigSchema>
|
||||
export type SisyphusConfig = z.infer<typeof SisyphusConfigSchema>
|
||||
@@ -0,0 +1,45 @@
|
||||
import { z } from "zod"
|
||||
|
||||
export const SkillSourceSchema = z.union([
|
||||
z.string(),
|
||||
z.object({
|
||||
path: z.string(),
|
||||
recursive: z.boolean().optional(),
|
||||
glob: z.string().optional(),
|
||||
}),
|
||||
])
|
||||
|
||||
export const SkillDefinitionSchema = z.object({
|
||||
description: z.string().optional(),
|
||||
template: z.string().optional(),
|
||||
from: z.string().optional(),
|
||||
model: z.string().optional(),
|
||||
agent: z.string().optional(),
|
||||
subtask: z.boolean().optional(),
|
||||
"argument-hint": z.string().optional(),
|
||||
license: z.string().optional(),
|
||||
compatibility: z.string().optional(),
|
||||
metadata: z.record(z.string(), z.unknown()).optional(),
|
||||
"allowed-tools": z.array(z.string()).optional(),
|
||||
disable: z.boolean().optional(),
|
||||
})
|
||||
|
||||
export const SkillEntrySchema = z.union([z.boolean(), SkillDefinitionSchema])
|
||||
|
||||
export const SkillsConfigSchema = z.union([
|
||||
z.array(z.string()),
|
||||
z
|
||||
.record(z.string(), SkillEntrySchema)
|
||||
.and(
|
||||
z
|
||||
.object({
|
||||
sources: z.array(SkillSourceSchema).optional(),
|
||||
enable: z.array(z.string()).optional(),
|
||||
disable: z.array(z.string()).optional(),
|
||||
})
|
||||
.partial()
|
||||
),
|
||||
])
|
||||
|
||||
export type SkillsConfig = z.infer<typeof SkillsConfigSchema>
|
||||
export type SkillDefinition = z.infer<typeof SkillDefinitionSchema>
|
||||
@@ -0,0 +1,20 @@
|
||||
import { z } from "zod"
|
||||
|
||||
export const TmuxLayoutSchema = z.enum([
|
||||
"main-horizontal", // main pane top, agent panes bottom stack
|
||||
"main-vertical", // main pane left, agent panes right stack (default)
|
||||
"tiled", // all panes same size grid
|
||||
"even-horizontal", // all panes horizontal row
|
||||
"even-vertical", // all panes vertical stack
|
||||
])
|
||||
|
||||
export const TmuxConfigSchema = z.object({
|
||||
enabled: z.boolean().default(false),
|
||||
layout: TmuxLayoutSchema.default("main-vertical"),
|
||||
main_pane_size: z.number().min(20).max(80).default(60),
|
||||
main_pane_min_width: z.number().min(40).default(120),
|
||||
agent_pane_min_width: z.number().min(20).default(40),
|
||||
})
|
||||
|
||||
export type TmuxConfig = z.infer<typeof TmuxConfigSchema>
|
||||
export type TmuxLayout = z.infer<typeof TmuxLayoutSchema>
|
||||
@@ -0,0 +1,15 @@
|
||||
import { z } from "zod"
|
||||
|
||||
export const WebsearchProviderSchema = z.enum(["exa", "tavily"])
|
||||
|
||||
export const WebsearchConfigSchema = z.object({
|
||||
/**
|
||||
* Websearch provider to use.
|
||||
* - "exa": Uses Exa websearch (default, works without API key)
|
||||
* - "tavily": Uses Tavily websearch (requires TAVILY_API_KEY)
|
||||
*/
|
||||
provider: WebsearchProviderSchema.optional(),
|
||||
})
|
||||
|
||||
export type WebsearchProvider = z.infer<typeof WebsearchProviderSchema>
|
||||
export type WebsearchConfig = z.infer<typeof WebsearchConfigSchema>
|
||||
Reference in New Issue
Block a user