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.
Files changed (302) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +452 -0
  3. package/dist/agents/descriptions.d.ts +6 -0
  4. package/dist/agents/designer.d.ts +2 -0
  5. package/dist/agents/explorer.d.ts +2 -0
  6. package/dist/agents/fixer.d.ts +2 -0
  7. package/dist/agents/index.d.ts +22 -0
  8. package/dist/agents/interpreter.d.ts +2 -0
  9. package/dist/agents/librarian.d.ts +2 -0
  10. package/dist/agents/oracle.d.ts +2 -0
  11. package/dist/agents/orchestrator.d.ts +27 -0
  12. package/dist/agents/overrides.d.ts +18 -0
  13. package/dist/agents/prompt-blocks.d.ts +97 -0
  14. package/dist/agents/steward.d.ts +3 -0
  15. package/dist/cli/config-io.d.ts +24 -0
  16. package/dist/cli/config-manager.d.ts +4 -0
  17. package/dist/cli/index.d.ts +2 -0
  18. package/dist/cli/index.js +1006 -0
  19. package/dist/cli/install.d.ts +2 -0
  20. package/dist/cli/mcps.d.ts +13 -0
  21. package/dist/cli/model-key-normalization.d.ts +1 -0
  22. package/dist/cli/paths.d.ts +35 -0
  23. package/dist/cli/providers.d.ts +137 -0
  24. package/dist/cli/skills.d.ts +22 -0
  25. package/dist/cli/system.d.ts +5 -0
  26. package/dist/cli/types.d.ts +38 -0
  27. package/dist/config/constants.d.ts +12 -0
  28. package/dist/config/index.d.ts +4 -0
  29. package/dist/config/loader.d.ts +40 -0
  30. package/dist/config/runtime-preset.d.ts +12 -0
  31. package/dist/config/schema.d.ts +281 -0
  32. package/dist/config/utils.d.ts +10 -0
  33. package/dist/discovery/local/types.d.ts +79 -0
  34. package/dist/discovery/local.d.ts +73 -0
  35. package/dist/discovery/mcp-servers.d.ts +88 -0
  36. package/dist/discovery/skills.d.ts +94 -0
  37. package/dist/hooks/apply-patch/codec.d.ts +7 -0
  38. package/dist/hooks/apply-patch/errors.d.ts +25 -0
  39. package/dist/hooks/apply-patch/execution-context.d.ts +27 -0
  40. package/dist/hooks/apply-patch/index.d.ts +15 -0
  41. package/dist/hooks/apply-patch/matching.d.ts +26 -0
  42. package/dist/hooks/apply-patch/operations.d.ts +3 -0
  43. package/dist/hooks/apply-patch/patch.d.ts +2 -0
  44. package/dist/hooks/apply-patch/prepared-changes.d.ts +17 -0
  45. package/dist/hooks/apply-patch/resolution.d.ts +19 -0
  46. package/dist/hooks/apply-patch/rewrite.d.ts +7 -0
  47. package/dist/hooks/apply-patch/test-helpers.d.ts +6 -0
  48. package/dist/hooks/apply-patch/types.d.ts +80 -0
  49. package/dist/hooks/auto-update-checker/cache.d.ts +11 -0
  50. package/dist/hooks/auto-update-checker/checker.d.ts +32 -0
  51. package/dist/hooks/auto-update-checker/constants.d.ts +11 -0
  52. package/dist/hooks/auto-update-checker/index.d.ts +18 -0
  53. package/dist/hooks/auto-update-checker/types.d.ts +22 -0
  54. package/dist/hooks/chat-headers.d.ts +16 -0
  55. package/dist/hooks/context-pressure-reminder/index.d.ts +33 -0
  56. package/dist/hooks/delegate-task-retry/guidance.d.ts +2 -0
  57. package/dist/hooks/delegate-task-retry/hook.d.ts +8 -0
  58. package/dist/hooks/delegate-task-retry/index.d.ts +4 -0
  59. package/dist/hooks/delegate-task-retry/patterns.d.ts +11 -0
  60. package/dist/hooks/filter-available-skills/index.d.ts +32 -0
  61. package/dist/hooks/foreground-fallback/index.d.ts +72 -0
  62. package/dist/hooks/image-hook.d.ts +5 -0
  63. package/dist/hooks/index.d.ts +14 -0
  64. package/dist/hooks/json-error-recovery/hook.d.ts +18 -0
  65. package/dist/hooks/json-error-recovery/index.d.ts +1 -0
  66. package/dist/hooks/phase-reminder/index.d.ts +26 -0
  67. package/dist/hooks/post-file-tool-nudge/index.d.ts +19 -0
  68. package/dist/hooks/task-session-manager/index.d.ts +52 -0
  69. package/dist/hooks/todo-continuation/index.d.ts +53 -0
  70. package/dist/hooks/todo-continuation/todo-hygiene.d.ts +35 -0
  71. package/dist/index.d.ts +5 -0
  72. package/dist/index.js +31782 -0
  73. package/dist/mcp/context7.d.ts +6 -0
  74. package/dist/mcp/grep-app.d.ts +6 -0
  75. package/dist/mcp/index.d.ts +13 -0
  76. package/dist/mcp/types.d.ts +12 -0
  77. package/dist/mcp/websearch.d.ts +9 -0
  78. package/dist/skills/registry.d.ts +29 -0
  79. package/dist/subscriptions/accounts-store.d.ts +57 -0
  80. package/dist/subscriptions/index.d.ts +13 -0
  81. package/dist/subscriptions/neuralwatt-scraper.d.ts +14 -0
  82. package/dist/subscriptions/opencode-go-scraper.d.ts +27 -0
  83. package/dist/subscriptions/types.d.ts +115 -0
  84. package/dist/subscriptions/usage-service.d.ts +74 -0
  85. package/dist/tools/ast-grep/cli.d.ts +15 -0
  86. package/dist/tools/ast-grep/constants.d.ts +25 -0
  87. package/dist/tools/ast-grep/downloader.d.ts +5 -0
  88. package/dist/tools/ast-grep/index.d.ts +10 -0
  89. package/dist/tools/ast-grep/tools.d.ts +3 -0
  90. package/dist/tools/ast-grep/types.d.ts +30 -0
  91. package/dist/tools/ast-grep/utils.d.ts +4 -0
  92. package/dist/tools/delegate.d.ts +14 -0
  93. package/dist/tools/index.d.ts +5 -0
  94. package/dist/tools/preset-manager.d.ts +27 -0
  95. package/dist/tools/smartfetch/binary.d.ts +3 -0
  96. package/dist/tools/smartfetch/cache.d.ts +6 -0
  97. package/dist/tools/smartfetch/constants.d.ts +12 -0
  98. package/dist/tools/smartfetch/index.d.ts +3 -0
  99. package/dist/tools/smartfetch/network.d.ts +38 -0
  100. package/dist/tools/smartfetch/secondary-model.d.ts +28 -0
  101. package/dist/tools/smartfetch/tool.d.ts +3 -0
  102. package/dist/tools/smartfetch/types.d.ts +122 -0
  103. package/dist/tools/smartfetch/utils.d.ts +18 -0
  104. package/dist/tui-state.d.ts +168 -0
  105. package/dist/tui.d.ts +37 -0
  106. package/dist/tui.js +1896 -0
  107. package/dist/utils/agent-variant.d.ts +63 -0
  108. package/dist/utils/compat.d.ts +30 -0
  109. package/dist/utils/env.d.ts +1 -0
  110. package/dist/utils/index.d.ts +9 -0
  111. package/dist/utils/internal-initiator.d.ts +6 -0
  112. package/dist/utils/logger.d.ts +8 -0
  113. package/dist/utils/polling.d.ts +21 -0
  114. package/dist/utils/session-manager.d.ts +55 -0
  115. package/dist/utils/session.d.ts +90 -0
  116. package/dist/utils/subagent-depth.d.ts +35 -0
  117. package/dist/utils/system-collapse.d.ts +6 -0
  118. package/dist/utils/task.d.ts +4 -0
  119. package/dist/utils/zip-extractor.d.ts +1 -0
  120. package/index.ts +1 -0
  121. package/opencode-dux.schema.json +634 -0
  122. package/package.json +103 -0
  123. package/src/agents/descriptions.ts +55 -0
  124. package/src/agents/designer.test.ts +86 -0
  125. package/src/agents/designer.ts +154 -0
  126. package/src/agents/display-name.test.ts +186 -0
  127. package/src/agents/explorer.test.ts +79 -0
  128. package/src/agents/explorer.ts +144 -0
  129. package/src/agents/fixer.test.ts +79 -0
  130. package/src/agents/fixer.ts +145 -0
  131. package/src/agents/index.test.ts +472 -0
  132. package/src/agents/index.ts +248 -0
  133. package/src/agents/interpreter.ts +136 -0
  134. package/src/agents/librarian.test.ts +80 -0
  135. package/src/agents/librarian.ts +145 -0
  136. package/src/agents/oracle.test.ts +89 -0
  137. package/src/agents/oracle.ts +184 -0
  138. package/src/agents/orchestrator.test.ts +116 -0
  139. package/src/agents/orchestrator.ts +574 -0
  140. package/src/agents/overrides.ts +95 -0
  141. package/src/agents/prompt-blocks.test.ts +114 -0
  142. package/src/agents/prompt-blocks.ts +640 -0
  143. package/src/agents/steward.ts +146 -0
  144. package/src/cli/config-io.test.ts +536 -0
  145. package/src/cli/config-io.ts +473 -0
  146. package/src/cli/config-manager.test.ts +141 -0
  147. package/src/cli/config-manager.ts +4 -0
  148. package/src/cli/index.ts +88 -0
  149. package/src/cli/install.ts +282 -0
  150. package/src/cli/mcps.test.ts +62 -0
  151. package/src/cli/mcps.ts +39 -0
  152. package/src/cli/model-key-normalization.test.ts +21 -0
  153. package/src/cli/model-key-normalization.ts +60 -0
  154. package/src/cli/paths.test.ts +167 -0
  155. package/src/cli/paths.ts +144 -0
  156. package/src/cli/providers.test.ts +118 -0
  157. package/src/cli/providers.ts +141 -0
  158. package/src/cli/skills.test.ts +111 -0
  159. package/src/cli/skills.ts +103 -0
  160. package/src/cli/system.test.ts +91 -0
  161. package/src/cli/system.ts +180 -0
  162. package/src/cli/types.ts +43 -0
  163. package/src/config/constants.ts +58 -0
  164. package/src/config/index.ts +4 -0
  165. package/src/config/loader.test.ts +1194 -0
  166. package/src/config/loader.ts +269 -0
  167. package/src/config/model-resolution.test.ts +176 -0
  168. package/src/config/runtime-preset.test.ts +61 -0
  169. package/src/config/runtime-preset.ts +37 -0
  170. package/src/config/schema.ts +248 -0
  171. package/src/config/utils.test.ts +41 -0
  172. package/src/config/utils.ts +23 -0
  173. package/src/discovery/local/types.ts +85 -0
  174. package/src/discovery/local.ts +322 -0
  175. package/src/discovery/mcp-servers.ts +804 -0
  176. package/src/discovery/skills.ts +959 -0
  177. package/src/hooks/apply-patch/codec.test.ts +184 -0
  178. package/src/hooks/apply-patch/codec.ts +352 -0
  179. package/src/hooks/apply-patch/errors.ts +117 -0
  180. package/src/hooks/apply-patch/execution-context.ts +432 -0
  181. package/src/hooks/apply-patch/hook.test.ts +768 -0
  182. package/src/hooks/apply-patch/index.ts +126 -0
  183. package/src/hooks/apply-patch/matching.test.ts +215 -0
  184. package/src/hooks/apply-patch/matching.ts +586 -0
  185. package/src/hooks/apply-patch/operations.test.ts +1535 -0
  186. package/src/hooks/apply-patch/operations.ts +3 -0
  187. package/src/hooks/apply-patch/patch.ts +9 -0
  188. package/src/hooks/apply-patch/prepared-changes.ts +400 -0
  189. package/src/hooks/apply-patch/resolution.test.ts +420 -0
  190. package/src/hooks/apply-patch/resolution.ts +437 -0
  191. package/src/hooks/apply-patch/rewrite.ts +496 -0
  192. package/src/hooks/apply-patch/test-helpers.ts +52 -0
  193. package/src/hooks/apply-patch/types.ts +111 -0
  194. package/src/hooks/auto-update-checker/cache.test.ts +179 -0
  195. package/src/hooks/auto-update-checker/cache.ts +188 -0
  196. package/src/hooks/auto-update-checker/checker.test.ts +159 -0
  197. package/src/hooks/auto-update-checker/checker.ts +308 -0
  198. package/src/hooks/auto-update-checker/constants.ts +33 -0
  199. package/src/hooks/auto-update-checker/index.test.ts +282 -0
  200. package/src/hooks/auto-update-checker/index.ts +225 -0
  201. package/src/hooks/auto-update-checker/types.ts +26 -0
  202. package/src/hooks/chat-headers.test.ts +236 -0
  203. package/src/hooks/chat-headers.ts +97 -0
  204. package/src/hooks/context-pressure-reminder/index.test.ts +179 -0
  205. package/src/hooks/context-pressure-reminder/index.ts +137 -0
  206. package/src/hooks/delegate-task-retry/guidance.ts +41 -0
  207. package/src/hooks/delegate-task-retry/hook.ts +23 -0
  208. package/src/hooks/delegate-task-retry/index.test.ts +38 -0
  209. package/src/hooks/delegate-task-retry/index.ts +7 -0
  210. package/src/hooks/delegate-task-retry/patterns.ts +79 -0
  211. package/src/hooks/filter-available-skills/index.test.ts +297 -0
  212. package/src/hooks/filter-available-skills/index.ts +160 -0
  213. package/src/hooks/foreground-fallback/index.test.ts +624 -0
  214. package/src/hooks/foreground-fallback/index.ts +374 -0
  215. package/src/hooks/image-hook.ts +6 -0
  216. package/src/hooks/index.ts +17 -0
  217. package/src/hooks/json-error-recovery/hook.ts +73 -0
  218. package/src/hooks/json-error-recovery/index.test.ts +111 -0
  219. package/src/hooks/json-error-recovery/index.ts +6 -0
  220. package/src/hooks/phase-reminder/index.test.ts +74 -0
  221. package/src/hooks/phase-reminder/index.ts +85 -0
  222. package/src/hooks/post-file-tool-nudge/index.test.ts +94 -0
  223. package/src/hooks/post-file-tool-nudge/index.ts +63 -0
  224. package/src/hooks/task-session-manager/index.test.ts +833 -0
  225. package/src/hooks/task-session-manager/index.ts +434 -0
  226. package/src/hooks/todo-continuation/index.test.ts +3026 -0
  227. package/src/hooks/todo-continuation/index.ts +878 -0
  228. package/src/hooks/todo-continuation/todo-hygiene.test.ts +204 -0
  229. package/src/hooks/todo-continuation/todo-hygiene.ts +207 -0
  230. package/src/index.ts +1672 -0
  231. package/src/mcp/context7.ts +14 -0
  232. package/src/mcp/grep-app.ts +11 -0
  233. package/src/mcp/index.test.ts +96 -0
  234. package/src/mcp/index.ts +66 -0
  235. package/src/mcp/types.ts +16 -0
  236. package/src/mcp/websearch.ts +47 -0
  237. package/src/skills/codemap/README.md +60 -0
  238. package/src/skills/codemap/SKILL.md +174 -0
  239. package/src/skills/codemap/scripts/codemap.mjs +483 -0
  240. package/src/skills/codemap/scripts/codemap.test.ts +129 -0
  241. package/src/skills/registry.ts +218 -0
  242. package/src/skills/simplify/README.md +19 -0
  243. package/src/skills/simplify/SKILL.md +138 -0
  244. package/src/subscriptions/accounts-store.test.ts +236 -0
  245. package/src/subscriptions/accounts-store.ts +184 -0
  246. package/src/subscriptions/index.ts +30 -0
  247. package/src/subscriptions/neuralwatt-scraper.ts +108 -0
  248. package/src/subscriptions/opencode-go-scraper.ts +301 -0
  249. package/src/subscriptions/types.ts +145 -0
  250. package/src/subscriptions/usage-service.test.ts +202 -0
  251. package/src/subscriptions/usage-service.ts +651 -0
  252. package/src/tools/ast-grep/cli.ts +257 -0
  253. package/src/tools/ast-grep/constants.ts +214 -0
  254. package/src/tools/ast-grep/downloader.ts +131 -0
  255. package/src/tools/ast-grep/index.ts +24 -0
  256. package/src/tools/ast-grep/tools.ts +117 -0
  257. package/src/tools/ast-grep/types.ts +51 -0
  258. package/src/tools/ast-grep/utils.ts +126 -0
  259. package/src/tools/delegate-handoff.test.ts +18 -0
  260. package/src/tools/delegate.ts +508 -0
  261. package/src/tools/index.ts +8 -0
  262. package/src/tools/preset-manager.test.ts +795 -0
  263. package/src/tools/preset-manager.ts +332 -0
  264. package/src/tools/smartfetch/binary.ts +58 -0
  265. package/src/tools/smartfetch/cache.test.ts +34 -0
  266. package/src/tools/smartfetch/cache.ts +112 -0
  267. package/src/tools/smartfetch/constants.ts +29 -0
  268. package/src/tools/smartfetch/index.ts +8 -0
  269. package/src/tools/smartfetch/network.test.ts +178 -0
  270. package/src/tools/smartfetch/network.ts +614 -0
  271. package/src/tools/smartfetch/secondary-model.test.ts +85 -0
  272. package/src/tools/smartfetch/secondary-model.ts +276 -0
  273. package/src/tools/smartfetch/tool.test.ts +60 -0
  274. package/src/tools/smartfetch/tool.ts +832 -0
  275. package/src/tools/smartfetch/types.ts +135 -0
  276. package/src/tools/smartfetch/utils.test.ts +24 -0
  277. package/src/tools/smartfetch/utils.ts +456 -0
  278. package/src/tui-state.test.ts +867 -0
  279. package/src/tui-state.ts +1255 -0
  280. package/src/tui.test.ts +336 -0
  281. package/src/tui.ts +1539 -0
  282. package/src/utils/agent-variant.test.ts +244 -0
  283. package/src/utils/agent-variant.ts +187 -0
  284. package/src/utils/compat.ts +91 -0
  285. package/src/utils/env.ts +12 -0
  286. package/src/utils/index.ts +9 -0
  287. package/src/utils/internal-initiator.ts +28 -0
  288. package/src/utils/logger.test.ts +220 -0
  289. package/src/utils/logger.ts +136 -0
  290. package/src/utils/polling.test.ts +191 -0
  291. package/src/utils/polling.ts +67 -0
  292. package/src/utils/session-manager.test.ts +173 -0
  293. package/src/utils/session-manager.ts +356 -0
  294. package/src/utils/session.test.ts +110 -0
  295. package/src/utils/session.ts +389 -0
  296. package/src/utils/subagent-depth.test.ts +170 -0
  297. package/src/utils/subagent-depth.ts +75 -0
  298. package/src/utils/system-collapse.test.ts +86 -0
  299. package/src/utils/system-collapse.ts +24 -0
  300. package/src/utils/task.test.ts +24 -0
  301. package/src/utils/task.ts +20 -0
  302. package/src/utils/zip-extractor.ts +102 -0
@@ -0,0 +1,184 @@
1
+ import type { AgentDefinition } from './orchestrator';
2
+ import { resolvePrompt } from './orchestrator';
3
+ import {
4
+ formatBlockedOutputBlock,
5
+ formatOracleAgentVariantPolicyXml,
6
+ NEEDS_USER_OUTPUT_FORMAT_BLOCK,
7
+ ORACLE_MODEL_TIER_BLOCK,
8
+ ORACLE_PLAN_HANDOFF_BLOCK,
9
+ REPO_RULES_PRECEDENCE_BLOCK,
10
+ SELF_REVIEW_BLOCK,
11
+ SUBAGENT_NEEDS_USER_FORMAT,
12
+ USER_CHOICE_POLICY_BLOCK,
13
+ } from './prompt-blocks';
14
+
15
+ const ORACLE_CRITICAL_INVARIANTS = `<critical_invariants>
16
+ Violating any = failure mode.
17
+ 1) NEVER implement changes - read-only analysis only.
18
+ 2) ALWAYS include <confidence> with explicit assumptions.
19
+ 3) NEVER skip <risks> section for high/max variants.
20
+ 4) NEVER modify files or delegate to subagents.
21
+ </critical_invariants>`;
22
+
23
+ const ORACLE_PROMPT = `<role>
24
+ You are Oracle, a strategic technical advisor and code reviewer focused on high-leverage analysis.
25
+ </role>
26
+
27
+ ${ORACLE_CRITICAL_INVARIANTS}
28
+
29
+ ${REPO_RULES_PRECEDENCE_BLOCK}
30
+
31
+ <production_safety_gate>
32
+ Before implementing any optimization, refactoring, or "improvement" to agent
33
+ prompts or system behavior, verify ALL of the following:
34
+
35
+ 1. **Security**: No security implications (auth, data integrity, privilege
36
+ escalation, input validation, secret handling)
37
+ 2. **Correctness**: Current behavior is demonstrably broken or produces wrong
38
+ outputs (not just "could be cleaner")
39
+ 3. **User Impact**: Change affects internal implementation only - no breaking
40
+ changes to user-facing behavior without explicit approval
41
+ 4. **Test Coverage**: Existing tests cover the affected area AND will catch
42
+ regressions
43
+ 5. **Rollback Plan**: Change can be reverted in a single commit if issues arise
44
+
45
+ **If ANY check fails**: Do NOT implement. Flag for human review instead.
46
+
47
+ **Philosophy**: "If it's good enough for production, leave it alone." Only fix
48
+ what's actually broken, not what could theoretically be cleaner.
49
+ </production_safety_gate>
50
+
51
+ <capabilities>
52
+ - root-cause debugging
53
+ - architecture tradeoff analysis
54
+ - correctness, performance, and maintainability review
55
+ - simplification and YAGNI guidance
56
+ </capabilities>
57
+
58
+ <tool_routing>
59
+ | Need | Tool | Constraint |
60
+ |------|------|------------|
61
+ | Current repo state | read, grep, ast_grep_search | Verify claims against actual code |
62
+ | External API behavior | Context7, webfetch (confirming) | Use librarian-supplied citations; if none provided, note in <blocked> |
63
+ | Best practices / how-to | Context7, websearch | Synthesize from authoritative sources only |
64
+ | Version-specific details | Context7 with version param, GitHub releases | Always label version in output |
65
+ </tool_routing>
66
+
67
+ ${ORACLE_MODEL_TIER_BLOCK}
68
+
69
+ <workflow>
70
+ 1) Review the orchestrator-provided context (paths, symbols, snippets, steward citations).
71
+ 2) Verify critical claims against current repo state using read/search tools when needed.
72
+ 3) Analyze at the depth dictated by variant - surface root cause, tradeoffs, and risks.
73
+ 4) Produce structured output with actionable next steps and explicit confidence levels.
74
+ When the orchestrator delegates for pre-implementation planning, include a
75
+ \`<plan>\` section with ordered steps, file targets, and verification gates -
76
+ structured for user review before @fixer runs.
77
+ </workflow>
78
+
79
+ ${ORACLE_PLAN_HANDOFF_BLOCK}
80
+
81
+ <analysis_recovery>
82
+ If your analysis is blocked by missing external knowledge, return <blocked>
83
+ with exact research needs (which libraries, versions, or APIs need investigation).
84
+ If blocked by ambiguous context, use <needs_user> with specific clarification
85
+ questions. Never guess or hallucinate external API behavior.
86
+ </analysis_recovery>
87
+
88
+ <constraints>
89
+ - NEVER return vague recommendations without decision criteria.
90
+ - NEVER skip risk assessment for high or max variants.
91
+ - NEVER ignore provided file paths and symbols.
92
+ </constraints>
93
+
94
+ ${USER_CHOICE_POLICY_BLOCK}
95
+ <oracle_choice_supplement>
96
+ - Prioritization forks (ship speed vs depth vs cost vs risk appetite) when tradeoffs are balanced: <needs_user>-each option \`description\` says what the user optimizes for and what they give up.
97
+ - Scope / product semantics (who the feature is for, failure tolerance, SLO) when analysis hinges on it: <needs_user> before locking a recommendation.
98
+ </oracle_choice_supplement>
99
+
100
+ ${formatOracleAgentVariantPolicyXml()}
101
+
102
+ ${SUBAGENT_NEEDS_USER_FORMAT}
103
+
104
+ ${SELF_REVIEW_BLOCK}
105
+
106
+ <output_format>
107
+ If the caller explicitly requests concise output (e.g., prompt includes "briefly", "concise", "short", or "tl;dr"), keep section headers but compress each section to 1-2 bullets.
108
+ <diagnosis>
109
+ Root cause or decision context.
110
+ </diagnosis>
111
+ <plan>
112
+ Include when orchestrator delegates for pre-implementation planning:
113
+ - Ordered implementation steps
114
+ - File targets
115
+ - Verification gates
116
+ - Tradeoffs between viable approaches
117
+ </plan>
118
+ <recommendation>
119
+ Primary recommendation with why.
120
+ </recommendation>
121
+ <tradeoffs>
122
+ - option A vs option B tradeoff bullets
123
+ </tradeoffs>
124
+ <risks>
125
+ - concrete risks and severity
126
+ </risks>
127
+ <confidence>
128
+ - overall confidence: [high/medium/low]
129
+ - confidence by key claim: [claim -> level]
130
+ - explicit assumptions made due to missing context
131
+ </confidence>
132
+ <action_items>
133
+ - explicit next steps with file paths where possible
134
+ </action_items>
135
+ ${formatBlockedOutputBlock('analysis cannot be completed due to missing information or tools')}
136
+ ${NEEDS_USER_OUTPUT_FORMAT_BLOCK}
137
+
138
+ Batch every scope/priority/risk choice in one <needs_user> handoff.
139
+
140
+ <good_example>
141
+ <needs_user>
142
+ <reason>Tradeoff between speed and safety requires user priority call.</reason>
143
+ <questions>[{"question": "Which optimization target takes priority?", "header": "Optimization target", "options": [{"label": "Speed", "description": "Faster execution, less validation-risk of edge-case failures"}, {"label": "Safety", "description": "Comprehensive validation, slower-guarantees correctness"}]}]</questions>
144
+ </needs_user>
145
+ </good_example>
146
+ </output_format>
147
+
148
+ <good_example>
149
+ Issue: flaky queue retries.
150
+ Response: identifies race between backoff timer and ack write, recommends idempotent ack token, lists migration risk, proposes stepwise rollout and test targets.
151
+ <reasoning>High variant response should explain root cause and include actionable risk-aware steps.</reasoning>
152
+ </good_example>
153
+
154
+ <bad_example>
155
+ Issue: flaky queue retries.
156
+ Response:
157
+ <diagnosis>Queue is flaky.</diagnosis>
158
+ <recommendation>Increase timeout and maybe refactor retry logic.</recommendation>
159
+ <tradeoffs>- not provided</tradeoffs>
160
+ <risks>- not provided</risks>
161
+ <confidence>- not provided</confidence>
162
+ <action_items>- not provided</action_items>
163
+ <reasoning>Still vague and unusable: no root cause, no decision criteria, no quantified confidence, and no concrete next steps.</reasoning>
164
+ </bad_example>`;
165
+
166
+ export function createOracleAgent(
167
+ model: string,
168
+ customPrompt?: string,
169
+ customAppendPrompt?: string,
170
+ ): AgentDefinition {
171
+ const prompt = resolvePrompt(ORACLE_PROMPT, customPrompt, customAppendPrompt);
172
+
173
+ return {
174
+ name: 'oracle',
175
+ description:
176
+ 'Strategic technical advisor. Use for architecture decisions, complex debugging, code review, simplification, and engineering guidance.',
177
+ config: {
178
+ model,
179
+ // 0.15 provides enough structure for analytical reasoning while allowing slight flexibility for nuanced tradeoff evaluation
180
+ temperature: 0.15,
181
+ prompt,
182
+ },
183
+ };
184
+ }
@@ -0,0 +1,116 @@
1
+ import { describe, expect, test } from 'bun:test';
2
+ import { buildOrchestratorPrompt, resolvePrompt } from './orchestrator';
3
+
4
+ describe('resolvePrompt', () => {
5
+ test('returns base when neither custom nor append provided', () => {
6
+ const result = resolvePrompt('BASE PROMPT');
7
+ expect(result).toBe('BASE PROMPT');
8
+ });
9
+
10
+ test('custom prompt replaces base entirely', () => {
11
+ const result = resolvePrompt('BASE', 'CUSTOM');
12
+ expect(result).toBe('CUSTOM');
13
+ });
14
+
15
+ test('append prompt is appended to base', () => {
16
+ const result = resolvePrompt('BASE', undefined, 'APPEND');
17
+ expect(result).toBe('BASE\n\nAPPEND');
18
+ });
19
+
20
+ test('custom prompt wins over append (both provided)', () => {
21
+ const result = resolvePrompt('BASE', 'CUSTOM', 'APPEND');
22
+ expect(result).toBe('CUSTOM');
23
+ });
24
+
25
+ test('empty string custom prompt replaces base with empty', () => {
26
+ const result = resolvePrompt('BASE', '');
27
+ expect(result).toBe('');
28
+ });
29
+
30
+ test('empty string append adds extra newline', () => {
31
+ const result = resolvePrompt('BASE', undefined, '');
32
+ expect(result).toBe('BASE\n\n');
33
+ });
34
+
35
+ test('base is undefined', () => {
36
+ const result = resolvePrompt(undefined as unknown as string, 'CUSTOM');
37
+ expect(result).toBe('CUSTOM');
38
+ });
39
+ });
40
+
41
+ describe('buildOrchestratorPrompt', () => {
42
+ test('includes all agent descriptions when no agents disabled', () => {
43
+ const prompt = buildOrchestratorPrompt();
44
+ expect(prompt).toContain('@explorer');
45
+ expect(prompt).toContain('@librarian');
46
+ expect(prompt).toContain('@oracle');
47
+ expect(prompt).toContain('@designer');
48
+ expect(prompt).toContain('@fixer');
49
+ expect(prompt).toContain('@steward');
50
+ expect(prompt).toContain('@interpreter');
51
+ });
52
+
53
+ test('includes routing priority, question tool, oracle matrix, steward/interpreter', () => {
54
+ const prompt = buildOrchestratorPrompt();
55
+ expect(prompt).toContain('<routing_priority>');
56
+ expect(prompt).toContain('<first_gate>');
57
+ expect(prompt).toContain('delegate_subagent(agent: "steward"');
58
+ expect(prompt).toContain('delegate_subagent(agent: "designer"');
59
+ expect(prompt).toContain('<orchestrator_clarification>');
60
+ expect(prompt).toContain('<needs_user>');
61
+ expect(prompt).toContain('`question`');
62
+ expect(prompt).toContain('continue_session_id');
63
+ expect(prompt).toContain('Nine invariants');
64
+ expect(prompt).toContain('NEVER use default (flash) + low');
65
+ expect(prompt).toContain('<steward_protocol>');
66
+ expect(prompt).toContain('<interpreter_protocol>');
67
+ });
68
+
69
+ test('includes critical_invariants and procedural_invariants blocks', () => {
70
+ const prompt = buildOrchestratorPrompt();
71
+ expect(prompt).toContain('<critical_invariants>');
72
+ expect(prompt).toContain('<procedural_invariants>');
73
+ expect(prompt).toContain('NEVER edit, write, read');
74
+ expect(prompt).toContain('Report verification before declaring success');
75
+ });
76
+
77
+ test('includes planning_gate block', () => {
78
+ const prompt = buildOrchestratorPrompt();
79
+ expect(prompt).toContain('<planning_gate>');
80
+ expect(prompt).toContain('1) ANALYSIS');
81
+ expect(prompt).toContain('4) IMPLEMENT');
82
+ expect(prompt).toContain('Skip this gate ONLY when');
83
+ });
84
+
85
+ test('context_budget is near the start of the prompt (after <role>)', () => {
86
+ const prompt = buildOrchestratorPrompt();
87
+ const roleIndex = prompt.indexOf('<role>');
88
+ const contextBudgetIndex = prompt.indexOf('<context_budget>');
89
+ const criticalInvariantsIndex = prompt.indexOf('<critical_invariants>');
90
+ expect(contextBudgetIndex).toBeGreaterThan(roleIndex);
91
+ expect(contextBudgetIndex).toBeLessThan(criticalInvariantsIndex);
92
+ });
93
+
94
+ test('first_gate analysis gate references oracle when oracle enabled', () => {
95
+ const prompt = buildOrchestratorPrompt();
96
+ expect(prompt).toContain('Analysis: blocking @oracle');
97
+ expect(prompt).not.toContain('Analysis gate (@oracle / thinker)');
98
+ });
99
+
100
+ test('injects oracle model names when provided', () => {
101
+ const prompt = buildOrchestratorPrompt(
102
+ 'openai/gpt-5.5',
103
+ 'openai/gpt-5.5-pro',
104
+ );
105
+ expect(prompt).toContain('openai/gpt-5.5-pro');
106
+ expect(prompt).toContain('openai/gpt-5.5');
107
+ expect(prompt).not.toContain('{{ORACLE_DEFAULT_MODEL}}');
108
+ expect(prompt).not.toContain('{{ORACLE_SMART_MODEL_OR_FALLBACK}}');
109
+ });
110
+
111
+ test('empty model names do not break prompt', () => {
112
+ const prompt = buildOrchestratorPrompt('', '');
113
+ // Should still produce valid prompt without template placeholders
114
+ expect(prompt).not.toContain('{{');
115
+ });
116
+ });