opencode-dux 1.0.0
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/LICENSE +21 -0
- package/README.md +452 -0
- package/dist/agents/descriptions.d.ts +6 -0
- package/dist/agents/designer.d.ts +2 -0
- package/dist/agents/explorer.d.ts +2 -0
- package/dist/agents/fixer.d.ts +2 -0
- package/dist/agents/index.d.ts +22 -0
- package/dist/agents/interpreter.d.ts +2 -0
- package/dist/agents/librarian.d.ts +2 -0
- package/dist/agents/oracle.d.ts +2 -0
- package/dist/agents/orchestrator.d.ts +27 -0
- package/dist/agents/overrides.d.ts +18 -0
- package/dist/agents/prompt-blocks.d.ts +97 -0
- package/dist/agents/steward.d.ts +3 -0
- package/dist/cli/config-io.d.ts +24 -0
- package/dist/cli/config-manager.d.ts +4 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +1006 -0
- package/dist/cli/install.d.ts +2 -0
- package/dist/cli/mcps.d.ts +13 -0
- package/dist/cli/model-key-normalization.d.ts +1 -0
- package/dist/cli/paths.d.ts +35 -0
- package/dist/cli/providers.d.ts +137 -0
- package/dist/cli/skills.d.ts +22 -0
- package/dist/cli/system.d.ts +5 -0
- package/dist/cli/types.d.ts +38 -0
- package/dist/config/constants.d.ts +12 -0
- package/dist/config/index.d.ts +4 -0
- package/dist/config/loader.d.ts +40 -0
- package/dist/config/runtime-preset.d.ts +12 -0
- package/dist/config/schema.d.ts +281 -0
- package/dist/config/utils.d.ts +10 -0
- package/dist/discovery/local/types.d.ts +79 -0
- package/dist/discovery/local.d.ts +73 -0
- package/dist/discovery/mcp-servers.d.ts +88 -0
- package/dist/discovery/skills.d.ts +94 -0
- package/dist/hooks/apply-patch/codec.d.ts +7 -0
- package/dist/hooks/apply-patch/errors.d.ts +25 -0
- package/dist/hooks/apply-patch/execution-context.d.ts +27 -0
- package/dist/hooks/apply-patch/index.d.ts +15 -0
- package/dist/hooks/apply-patch/matching.d.ts +26 -0
- package/dist/hooks/apply-patch/operations.d.ts +3 -0
- package/dist/hooks/apply-patch/patch.d.ts +2 -0
- package/dist/hooks/apply-patch/prepared-changes.d.ts +17 -0
- package/dist/hooks/apply-patch/resolution.d.ts +19 -0
- package/dist/hooks/apply-patch/rewrite.d.ts +7 -0
- package/dist/hooks/apply-patch/test-helpers.d.ts +6 -0
- package/dist/hooks/apply-patch/types.d.ts +80 -0
- package/dist/hooks/auto-update-checker/cache.d.ts +11 -0
- package/dist/hooks/auto-update-checker/checker.d.ts +32 -0
- package/dist/hooks/auto-update-checker/constants.d.ts +11 -0
- package/dist/hooks/auto-update-checker/index.d.ts +18 -0
- package/dist/hooks/auto-update-checker/types.d.ts +22 -0
- package/dist/hooks/chat-headers.d.ts +16 -0
- package/dist/hooks/context-pressure-reminder/index.d.ts +33 -0
- package/dist/hooks/delegate-task-retry/guidance.d.ts +2 -0
- package/dist/hooks/delegate-task-retry/hook.d.ts +8 -0
- package/dist/hooks/delegate-task-retry/index.d.ts +4 -0
- package/dist/hooks/delegate-task-retry/patterns.d.ts +11 -0
- package/dist/hooks/filter-available-skills/index.d.ts +32 -0
- package/dist/hooks/foreground-fallback/index.d.ts +72 -0
- package/dist/hooks/image-hook.d.ts +5 -0
- package/dist/hooks/index.d.ts +14 -0
- package/dist/hooks/json-error-recovery/hook.d.ts +18 -0
- package/dist/hooks/json-error-recovery/index.d.ts +1 -0
- package/dist/hooks/phase-reminder/index.d.ts +26 -0
- package/dist/hooks/post-file-tool-nudge/index.d.ts +19 -0
- package/dist/hooks/task-session-manager/index.d.ts +52 -0
- package/dist/hooks/todo-continuation/index.d.ts +53 -0
- package/dist/hooks/todo-continuation/todo-hygiene.d.ts +35 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +31782 -0
- package/dist/mcp/context7.d.ts +6 -0
- package/dist/mcp/grep-app.d.ts +6 -0
- package/dist/mcp/index.d.ts +13 -0
- package/dist/mcp/types.d.ts +12 -0
- package/dist/mcp/websearch.d.ts +9 -0
- package/dist/skills/registry.d.ts +29 -0
- package/dist/subscriptions/accounts-store.d.ts +57 -0
- package/dist/subscriptions/index.d.ts +13 -0
- package/dist/subscriptions/neuralwatt-scraper.d.ts +14 -0
- package/dist/subscriptions/opencode-go-scraper.d.ts +27 -0
- package/dist/subscriptions/types.d.ts +115 -0
- package/dist/subscriptions/usage-service.d.ts +74 -0
- package/dist/tools/ast-grep/cli.d.ts +15 -0
- package/dist/tools/ast-grep/constants.d.ts +25 -0
- package/dist/tools/ast-grep/downloader.d.ts +5 -0
- package/dist/tools/ast-grep/index.d.ts +10 -0
- package/dist/tools/ast-grep/tools.d.ts +3 -0
- package/dist/tools/ast-grep/types.d.ts +30 -0
- package/dist/tools/ast-grep/utils.d.ts +4 -0
- package/dist/tools/delegate.d.ts +14 -0
- package/dist/tools/index.d.ts +5 -0
- package/dist/tools/preset-manager.d.ts +27 -0
- package/dist/tools/smartfetch/binary.d.ts +3 -0
- package/dist/tools/smartfetch/cache.d.ts +6 -0
- package/dist/tools/smartfetch/constants.d.ts +12 -0
- package/dist/tools/smartfetch/index.d.ts +3 -0
- package/dist/tools/smartfetch/network.d.ts +38 -0
- package/dist/tools/smartfetch/secondary-model.d.ts +28 -0
- package/dist/tools/smartfetch/tool.d.ts +3 -0
- package/dist/tools/smartfetch/types.d.ts +122 -0
- package/dist/tools/smartfetch/utils.d.ts +18 -0
- package/dist/tui-state.d.ts +168 -0
- package/dist/tui.d.ts +37 -0
- package/dist/tui.js +1896 -0
- package/dist/utils/agent-variant.d.ts +63 -0
- package/dist/utils/compat.d.ts +30 -0
- package/dist/utils/env.d.ts +1 -0
- package/dist/utils/index.d.ts +9 -0
- package/dist/utils/internal-initiator.d.ts +6 -0
- package/dist/utils/logger.d.ts +8 -0
- package/dist/utils/polling.d.ts +21 -0
- package/dist/utils/session-manager.d.ts +55 -0
- package/dist/utils/session.d.ts +90 -0
- package/dist/utils/subagent-depth.d.ts +35 -0
- package/dist/utils/system-collapse.d.ts +6 -0
- package/dist/utils/task.d.ts +4 -0
- package/dist/utils/zip-extractor.d.ts +1 -0
- package/index.ts +1 -0
- package/opencode-dux.schema.json +634 -0
- package/package.json +103 -0
- package/src/agents/descriptions.ts +55 -0
- package/src/agents/designer.test.ts +86 -0
- package/src/agents/designer.ts +154 -0
- package/src/agents/display-name.test.ts +186 -0
- package/src/agents/explorer.test.ts +79 -0
- package/src/agents/explorer.ts +144 -0
- package/src/agents/fixer.test.ts +79 -0
- package/src/agents/fixer.ts +145 -0
- package/src/agents/index.test.ts +472 -0
- package/src/agents/index.ts +248 -0
- package/src/agents/interpreter.ts +136 -0
- package/src/agents/librarian.test.ts +80 -0
- package/src/agents/librarian.ts +145 -0
- package/src/agents/oracle.test.ts +89 -0
- package/src/agents/oracle.ts +184 -0
- package/src/agents/orchestrator.test.ts +116 -0
- package/src/agents/orchestrator.ts +574 -0
- package/src/agents/overrides.ts +95 -0
- package/src/agents/prompt-blocks.test.ts +114 -0
- package/src/agents/prompt-blocks.ts +640 -0
- package/src/agents/steward.ts +146 -0
- package/src/cli/config-io.test.ts +536 -0
- package/src/cli/config-io.ts +473 -0
- package/src/cli/config-manager.test.ts +141 -0
- package/src/cli/config-manager.ts +4 -0
- package/src/cli/index.ts +88 -0
- package/src/cli/install.ts +282 -0
- package/src/cli/mcps.test.ts +62 -0
- package/src/cli/mcps.ts +39 -0
- package/src/cli/model-key-normalization.test.ts +21 -0
- package/src/cli/model-key-normalization.ts +60 -0
- package/src/cli/paths.test.ts +167 -0
- package/src/cli/paths.ts +144 -0
- package/src/cli/providers.test.ts +118 -0
- package/src/cli/providers.ts +141 -0
- package/src/cli/skills.test.ts +111 -0
- package/src/cli/skills.ts +103 -0
- package/src/cli/system.test.ts +91 -0
- package/src/cli/system.ts +180 -0
- package/src/cli/types.ts +43 -0
- package/src/config/constants.ts +58 -0
- package/src/config/index.ts +4 -0
- package/src/config/loader.test.ts +1194 -0
- package/src/config/loader.ts +269 -0
- package/src/config/model-resolution.test.ts +176 -0
- package/src/config/runtime-preset.test.ts +61 -0
- package/src/config/runtime-preset.ts +37 -0
- package/src/config/schema.ts +248 -0
- package/src/config/utils.test.ts +41 -0
- package/src/config/utils.ts +23 -0
- package/src/discovery/local/types.ts +85 -0
- package/src/discovery/local.ts +322 -0
- package/src/discovery/mcp-servers.ts +804 -0
- package/src/discovery/skills.ts +959 -0
- package/src/hooks/apply-patch/codec.test.ts +184 -0
- package/src/hooks/apply-patch/codec.ts +352 -0
- package/src/hooks/apply-patch/errors.ts +117 -0
- package/src/hooks/apply-patch/execution-context.ts +432 -0
- package/src/hooks/apply-patch/hook.test.ts +768 -0
- package/src/hooks/apply-patch/index.ts +126 -0
- package/src/hooks/apply-patch/matching.test.ts +215 -0
- package/src/hooks/apply-patch/matching.ts +586 -0
- package/src/hooks/apply-patch/operations.test.ts +1535 -0
- package/src/hooks/apply-patch/operations.ts +3 -0
- package/src/hooks/apply-patch/patch.ts +9 -0
- package/src/hooks/apply-patch/prepared-changes.ts +400 -0
- package/src/hooks/apply-patch/resolution.test.ts +420 -0
- package/src/hooks/apply-patch/resolution.ts +437 -0
- package/src/hooks/apply-patch/rewrite.ts +496 -0
- package/src/hooks/apply-patch/test-helpers.ts +52 -0
- package/src/hooks/apply-patch/types.ts +111 -0
- package/src/hooks/auto-update-checker/cache.test.ts +179 -0
- package/src/hooks/auto-update-checker/cache.ts +188 -0
- package/src/hooks/auto-update-checker/checker.test.ts +159 -0
- package/src/hooks/auto-update-checker/checker.ts +308 -0
- package/src/hooks/auto-update-checker/constants.ts +33 -0
- package/src/hooks/auto-update-checker/index.test.ts +282 -0
- package/src/hooks/auto-update-checker/index.ts +225 -0
- package/src/hooks/auto-update-checker/types.ts +26 -0
- package/src/hooks/chat-headers.test.ts +236 -0
- package/src/hooks/chat-headers.ts +97 -0
- package/src/hooks/context-pressure-reminder/index.test.ts +179 -0
- package/src/hooks/context-pressure-reminder/index.ts +137 -0
- package/src/hooks/delegate-task-retry/guidance.ts +41 -0
- package/src/hooks/delegate-task-retry/hook.ts +23 -0
- package/src/hooks/delegate-task-retry/index.test.ts +38 -0
- package/src/hooks/delegate-task-retry/index.ts +7 -0
- package/src/hooks/delegate-task-retry/patterns.ts +79 -0
- package/src/hooks/filter-available-skills/index.test.ts +297 -0
- package/src/hooks/filter-available-skills/index.ts +160 -0
- package/src/hooks/foreground-fallback/index.test.ts +624 -0
- package/src/hooks/foreground-fallback/index.ts +374 -0
- package/src/hooks/image-hook.ts +6 -0
- package/src/hooks/index.ts +17 -0
- package/src/hooks/json-error-recovery/hook.ts +73 -0
- package/src/hooks/json-error-recovery/index.test.ts +111 -0
- package/src/hooks/json-error-recovery/index.ts +6 -0
- package/src/hooks/phase-reminder/index.test.ts +74 -0
- package/src/hooks/phase-reminder/index.ts +85 -0
- package/src/hooks/post-file-tool-nudge/index.test.ts +94 -0
- package/src/hooks/post-file-tool-nudge/index.ts +63 -0
- package/src/hooks/task-session-manager/index.test.ts +833 -0
- package/src/hooks/task-session-manager/index.ts +434 -0
- package/src/hooks/todo-continuation/index.test.ts +3026 -0
- package/src/hooks/todo-continuation/index.ts +878 -0
- package/src/hooks/todo-continuation/todo-hygiene.test.ts +204 -0
- package/src/hooks/todo-continuation/todo-hygiene.ts +207 -0
- package/src/index.ts +1672 -0
- package/src/mcp/context7.ts +14 -0
- package/src/mcp/grep-app.ts +11 -0
- package/src/mcp/index.test.ts +96 -0
- package/src/mcp/index.ts +66 -0
- package/src/mcp/types.ts +16 -0
- package/src/mcp/websearch.ts +47 -0
- package/src/skills/codemap/README.md +60 -0
- package/src/skills/codemap/SKILL.md +174 -0
- package/src/skills/codemap/scripts/codemap.mjs +483 -0
- package/src/skills/codemap/scripts/codemap.test.ts +129 -0
- package/src/skills/registry.ts +218 -0
- package/src/skills/simplify/README.md +19 -0
- package/src/skills/simplify/SKILL.md +138 -0
- package/src/subscriptions/accounts-store.test.ts +236 -0
- package/src/subscriptions/accounts-store.ts +184 -0
- package/src/subscriptions/index.ts +30 -0
- package/src/subscriptions/neuralwatt-scraper.ts +108 -0
- package/src/subscriptions/opencode-go-scraper.ts +301 -0
- package/src/subscriptions/types.ts +145 -0
- package/src/subscriptions/usage-service.test.ts +202 -0
- package/src/subscriptions/usage-service.ts +651 -0
- package/src/tools/ast-grep/cli.ts +257 -0
- package/src/tools/ast-grep/constants.ts +214 -0
- package/src/tools/ast-grep/downloader.ts +131 -0
- package/src/tools/ast-grep/index.ts +24 -0
- package/src/tools/ast-grep/tools.ts +117 -0
- package/src/tools/ast-grep/types.ts +51 -0
- package/src/tools/ast-grep/utils.ts +126 -0
- package/src/tools/delegate-handoff.test.ts +18 -0
- package/src/tools/delegate.ts +508 -0
- package/src/tools/index.ts +8 -0
- package/src/tools/preset-manager.test.ts +795 -0
- package/src/tools/preset-manager.ts +332 -0
- package/src/tools/smartfetch/binary.ts +58 -0
- package/src/tools/smartfetch/cache.test.ts +34 -0
- package/src/tools/smartfetch/cache.ts +112 -0
- package/src/tools/smartfetch/constants.ts +29 -0
- package/src/tools/smartfetch/index.ts +8 -0
- package/src/tools/smartfetch/network.test.ts +178 -0
- package/src/tools/smartfetch/network.ts +614 -0
- package/src/tools/smartfetch/secondary-model.test.ts +85 -0
- package/src/tools/smartfetch/secondary-model.ts +276 -0
- package/src/tools/smartfetch/tool.test.ts +60 -0
- package/src/tools/smartfetch/tool.ts +832 -0
- package/src/tools/smartfetch/types.ts +135 -0
- package/src/tools/smartfetch/utils.test.ts +24 -0
- package/src/tools/smartfetch/utils.ts +456 -0
- package/src/tui-state.test.ts +867 -0
- package/src/tui-state.ts +1255 -0
- package/src/tui.test.ts +336 -0
- package/src/tui.ts +1539 -0
- package/src/utils/agent-variant.test.ts +244 -0
- package/src/utils/agent-variant.ts +187 -0
- package/src/utils/compat.ts +91 -0
- package/src/utils/env.ts +12 -0
- package/src/utils/index.ts +9 -0
- package/src/utils/internal-initiator.ts +28 -0
- package/src/utils/logger.test.ts +220 -0
- package/src/utils/logger.ts +136 -0
- package/src/utils/polling.test.ts +191 -0
- package/src/utils/polling.ts +67 -0
- package/src/utils/session-manager.test.ts +173 -0
- package/src/utils/session-manager.ts +356 -0
- package/src/utils/session.test.ts +110 -0
- package/src/utils/session.ts +389 -0
- package/src/utils/subagent-depth.test.ts +170 -0
- package/src/utils/subagent-depth.ts +75 -0
- package/src/utils/system-collapse.test.ts +86 -0
- package/src/utils/system-collapse.ts +24 -0
- package/src/utils/task.test.ts +24 -0
- package/src/utils/task.ts +20 -0
- package/src/utils/zip-extractor.ts +102 -0
|
@@ -0,0 +1,574 @@
|
|
|
1
|
+
import type { AgentConfig } from '@opencode-ai/sdk/v2';
|
|
2
|
+
import { AGENT_DESCRIPTIONS } from './descriptions';
|
|
3
|
+
import {
|
|
4
|
+
buildConsolidatedVariantGuide,
|
|
5
|
+
buildDiscoveryGuidanceBlock,
|
|
6
|
+
buildInterpreterOrchestratorProtocolBlock,
|
|
7
|
+
buildStewardOrchestratorProtocolBlock,
|
|
8
|
+
CRITICAL_INVARIANTS,
|
|
9
|
+
FIXER_ORCHESTRATOR_DELEGATION_VARIANT_RULE,
|
|
10
|
+
formatOrchestratorOracleVariantDepthSection,
|
|
11
|
+
ORCHESTRATOR_CLARIFICATION_HANDOFF,
|
|
12
|
+
PLANNING_GATE_BLOCK,
|
|
13
|
+
STEWARD_CITATION_HEADER,
|
|
14
|
+
} from './prompt-blocks';
|
|
15
|
+
|
|
16
|
+
export interface AgentDefinition {
|
|
17
|
+
name: string;
|
|
18
|
+
displayName?: string;
|
|
19
|
+
description?: string;
|
|
20
|
+
config: AgentConfig;
|
|
21
|
+
/** Priority-ordered model entries for runtime fallback resolution. */
|
|
22
|
+
_modelArray?: Array<{ id: string; variant?: string }>;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Resolve agent prompt from base/custom/append inputs.
|
|
27
|
+
* If customPrompt is provided, it replaces the base entirely.
|
|
28
|
+
* Otherwise, customAppendPrompt is appended to the base.
|
|
29
|
+
*/
|
|
30
|
+
export function resolvePrompt(
|
|
31
|
+
base: string,
|
|
32
|
+
customPrompt?: string,
|
|
33
|
+
customAppendPrompt?: string,
|
|
34
|
+
): string {
|
|
35
|
+
if (customPrompt !== undefined) return customPrompt;
|
|
36
|
+
if (customAppendPrompt !== undefined)
|
|
37
|
+
return `${base}\n\n${customAppendPrompt}`;
|
|
38
|
+
return base;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Validation routing lines that reference agents
|
|
42
|
+
const VALIDATION_ROUTING = [
|
|
43
|
+
'- Route ALL UI/UX work (design, review, validation, planning for TSX/JSX changes) to @designer',
|
|
44
|
+
'- Route in-repo agent/IDE rule and conventions briefing to @steward',
|
|
45
|
+
'- Route code review, simplification, maintainability review, and YAGNI checks to @oracle',
|
|
46
|
+
'- Route test writing, test updates, and changes touching test files to @fixer',
|
|
47
|
+
"- If a request spans multiple lanes, delegate each lane independently. Omit a lane only when it overlaps with another lane's scope (e.g., @oracle code review already covers the same ground as @designer UI review for a backend-only change).",
|
|
48
|
+
];
|
|
49
|
+
|
|
50
|
+
// Parallel delegation examples
|
|
51
|
+
const PARALLEL_DELEGATION_EXAMPLES = [
|
|
52
|
+
'- Multiple @explorer searches across different domains?',
|
|
53
|
+
'- Multiple @explorers scoped by directory for faster codebase discovery?',
|
|
54
|
+
'- @explorer + @librarian research in parallel?',
|
|
55
|
+
'- Multiple @librarians researching different libraries in parallel?',
|
|
56
|
+
'- Multiple @fixer instances for faster, scoped implementation?',
|
|
57
|
+
'- After required blocking @steward, multiple @explorers scoped by directory for faster discovery?',
|
|
58
|
+
];
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Build the orchestrator prompt.
|
|
62
|
+
* @returns The complete orchestrator prompt string
|
|
63
|
+
*/
|
|
64
|
+
export function buildOrchestratorPrompt(
|
|
65
|
+
oracleDefaultModel?: string,
|
|
66
|
+
oracleSmartModel?: string,
|
|
67
|
+
): string {
|
|
68
|
+
// Filter agent descriptions
|
|
69
|
+
const enabledAgents = Object.values(AGENT_DESCRIPTIONS).join('\n\n');
|
|
70
|
+
|
|
71
|
+
const enabledValidationRouting = VALIDATION_ROUTING.join('\n');
|
|
72
|
+
|
|
73
|
+
const enabledParallelExamples = PARALLEL_DELEGATION_EXAMPLES.join('\n');
|
|
74
|
+
|
|
75
|
+
const oracleDefaultResolved = oracleDefaultModel ?? '';
|
|
76
|
+
const oracleSmartResolved = oracleSmartModel ?? oracleDefaultModel ?? '';
|
|
77
|
+
const singleTierMode =
|
|
78
|
+
!oracleSmartResolved || oracleSmartResolved === oracleDefaultResolved;
|
|
79
|
+
// Use placeholder strings when models are not yet configured, so prompt
|
|
80
|
+
// examples render with readable text instead of empty model: "" strings.
|
|
81
|
+
const oracleDefault = oracleDefaultResolved || '<oracle-default>';
|
|
82
|
+
const oracleSmart =
|
|
83
|
+
oracleSmartResolved || oracleDefaultResolved || '<oracle-smart>';
|
|
84
|
+
const modelPoolLines = singleTierMode
|
|
85
|
+
? `- single tier: ${oracleDefault} (no separate smart model configured; treat as one-tier - raise variant by one step where smart would otherwise apply)`
|
|
86
|
+
: `- default: ${oracleDefault}\n- smart: ${oracleSmart}`;
|
|
87
|
+
|
|
88
|
+
const stewardProtocolBlock = buildStewardOrchestratorProtocolBlock();
|
|
89
|
+
|
|
90
|
+
const interpreterProtocolBlock = buildInterpreterOrchestratorProtocolBlock();
|
|
91
|
+
|
|
92
|
+
const firstGateItems: string[] = [];
|
|
93
|
+
|
|
94
|
+
// Item 1: Convention briefs
|
|
95
|
+
firstGateItems.push(
|
|
96
|
+
'1) Convention briefs: blocking @steward first. Require root `AGENTS.md` (then `AGENT.md` if both exist) + steward_paths. @steward cites verbatim text only — it does NOT analyze, compare, or evaluate rules. NEVER delegate to @steward for: "analyze rules", "find contradictions", "check consistency", "identify gaps", or any task requiring evaluation of steward_paths content. Those are @oracle analysis tasks.',
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
// Item 2: Analysis gate
|
|
100
|
+
firstGateItems.push(
|
|
101
|
+
'2) Analysis: blocking @oracle for any technical reasoning (debugging, review, root cause, architecture, tradeoffs, risk — including quick opinions). This INCLUDES rules analysis: "are conventions consistent?", "do these rules conflict?", "find gaps in agent prompts." @steward only cites rules verbatim; @oracle evaluates them. Never reason through these in orchestrator messages.',
|
|
102
|
+
);
|
|
103
|
+
|
|
104
|
+
// Item 3: Direct answer boundary
|
|
105
|
+
firstGateItems.push(
|
|
106
|
+
'3) Direct answer only for: pure meta (how delegation works), repeating prior subagent output verbatim. NOT for debugging, review, or product diagnosis.',
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
// Item 4: New UI
|
|
110
|
+
firstGateItems.push(
|
|
111
|
+
'4) ANY user-facing UI work (new pages, existing component modifications, TSX/JSX changes, layout, styling, visual elements): blocking @designer FIRST — before any @oracle analysis or @fixer implementation. @designer evaluates UX impact, component architecture, a11y, and styling system fit, then produces `<implementation_notes>`. @oracle may be consulted AFTER @designer only for complex technical concerns (state management, data flow, performance), never instead of @designer. @fixer implements from `<implementation_notes>` only — never invents UI or makes UX decisions. Exception: trivial copy-only text changes where the user provides exact before/after strings with no structural, layout, or behavioral modification. Pure backend logic (hooks, utilities, API calls) inside a component file does NOT trigger this rule — only changes that affect what the user sees or how they interact.',
|
|
112
|
+
);
|
|
113
|
+
|
|
114
|
+
const firstGateBody = firstGateItems.join('\n');
|
|
115
|
+
|
|
116
|
+
const firstGateBlock = `<first_gate>
|
|
117
|
+
${firstGateBody}
|
|
118
|
+
</first_gate>
|
|
119
|
+
|
|
120
|
+
`;
|
|
121
|
+
|
|
122
|
+
return `<role>
|
|
123
|
+
You are a coding orchestrator. Your job is routing, delegation, integration, and verification.
|
|
124
|
+
|
|
125
|
+
See <interpreter_protocol> for image handling.
|
|
126
|
+
</role>
|
|
127
|
+
|
|
128
|
+
<context_budget>
|
|
129
|
+
When the latest user turn includes "### Context budget (plugin telemetry)" (live usage from this plugin), the orchestrator session is near the model context ceiling-continuing may error with no context left. Before large new delegations or heavy tool fanout, tell the user to run \`/compact\` or continue in a new session. If a blocking delegation is mid-flight, finish the smallest safe step first, then compact.
|
|
130
|
+
</context_budget>
|
|
131
|
+
|
|
132
|
+
${CRITICAL_INVARIANTS}
|
|
133
|
+
|
|
134
|
+
${firstGateBlock}${PLANNING_GATE_BLOCK}
|
|
135
|
+
<agents>
|
|
136
|
+
${enabledAgents}
|
|
137
|
+
</agents>
|
|
138
|
+
|
|
139
|
+
<routing_priority>
|
|
140
|
+
When instructions conflict: (1) when in doubt about safety implications, escalate to smart @oracle depth; (2) specialists per <first_gate> + <agents>; (3) cost → \`model\` + \`variant\`, not skipped delegation.
|
|
141
|
+
</routing_priority>
|
|
142
|
+
|
|
143
|
+
<constraints>
|
|
144
|
+
- Defaults: <first_gate> items 1-4, then <routing>/<execution>. Below = hard prohibitions.
|
|
145
|
+
- NEVER edit files or run codebase discovery (grep/glob/read) yourself-@fixer / @explorer only.
|
|
146
|
+
- NEVER read rule corpora yourself-item 1 + <steward_protocol> when @steward is listed (else explorer globs: \`AGENTS.md\` / \`AGENT.md\` / \`**/.docs\` / \`**/.cursor/rules\`).
|
|
147
|
+
- NEVER treat @steward as analyzer — merge citations; @explorer locates files + @oracle diagnoses. @steward cites verbatim text from steward_paths; it does NOT evaluate rules for consistency, correctness, or applicability. Rules analysis is @oracle's domain.
|
|
148
|
+
- NEVER loop past 3 failed @fixer rounds with oracle escalation-stop and report.
|
|
149
|
+
- NEVER delegate with unknown tools. Use \`delegate_subagent\` only.
|
|
150
|
+
${FIXER_ORCHESTRATOR_DELEGATION_VARIANT_RULE}
|
|
151
|
+
- NEVER delegate @steward with mode: "fire_forget" - steward must always be blocking. Its citations are required input for all downstream agents.
|
|
152
|
+
- NEVER issue @steward and @oracle (or @steward and any other blocking agent) in the same tool-call turn - steward MUST complete first because its citations are required input for all downstream agents. Always emit steward alone, wait for its result, then emit the next agent.
|
|
153
|
+
- NEVER parallel @explorers on overlapping scope-different directories only, named explicitly.
|
|
154
|
+
- NEVER proceed to @fixer before the user has explicitly confirmed the plan. If the user has not responded, stop and wait.
|
|
155
|
+
</constraints>
|
|
156
|
+
|
|
157
|
+
<routing>
|
|
158
|
+
<decision_tree>
|
|
159
|
+
- Pure meta only (how delegation works; repeat prior subagent text verbatim): answer directly — not technical Q/A.
|
|
160
|
+
- **Images present**: per <interpreter_protocol>.
|
|
161
|
+
- **UI work detected** (user request mentions TSX/JSX files, components, pages, layouts, styling, user-facing visual elements, or describes screens/modals/forms/buttons/tables/lists): route to @designer FIRST per <first_gate> 4 + <ui_routing_precedence>. @oracle analysis comes AFTER @designer produces \`<implementation_notes>\`, never before or instead of it. This check runs BEFORE the analysis branch below.
|
|
162
|
+
- Locate files/symbols/tests/config links: @explorer. External docs/API/releases: @librarian.
|
|
163
|
+
- Rules & \`AGENTS.md\` / \`AGENT.md\`: <first_gate> 1 + <steward_protocol>. (Citing verbatim: @steward. Analyzing rules: @oracle.)
|
|
164
|
+
- Analysis / thinking (NON-UI tasks only — UI tasks route to @designer first per above): <first_gate> 2 + <oracle_model_and_variant_selection>.
|
|
165
|
+
- Full implementation order: <execution>; never skip item 1 for code-affecting work.
|
|
166
|
+
</decision_tree>
|
|
167
|
+
|
|
168
|
+
<ui_routing_precedence>
|
|
169
|
+
When a user request involves ANY UI work — detected by: file paths ending in .tsx/.jsx, mentions of components/pages/layouts/styling/CSS, describes screens/modals/forms/buttons/tables/lists, or requests adding/changing anything user-facing — @designer MUST be the FIRST specialist consulted.
|
|
170
|
+
|
|
171
|
+
This is a HARD GATE. It takes precedence over:
|
|
172
|
+
- The analysis path (<first_gate> item 2): do NOT route UI requests to @oracle first for "analysis."
|
|
173
|
+
- The existing-code path (<execution> step 3): UI changes to existing files are NOT "existing code changes" that skip @designer.
|
|
174
|
+
- Any "quick look" or "scoping" impulse: do NOT pre-analyze UI work yourself or through @oracle before @designer.
|
|
175
|
+
|
|
176
|
+
Only after @designer produces \`<implementation_notes>\` should @oracle be consulted (for complex technical concerns) or @fixer implement. If you are unsure whether something is UI work, default to routing it to @designer first — false positives cost one extra round-trip; false negatives cost a broken UX chain.
|
|
177
|
+
</ui_routing_precedence>
|
|
178
|
+
|
|
179
|
+
<good_example>
|
|
180
|
+
User: "Where is retry logic configured?"
|
|
181
|
+
Action: Delegate to @explorer, return mapped file paths and lines.
|
|
182
|
+
<reasoning>Codebase location request is discovery, not direct Q and A.</reasoning>
|
|
183
|
+
</good_example>
|
|
184
|
+
|
|
185
|
+
<bad_example>
|
|
186
|
+
User: "Where is retry logic configured?"
|
|
187
|
+
Action: Read random files and guess from memory.
|
|
188
|
+
<reasoning>This violates discovery routing and lowers accuracy.</reasoning>
|
|
189
|
+
</bad_example>
|
|
190
|
+
|
|
191
|
+
<validation_routing>
|
|
192
|
+
${enabledValidationRouting}
|
|
193
|
+
</validation_routing>
|
|
194
|
+
</routing>
|
|
195
|
+
|
|
196
|
+
<delegation>
|
|
197
|
+
<tool_schema name="delegate_subagent">
|
|
198
|
+
- Required: \`agent\`, \`prompt\`
|
|
199
|
+
- Optional: \`model\`, \`variant\`, \`mode\`
|
|
200
|
+
- \`mode: "blocking"\` waits for result before continuing - use when downstream steps depend on the output
|
|
201
|
+
- \`mode: "fire_forget"\` returns session id immediately - use for parallel independent long-running tasks; retrieve results via session id later
|
|
202
|
+
</tool_schema>
|
|
203
|
+
|
|
204
|
+
\`continue_session_id\`: Reuse for iterative work on the same scope -
|
|
205
|
+
applies to ALL agents, not just @fixer. After user answers a <needs_user>,
|
|
206
|
+
resume the same specialist session.
|
|
207
|
+
|
|
208
|
+
${buildConsolidatedVariantGuide()}
|
|
209
|
+
|
|
210
|
+
<rules>
|
|
211
|
+
- Always pass concise context: paths, symbols, and goals; do not dump full files.
|
|
212
|
+
- Prefer parallel delegation for independent work streams.
|
|
213
|
+
- When the orchestrator model supports high parallel tool fanout, issue multi-call parallel delegations in a single turn.
|
|
214
|
+
- Only parallelize independent tasks. Keep dependent steps sequential.
|
|
215
|
+
- Never skip delegation for code changes. Even trivial edits should go through @fixer for consistency.
|
|
216
|
+
- When a blocking @steward call is needed, it MUST be the ONLY tool call in that turn. Wait for steward's result before issuing any other delegate_subagent calls. This is enforced at runtime but must also be followed in prompt output to avoid wasted retries.
|
|
217
|
+
${enabledParallelExamples}
|
|
218
|
+
</rules>
|
|
219
|
+
|
|
220
|
+
<good_example>
|
|
221
|
+
User: "Find all callers of \`delegate_subagent\` and tell me their signatures."
|
|
222
|
+
Action: Two parallel \`delegate_subagent(agent: "explorer", ...)\` calls - one for src/agents, one for src/hooks.
|
|
223
|
+
<reasoning>Independent searches in different directories should fan out in parallel.</reasoning>
|
|
224
|
+
</good_example>
|
|
225
|
+
|
|
226
|
+
<good_example>
|
|
227
|
+
\`delegate_subagent(agent: "oracle", prompt: "...", model: "${oracleSmart}", variant: "high", mode: "blocking")\`
|
|
228
|
+
<reasoning>Explicit model + variant for oracle gives deterministic routing and escalation.</reasoning>
|
|
229
|
+
</good_example>
|
|
230
|
+
|
|
231
|
+
<bad_example>
|
|
232
|
+
\`delegate_subagent(agent: "oracle", prompt: "...")\`
|
|
233
|
+
<reasoning>Missing \`model\` violates explicit oracle model selection policy.</reasoning>
|
|
234
|
+
</bad_example>
|
|
235
|
+
</delegation>
|
|
236
|
+
|
|
237
|
+
<subagent_recovery>
|
|
238
|
+
When a delegation returns <blocked> or unexpected results, follow this recovery
|
|
239
|
+
protocol before escalating:
|
|
240
|
+
|
|
241
|
+
<recovery_principle>
|
|
242
|
+
Always preserve session context: use the \`session_id\` from the
|
|
243
|
+
\`<delegate_session_continue>\` tag appended to the subagent result.
|
|
244
|
+
Pass it as \`continue_session_id\` when re-delegating to the SAME subagent.
|
|
245
|
+
This avoids re-explaining the entire task from scratch.
|
|
246
|
+
</recovery_principle>
|
|
247
|
+
|
|
248
|
+
<recovery_decision_tree>
|
|
249
|
+
When you see <blocked>, classify the blocker and follow the matching path:
|
|
250
|
+
|
|
251
|
+
1) BLOCKER: Missing tools (e.g. "ast_grep_search unavailable",
|
|
252
|
+
"github MCP not configured")
|
|
253
|
+
→ Option A: Re-delegate to the SAME subagent with \`continue_session_id\` and
|
|
254
|
+
tighter scope OR tool fallback instructions.
|
|
255
|
+
→ Option B: Call the discovery tools (\`discover_mcp_servers\` or
|
|
256
|
+
\`discover_skills\`) to find installable MCP servers or skills that provide
|
|
257
|
+
the missing capability. Present top 1-3 recommendations to the user and ask
|
|
258
|
+
if they want to install. See <discovery_guidance> for when and how to call
|
|
259
|
+
these tools.
|
|
260
|
+
→ If the subagent's <blocked> includes a \`suggested_fallback\`, pass it
|
|
261
|
+
verbatim.
|
|
262
|
+
|
|
263
|
+
2) BLOCKER: Missing repo context (specific file paths, symbols, steward
|
|
264
|
+
citations)
|
|
265
|
+
→ STEP A: Retrieve the missing info by delegating to @explorer (for
|
|
266
|
+
file/symbol lookups; blocking) or @steward (for repo rules; ALWAYS
|
|
267
|
+
blocking). Do NOT read files yourself.
|
|
268
|
+
→ STEP B: Re-delegate to the ORIGINAL subagent with \`continue_session_id\`.
|
|
269
|
+
Include the retrieved info in the resume prompt, prefixed with
|
|
270
|
+
"Here is the missing context you requested:"
|
|
271
|
+
→ If the subagent's <blocked> includes a \`retrieval_hint\`, use it
|
|
272
|
+
directly as the @explorer/@steward prompt.
|
|
273
|
+
|
|
274
|
+
3) BLOCKER: Missing external information (librarian research needed, API docs,
|
|
275
|
+
version specifics)
|
|
276
|
+
→ STEP A: Delegate to @librarian (or webfetch/websearch) with the exact
|
|
277
|
+
research query from the subagent's <blocked>. Use \`retrieval_hint\` if
|
|
278
|
+
provided.
|
|
279
|
+
→ STEP B: Re-delegate to the ORIGINAL subagent with \`continue_session_id\`.
|
|
280
|
+
Include the librarian's findings in the resume prompt.
|
|
281
|
+
|
|
282
|
+
4) BLOCKER: Missing user clarification (<needs_user> returned alongside or
|
|
283
|
+
instead of <blocked>)
|
|
284
|
+
→ Use the ORCHESTRATOR_CLARIFICATION_HANDOFF protocol (9 invariants).
|
|
285
|
+
→ After user answers, re-delegate with \`continue_session_id\`, same
|
|
286
|
+
agent/model/variant.
|
|
287
|
+
|
|
288
|
+
5) RESULT: Empty output or <no_results>
|
|
289
|
+
→ Re-delegate to the SAME subagent with \`continue_session_id\`, tighter
|
|
290
|
+
scope, and explicit output format requirements. Use \`mode: "blocking"\`.
|
|
291
|
+
|
|
292
|
+
6) RESULT: @oracle plan missing concrete file paths or specific change descriptions
|
|
293
|
+
→ Re-delegate @oracle with \`continue_session_id\` and
|
|
294
|
+
"Make the plan concrete enough for @fixer to implement without ambiguity.
|
|
295
|
+
Include file paths, exact changes, and verification gates."
|
|
296
|
+
</recovery_decision_tree>
|
|
297
|
+
|
|
298
|
+
<session_id_extraction>
|
|
299
|
+
After a blocking delegation, the result includes a tag like:
|
|
300
|
+
<delegate_session_continue session_id="abc123" agent="oracle" />
|
|
301
|
+
Extract the \`session_id\` value and use it as \`continue_session_id\` when
|
|
302
|
+
re-delegating to the same agent.
|
|
303
|
+
</session_id_extraction>
|
|
304
|
+
|
|
305
|
+
<recovery_examples>
|
|
306
|
+
<good_example>
|
|
307
|
+
@oracle returns:
|
|
308
|
+
\`<blocked>\`Missing Context7 docs for Next.js App Router caching behavior.
|
|
309
|
+
<retrieval_hint>Search Context7 for "/vercel/next.js" with query
|
|
310
|
+
"App Router caching and revalidation patterns in Next.js 14+"</retrieval_hint>
|
|
311
|
+
<suggested_agent>librarian</suggested_agent>
|
|
312
|
+
\`</blocked>\`
|
|
313
|
+
...<delegate_session_continue session_id="ora_789" agent="oracle"/>
|
|
314
|
+
Orchestrator:
|
|
315
|
+
1) delegate_subagent(agent: "librarian", prompt: "Search Context7 for...")
|
|
316
|
+
2) delegate_subagent(agent: "oracle",
|
|
317
|
+
continue_session_id: "ora_789",
|
|
318
|
+
prompt: "Here is the missing context you requested:
|
|
319
|
+
\n\n[librarian results]")
|
|
320
|
+
<reasoning>Retrieve external info via librarian, then resume oracle with
|
|
321
|
+
continue_session_id to preserve all prior analysis context.</reasoning>
|
|
322
|
+
</good_example>
|
|
323
|
+
|
|
324
|
+
<good_example>
|
|
325
|
+
@fixer returns:
|
|
326
|
+
\`<blocked>\`Cannot locate retry configuration - need path to RetryConfig interface
|
|
327
|
+
and its implementation file.
|
|
328
|
+
<retrieval_hint>grep for "RetryConfig" in src/ and "interface RetryConfig"
|
|
329
|
+
pattern</retrieval_hint>
|
|
330
|
+
\`</blocked>\`
|
|
331
|
+
...<delegate_session_continue session_id="fix_456" agent="fixer"/>
|
|
332
|
+
Orchestrator:
|
|
333
|
+
1) delegate_subagent(agent: "explorer",
|
|
334
|
+
prompt: "grep for 'RetryConfig' in src/ and find 'interface RetryConfig'")
|
|
335
|
+
2) delegate_subagent(agent: "fixer",
|
|
336
|
+
continue_session_id: "fix_456",
|
|
337
|
+
prompt: "Here is the missing context you requested:
|
|
338
|
+
\n\n[explorer results]")
|
|
339
|
+
<reasoning>Retrieve repo info via explorer, then resume fixer with
|
|
340
|
+
continue_session_id.</reasoning>
|
|
341
|
+
</good_example>
|
|
342
|
+
|
|
343
|
+
<bad_example>
|
|
344
|
+
@oracle returns \`<blocked>\` "needs librarian research"
|
|
345
|
+
Orchestrator: Reads files with glob/read to find the info itself.
|
|
346
|
+
<reasoning>Violates critical invariant - NEVER read files yourself.</reasoning>
|
|
347
|
+
</bad_example>
|
|
348
|
+
|
|
349
|
+
<bad_example>
|
|
350
|
+
@oracle returns \`<blocked>\`
|
|
351
|
+
Orchestrator: delegate_subagent(agent: "oracle",
|
|
352
|
+
prompt: "Try again with more context")
|
|
353
|
+
(no continue_session_id, no retrieved info)
|
|
354
|
+
<reasoning>Re-delegating without retrieving the missing info and without
|
|
355
|
+
continue_session_id wastes the oracle's prior analysis and guarantees the
|
|
356
|
+
same blocked result.</reasoning>
|
|
357
|
+
</bad_example>
|
|
358
|
+
</recovery_examples>
|
|
359
|
+
|
|
360
|
+
<hard_limit>
|
|
361
|
+
After 2 recovery attempts per delegation (where each attempt =
|
|
362
|
+
retrieve + re-delegate), stop and escalate to the user with:
|
|
363
|
+
- What the original subagent was asked to do
|
|
364
|
+
- What blocker was reported
|
|
365
|
+
- What retrieval was attempted (and results)
|
|
366
|
+
- What remains unresolved
|
|
367
|
+
Do NOT loop indefinitely.
|
|
368
|
+
</hard_limit>
|
|
369
|
+
</subagent_recovery>
|
|
370
|
+
|
|
371
|
+
${buildDiscoveryGuidanceBlock()}
|
|
372
|
+
|
|
373
|
+
${stewardProtocolBlock}${interpreterProtocolBlock}<execution>
|
|
374
|
+
Ordered lifecycle for code-affecting tasks:
|
|
375
|
+
|
|
376
|
+
1) STEWARD BRIEF: Per <steward_protocol> — copy citations verbatim into ALL downstream prompts with explicit precedence: \`${STEWARD_CITATION_HEADER}\`.
|
|
377
|
+
|
|
378
|
+
2) ANALYSIS: Blocking @oracle for any code-affecting task. Skip when the task qualifies under any <planning_gate> skip criterion: pure meta, mechanical edits, or user-provided exact implementation. For all other tasks, @oracle analyzes the approach.
|
|
379
|
+
|
|
380
|
+
2.5) PLAN PRESENTATION & USER CONFIRMATION:
|
|
381
|
+
- After @oracle returns, relay the plan to the user for approval before any implementation.
|
|
382
|
+
- If @oracle used <needs_user> with decision forks: extract questions via \`question\` tool, relay user answers back via continue_session_id, then present the final plan.
|
|
383
|
+
- If no forks: present the plan as text (file targets, key changes, risks), ask user to confirm or request adjustments (require explicit "yes"/"proceed"/"approved" before advancing to step 3).
|
|
384
|
+
- Do NOT proceed to step 3 until the user has explicitly approved the plan.
|
|
385
|
+
- If the user requests changes: re-delegate @oracle with continue_session_id for adjustments, then re-present. Repeat until approval.
|
|
386
|
+
|
|
387
|
+
3) IMPLEMENTATION:
|
|
388
|
+
- Before delegating to @fixer, verify the @oracle plan includes:
|
|
389
|
+
✓ concrete file paths
|
|
390
|
+
✓ specific changes (not "refactor X" but "rename getCwd→getCurrentWorkingDir in src/utils/fs.ts:42")
|
|
391
|
+
✓ verification gates
|
|
392
|
+
- If the plan is missing any of the three structural elements above (file paths, specific changes, verification gates), re-delegate @oracle with \`continue_session_id\` and
|
|
393
|
+
"Make the plan concrete enough for @fixer to implement without ambiguity."
|
|
394
|
+
- Any UI work (new or existing): @designer (review mode) → @oracle (optional, only for complex technical concerns like state mgmt, data flow, or performance) → @fixer
|
|
395
|
+
@fixer implements from \`<implementation_notes>\` only — never invents UI.
|
|
396
|
+
- Non-UI existing code changes: @oracle → @fixer
|
|
397
|
+
- Mechanical edits (typo, rename, known path): @fixer low
|
|
398
|
+
Skip <planning_gate> and @oracle analysis per execution step 2; apply
|
|
399
|
+
<first_gate> item 1 (steward) only if the edit touches
|
|
400
|
+
convention-governed areas.
|
|
401
|
+
|
|
402
|
+
4) PARALLEL FIXER: Split by directory or concern. Pass \`<implementation_notes>\`
|
|
403
|
+
as context. If fixers touch overlapping interfaces, serialize them: first
|
|
404
|
+
fixer changes the interface → verify → second fixer adapts. Never run
|
|
405
|
+
overlapping-scope fixers in parallel.
|
|
406
|
+
Reuse \`continue_session_id\` for iterative work on the same scope.
|
|
407
|
+
|
|
408
|
+
5) VERIFICATION: Follow <verification> - run checks before declaring success.
|
|
409
|
+
</execution>
|
|
410
|
+
|
|
411
|
+
<verification>
|
|
412
|
+
- Before declaring success on work that touched code or tests, account for validation: prioritize evidence from delegated agents' \`<verification>\` output (especially @fixer). If edits ran but validation is missing, empty, or only contains placeholders, re-delegate a minimal check pass (typically @fixer: run scoped typecheck/tests) rather than assuming green.
|
|
413
|
+
- You do not land patches yourself; "verification" means closing the loop on whether project checks ran and what they reported-not skipping them silently after edits.
|
|
414
|
+
- Note: Running project checks (typecheck, test) via shell is NOT "reading files yourself" - it's verification. Only avoid reading source files directly.
|
|
415
|
+
- If your host exposes runnable read-only check tools, you may run them yourself as mechanical verification after @fixer completes — these are NOT 'reading files yourself.' If not, rely on @fixer's reported commands and outcomes. Run the smallest scoped check first in either case.
|
|
416
|
+
- Run project-defined checks before declaring success. Detect from the project (e.g. \`bun run check:ci\`, \`bun run typecheck\`, \`bun test\` for Bun/TypeScript repos; \`pnpm test\`, \`npm test\`, \`pytest\`, \`cargo test\`, \`go test ./...\` for others). Check fixer's \`<verification>\` output for the commands it ran, or delegate detection to @explorer if needed.
|
|
417
|
+
- Prefer the smallest scoped check first (typecheck or single-file test) before full suite.
|
|
418
|
+
- Confirm every delegated task returned a non-blocked result. Re-delegate or escalate on \`<blocked>\` or \`<no_results>\` outputs.
|
|
419
|
+
- Verify the final output addresses the same entities, scope, and question type as the user's request. If unsure about alignment, delegate to @oracle to verify.
|
|
420
|
+
</verification>
|
|
421
|
+
|
|
422
|
+
|
|
423
|
+
<oracle_model_pool>
|
|
424
|
+
${modelPoolLines}
|
|
425
|
+
</oracle_model_pool>
|
|
426
|
+
|
|
427
|
+
<oracle_model_and_variant_selection>
|
|
428
|
+
Only @oracle does analysis (item 2). VARIANT = depth; MODEL = tier.
|
|
429
|
+
|
|
430
|
+
${formatOrchestratorOracleVariantDepthSection()}
|
|
431
|
+
|
|
432
|
+
MODEL:
|
|
433
|
+
- default (flash): low-cost oracle for standard debugging and scoped reviews - use variants medium, high, or max only (never low)
|
|
434
|
+
- smart (pro): novel architecture, unclear root cause, cross-framework subtlety, security/concurrency, or when flash analysis was wrong/low-confidence - variants low through max
|
|
435
|
+
|
|
436
|
+
When variant is omitted from delegate_subagent, Oracle defaults to medium.
|
|
437
|
+
|
|
438
|
+
Scenario → model+variant quick reference:
|
|
439
|
+
| Scenario | Model | Variant |
|
|
440
|
+
|---|---|---|
|
|
441
|
+
| Default starting point | default | medium |
|
|
442
|
+
| Multi-file or moderate ambiguity | default | high |
|
|
443
|
+
| Systemic non-security issue | default | max |
|
|
444
|
+
| Flash output was insufficient | smart | medium |
|
|
445
|
+
| Novel/unclear domain | smart | high |
|
|
446
|
+
| Auth, security, exploit, data-integrity | smart | max |
|
|
447
|
+
| Quick smart follow-up | smart | low |
|
|
448
|
+
|
|
449
|
+
NEVER use default (flash) + low. NEVER use default for security-critical analysis. Use smart + high or smart + max depending on risk.
|
|
450
|
+
When smart is not configured, keep default model but raise variant one step versus what you would pick with smart available (e.g. prefer default + high where you would have chosen smart + medium).
|
|
451
|
+
|
|
452
|
+
<oracle_escalation_flow>
|
|
453
|
+
⚠️ If you are unsure whether a task is security-critical, novel, or high-risk, do NOT classify it yourself. Delegate to @oracle (default + medium or default + high) for a preliminary classification. Use the oracle's \`<confidence>\` level and \`<recommendation>\` to determine escalation need.
|
|
454
|
+
|
|
455
|
+
⚠️ Escalation sequence for the same unresolved issue:
|
|
456
|
+
1. default + medium
|
|
457
|
+
2. smart + medium
|
|
458
|
+
3. smart + max
|
|
459
|
+
MUST change model or variant at each step — never repeat the same combo.
|
|
460
|
+
If smart is unavailable, escalate variant instead (medium → high → max on default).
|
|
461
|
+
|
|
462
|
+
⚠️ Single-tier mode (no smart model): Escalate variant instead of model.
|
|
463
|
+
default+medium → default+high → default+max
|
|
464
|
+
</oracle_escalation_flow>
|
|
465
|
+
|
|
466
|
+
<model_examples>
|
|
467
|
+
<good_example>
|
|
468
|
+
User: "Trace why this retry counter drifts in one service."
|
|
469
|
+
Action: \`delegate_subagent(agent: "oracle", prompt: "...", model: "${oracleDefault}", variant: "medium", mode: "blocking")\`
|
|
470
|
+
<reasoning>Default starting point for analysis. If @oracle identifies security implications, escalate model/variant per the scenario table.</reasoning>
|
|
471
|
+
</good_example>
|
|
472
|
+
|
|
473
|
+
<bad_example>
|
|
474
|
+
User: "Check JWT verification for signature-bypass paths."
|
|
475
|
+
Action: \`delegate_subagent(agent: "oracle", prompt: "...", model: "<default-model>", variant: "medium", mode: "blocking")\`
|
|
476
|
+
<reasoning>Security-critical analysis must not use default model. Use smart + high or smart + max.</reasoning>
|
|
477
|
+
</bad_example>
|
|
478
|
+
</model_examples>
|
|
479
|
+
|
|
480
|
+
<multi_agent_examples>
|
|
481
|
+
<good_example>
|
|
482
|
+
User: "Fix the flaky queue retry in src/queue.ts"
|
|
483
|
+
Action:
|
|
484
|
+
1) steward(medium) → cites AGENTS.md test conventions
|
|
485
|
+
2) oracle(default, high) → diagnoses race condition, produces plan
|
|
486
|
+
3) fixer(medium) → implements plan, runs tests
|
|
487
|
+
<reasoning>Complete chain: steward briefs, oracle analyzes, fixer implements - each blocking and sequential.</reasoning>
|
|
488
|
+
</good_example>
|
|
489
|
+
|
|
490
|
+
<good_example>
|
|
491
|
+
@explorer returns <blocked>: "ast_grep_search unavailable"
|
|
492
|
+
Orchestrator: Re-delegates with "use regex fallback, narrow to src/agents/ only."
|
|
493
|
+
<reasoning>Blocked output requires tighter rescoping or tool fallback, not abandonment.</reasoning>
|
|
494
|
+
</good_example>
|
|
495
|
+
|
|
496
|
+
<good_example>
|
|
497
|
+
@designer returns:
|
|
498
|
+
<needs_user>
|
|
499
|
+
<reason>Config panel entry point ambiguous: modal or inline?</reason>
|
|
500
|
+
<questions>[{"question": "Should the config panel be a modal overlay or an inline section?", "header": "Config panel style", "options": [{"label": "Modal", "description": "Overlay dialog; better focus, interrupts workflow"}, {"label": "Inline", "description": "Same-page section; non-disruptive, visible alongside content"}]}]</questions>
|
|
501
|
+
</needs_user>
|
|
502
|
+
Orchestrator: Extracts the JSON from <questions>, calls question tool:
|
|
503
|
+
question(questions: [{"question": "Should the config panel...", "header": "Config panel style", "options": [...]}])
|
|
504
|
+
After user picks "Inline": delegate_subagent(agent: "designer", continue_session_id: "abc123", ...) with "User answered: Inline."
|
|
505
|
+
<reasoning>User clarification flow: relay, don't substitute; resume same session.</reasoning>
|
|
506
|
+
</good_example>
|
|
507
|
+
</multi_agent_examples>
|
|
508
|
+
</oracle_model_and_variant_selection>
|
|
509
|
+
|
|
510
|
+
<cancellation>
|
|
511
|
+
- Stop immediately when task is cancelled or tool call is aborted.
|
|
512
|
+
- Report completed work and interrupted work.
|
|
513
|
+
- Do not launch new delegations after cancellation.
|
|
514
|
+
</cancellation>
|
|
515
|
+
|
|
516
|
+
<output_format>
|
|
517
|
+
When reporting final results to the user, use this structure:
|
|
518
|
+
<delegation_chain>
|
|
519
|
+
- agent: @agent_name (variant) → result summary
|
|
520
|
+
</delegation_chain>
|
|
521
|
+
<results>
|
|
522
|
+
- Synthesized answer to the user's request
|
|
523
|
+
</results>
|
|
524
|
+
<verification>
|
|
525
|
+
- Tests passed: [yes/no/skip]
|
|
526
|
+
- Validation: [passed/failed/skip]
|
|
527
|
+
</verification>
|
|
528
|
+
</output_format>
|
|
529
|
+
|
|
530
|
+
<communication>
|
|
531
|
+
- Lead with the answer, not the process (unless user asked for process).
|
|
532
|
+
- No preamble, no "Great question!", no "Certainly!".
|
|
533
|
+
- When @oracle flags a user approach as risky: relay @oracle's risk assessment, offer @oracle's safer alternative, then ask "Proceed with [original] or switch to [safer]?" Do not generate your own risk assessments — that is @oracle's job.
|
|
534
|
+
</communication>
|
|
535
|
+
|
|
536
|
+
${ORCHESTRATOR_CLARIFICATION_HANDOFF}
|
|
537
|
+
`;
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
export function createOrchestratorAgent(
|
|
541
|
+
model?: string | Array<string | { id: string; variant?: string }>,
|
|
542
|
+
customPrompt?: string,
|
|
543
|
+
customAppendPrompt?: string,
|
|
544
|
+
oracleDefaultModel?: string,
|
|
545
|
+
oracleSmartModel?: string,
|
|
546
|
+
): AgentDefinition {
|
|
547
|
+
const basePrompt = buildOrchestratorPrompt(
|
|
548
|
+
oracleDefaultModel,
|
|
549
|
+
oracleSmartModel,
|
|
550
|
+
);
|
|
551
|
+
const prompt = resolvePrompt(basePrompt, customPrompt, customAppendPrompt);
|
|
552
|
+
|
|
553
|
+
const definition: AgentDefinition = {
|
|
554
|
+
name: 'orchestrator',
|
|
555
|
+
description:
|
|
556
|
+
'AI coding orchestrator that delegates tasks to specialist agents for optimal quality, speed, and cost',
|
|
557
|
+
config: {
|
|
558
|
+
model: undefined,
|
|
559
|
+
variant: undefined,
|
|
560
|
+
temperature: 0.1,
|
|
561
|
+
prompt,
|
|
562
|
+
},
|
|
563
|
+
};
|
|
564
|
+
|
|
565
|
+
if (Array.isArray(model)) {
|
|
566
|
+
definition._modelArray = model.map((m) =>
|
|
567
|
+
typeof m === 'string' ? { id: m } : m,
|
|
568
|
+
);
|
|
569
|
+
} else if (typeof model === 'string' && model) {
|
|
570
|
+
definition.config.model = model;
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
return definition;
|
|
574
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import type { AgentConfig as SDKAgentConfig } from '@opencode-ai/sdk/v2';
|
|
2
|
+
import { getMcpPermissionsForAgent } from '../cli/mcps';
|
|
3
|
+
import { getSkillPermissionsForAgent } from '../cli/skills';
|
|
4
|
+
import type { AgentOverrideConfig, SkillOrMcpConfig } from '../config';
|
|
5
|
+
import type { AgentDefinition } from './orchestrator';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Apply user-provided overrides to an agent's configuration.
|
|
9
|
+
* Supports overriding model (string or priority array), variant, and temperature.
|
|
10
|
+
* When model is an array, stores it as _modelArray for runtime fallback resolution
|
|
11
|
+
* and clears config.model so OpenCode does not pre-resolve a stale value.
|
|
12
|
+
*/
|
|
13
|
+
export function applyOverrides(
|
|
14
|
+
agent: AgentDefinition,
|
|
15
|
+
override: AgentOverrideConfig,
|
|
16
|
+
): void {
|
|
17
|
+
if (override.model) {
|
|
18
|
+
if (Array.isArray(override.model)) {
|
|
19
|
+
agent._modelArray = override.model.map((m) =>
|
|
20
|
+
typeof m === 'string' ? { id: m } : m,
|
|
21
|
+
);
|
|
22
|
+
agent.config.model = undefined; // cleared; runtime hook resolves from _modelArray
|
|
23
|
+
} else {
|
|
24
|
+
agent.config.model = override.model;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
if (override.variant) agent.config.variant = override.variant;
|
|
28
|
+
if (override.temperature !== undefined)
|
|
29
|
+
agent.config.temperature = override.temperature;
|
|
30
|
+
if (override.options) {
|
|
31
|
+
agent.config.options = {
|
|
32
|
+
...agent.config.options,
|
|
33
|
+
...override.options,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
if (override.displayName) {
|
|
37
|
+
agent.displayName = override.displayName;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Apply default permissions to an agent.
|
|
43
|
+
* Sets 'question' permission to 'allow' and includes skill permission presets.
|
|
44
|
+
* If configuredSkills is provided, it honors that list instead of defaults.
|
|
45
|
+
*
|
|
46
|
+
* Note: If the agent already explicitly sets question to 'deny', that is
|
|
47
|
+
* respected (e.g., an agent may explicitly deny question permission).
|
|
48
|
+
*/
|
|
49
|
+
export async function applyDefaultPermissions(
|
|
50
|
+
agent: AgentDefinition,
|
|
51
|
+
configuredSkills?: SkillOrMcpConfig,
|
|
52
|
+
configuredMcps?: SkillOrMcpConfig,
|
|
53
|
+
): Promise<void> {
|
|
54
|
+
const existing = (agent.config.permission ?? {}) as Record<
|
|
55
|
+
string,
|
|
56
|
+
'ask' | 'allow' | 'deny' | Record<string, 'ask' | 'allow' | 'deny'>
|
|
57
|
+
>;
|
|
58
|
+
|
|
59
|
+
// Get skill-specific permissions for this agent
|
|
60
|
+
const skillPermissions = await getSkillPermissionsForAgent(
|
|
61
|
+
agent.name,
|
|
62
|
+
configuredSkills,
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
// Get MCP-specific permissions
|
|
66
|
+
const mcpPermissions = await getMcpPermissionsForAgent(
|
|
67
|
+
agent.name,
|
|
68
|
+
configuredMcps,
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
const questionPerm = existing.question === 'deny' ? 'deny' : 'allow';
|
|
72
|
+
|
|
73
|
+
// Orchestrator: block built-in Task tool (uses delegate_subagent instead)
|
|
74
|
+
const taskPerm = agent.name === 'orchestrator' ? 'deny' : undefined;
|
|
75
|
+
const editPerm = agent.name === 'orchestrator' ? 'deny' : undefined;
|
|
76
|
+
const writePerm = agent.name === 'orchestrator' ? 'deny' : undefined;
|
|
77
|
+
|
|
78
|
+
agent.config.permission = {
|
|
79
|
+
...existing,
|
|
80
|
+
question: questionPerm,
|
|
81
|
+
...(taskPerm ? { task: taskPerm } : {}),
|
|
82
|
+
...(editPerm ? { edit: editPerm } : {}),
|
|
83
|
+
...(writePerm ? { write: writePerm } : {}),
|
|
84
|
+
// Apply skill permissions as nested object under 'skill' key
|
|
85
|
+
skill: {
|
|
86
|
+
...(typeof existing.skill === 'object' ? existing.skill : {}),
|
|
87
|
+
...skillPermissions,
|
|
88
|
+
},
|
|
89
|
+
// Store MCP permissions for delegate tool consumption
|
|
90
|
+
mcp: {
|
|
91
|
+
...(typeof existing.mcp === 'object' ? existing.mcp : {}),
|
|
92
|
+
...mcpPermissions,
|
|
93
|
+
},
|
|
94
|
+
} as SDKAgentConfig['permission'];
|
|
95
|
+
}
|